Files
grecia/app/models/poll/stats.rb
Javi Martín a552645e7f Add tests to poll stats
While we already had "one test to rule all stats", testing each method
individually makes reading, adding and changing tests easier.

Note we need to make all methods being tested public. We could also test
them using methods like `stats.generate[:total_valid_votes]` instead of
`stats.total_valid_votes`, but then the tests would be more difficult to
read.
2019-05-21 13:50:16 +02:00

104 lines
2.5 KiB
Ruby

class Poll::Stats
include Statisticable
alias_method :poll, :resource
def self.stats_methods
super +
%i[total_valid_votes total_white_votes total_null_votes
total_participants_web total_web_valid total_web_white total_web_null
total_participants_booth total_booth_valid total_booth_white total_booth_null
total_participants_web_percentage total_participants_booth_percentage
valid_percentage_web valid_percentage_booth total_valid_percentage
white_percentage_web white_percentage_booth total_white_percentage
null_percentage_web null_percentage_booth total_null_percentage]
end
def total_participants
total_participants_web + total_participants_booth
end
%i[web booth].each do |channel|
define_method :"total_participants_#{channel}" do
send(:"total_#{channel}_valid") +
send(:"total_#{channel}_white") +
send(:"total_#{channel}_null")
end
define_method :"total_participants_#{channel}_percentage" do
calculate_percentage(send(:"total_participants_#{channel}"), total_participants)
end
end
def total_web_valid
voters.where(origin: "web").count - total_web_white
end
def total_web_white
0
end
def total_web_null
0
end
def total_booth_valid
recounts.sum(:total_amount)
end
def total_booth_white
recounts.sum(:white_amount)
end
def total_booth_null
recounts.sum(:null_amount)
end
def valid_percentage_web
calculate_percentage(total_web_valid, total_valid_votes)
end
def white_percentage_web
calculate_percentage(total_web_white, total_white_votes)
end
def null_percentage_web
calculate_percentage(total_web_null, total_null_votes)
end
%i[valid white null].each do |type|
define_method :"#{type}_percentage_booth" do
calculate_percentage(send(:"total_booth_#{type}"), send(:"total_#{type}_votes"))
end
define_method :"total_#{type}_votes" do
send(:"total_web_#{type}") + send(:"total_booth_#{type}")
end
define_method :"total_#{type}_percentage" do
calculate_percentage(send(:"total_#{type}_votes"), total_participants)
end
end
private
def participants
User.where(id: voters.pluck(:user_id))
end
def voters
poll.voters
end
def recounts
poll.recounts
end
stats_cache(*stats_methods)
stats_cache :voters, :recounts
def stats_cache(key, &block)
Rails.cache.fetch("polls_stats/#{poll.id}/#{key}/v12", &block)
end
end