# 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 describe "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 describe "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 { CachedCounting.disable } it "can dispatch data via background thread" do freeze_time d1 = Time.now.utc.to_date RailsCacheCounter.perform_increment!("a,a", async: true) RailsCacheCounter.perform_increment!("b", async: true) 20.times { RailsCacheCounter.perform_increment!("a,a", async: true) } freeze_time 2.days.from_now d2 = Time.now.utc.to_date RailsCacheCounter.perform_increment!("a,a", async: true) RailsCacheCounter.perform_increment!("d", async: true) 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