This rule was added in rubocop 1.79. We were inconsistent about it, so we're adding it to get more consistency.
272 lines
6.5 KiB
Ruby
272 lines
6.5 KiB
Ruby
require "rails_helper"
|
|
|
|
describe Statisticable do
|
|
before do
|
|
dummy_stats = Class.new do
|
|
include Statisticable
|
|
|
|
attr_accessor :total
|
|
stats_cache :total
|
|
|
|
def full_cache_key_for(key)
|
|
"dummy_stats/#{object_id}/#{key}"
|
|
end
|
|
|
|
def participants
|
|
User.all
|
|
end
|
|
alias_method :participants_from_original_table, :participants
|
|
|
|
def total_participants
|
|
User.count
|
|
end
|
|
|
|
def participation_date
|
|
Time.current
|
|
end
|
|
end
|
|
|
|
stub_const("DummyStats", dummy_stats)
|
|
end
|
|
|
|
let(:resource) { double(id: 1, class: double(table_name: "")) }
|
|
let(:stats) { DummyStats.new(resource) }
|
|
|
|
describe "#gender?" do
|
|
context "No participants" do
|
|
it "is false" do
|
|
expect(stats.gender?).to be false
|
|
end
|
|
end
|
|
|
|
context "All participants have no defined gender" do
|
|
before { create(:user, gender: nil) }
|
|
|
|
it "is false" do
|
|
expect(stats.gender?).to be false
|
|
end
|
|
end
|
|
|
|
context "There's a male participant" do
|
|
before { create(:user, gender: "male") }
|
|
|
|
it "is true" do
|
|
expect(stats.gender?).to be true
|
|
end
|
|
end
|
|
|
|
context "There's a female participant" do
|
|
before { create(:user, gender: "female") }
|
|
|
|
it "is true" do
|
|
expect(stats.gender?).to be true
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#age?" do
|
|
context "No participants" do
|
|
it "is false" do
|
|
expect(stats.age?).to be false
|
|
end
|
|
end
|
|
|
|
context "All participants have no defined age" do
|
|
before { create(:user, date_of_birth: nil) }
|
|
|
|
it "is false" do
|
|
expect(stats.age?).to be false
|
|
end
|
|
end
|
|
|
|
context "All participants have impossible ages" do
|
|
before do
|
|
create(:user, date_of_birth: 3.seconds.ago)
|
|
create(:user, date_of_birth: 3000.years.ago)
|
|
end
|
|
|
|
it "is false" do
|
|
expect(stats.age?).to be false
|
|
end
|
|
end
|
|
|
|
context "There's a participant with a defined age" do
|
|
before { create(:user, date_of_birth: 30.years.ago) }
|
|
|
|
it "is true" do
|
|
expect(stats.age?).to be true
|
|
end
|
|
end
|
|
|
|
context "Partipation took place a long time ago" do
|
|
before do
|
|
create(:user, date_of_birth: 2000.years.ago)
|
|
allow(stats).to receive(:participation_date).and_return(1900.years.ago)
|
|
end
|
|
|
|
it "is true" do
|
|
expect(stats.age?).to be true
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#geozone?" do
|
|
context "No participants" do
|
|
it "is false" do
|
|
expect(stats.geozone?).to be false
|
|
end
|
|
end
|
|
|
|
context "All participants have no defined geozone" do
|
|
before { create(:user, geozone: nil) }
|
|
|
|
it "is false" do
|
|
expect(stats.geozone?).to be false
|
|
end
|
|
end
|
|
|
|
context "There's a participant with a defined geozone" do
|
|
before { create(:user, geozone: create(:geozone)) }
|
|
|
|
it "is true" do
|
|
expect(stats.geozone?).to be true
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#total_no_demographic_data" do
|
|
it "returns users with no defined gender" do
|
|
create(:user, gender: nil)
|
|
|
|
expect(stats.total_no_demographic_data).to be 1
|
|
end
|
|
|
|
it "returns users with no defined age" do
|
|
create(:user, gender: "female", date_of_birth: nil)
|
|
|
|
expect(stats.total_no_demographic_data).to be 1
|
|
end
|
|
|
|
it "returns users with no defined geozone" do
|
|
create(:user, gender: "female", geozone: nil)
|
|
|
|
expect(stats.total_no_demographic_data).to be 1
|
|
end
|
|
|
|
it "returns users with no defined gender, age nor geozone" do
|
|
create(:user, gender: nil, date_of_birth: nil, geozone: nil)
|
|
|
|
expect(stats.total_no_demographic_data).to be 1
|
|
end
|
|
|
|
it "doesn't return users with defined gender, age and geozone" do
|
|
create(:user, gender: "male", date_of_birth: 20.years.ago, geozone: create(:geozone))
|
|
|
|
expect(stats.total_no_demographic_data).to be 0
|
|
end
|
|
end
|
|
|
|
describe "#stats_methods" do
|
|
it "includes total participants" do
|
|
expect(stats.stats_methods).to include(:total_participants)
|
|
end
|
|
|
|
context "no gender stats" do
|
|
before { allow(stats).to receive(:gender?).and_return(false) }
|
|
|
|
it "doesn't include gender methods" do
|
|
expect(stats.stats_methods).not_to include(:total_male_participants)
|
|
end
|
|
end
|
|
|
|
context "no age stats" do
|
|
before { allow(stats).to receive(:age?).and_return(false) }
|
|
|
|
it "doesn't include age methods" do
|
|
expect(stats.stats_methods).not_to include(:participants_by_age)
|
|
end
|
|
end
|
|
|
|
context "no geozone stats" do
|
|
before { allow(stats).to receive(:geozone?).and_return(false) }
|
|
|
|
it "doesn't include age methods" do
|
|
expect(stats.stats_methods).not_to include(:participants_by_geozone)
|
|
end
|
|
end
|
|
|
|
context "all gender, age and geozone stats" do
|
|
before do
|
|
allow(stats).to receive_messages(gender?: true, age?: true, geozone?: true)
|
|
end
|
|
|
|
it "includes all stats methods" do
|
|
expect(stats.stats_methods).to include(:total_male_participants)
|
|
expect(stats.stats_methods).to include(:participants_by_age)
|
|
expect(stats.stats_methods).to include(:participants_by_geozone)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#generate" do
|
|
it "drops the temporary table after finishing" do
|
|
stats.generate
|
|
|
|
expect { stats.send(:participants_class).first }.to raise_exception(ActiveRecord::StatementInvalid)
|
|
end
|
|
|
|
it "can be executed twice without errors" do
|
|
stats.generate
|
|
|
|
expect { stats.generate }.not_to raise_exception
|
|
end
|
|
|
|
it "can be executed twice in parallel since it uses a transaction" do
|
|
other_stats = DummyStats.new(stats.resource)
|
|
|
|
[stats, other_stats].map do |stat|
|
|
Thread.new { stat.generate }
|
|
end.each(&:join)
|
|
end
|
|
end
|
|
|
|
describe "cache", :with_cache do
|
|
it "expires the cache at the end of the day by default" do
|
|
time = Time.current
|
|
|
|
travel_to(time) do
|
|
stats.total = 6
|
|
|
|
expect(stats.total).to eq 6
|
|
|
|
stats.total = 7
|
|
|
|
expect(stats.total).to eq 6
|
|
end
|
|
|
|
travel_to(time.end_of_day) do
|
|
expect(stats.total).to eq 6
|
|
end
|
|
|
|
travel_to(time.end_of_day + 1.second) do
|
|
expect(stats.total).to eq 7
|
|
end
|
|
end
|
|
|
|
it "does not use the cache with cache: false" do
|
|
stats = DummyStats.new(resource, cache: false)
|
|
time = Time.current
|
|
|
|
travel_to(time) do
|
|
stats.total = 6
|
|
|
|
expect(stats.total).to eq 6
|
|
|
|
stats.total = 7
|
|
|
|
expect(stats.total).to eq 7
|
|
end
|
|
end
|
|
end
|
|
end
|