diff options
Diffstat (limited to 'spec/models/broadcast_message_spec.rb')
-rw-r--r-- | spec/models/broadcast_message_spec.rb | 102 |
1 files changed, 93 insertions, 9 deletions
diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb index 5fcf6813b0a..7485496cf90 100644 --- a/spec/models/broadcast_message_spec.rb +++ b/spec/models/broadcast_message_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BroadcastMessage do +RSpec.describe BroadcastMessage, feature_category: :onboarding do subject { build(:broadcast_message) } it { is_expected.to be_valid } @@ -24,11 +24,17 @@ RSpec.describe BroadcastMessage do it { is_expected.to allow_value(1).for(:broadcast_type) } it { is_expected.not_to allow_value(nil).for(:broadcast_type) } it { is_expected.not_to allow_value(nil).for(:target_access_levels) } + it { is_expected.not_to allow_value(nil).for(:show_in_cli) } it do is_expected.to validate_inclusion_of(:target_access_levels) .in_array(described_class::ALLOWED_TARGET_ACCESS_LEVELS) end + + it do + is_expected.to validate_inclusion_of(:show_in_cli) + .in_array([true, false]) + end end describe 'default values' do @@ -38,7 +44,7 @@ RSpec.describe BroadcastMessage do it { expect(message.font).to eq('#FFFFFF') } end - shared_examples 'time constrainted' do |broadcast_type| + shared_examples 'time constrained' do |broadcast_type| it 'returns message if time match' do message = create(:broadcast_message, broadcast_type: broadcast_type) @@ -226,7 +232,7 @@ RSpec.describe BroadcastMessage do # Regression test for https://gitlab.com/gitlab-org/gitlab/-/issues/353076 context 'when cache returns stale data (e.g. nil target_access_levels)' do let(:message) { build(:broadcast_message, :banner, target_access_levels: nil) } - let(:cache) { Gitlab::JsonCache.new } + let(:cache) { Gitlab::Cache::JsonCaches::JsonKeyed.new } before do cache.write(described_class::BANNER_CACHE_KEY, [message]) @@ -246,7 +252,7 @@ RSpec.describe BroadcastMessage do end end - it_behaves_like 'time constrainted', :banner + it_behaves_like 'time constrained', :banner it_behaves_like 'message cache', :banner it_behaves_like 'matches with current path', :banner it_behaves_like 'matches with user access level', :banner @@ -278,7 +284,7 @@ RSpec.describe BroadcastMessage do end end - it_behaves_like 'time constrainted', :banner + it_behaves_like 'time constrained', :banner it_behaves_like 'message cache', :banner it_behaves_like 'matches with current path', :banner it_behaves_like 'matches with user access level', :banner @@ -308,7 +314,7 @@ RSpec.describe BroadcastMessage do end end - it_behaves_like 'time constrainted', :notification + it_behaves_like 'time constrained', :notification it_behaves_like 'message cache', :notification it_behaves_like 'matches with current path', :notification it_behaves_like 'matches with user access level', :notification @@ -331,6 +337,18 @@ RSpec.describe BroadcastMessage do end end + describe '.current_show_in_cli_banner_messages', :use_clean_rails_memory_store_caching do + subject { -> { described_class.current_show_in_cli_banner_messages } } + + it 'only returns banner messages that has show_in_cli as true' do + show_in_cli_message = create(:broadcast_message) + create(:broadcast_message, broadcast_type: :notification) + create(:broadcast_message, show_in_cli: false) + + expect(subject.call).to contain_exactly(show_in_cli_message) + end + end + describe '#attributes' do it 'includes message_html field' do expect(subject.attributes.keys).to include("cached_markdown_version", "message_html") @@ -397,11 +415,77 @@ RSpec.describe BroadcastMessage do it 'flushes the Redis cache' do message = create(:broadcast_message) - expect(Rails.cache).to receive(:delete).with("#{described_class::CACHE_KEY}:#{Gitlab.revision}") - expect(Rails.cache).to receive(:delete).with("#{described_class::BANNER_CACHE_KEY}:#{Gitlab.revision}") - expect(Rails.cache).to receive(:delete).with("#{described_class::NOTIFICATION_CACHE_KEY}:#{Gitlab.revision}") + expect(Rails.cache).to receive(:delete).with(described_class::CACHE_KEY) + expect(Rails.cache).to receive(:delete).with(described_class::BANNER_CACHE_KEY) + expect(Rails.cache).to receive(:delete).with(described_class::NOTIFICATION_CACHE_KEY) message.flush_redis_cache end + + context 'with GitLab revision changes', :use_clean_rails_redis_caching do + it 'validates correct cache creating, flushing and cache recreation cycle' do + message = create(:broadcast_message, broadcast_type: :banner) + new_strategy_value = { revision: 'abc123', version: '_version_' } + + expect(described_class).to receive(:current_and_future_messages).and_call_original.exactly(4).times + + # 1st non-cache hit + described_class.current + # validate seed and cache used + described_class.current + + # seed the other cache + original_strategy_value = Gitlab::Cache::JsonCache::STRATEGY_KEY_COMPONENTS + stub_const('Gitlab::Cache::JsonCaches::JsonKeyed::STRATEGY_KEY_COMPONENTS', new_strategy_value) + + # 2nd non-cache hit + described_class.current + # validate seed and cache used + described_class.current + + # delete on original cache + stub_const('Gitlab::Cache::JsonCaches::JsonKeyed::STRATEGY_KEY_COMPONENTS', original_strategy_value) + # validate seed and cache used - this adds another hit and shouldn't will be fixed with append write concept + described_class.current + message.destroy! + + # 3rd non-cache hit due to flushing of cache on current Gitlab.revision + described_class.current + # validate seed and cache used + described_class.current + + # other revision of GitLab does gets cache destroyed + stub_const('Gitlab::Cache::JsonCaches::JsonKeyed::STRATEGY_KEY_COMPONENTS', new_strategy_value) + + # 4th non-cache hit on the simulated other revision + described_class.current + # validate seed and cache used + described_class.current + + # switch back to original and validate cache still exists + stub_const('Gitlab::Cache::JsonCaches::JsonKeyed::STRATEGY_KEY_COMPONENTS', original_strategy_value) + # validate seed and cache used + described_class.current + end + + it 'handles there being no messages with cache' do + expect(described_class).to receive(:current_and_future_messages).and_call_original.once + + # 1st non-cache hit + expect(described_class.current).to eq([]) + # validate seed and cache used + expect(described_class.current).to eq([]) + end + end + end + + describe '#current_and_future_messages' do + let_it_be(:message_a) { create(:broadcast_message, ends_at: 1.day.ago) } + let_it_be(:message_b) { create(:broadcast_message, ends_at: Time.current + 2.days) } + let_it_be(:message_c) { create(:broadcast_message, ends_at: Time.current + 7.days) } + + it 'returns only current and future messages by ascending ends_at' do + expect(described_class.current_and_future_messages).to eq [message_b, message_c] + end end end |