Use stats objects instead of hashes

It will make it far easier to call other methods on the stats object,
and we're already caching the methods.

We had to remove the view fragment caching because the stats object
isn't as easy to cache. The good thing about it is the view will
automatically be updated when we change logic regarding which stats to
show, and the methods taking long to execute are cached in the model.
This commit is contained in:
Javi Martín
2019-03-18 15:38:53 +01:00
parent eba30d1585
commit 76c7827cf4
9 changed files with 244 additions and 290 deletions

View File

@@ -6,16 +6,12 @@ module Budgets
def show def show
authorize! :read_stats, @budget authorize! :read_stats, @budget
@stats = load_stats @stats = Budget::Stats.new(@budget)
@headings = @budget.headings.sort_by_name @headings = @budget.headings.sort_by_name
end end
private private
def load_stats
Budget::Stats.new(@budget).generate
end
def load_budget def load_budget
@budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id]) @budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id])
end end

View File

@@ -33,7 +33,7 @@ class PollsController < ApplicationController
end end
def stats def stats
@stats = Poll::Stats.new(@poll).generate @stats = Poll::Stats.new(@poll)
end end
def results def results

View File

@@ -13,8 +13,6 @@ class Budget::Stats
User.where(id: (authors + voters + balloters + poll_ballot_voters).uniq.compact) User.where(id: (authors + voters + balloters + poll_ballot_voters).uniq.compact)
end end
private
def total_participants def total_participants
participants.distinct.count participants.distinct.count
end end
@@ -43,6 +41,31 @@ class Budget::Stats
budget.investments.unfeasible.count budget.investments.unfeasible.count
end end
def headings
groups = Hash.new(0)
budget.headings.order("id ASC").each do |heading|
groups[heading.id] = Hash.new(0).merge(calculate_heading_totals(heading))
end
groups[:total] = Hash.new(0)
groups[:total][:total_investments_count] = groups.collect {|_k, v| v[:total_investments_count]}.sum
groups[:total][:total_participants_support_phase] = groups.collect {|_k, v| v[:total_participants_support_phase]}.sum
groups[:total][:total_participants_vote_phase] = groups.collect {|_k, v| v[:total_participants_vote_phase]}.sum
groups[:total][:total_participants_all_phase] = groups.collect {|_k, v| v[:total_participants_all_phase]}.sum
budget.headings.each do |heading|
groups[heading.id].merge!(calculate_heading_stats_with_totals(groups[heading.id], groups[:total], heading.population))
end
groups[:total][:percentage_participants_support_phase] = groups.collect {|_k, v| v[:percentage_participants_support_phase]}.sum
groups[:total][:percentage_participants_vote_phase] = groups.collect {|_k, v| v[:percentage_participants_vote_phase]}.sum
groups[:total][:percentage_participants_all_phase] = groups.collect {|_k, v| v[:percentage_participants_all_phase]}.sum
groups
end
private
def authors def authors
budget.investments.pluck(:author_id) budget.investments.pluck(:author_id)
end end
@@ -71,29 +94,6 @@ class Budget::Stats
end end
end end
def headings
groups = Hash.new(0)
budget.headings.order("id ASC").each do |heading|
groups[heading.id] = Hash.new(0).merge(calculate_heading_totals(heading))
end
groups[:total] = Hash.new(0)
groups[:total][:total_investments_count] = groups.collect {|_k, v| v[:total_investments_count]}.sum
groups[:total][:total_participants_support_phase] = groups.collect {|_k, v| v[:total_participants_support_phase]}.sum
groups[:total][:total_participants_vote_phase] = groups.collect {|_k, v| v[:total_participants_vote_phase]}.sum
groups[:total][:total_participants_all_phase] = groups.collect {|_k, v| v[:total_participants_all_phase]}.sum
budget.headings.each do |heading|
groups[heading.id].merge!(calculate_heading_stats_with_totals(groups[heading.id], groups[:total], heading.population))
end
groups[:total][:percentage_participants_support_phase] = groups.collect {|_k, v| v[:percentage_participants_support_phase]}.sum
groups[:total][:percentage_participants_vote_phase] = groups.collect {|_k, v| v[:percentage_participants_vote_phase]}.sum
groups[:total][:percentage_participants_all_phase] = groups.collect {|_k, v| v[:percentage_participants_all_phase]}.sum
groups
end
def calculate_heading_totals(heading) def calculate_heading_totals(heading)
{ {
total_investments_count: heading.investments.count, total_investments_count: heading.investments.count,

View File

@@ -9,7 +9,7 @@ module Statisticable
end end
def generate def generate
self.class.stats_methods.map { |stat_name| [stat_name, send(stat_name)] }.to_h self.class.stats_methods.each { |stat_name| send(stat_name) }
end end
def total_male_participants def total_male_participants

View File

@@ -8,7 +8,6 @@
social_description: @budget.description_finished %> social_description: @budget.description_finished %>
<% end %> <% end %>
<% cache [@stats] do %>
<div class="participation-stats budgets-stats"> <div class="participation-stats budgets-stats">
<div class="expanded no-margin-top padding header"> <div class="expanded no-margin-top padding header">
<div class="row"> <div class="row">
@@ -67,23 +66,23 @@
<h4><%= t("stats.budgets.total_investments") %></h4> <h4><%= t("stats.budgets.total_investments") %></h4>
<%= number_with_info_tags( <%= number_with_info_tags(
@stats[:total_budget_investments], @stats.total_budget_investments,
t("stats.budgets.total_investments"), t("stats.budgets.total_investments"),
html_class: "total-investments" html_class: "total-investments"
) %> ) %>
<%= number_with_info_tags(@stats[:total_unfeasible_investments], <%= number_with_info_tags(@stats.total_unfeasible_investments,
t("stats.budgets.total_unfeasible_investments")) %> t("stats.budgets.total_unfeasible_investments")) %>
<%= number_with_info_tags(@stats[:total_selected_investments], <%= number_with_info_tags(@stats.total_selected_investments,
t("stats.budgets.total_selected_investments")) %> t("stats.budgets.total_selected_investments")) %>
</div> </div>
<div id="stats_by_phase" class="stats-group"> <div id="stats_by_phase" class="stats-group">
<h4><%= t("stats.budgets.by_phase") %></h4> <h4><%= t("stats.budgets.by_phase") %></h4>
<%= number_with_info_tags(@stats[:total_participants_support_phase], <%= number_with_info_tags(@stats.total_participants_support_phase,
t("stats.budgets.participants_support_phase")) %> t("stats.budgets.participants_support_phase")) %>
<%= number_with_info_tags(@stats[:total_participants_vote_phase], <%= number_with_info_tags(@stats.total_participants_vote_phase,
t("stats.budgets.participants_voting_phase")) %> t("stats.budgets.participants_voting_phase")) %>
</div> </div>
@@ -120,21 +119,21 @@
</td> </td>
<td id="total_spending_proposals_heading_<%= heading.id %>" <td id="total_spending_proposals_heading_<%= heading.id %>"
class="text-center border-left border-right"> class="text-center border-left border-right">
<%= @stats[:headings][heading.id][:total_investments_count] %> <%= @stats.headings[heading.id][:total_investments_count] %>
</td> </td>
<% ["support", "vote", "all"].each do |phase| %> <% ["support", "vote", "all"].each do |phase| %>
<td id="total_participants_<%= phase %>_phase_heading_<%= heading.id %>" <td id="total_participants_<%= phase %>_phase_heading_<%= heading.id %>"
class="border-left text-center"> class="border-left text-center">
<%= @stats[:headings][heading.id]["total_participants_#{phase}_phase".to_sym] %> <%= @stats.headings[heading.id]["total_participants_#{phase}_phase".to_sym] %>
</td> </td>
<td id="percentage_participants_<%= phase %>_phase_heading_<%= heading.id %>" <td id="percentage_participants_<%= phase %>_phase_heading_<%= heading.id %>"
class="border-left border-right text-center"> class="border-left border-right text-center">
<%= number_to_stats_percentage(@stats[:headings][heading.id]["percentage_participants_#{phase}_phase".to_sym]) %> <%= number_to_stats_percentage(@stats.headings[heading.id]["percentage_participants_#{phase}_phase".to_sym]) %>
</td> </td>
<td id="percentage_district_population_<%= phase %>_phase_heading_<%= heading.id %>" <td id="percentage_district_population_<%= phase %>_phase_heading_<%= heading.id %>"
class="text-center border-right"> class="text-center border-right">
<%= number_to_stats_percentage(@stats[:headings][heading.id]["percentage_district_population_#{phase}_phase".to_sym]) %> <%= number_to_stats_percentage(@stats.headings[heading.id]["percentage_district_population_#{phase}_phase".to_sym]) %>
</td> </td>
<% end %> <% end %>
</tr> </tr>
@@ -148,7 +147,7 @@
<div class="small-12 column"> <div class="small-12 column">
<div id="total_unknown_gender_or_age"> <div id="total_unknown_gender_or_age">
<p class="help-text"> <p class="help-text">
<%= t("stats.budgets.no_demographic_data", total: @stats[:total_unknown_gender_or_age]) %> <%= t("stats.budgets.no_demographic_data", total: @stats.total_unknown_gender_or_age) %>
</p> </p>
<p class="help-text"> <p class="help-text">
<%= t("stats.budgets.participatory_disclaimer") %> <%= t("stats.budgets.participatory_disclaimer") %>
@@ -162,4 +161,3 @@
</div> </div>
</div> </div>
</div> </div>
<% end %>

View File

@@ -31,9 +31,9 @@
<% Poll::Stats::CHANNELS.each do |channel| %> <% Poll::Stats::CHANNELS.each do |channel| %>
<%= number_with_info_tags( <%= number_with_info_tags(
@stats[:"total_participants_#{channel}"], @stats.send("total_participants_#{channel}"),
t("stats.polls.#{channel}_percentage", t("stats.polls.#{channel}_percentage",
percentage: number_to_stats_percentage(@stats[:"total_participants_#{channel}_percentage"]) percentage: number_to_stats_percentage(@stats.send(:"total_participants_#{channel}_percentage"))
), ),
html_class: channel html_class: channel
) %> ) %>
@@ -59,14 +59,14 @@
<% Poll::Stats::CHANNELS.each do |channel| %> <% Poll::Stats::CHANNELS.each do |channel| %>
<td> <td>
<%= @stats[:"total_#{channel}_valid"] %> <%= @stats.send(:"total_#{channel}_valid") %>
<small><em>(<%= @stats[:"valid_percentage_#{channel}"].round(2) %>%)</em></small> <small><em>(<%= @stats.send(:"valid_percentage_#{channel}").round(2) %>%)</em></small>
</td> </td>
<% end %> <% end %>
<td> <td>
<%= @stats[:total_valid_votes] %> <%= @stats.total_valid_votes %>
<small><em>(<%= @stats[:total_valid_percentage].round(2) %>%)</em></small> <small><em>(<%= @stats.total_valid_percentage.round(2) %>%)</em></small>
</td> </td>
</tr> </tr>
@@ -75,13 +75,13 @@
<% Poll::Stats::CHANNELS.each do |channel| %> <% Poll::Stats::CHANNELS.each do |channel| %>
<td> <td>
<%= @stats[:"total_#{channel}_white"] %> <%= @stats.send(:"total_#{channel}_white") %>
<small><em>(<%= @stats[:"white_percentage_#{channel}"].round(2) %>%)</em></small> <small><em>(<%= @stats.send(:"white_percentage_#{channel}").round(2) %>%)</em></small>
</td> </td>
<% end %> <% end %>
<td><%= @stats[:total_white_votes] %> <td><%= @stats.total_white_votes %>
<small><em>(<%= @stats[:total_white_percentage].round(2) %>%)</em></small> <small><em>(<%= @stats.total_white_percentage.round(2) %>%)</em></small>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -89,14 +89,14 @@
<% Poll::Stats::CHANNELS.each do |channel| %> <% Poll::Stats::CHANNELS.each do |channel| %>
<td> <td>
<%= @stats[:"total_#{channel}_null"] %> <%= @stats.send(:"total_#{channel}_null") %>
<small><em>(<%= @stats[:"null_percentage_#{channel}"].round(2) %>%)</em></small> <small><em>(<%= @stats.send(:"null_percentage_#{channel}").round(2) %>%)</em></small>
</td> </td>
<% end %> <% end %>
<td> <td>
<%= @stats[:total_null_votes] %> <%= @stats.total_null_votes %>
<small><em>(<%= @stats[:total_null_percentage].round(2) %>%)</em></small> <small><em>(<%= @stats.total_null_percentage.round(2) %>%)</em></small>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -104,12 +104,12 @@
<% Poll::Stats::CHANNELS.each do |channel| %> <% Poll::Stats::CHANNELS.each do |channel| %>
<td> <td>
<%= @stats[:"total_participants_#{channel}"] %> <%= @stats.send(:"total_participants_#{channel}") %>
<small><em>(<%= @stats[:"total_participants_#{channel}_percentage"].round(2) %>%)</em></small> <small><em>(<%= @stats.send(:"total_participants_#{channel}_percentage").round(2) %>%)</em></small>
</td> </td>
<% end %> <% end %>
<td><%= @stats[:total_participants] %></td> <td><%= @stats.total_participants %></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@@ -5,7 +5,7 @@
<h4><%= t("stats.total_participants") %></h4> <h4><%= t("stats.total_participants") %></h4>
<%= number_with_info_tags( <%= number_with_info_tags(
stats[:total_participants], stats.total_participants,
"", "",
html_class: "participants total-participants" html_class: "participants total-participants"
) %> ) %>
@@ -15,14 +15,14 @@
<h4><%= t("stats.by_gender") %></h4> <h4><%= t("stats.by_gender") %></h4>
<%= number_with_info_tags( <%= number_with_info_tags(
stats[:total_male_participants], stats.total_male_participants,
t("stats.men_percentage", percentage: number_to_stats_percentage(stats[:male_percentage])), t("stats.men_percentage", percentage: number_to_stats_percentage(stats.male_percentage)),
html_class: "participants male" html_class: "participants male"
) %> ) %>
<%= number_with_info_tags( <%= number_with_info_tags(
stats[:total_female_participants], stats.total_female_participants,
t("stats.women_percentage", percentage: number_to_stats_percentage(stats[:female_percentage])), t("stats.women_percentage", percentage: number_to_stats_percentage(stats.female_percentage)),
html_class: "participants female" html_class: "participants female"
) %> ) %>
</div> </div>
@@ -39,7 +39,7 @@
</thead> </thead>
<tbody> <tbody>
<% stats[:participants_by_age].values.each do |group| %> <% stats.participants_by_age.values.each do |group| %>
<tr> <tr>
<td><%= group[:range] %></td> <td><%= group[:range] %></td>
<td> <td>
@@ -70,7 +70,7 @@
</thead> </thead>
<tbody> <tbody>
<% stats[:participants_by_geozone].each do |geozone, participants| %> <% stats.participants_by_geozone.each do |geozone, participants| %>
<tr> <tr>
<td><%= geozone %></td> <td><%= geozone %></td>
<td><%= "#{participants[:total][:count]} (#{number_to_stats_percentage(participants[:total][:percentage])})" %></td> <td><%= "#{participants[:total][:count]} (#{number_to_stats_percentage(participants[:total][:percentage])})" %></td>

View File

@@ -33,7 +33,7 @@ describe Budget::Stats do
expect(stats.participants).to match_array( expect(stats.participants).to match_array(
[author, author_and_voter, voter, voter_and_balloter, balloter, poll_balloter] [author, author_and_voter, voter, voter_and_balloter, balloter, poll_balloter]
) )
expect(stats.generate[:total_participants]).to be 6 expect(stats.total_participants).to be 6
end end
end end
@@ -42,7 +42,7 @@ describe Budget::Stats do
2.times { create(:vote, votable: investment) } 2.times { create(:vote, votable: investment) }
create(:budget_ballot_line, investment: investment) create(:budget_ballot_line, investment: investment)
expect(stats.generate[:total_participants_support_phase]).to be 2 expect(stats.total_participants_support_phase).to be 2
end end
it "counts a user who is voter and balloter" do it "counts a user who is voter and balloter" do
@@ -50,7 +50,7 @@ describe Budget::Stats do
create(:vote, votable: investment, voter: voter_and_balloter) create(:vote, votable: investment, voter: voter_and_balloter)
create(:budget_ballot_line, investment: investment, user: voter_and_balloter) create(:budget_ballot_line, investment: investment, user: voter_and_balloter)
expect(stats.generate[:total_participants_support_phase]).to be 1 expect(stats.total_participants_support_phase).to be 1
end end
end end
@@ -59,7 +59,7 @@ describe Budget::Stats do
2.times { create(:budget_ballot_line, investment: investment) } 2.times { create(:budget_ballot_line, investment: investment) }
create(:vote, votable: investment) create(:vote, votable: investment)
expect(stats.generate[:total_participants_vote_phase]).to be 2 expect(stats.total_participants_vote_phase).to be 2
end end
it "counts a user who is voter and balloter" do it "counts a user who is voter and balloter" do
@@ -67,14 +67,14 @@ describe Budget::Stats do
create(:vote, votable: investment, voter: voter_and_balloter) create(:vote, votable: investment, voter: voter_and_balloter)
create(:budget_ballot_line, investment: investment, user: voter_and_balloter) create(:budget_ballot_line, investment: investment, user: voter_and_balloter)
expect(stats.generate[:total_participants_vote_phase]).to be 1 expect(stats.total_participants_vote_phase).to be 1
end end
it "includes balloters and poll balloters" do it "includes balloters and poll balloters" do
create(:budget_ballot_line, investment: investment) create(:budget_ballot_line, investment: investment)
create(:poll_voter, :from_booth, budget: budget) create(:poll_voter, :from_booth, budget: budget)
expect(stats.generate[:total_participants_vote_phase]).to be 2 expect(stats.total_participants_vote_phase).to be 2
end end
it "counts once a user who is balloter and poll balloter" do it "counts once a user who is balloter and poll balloter" do
@@ -82,7 +82,7 @@ describe Budget::Stats do
create(:budget_ballot_line, investment: investment, user: poller_and_balloter) create(:budget_ballot_line, investment: investment, user: poller_and_balloter)
create(:poll_voter, :from_booth, user: poller_and_balloter, budget: budget) create(:poll_voter, :from_booth, user: poller_and_balloter, budget: budget)
expect(stats.generate[:total_participants_vote_phase]).to be 1 expect(stats.total_participants_vote_phase).to be 1
end end
it "doesn't count nil user ids" do it "doesn't count nil user ids" do
@@ -90,7 +90,7 @@ describe Budget::Stats do
ballot: create(:budget_ballot, budget: budget, user: nil, physical: true) ballot: create(:budget_ballot, budget: budget, user: nil, physical: true)
) )
expect(stats.generate[:total_participants_vote_phase]).to be 0 expect(stats.total_participants_vote_phase).to be 0
end end
end end
@@ -99,7 +99,7 @@ describe Budget::Stats do
2.times { create(:budget_investment, budget: budget) } 2.times { create(:budget_investment, budget: budget) }
create(:budget_investment, budget: create(:budget)) create(:budget_investment, budget: create(:budget))
expect(stats.generate[:total_budget_investments]).to be 2 expect(stats.total_budget_investments).to be 2
end end
end end
@@ -108,7 +108,7 @@ describe Budget::Stats do
create(:budget_ballot_line, investment: investment) create(:budget_ballot_line, investment: investment)
create(:budget_ballot_line, investment: create(:budget_investment, :selected, budget: budget)) create(:budget_ballot_line, investment: create(:budget_investment, :selected, budget: budget))
expect(stats.generate[:total_votes]).to be 2 expect(stats.total_votes).to be 2
end end
end end
@@ -118,7 +118,7 @@ describe Budget::Stats do
create(:budget_investment, :selected, budget: create(:budget)) create(:budget_investment, :selected, budget: create(:budget))
create(:budget_investment, :unfeasible, budget: budget) create(:budget_investment, :unfeasible, budget: budget)
expect(stats.generate[:total_selected_investments]).to be 3 expect(stats.total_selected_investments).to be 3
end end
end end
@@ -128,7 +128,7 @@ describe Budget::Stats do
create(:budget_investment, :unfeasible, budget: create(:budget)) create(:budget_investment, :unfeasible, budget: create(:budget))
create(:budget_investment, :selected, budget: budget) create(:budget_investment, :selected, budget: budget)
expect(stats.generate[:total_unfeasible_investments]).to be 3 expect(stats.total_unfeasible_investments).to be 3
end end
end end
@@ -143,31 +143,31 @@ describe Budget::Stats do
describe "#total_male_participants" do describe "#total_male_participants" do
it "returns the number of total male participants" do it "returns the number of total male participants" do
expect(stats.generate[:total_male_participants]).to be 3 expect(stats.total_male_participants).to be 3
end end
end end
describe "#total_female_participants" do describe "#total_female_participants" do
it "returns the number of total female participants" do it "returns the number of total female participants" do
expect(stats.generate[:total_female_participants]).to be 2 expect(stats.total_female_participants).to be 2
end end
end end
describe "#total_unknown_gender_or_age" do describe "#total_unknown_gender_or_age" do
it "returns the number of total unknown participants' gender or age" do it "returns the number of total unknown participants' gender or age" do
expect(stats.generate[:total_unknown_gender_or_age]).to be 1 expect(stats.total_unknown_gender_or_age).to be 1
end end
end end
describe "#male_percentage" do describe "#male_percentage" do
it "returns the percentage of male participants" do it "returns the percentage of male participants" do
expect(stats.generate[:male_percentage]).to be 60.0 expect(stats.male_percentage).to be 60.0
end end
end end
describe "#female_percentage" do describe "#female_percentage" do
it "returns the percentage of female participants" do it "returns the percentage of female participants" do
expect(stats.generate[:female_percentage]).to be 40.0 expect(stats.female_percentage).to be 40.0
end end
end end
end end
@@ -182,18 +182,18 @@ describe Budget::Stats do
end end
it "returns the age groups hash" do it "returns the age groups hash" do
expect(stats.generate[:participants_by_age]["16 - 19"][:count]).to be 0 expect(stats.participants_by_age["16 - 19"][:count]).to be 0
expect(stats.generate[:participants_by_age]["20 - 24"][:count]).to be 4 expect(stats.participants_by_age["20 - 24"][:count]).to be 4
expect(stats.generate[:participants_by_age]["25 - 29"][:count]).to be 0 expect(stats.participants_by_age["25 - 29"][:count]).to be 0
expect(stats.generate[:participants_by_age]["30 - 34"][:count]).to be 1 expect(stats.participants_by_age["30 - 34"][:count]).to be 1
expect(stats.generate[:participants_by_age]["35 - 39"][:count]).to be 0 expect(stats.participants_by_age["35 - 39"][:count]).to be 0
expect(stats.generate[:participants_by_age]["40 - 44"][:count]).to be 3 expect(stats.participants_by_age["40 - 44"][:count]).to be 3
expect(stats.generate[:participants_by_age]["45 - 49"][:count]).to be 0 expect(stats.participants_by_age["45 - 49"][:count]).to be 0
expect(stats.generate[:participants_by_age]["50 - 54"][:count]).to be 2 expect(stats.participants_by_age["50 - 54"][:count]).to be 2
expect(stats.generate[:participants_by_age]["55 - 59"][:count]).to be 0 expect(stats.participants_by_age["55 - 59"][:count]).to be 0
expect(stats.generate[:participants_by_age]["60 - 64"][:count]).to be 0 expect(stats.participants_by_age["60 - 64"][:count]).to be 0
expect(stats.generate[:participants_by_age]["65 - 69"][:count]).to be 0 expect(stats.participants_by_age["65 - 69"][:count]).to be 0
expect(stats.generate[:participants_by_age]["70 - 74"][:count]).to be 0 expect(stats.participants_by_age["70 - 74"][:count]).to be 0
end end
end end
@@ -206,7 +206,7 @@ describe Budget::Stats do
end end
it "returns headings data" do it "returns headings data" do
heading_stats = stats.generate[:headings][investment.heading.id] heading_stats = stats.headings[investment.heading.id]
expect(heading_stats[:total_investments_count]).to be 2 expect(heading_stats[:total_investments_count]).to be 2
expect(heading_stats[:total_participants_support_phase]).to be 2 expect(heading_stats[:total_participants_support_phase]).to be 2
expect(heading_stats[:total_participants_vote_phase]).to be 1 expect(heading_stats[:total_participants_vote_phase]).to be 1

View File

@@ -183,44 +183,4 @@ describe Poll::Stats do
expect(stats.participants_by_geozone["Midgar"][:percentage]).to eq(33.333) expect(stats.participants_by_geozone["Midgar"][:percentage]).to eq(33.333)
end end
end end
describe "#generate" do
it "generates the correct stats" do
poll = create(:poll)
2.times { create(:poll_voter, :from_web, poll: poll) }
3.times { create(:poll_voter, :from_booth, poll: poll) }
create(:poll_recount, :from_booth, poll: poll,
white_amount: 1, null_amount: 0, total_amount: 2)
stats = Poll::Stats.new(poll).generate
expect(stats[:total_participants]).to eq(5)
expect(stats[:total_participants_web]).to eq(2)
expect(stats[:total_participants_booth]).to eq(3)
expect(stats[:total_valid_votes]).to eq(4)
expect(stats[:total_white_votes]).to eq(1)
expect(stats[:total_null_votes]).to eq(0)
expect(stats[:total_web_valid]).to eq(2)
expect(stats[:total_web_white]).to eq(0)
expect(stats[:total_web_null]).to eq(0)
expect(stats[:total_booth_valid]).to eq(2)
expect(stats[:total_booth_white]).to eq(1)
expect(stats[:total_booth_null]).to eq(0)
expect(stats[:total_participants_web_percentage]).to eq(40)
expect(stats[:total_participants_booth_percentage]).to eq(60)
expect(stats[:valid_percentage_web]).to eq(50)
expect(stats[:white_percentage_web]).to eq(0)
expect(stats[:null_percentage_web]).to eq(0)
expect(stats[:valid_percentage_booth]).to eq(50)
expect(stats[:white_percentage_booth]).to eq(100)
expect(stats[:null_percentage_booth]).to eq(0)
expect(stats[:total_valid_percentage]).to eq(80)
expect(stats[:total_white_percentage]).to eq(20)
expect(stats[:total_null_percentage]).to eq(0)
end
end
end end