# frozen_string_literal: true class TestCachedCounting def self.clear! @data = nil end def self.data @data ||= {} end def self.write_cache!(key, count, date) data[key] = count end end RSpec.describe CachedCounting do it "should be default disabled in test" do expect(CachedCounting.enabled?).to eq(false) end context "backing implementation" do it "can correctly check for flush to db lock" do CachedCounting.clear_flush_to_db_lock! expect(CachedCounting.allowed_to_flush_to_db?).to eq(true) expect(CachedCounting.allowed_to_flush_to_db?).to eq(false) t = CachedCounting::DB_FLUSH_COOLDOWN_SECONDS # let expiry be between 2 seconds to allow for slow calls and so on expect(CachedCounting.flush_to_db_lock_ttl).to be_between(t - 2, t) CachedCounting.clear_flush_to_db_lock! end context "with a test counting class" do before do CachedCounting.reset TestCachedCounting.clear! end it "can dispatch counts to backing class" do CachedCounting.queue("a,a", TestCachedCounting) CachedCounting.queue("a,a", TestCachedCounting) CachedCounting.queue("b", TestCachedCounting) CachedCounting.flush_in_memory CachedCounting.flush_to_db expect(TestCachedCounting.data).to eq({ "a,a" => 2, "b" => 1 }) end end end context "active record" do class RailsCacheCounter < ActiveRecord::Base include CachedCounting self.table_name = "posts" def self.cache_data @cache_data ||= {} end def self.clear_cache_data @cache_data = nil end def self.write_cache!(key, val, date) cache_data[[key, date]] = val end end before do CachedCounting.reset CachedCounting.enable end after do CachedCounting.disable end it "can dispatch data via background thread" do freeze_time d1 = Time.now.utc.to_date RailsCacheCounter.perform_increment!("a,a") RailsCacheCounter.perform_increment!("b") 20.times do RailsCacheCounter.perform_increment!("a,a") end freeze_time 2.days.from_now d2 = Time.now.utc.to_date RailsCacheCounter.perform_increment!("a,a") RailsCacheCounter.perform_increment!("d") CachedCounting.flush expected = { ["a,a", d1] => 21, ["b", d1] => 1, ["a,a", d2] => 1, ["d", d2] => 1, } expect(RailsCacheCounter.cache_data).to eq(expected) end end end