diff --git a/app/components/admin/stats/budget_supporting_component.html.erb b/app/components/admin/stats/budget_supporting_component.html.erb new file mode 100644 index 000000000..2d74625d9 --- /dev/null +++ b/app/components/admin/stats/budget_supporting_component.html.erb @@ -0,0 +1,55 @@ +<% content_for :head do %> + <%= javascript_include_tag "stat_graphs", "data-turbolinks-track" => "reload" %> +<% end %> + +<%= back_link_to budgets_admin_stats_path %> + +

<%= budget.name %> - <%= t("admin.stats.budget_supporting.title") %>

+ +
+
+
+ +
+ +
+

+ <%= t("admin.stats.budget_supporting.participant_count") %> +
+ + <%= user_count %> + +

+
+
+
+ +<%= render "admin/stats/graph", name: "user_supported_budgets", event: "", count: user_count %> + + + + + + + + + + + <% user_count_by_heading.each do |heading, count| %> + + + + + <% end %> + +
<%= t("admin.stats.budget_supporting.headings") %><%= t("admin.stats.budget_supporting.users") %>
+ <%= heading.name %> + + <%= number_with_delimiter count %> +
diff --git a/app/components/admin/stats/budget_supporting_component.rb b/app/components/admin/stats/budget_supporting_component.rb new file mode 100644 index 000000000..5dde0b4af --- /dev/null +++ b/app/components/admin/stats/budget_supporting_component.rb @@ -0,0 +1,36 @@ +class Admin::Stats::BudgetSupportingComponent < ApplicationComponent + attr_reader :budget + + def initialize(budget) + @budget = budget + end + + private + + def votes + Vote.where(votable_type: "Budget::Investment") + .includes(:budget_investment) + .where(budget_investments: { heading_id: budget.heading_ids }) + end + + def vote_count + votes.count + end + + def user_count + votes.select(:voter_id).distinct.count + end + + def user_count_by_heading + budget.headings.map do |heading| + [heading, voters_in_heading(heading)] + end + end + + def voters_in_heading(heading) + Vote.where(votable_type: "Budget::Investment") + .includes(:budget_investment) + .where(budget_investments: { heading_id: heading.id }) + .select("votes.voter_id").distinct.count + end +end diff --git a/app/controllers/admin/stats_controller.rb b/app/controllers/admin/stats_controller.rb index 8634788a8..fc4377a1d 100644 --- a/app/controllers/admin/stats_controller.rb +++ b/app/controllers/admin/stats_controller.rb @@ -56,19 +56,6 @@ class Admin::StatsController < Admin::BaseController def budget_supporting @budget = Budget.find(params[:budget_id]) - heading_ids = @budget.heading_ids - - votes = Vote.where(votable_type: "Budget::Investment"). - includes(:budget_investment). - where(budget_investments: { heading_id: heading_ids }) - - @vote_count = votes.count - @user_count = votes.select(:voter_id).distinct.count - - @voters_in_heading = {} - @budget.headings.each do |heading| - @voters_in_heading[heading] = voters_in_heading(heading) - end end def budget_balloting @@ -85,13 +72,4 @@ class Admin::StatsController < Admin::BaseController def sdg @goals = SDG::Goal.order(:code) end - - private - - def voters_in_heading(heading) - Vote.where(votable_type: "Budget::Investment"). - includes(:budget_investment). - where(budget_investments: { heading_id: heading.id }). - select("votes.voter_id").distinct.count - end end diff --git a/app/views/admin/stats/budget_supporting.html.erb b/app/views/admin/stats/budget_supporting.html.erb index 8affe4cd2..aa165ee19 100644 --- a/app/views/admin/stats/budget_supporting.html.erb +++ b/app/views/admin/stats/budget_supporting.html.erb @@ -1,55 +1 @@ -<% content_for :head do %> - <%= javascript_include_tag "stat_graphs", "data-turbolinks-track" => "reload" %> -<% end %> - -<%= back_link_to budgets_admin_stats_path %> - -

<%= @budget.name %> - <%= t("admin.stats.budget_supporting.title") %>

- -
-
-
- -
- -
-

- <%= t("admin.stats.budget_supporting.participant_count") %> -
- - <%= @user_count %> - -

-
-
-
- -<%= render "graph", name: "user_supported_budgets", event: "", count: @user_count %> - - - - - - - - - - - <% @voters_in_heading.each do |heading, count| %> - - - - - <% end %> - -
<%= t("admin.stats.budget_supporting.headings") %><%= t("admin.stats.budget_supporting.users") %>
- <%= heading.name %> - - <%= number_with_delimiter count %> -
+<%= render Admin::Stats::BudgetSupportingComponent.new(@budget) %> diff --git a/spec/components/admin/stats/budget_supporting_component_spec.rb b/spec/components/admin/stats/budget_supporting_component_spec.rb new file mode 100644 index 000000000..0fefa4f98 --- /dev/null +++ b/spec/components/admin/stats/budget_supporting_component_spec.rb @@ -0,0 +1,51 @@ +require "rails_helper" + +describe Admin::Stats::BudgetSupportingComponent do + let(:budget) { create(:budget, :balloting) } + let(:heading) { create(:budget_heading, budget: budget, name: "Main heading") } + let(:investment) { create(:budget_investment, :feasible, :selected, heading: heading) } + + it "shows the number of supports in investment projects" do + another_heading = create(:budget_heading, budget: budget) + another_investment = create(:budget_investment, heading: another_heading) + + create(:user, :level_two, votables: [investment, another_investment]) + create(:user, :level_two, votables: [investment]) + create(:user, :level_two) + + render_inline Admin::Stats::BudgetSupportingComponent.new(budget) + + expect(page).to have_css "p", exact_text: "Votes 3", normalize_ws: true + end + + it "shows the number of users that have supported an investment project" do + another_heading = create(:budget_heading, budget: budget) + another_investment = create(:budget_investment, heading: another_heading) + + create(:user, :level_two, votables: [investment, another_investment]) + create(:user, :level_two, votables: [investment]) + create(:user, :level_two) + + render_inline Admin::Stats::BudgetSupportingComponent.new(budget) + + expect(page).to have_css "p", exact_text: "Participants 2", normalize_ws: true + end + + it "shows the number of users that have supported investments projects per heading" do + group_districts = create(:budget_group, budget: budget) + north_district = create(:budget_heading, group: group_districts, name: "North district") + create(:budget_heading, group: group_districts, name: "South district") + + create(:budget_investment, heading: heading, voters: [create(:user)]) + create(:budget_investment, heading: north_district, voters: [create(:user)]) + create(:budget_investment, heading: north_district, voters: [create(:user)]) + + render_inline Admin::Stats::BudgetSupportingComponent.new(budget) + + page.find ".user-count-by-heading tbody" do |table_body| + expect(table_body).to have_css "tr", exact_text: "Main heading 1", normalize_ws: true + expect(table_body).to have_css "tr", exact_text: "North district 2", normalize_ws: true + expect(table_body).to have_css "tr", exact_text: "South district 0", normalize_ws: true + end + end +end diff --git a/spec/system/admin/stats_spec.rb b/spec/system/admin/stats_spec.rb index 62f11d3a2..5bde3e8c0 100644 --- a/spec/system/admin/stats_spec.rb +++ b/spec/system/admin/stats_spec.rb @@ -91,23 +91,7 @@ describe "Stats", :admin do let(:budget) { create(:budget) } let(:heading_all_city) { create(:budget_heading, budget: budget) } - scenario "Number of supports in investment projects" do - group_2 = create(:budget_group, budget: budget) - - create(:budget_investment, heading: create(:budget_heading, group: group_2), voters: [create(:user)]) - create(:budget_investment, heading: heading_all_city, voters: [create(:user), create(:user)]) - - visit admin_stats_path - click_link "Participatory Budgets" - within("#budget_#{budget.id}") do - click_link "Supporting phase" - end - - expect(page).to have_content "VOTES\n3" - expect(page).to have_link "Go back", count: 1 - end - - scenario "Number of users that have supported an investment project" do + scenario "Number of users and supports in investment projects" do group_2 = create(:budget_group, budget: budget) investment1 = create(:budget_investment, heading: create(:budget_heading, group: group_2)) investment2 = create(:budget_investment, heading: heading_all_city) @@ -122,43 +106,9 @@ describe "Stats", :admin do click_link "Supporting phase" end + expect(page).to have_content "VOTES\n3" expect(page).to have_content "PARTICIPANTS\n2" - end - - scenario "Number of users that have supported investments projects per geozone" do - budget = create(:budget) - - group_all_city = create(:budget_group, budget: budget) - group_districts = create(:budget_group, budget: budget) - - all_city = create(:budget_heading, group: group_all_city) - carabanchel = create(:budget_heading, group: group_districts) - barajas = create(:budget_heading, group: group_districts) - - create(:budget_investment, heading: all_city, voters: [create(:user)]) - create(:budget_investment, heading: carabanchel, voters: [create(:user)]) - create(:budget_investment, heading: carabanchel, voters: [create(:user)]) - - visit admin_stats_path - click_link "Participatory Budgets" - within("#budget_#{budget.id}") do - click_link "Supporting phase" - end - - within("#budget_heading_#{all_city.id}") do - expect(page).to have_content all_city.name - expect(page).to have_content 1 - end - - within("#budget_heading_#{carabanchel.id}") do - expect(page).to have_content carabanchel.name - expect(page).to have_content 2 - end - - within("#budget_heading_#{barajas.id}") do - expect(page).to have_content barajas.name - expect(page).to have_content 0 - end + expect(page).to have_link "Go back", count: 1 end scenario "hide final voting link" do