From 9683ede220f184f188ff4b86e68461b2f09b2872 Mon Sep 17 00:00:00 2001 From: George Eaton Date: Thu, 26 Sep 2024 16:21:26 +0100 Subject: [PATCH] Default to EMERGENCY_BANNER_REDIS_URL in Banner's Redis This is a new environment variable we've currently added to Integration to allow us to using Whitehall's Redis instance, which is shared with Static. For environments that don't have this variable set yet (i.e. Staging and Production) we fallback on the default `REDIS_URL`. This is temporary - once we've moved all environments over to the new URL we can remove this default. `mock_env` is shamelessly copied from [here](https://gist.github.com/jazzytomato/79bb6ff516d93486df4e14169f4426af) and allows us to specify some environment variables that won't persist between tests. The memoization of the instance variable in the class method was a tricky one to overcome, as the setup persisted across tests. I've had to manually clear it on these new tests to get this working. --- lib/emergency_banner/display.rb | 1 + test/unit/emergency_banner/display_test.rb | 55 ++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/lib/emergency_banner/display.rb b/lib/emergency_banner/display.rb index cfa92da7a..de9171f9d 100644 --- a/lib/emergency_banner/display.rb +++ b/lib/emergency_banner/display.rb @@ -3,6 +3,7 @@ class Display class << self def client @client ||= Redis.new( + url: ENV.fetch("EMERGENCY_BANNER_REDIS_URL", ENV["REDIS_URL"]), reconnect_attempts: [ 15, 30, diff --git a/test/unit/emergency_banner/display_test.rb b/test/unit/emergency_banner/display_test.rb index f6a6bf24e..70fb108a9 100644 --- a/test/unit/emergency_banner/display_test.rb +++ b/test/unit/emergency_banner/display_test.rb @@ -7,6 +7,51 @@ @banner = EmergencyBanner::Display.new end + context ".client" do + context "when the EMERGENCY_BANNER_REDIS_URL environment variable has been set" do + should "use that value as the URL for the Redis client" do + mock_env("EMERGENCY_BANNER_REDIS_URL" => "redis://emergency-banner") do + EmergencyBanner::Display.instance_variable_set(:@client, nil) + + Redis.expects(:new).with( + url: "redis://emergency-banner", + reconnect_attempts: [ + 15, + 30, + 45, + 60, + ], + ) + + EmergencyBanner::Display.client + end + end + end + + context "when the EMERGENCY_BANNER_REDIS_URL environment variable has not been set" do + should "use the default REDIS_URL as the URL for the Redis client" do + mock_env({ + "EMERGENCY_BANNER_REDIS_URL" => nil, + "REDIS_URL" => "redis://my-redis-url", + }) do + EmergencyBanner::Display.instance_variable_set(:@client, nil) + + Redis.expects(:new).with( + url: "redis://my-redis-url", + reconnect_attempts: [ + 15, + 30, + 45, + 60, + ], + ) + + EmergencyBanner::Display.client + end + end + end + end + context "#enabled?" do should "return enabled is false when redis connection times out and send an error notification" do err = Redis::CannotConnectError.new("Timed out connecting to Redis") @@ -155,5 +200,15 @@ assert_nil @banner.link_text end end + + def mock_env(partial_env_hash) + old_env = ENV.to_hash + ENV.update partial_env_hash + begin + yield + ensure + ENV.replace old_env + end + end end # rubocop:enable Rails/RefuteMethods