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.vote_count") %>
+
+
+ <%= vote_count %>
+
+
+
+
+
+
+ <%= t("admin.stats.budget_supporting.participant_count") %>
+
+
+ <%= user_count %>
+
+
+
+
+
+
+<%= render "admin/stats/graph", name: "user_supported_budgets", event: "", count: user_count %>
+
+
+
+
+ | <%= t("admin.stats.budget_supporting.headings") %> |
+ <%= t("admin.stats.budget_supporting.users") %> |
+
+
+
+
+ <% user_count_by_heading.each do |heading, count| %>
+
+ |
+ <%= heading.name %>
+ |
+
+ <%= number_with_delimiter count %>
+ |
+
+ <% end %>
+
+
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.vote_count") %>
-
-
- <%= @vote_count %>
-
-
-
-
-
-
- <%= t("admin.stats.budget_supporting.participant_count") %>
-
-
- <%= @user_count %>
-
-
-
-
-
-
-<%= render "graph", name: "user_supported_budgets", event: "", count: @user_count %>
-
-
-
-
- | <%= t("admin.stats.budget_supporting.headings") %> |
- <%= t("admin.stats.budget_supporting.users") %> |
-
-
-
-
- <% @voters_in_heading.each do |heading, count| %>
-
- |
- <%= heading.name %>
- |
-
- <%= number_with_delimiter count %>
- |
-
- <% end %>
-
-
+<%= 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