From c9d22be03cf095443d4f6f867749971e921b29ee Mon Sep 17 00:00:00 2001 From: Jits Date: Wed, 17 Apr 2019 14:51:45 +0100 Subject: [PATCH] Feature flag for Announcements --- ...uncements_processor_job_trigger_service.rb | 4 +- .../announcements_processor_service.rb | 2 + platform-hub-api/config/routes.rb | 6 +- .../announcement_templates_routing_spec.rb | 92 +++-- .../routing/announcements_routing_spec.rb | 112 ++++-- .../spec/routing/me_routing_spec.rb | 20 +- .../announcements_processor_service_spec.rb | 330 ++++++++++-------- platform-hub-web/src/app/app.module.js | 1 + platform-hub-web/src/app/app.routes.js | 10 +- .../src/app/help/faq/faq-entries.html | 4 +- .../src/app/layout/shell.component.js | 6 +- platform-hub-web/src/app/layout/shell.html | 3 +- 12 files changed, 374 insertions(+), 216 deletions(-) diff --git a/platform-hub-api/app/services/announcements_processor_job_trigger_service.rb b/platform-hub-api/app/services/announcements_processor_job_trigger_service.rb index 7c94dd56..810aee05 100644 --- a/platform-hub-api/app/services/announcements_processor_job_trigger_service.rb +++ b/platform-hub-api/app/services/announcements_processor_job_trigger_service.rb @@ -2,7 +2,9 @@ module AnnouncementsProcessorJobTriggerService extend self def trigger - if AnnouncementsProcessorJob.is_already_queued? + if !FeatureFlagService.is_enabled?(:announcements) + Rails.logger.info 'Announcements feature flag is turned off... will not trigger announcements processor job' + elsif AnnouncementsProcessorJob.is_already_queued? Rails.logger.info 'Announcements processor job already in queue... will not trigger another one' else Rails.logger.info 'Triggering the announcements processor job' diff --git a/platform-hub-api/app/services/announcements_processor_service.rb b/platform-hub-api/app/services/announcements_processor_service.rb index a47f2a3f..f889752f 100644 --- a/platform-hub-api/app/services/announcements_processor_service.rb +++ b/platform-hub-api/app/services/announcements_processor_service.rb @@ -6,6 +6,8 @@ def initialize email_batch_size, logger end def run + return unless FeatureFlagService.is_enabled?(:announcements) + Announcement.published.awaiting_delivery_or_resend.each(&method(:process)) end diff --git a/platform-hub-api/config/routes.rb b/platform-hub-api/config/routes.rb index 16e36733..ca53085c 100644 --- a/platform-hub-api/config/routes.rb +++ b/platform-hub-api/config/routes.rb @@ -10,7 +10,7 @@ post '/me/agree_terms_of_service', to: 'me#agree_terms_of_service' post '/me/complete_hub_onboarding', to: 'me#complete_hub_onboarding' post '/me/complete_services_onboarding', to: 'me#complete_services_onboarding' - post '/me/global_announcements/mark_all_read', to: 'me#global_announcements_mark_all_read' + post '/me/global_announcements/mark_all_read', to: 'me#global_announcements_mark_all_read', constraints: lambda { |_| FeatureFlagService.is_enabled?(:announcements) } get '/me/kubernetes_tokens', to: 'me#kubernetes_tokens', constraints: lambda { |_| FeatureFlagService.is_enabled?(:kubernetes_tokens) } resources :feature_flags, only: [ :index ] do @@ -102,12 +102,12 @@ except: [ :create ], constraints: { id: ContactList::ID_REGEX_FOR_ROUTES } - resources :announcement_templates do + resources :announcement_templates, constraints: lambda { |_| FeatureFlagService.is_enabled?(:announcements) } do get :form_field_types, on: :collection post :preview, on: :collection end - resources :announcements do + resources :announcements, constraints: lambda { |_| FeatureFlagService.is_enabled?(:announcements) } do get :global, on: :collection post :mark_sticky, on: :member post :unmark_sticky, on: :member diff --git a/platform-hub-api/spec/routing/announcement_templates_routing_spec.rb b/platform-hub-api/spec/routing/announcement_templates_routing_spec.rb index c1f9e85b..33cf7874 100644 --- a/platform-hub-api/spec/routing/announcement_templates_routing_spec.rb +++ b/platform-hub-api/spec/routing/announcement_templates_routing_spec.rb @@ -3,36 +3,84 @@ RSpec.describe AnnouncementTemplatesController, type: :routing do describe 'routing' do - it 'routes to #index' do - expect(:get => '/announcement_templates').to route_to('announcement_templates#index') - end + context 'with announcements feature flag enabled' do - it 'routes to #show' do - expect(:get => '/announcement_templates/1').to route_to('announcement_templates#show', :id => '1') - end + before do + FeatureFlagService.create_or_update(:announcements, true) + end - it 'routes to #create' do - expect(:post => '/announcement_templates').to route_to('announcement_templates#create') - end + it 'routes to #index' do + expect(:get => '/announcement_templates').to route_to('announcement_templates#index') + end - it 'routes to #update via PUT' do - expect(:put => '/announcement_templates/1').to route_to('announcement_templates#update', :id => '1') - end + it 'routes to #show' do + expect(:get => '/announcement_templates/1').to route_to('announcement_templates#show', :id => '1') + end - it 'routes to #update via PATCH' do - expect(:patch => '/announcement_templates/1').to route_to('announcement_templates#update', :id => '1') - end + it 'routes to #create' do + expect(:post => '/announcement_templates').to route_to('announcement_templates#create') + end - it 'routes to #destroy' do - expect(:delete => '/announcement_templates/1').to route_to('announcement_templates#destroy', :id => '1') - end + it 'routes to #update via PUT' do + expect(:put => '/announcement_templates/1').to route_to('announcement_templates#update', :id => '1') + end + + it 'routes to #update via PATCH' do + expect(:patch => '/announcement_templates/1').to route_to('announcement_templates#update', :id => '1') + end + + it 'routes to #destroy' do + expect(:delete => '/announcement_templates/1').to route_to('announcement_templates#destroy', :id => '1') + end + + it 'routes to #form_field_types' do + expect(:get => '/announcement_templates/form_field_types').to route_to('announcement_templates#form_field_types') + end + + it 'routes to #preview' do + expect(:post => '/announcement_templates/preview').to route_to('announcement_templates#preview') + end - it 'routes to #form_field_types' do - expect(:get => '/announcement_templates/form_field_types').to route_to('announcement_templates#form_field_types') end - it 'routes to #preview' do - expect(:post => '/announcement_templates/preview').to route_to('announcement_templates#preview') + context 'with announcements feature flag disabled' do + + before do + FeatureFlagService.create_or_update(:announcements, false) + end + + it 'routes to #index' do + expect(:get => '/announcement_templates').to_not be_routable + end + + it 'routes to #show' do + expect(:get => '/announcement_templates/1').to_not be_routable + end + + it 'routes to #create' do + expect(:post => '/announcement_templates').to_not be_routable + end + + it 'routes to #update via PUT' do + expect(:put => '/announcement_templates/1').to_not be_routable + end + + it 'routes to #update via PATCH' do + expect(:patch => '/announcement_templates/1').to_not be_routable + end + + it 'routes to #destroy' do + expect(:delete => '/announcement_templates/1').to_not be_routable + end + + it 'routes to #form_field_types' do + expect(:get => '/announcement_templates/form_field_types').to_not be_routable + end + + it 'routes to #preview' do + expect(:post => '/announcement_templates/preview').to_not be_routable + end + end end diff --git a/platform-hub-api/spec/routing/announcements_routing_spec.rb b/platform-hub-api/spec/routing/announcements_routing_spec.rb index 0f47ad54..11e733e2 100644 --- a/platform-hub-api/spec/routing/announcements_routing_spec.rb +++ b/platform-hub-api/spec/routing/announcements_routing_spec.rb @@ -3,44 +3,100 @@ RSpec.describe AnnouncementsController, type: :routing do describe 'routing' do - it 'routes to #index' do - expect(:get => '/announcements').to route_to('announcements#index') - end + context 'with announcements feature flag enabled' do - it 'routes to #global' do - expect(:get => '/announcements/global').to route_to('announcements#global') - end + before do + FeatureFlagService.create_or_update(:announcements, true) + end - it 'routes to #show' do - expect(:get => '/announcements/1').to route_to('announcements#show', :id => '1') - end + it 'routes to #index' do + expect(:get => '/announcements').to route_to('announcements#index') + end - it 'routes to #create' do - expect(:post => '/announcements').to route_to('announcements#create') - end + it 'routes to #global' do + expect(:get => '/announcements/global').to route_to('announcements#global') + end - it 'routes to #update via PUT' do - expect(:put => '/announcements/1').to route_to('announcements#update', :id => '1') - end + it 'routes to #show' do + expect(:get => '/announcements/1').to route_to('announcements#show', :id => '1') + end - it 'routes to #update via PATCH' do - expect(:patch => '/announcements/1').to route_to('announcements#update', :id => '1') - end + it 'routes to #create' do + expect(:post => '/announcements').to route_to('announcements#create') + end - it 'routes to #destroy' do - expect(:delete => '/announcements/1').to route_to('announcements#destroy', :id => '1') - end + it 'routes to #update via PUT' do + expect(:put => '/announcements/1').to route_to('announcements#update', :id => '1') + end - it 'routes to #mark_sticky' do - expect(:post => '/announcements/1/mark_sticky').to route_to('announcements#mark_sticky', :id => '1') - end + it 'routes to #update via PATCH' do + expect(:patch => '/announcements/1').to route_to('announcements#update', :id => '1') + end + + it 'routes to #destroy' do + expect(:delete => '/announcements/1').to route_to('announcements#destroy', :id => '1') + end + + it 'routes to #mark_sticky' do + expect(:post => '/announcements/1/mark_sticky').to route_to('announcements#mark_sticky', :id => '1') + end + + it 'routes to #unmark_sticky' do + expect(:post => '/announcements/1/unmark_sticky').to route_to('announcements#unmark_sticky', :id => '1') + end + + it 'routes to #resend' do + expect(:post => '/announcements/1/resend').to route_to('announcements#resend', :id => '1') + end - it 'routes to #unmark_sticky' do - expect(:post => '/announcements/1/unmark_sticky').to route_to('announcements#unmark_sticky', :id => '1') end - it 'routes to #resend' do - expect(:post => '/announcements/1/resend').to route_to('announcements#resend', :id => '1') + context 'with announcements feature flag disabled' do + + before do + FeatureFlagService.create_or_update(:announcements, false) + end + + it 'route to #index is not routable' do + expect(:get => '/announcements').to_not be_routable + end + + it 'route to #global is not routable' do + expect(:get => '/announcements/global').to_not be_routable + end + + it 'route to #show is not routable' do + expect(:get => '/announcements/1').to_not be_routable + end + + it 'route to #create is not routable' do + expect(:post => '/announcements').to_not be_routable + end + + it 'route to #update via PUT is not routable' do + expect(:put => '/announcements/1').to_not be_routable + end + + it 'route to #update via PATCH is not routable' do + expect(:patch => '/announcements/1').to_not be_routable + end + + it 'route to #destroy is not routable' do + expect(:delete => '/announcements/1').to_not be_routable + end + + it 'route to #mark_sticky is not routable' do + expect(:post => '/announcements/1/mark_sticky').to_not be_routable + end + + it 'route to #unmark_sticky is not routable' do + expect(:post => '/announcements/1/unmark_sticky').to_not be_routable + end + + it 'route to #resend is not routable' do + expect(:post => '/announcements/1/resend').to_not be_routable + end + end end diff --git a/platform-hub-api/spec/routing/me_routing_spec.rb b/platform-hub-api/spec/routing/me_routing_spec.rb index f2deb645..8dd19c68 100644 --- a/platform-hub-api/spec/routing/me_routing_spec.rb +++ b/platform-hub-api/spec/routing/me_routing_spec.rb @@ -33,8 +33,24 @@ expect(:post => '/me/complete_services_onboarding').to route_to('me#complete_services_onboarding') end - it 'routes to #global_announcements_mark_all_read' do - expect(:post => '/me/global_announcements/mark_all_read').to route_to('me#global_announcements_mark_all_read') + context 'with announcements feature flag enabled' do + before do + FeatureFlagService.create_or_update(:announcements, true) + end + + it 'routes to #global_announcements_mark_all_read' do + expect(:post => '/me/global_announcements/mark_all_read').to route_to('me#global_announcements_mark_all_read') + end + end + + context 'with announcements feature flag disabled' do + before do + FeatureFlagService.create_or_update(:announcements, false) + end + + it 'route to #global_announcements_mark_all_read is not routable' do + expect(:post => '/me/global_announcements/mark_all_read').to_not be_routable + end end context 'with kubernetes_tokens feature flag enabled' do diff --git a/platform-hub-api/spec/services/announcements_processor_service_spec.rb b/platform-hub-api/spec/services/announcements_processor_service_spec.rb index 232d4791..cdc4a577 100644 --- a/platform-hub-api/spec/services/announcements_processor_service_spec.rb +++ b/platform-hub-api/spec/services/announcements_processor_service_spec.rb @@ -5,166 +5,188 @@ include_context 'time helpers' describe '#run' do - let(:announcement_mailer) { class_double('announcement_mailer') } - let(:slack_notifier) { instance_double('Slack::Notifier') } - let!(:hub_user_1) { create :user, email: 'hub_user_1@example.org', created_at: 1.second.ago } - let!(:hub_user_2) { create :user, email: 'hub_user_2@example.org' } - - let :foo_contact_list do - instance_double 'ContactList', - id: 'foo', - email_addresses: [ hub_user_2.email, 'foo@example.org' ] - end - let :bar_contact_list do - instance_double 'ContactList', - id: 'bar', - email_addresses: [ 'bar@example.org', 'foo@example.org' ] - end - - let :a2_deliver_to do - { - hub_users: 'none', - contact_lists: 'foo', - slack_channels: [ '#foo', '#bar' ] - } - end - let :expected_a2_recipients do - foo_contact_list.email_addresses + context 'with announcements feature flag enabled' do + before do + FeatureFlagService.create_or_update(:announcements, true) + end + + let(:announcement_mailer) { class_double('announcement_mailer') } + let(:slack_notifier) { instance_double('Slack::Notifier') } + + let!(:hub_user_1) { create :user, email: 'hub_user_1@example.org', created_at: 1.second.ago } + let!(:hub_user_2) { create :user, email: 'hub_user_2@example.org' } + + let :foo_contact_list do + instance_double 'ContactList', + id: 'foo', + email_addresses: [ hub_user_2.email, 'foo@example.org' ] + end + let :bar_contact_list do + instance_double 'ContactList', + id: 'bar', + email_addresses: [ 'bar@example.org', 'foo@example.org' ] + end + + let :a2_deliver_to do + { + hub_users: 'none', + contact_lists: 'foo', + slack_channels: [ '#foo', '#bar' ] + } + end + let :expected_a2_recipients do + foo_contact_list.email_addresses + end + + let :a4_deliver_to do + { + hub_users: 'all', + contact_lists: [ 'foo', 'bar' ], + slack_channels: [] + } + end + let :expected_a4_recipients do + ([ hub_user_1.email, hub_user_2.email ] + foo_contact_list.email_addresses + bar_contact_list.email_addresses).uniq + end + + let :a5_deliver_to do + { + hub_users: '', + contact_lists: [], + slack_channels: [ '#foo' ] + } + end + + let :a10_deliver_to do + { + hub_users: 'all', + contact_lists: [ 'foo', 'bar' ], + slack_channels: [ '#baz' ] + } + end + let :expected_a10_recipients do + ([ hub_user_1.email, hub_user_2.email ] + foo_contact_list.email_addresses + bar_contact_list.email_addresses).uniq + end + + let :a11_deliver_to do + { + hub_users: 'all', + contact_lists: [ 'foo', 'bar' ], + slack_channels: [ '#baz' ] + } + end + let :expected_a11_recipients do + ([ hub_user_1.email, hub_user_2.email ] + foo_contact_list.email_addresses + bar_contact_list.email_addresses).uniq + end + + before do + stub_const 'AnnouncementMailer', announcement_mailer + stub_const 'SLACK_NOTIFIER', slack_notifier + + allow(ContactList).to receive(:find).with('foo').and_return(foo_contact_list) + allow(ContactList).to receive(:find).with('bar').and_return(bar_contact_list) + + @a1 = create :announcement, publish_at: 1.hour.ago, status: :delivered + @a2 = create :announcement, publish_at: 1.minute.ago, status: :awaiting_delivery, deliver_to: a2_deliver_to + @a3 = create :announcement, publish_at: 1.minute.ago, status: :delivering + @a4 = create :announcement, publish_at: 1.hour.ago, status: :awaiting_delivery, deliver_to: a4_deliver_to + @a5 = create :announcement, publish_at: 2.hours.ago, status: :awaiting_delivery, deliver_to: a5_deliver_to + @a6 = create :announcement, publish_at: 1.hour.from_now, status: :awaiting_delivery, deliver_to: { hub_users: 'all' } + @a7 = create :announcement, publish_at: 3.hours.ago, status: :awaiting_delivery, deliver_to: {} + @a8 = create :announcement, publish_at: 4.hours.ago, status: :awaiting_delivery, deliver_to: { slack_channels: [], contact_lists: [] } + @a9 = create :announcement, publish_at: 1.hour.ago, status: :awaiting_delivery, deliver_to: { hub_users: nil } + @a10 = create :announcement, publish_at: 5.hours.ago, status: :awaiting_resend, deliver_to: a10_deliver_to + @a11 = create :announcement_from_template, publish_at: 6.hours.ago, status: :awaiting_delivery, deliver_to: a11_deliver_to + @a12 = create :announcement_from_template, publish_at: 1.hour.from_now, status: :awaiting_resend, deliver_to: { hub_users: 'all' } + + @service = AnnouncementsProcessorService.new 50, Rails.logger + end + + it 'should process pending announcements that need to be delivered' do + expect(@service).to receive(:process).with(@a2).and_call_original + a2_mailer = double + expect(announcement_mailer).to receive(:announcement_email).with( + @a2.tap { |a| a.status = :delivering }, + expected_a2_recipients, + false + ).and_return(a2_mailer) + expect(a2_mailer).to receive(:deliver_later) + expect(slack_notifier).to receive(:post) + .with(attachments: anything, channel: '#foo', icon_emoji: anything) + expect(slack_notifier).to receive(:post) + .with(attachments: anything, channel: '#bar', icon_emoji: anything) + + expect(@service).to receive(:process).with(@a4).and_call_original + a4_mailer = double + expect(announcement_mailer).to receive(:announcement_email).with( + @a4.tap { |a| a.status = :delivering }, + expected_a4_recipients, + false + ).and_return(a4_mailer) + expect(a4_mailer).to receive(:deliver_later) + + expect(@service).to receive(:process).with(@a5).and_call_original + expect(slack_notifier).to receive(:post) + .with(attachments: anything, channel: '#foo', icon_emoji: anything) + + expect(@service).to receive(:process).with(@a7).and_call_original + + expect(@service).to receive(:process).with(@a8).and_call_original + + expect(@service).to receive(:process).with(@a9).and_call_original + + expect(@service).to receive(:process).with(@a10).and_call_original + a10_mailer = double + expect(announcement_mailer).to receive(:announcement_email).with( + @a10.tap { |a| a.status = :delivering }, + expected_a10_recipients, + true + ).and_return(a10_mailer) + expect(a10_mailer).to receive(:deliver_later) + expect(slack_notifier).to receive(:post) + .with(attachments: anything, channel: '#baz', icon_emoji: anything) + + expect(@service).to receive(:process).with(@a11).and_call_original + a11_mailer = double + expect(announcement_mailer).to receive(:announcement_email).with( + @a11.tap { |a| a.status = :delivering }, + expected_a10_recipients, + false + ).and_return(a11_mailer) + expect(a11_mailer).to receive(:deliver_later) + expect(slack_notifier).to receive(:post) + .with(attachments: anything, channel: '#baz', icon_emoji: anything) + + @service.run + + expect(@a1.reload.status).to eq 'delivered' + expect(@a2.reload.status).to eq 'delivered' + expect(@a3.reload.status).to eq 'delivering' + expect(@a4.reload.status).to eq 'delivered' + expect(@a5.reload.status).to eq 'delivered' + expect(@a6.reload.status).to eq 'awaiting_delivery' + expect(@a7.reload.status).to eq 'delivery_not_required' + expect(@a8.reload.status).to eq 'delivery_not_required' + expect(@a9.reload.status).to eq 'delivery_not_required' + expect(@a10.reload.status).to eq 'delivered' + expect(@a11.reload.status).to eq 'delivered' + end end - let :a4_deliver_to do - { - hub_users: 'all', - contact_lists: [ 'foo', 'bar' ], - slack_channels: [] - } - end - let :expected_a4_recipients do - ([ hub_user_1.email, hub_user_2.email ] + foo_contact_list.email_addresses + bar_contact_list.email_addresses).uniq - end + context 'with announcements feature flag disabled' do + before do + FeatureFlagService.create_or_update(:announcements, false) + end - let :a5_deliver_to do - { - hub_users: '', - contact_lists: [], - slack_channels: [ '#foo' ] - } - end + it 'should not do anything' do + service = AnnouncementsProcessorService.new(50, Rails.logger) - let :a10_deliver_to do - { - hub_users: 'all', - contact_lists: [ 'foo', 'bar' ], - slack_channels: [ '#baz' ] - } - end - let :expected_a10_recipients do - ([ hub_user_1.email, hub_user_2.email ] + foo_contact_list.email_addresses + bar_contact_list.email_addresses).uniq - end - - let :a11_deliver_to do - { - hub_users: 'all', - contact_lists: [ 'foo', 'bar' ], - slack_channels: [ '#baz' ] - } - end - let :expected_a11_recipients do - ([ hub_user_1.email, hub_user_2.email ] + foo_contact_list.email_addresses + bar_contact_list.email_addresses).uniq - end - - before do - stub_const 'AnnouncementMailer', announcement_mailer - stub_const 'SLACK_NOTIFIER', slack_notifier - - allow(ContactList).to receive(:find).with('foo').and_return(foo_contact_list) - allow(ContactList).to receive(:find).with('bar').and_return(bar_contact_list) - - @a1 = create :announcement, publish_at: 1.hour.ago, status: :delivered - @a2 = create :announcement, publish_at: 1.minute.ago, status: :awaiting_delivery, deliver_to: a2_deliver_to - @a3 = create :announcement, publish_at: 1.minute.ago, status: :delivering - @a4 = create :announcement, publish_at: 1.hour.ago, status: :awaiting_delivery, deliver_to: a4_deliver_to - @a5 = create :announcement, publish_at: 2.hours.ago, status: :awaiting_delivery, deliver_to: a5_deliver_to - @a6 = create :announcement, publish_at: 1.hour.from_now, status: :awaiting_delivery, deliver_to: { hub_users: 'all' } - @a7 = create :announcement, publish_at: 3.hours.ago, status: :awaiting_delivery, deliver_to: {} - @a8 = create :announcement, publish_at: 4.hours.ago, status: :awaiting_delivery, deliver_to: { slack_channels: [], contact_lists: [] } - @a9 = create :announcement, publish_at: 1.hour.ago, status: :awaiting_delivery, deliver_to: { hub_users: nil } - @a10 = create :announcement, publish_at: 5.hours.ago, status: :awaiting_resend, deliver_to: a10_deliver_to - @a11 = create :announcement_from_template, publish_at: 6.hours.ago, status: :awaiting_delivery, deliver_to: a11_deliver_to - @a12 = create :announcement_from_template, publish_at: 1.hour.from_now, status: :awaiting_resend, deliver_to: { hub_users: 'all' } - - @service = AnnouncementsProcessorService.new 50, Rails.logger - end + expect(Announcement).to receive(:published).never + expect(service).to receive(:process).never - it 'should process pending announcements that need to be delivered' do - expect(@service).to receive(:process).with(@a2).and_call_original - a2_mailer = double - expect(announcement_mailer).to receive(:announcement_email).with( - @a2.tap { |a| a.status = :delivering }, - expected_a2_recipients, - false - ).and_return(a2_mailer) - expect(a2_mailer).to receive(:deliver_later) - expect(slack_notifier).to receive(:post) - .with(attachments: anything, channel: '#foo', icon_emoji: anything) - expect(slack_notifier).to receive(:post) - .with(attachments: anything, channel: '#bar', icon_emoji: anything) - - expect(@service).to receive(:process).with(@a4).and_call_original - a4_mailer = double - expect(announcement_mailer).to receive(:announcement_email).with( - @a4.tap { |a| a.status = :delivering }, - expected_a4_recipients, - false - ).and_return(a4_mailer) - expect(a4_mailer).to receive(:deliver_later) - - expect(@service).to receive(:process).with(@a5).and_call_original - expect(slack_notifier).to receive(:post) - .with(attachments: anything, channel: '#foo', icon_emoji: anything) - - expect(@service).to receive(:process).with(@a7).and_call_original - - expect(@service).to receive(:process).with(@a8).and_call_original - - expect(@service).to receive(:process).with(@a9).and_call_original - - expect(@service).to receive(:process).with(@a10).and_call_original - a10_mailer = double - expect(announcement_mailer).to receive(:announcement_email).with( - @a10.tap { |a| a.status = :delivering }, - expected_a10_recipients, - true - ).and_return(a10_mailer) - expect(a10_mailer).to receive(:deliver_later) - expect(slack_notifier).to receive(:post) - .with(attachments: anything, channel: '#baz', icon_emoji: anything) - - expect(@service).to receive(:process).with(@a11).and_call_original - a11_mailer = double - expect(announcement_mailer).to receive(:announcement_email).with( - @a11.tap { |a| a.status = :delivering }, - expected_a10_recipients, - false - ).and_return(a11_mailer) - expect(a11_mailer).to receive(:deliver_later) - expect(slack_notifier).to receive(:post) - .with(attachments: anything, channel: '#baz', icon_emoji: anything) - - @service.run - - expect(@a1.reload.status).to eq 'delivered' - expect(@a2.reload.status).to eq 'delivered' - expect(@a3.reload.status).to eq 'delivering' - expect(@a4.reload.status).to eq 'delivered' - expect(@a5.reload.status).to eq 'delivered' - expect(@a6.reload.status).to eq 'awaiting_delivery' - expect(@a7.reload.status).to eq 'delivery_not_required' - expect(@a8.reload.status).to eq 'delivery_not_required' - expect(@a9.reload.status).to eq 'delivery_not_required' - expect(@a10.reload.status).to eq 'delivered' - expect(@a11.reload.status).to eq 'delivered' + service.run + end end end diff --git a/platform-hub-web/src/app/app.module.js b/platform-hub-web/src/app/app.module.js index 1a41f7c9..28cf7b6e 100644 --- a/platform-hub-web/src/app/app.module.js +++ b/platform-hub-web/src/app/app.module.js @@ -121,6 +121,7 @@ angular .constant('apiEndpoint', apiEndpoint) .constant('apiBackoffTimeMs', 2000) .constant('featureFlagKeys', { + announcements: 'announcements', dockerRepos: 'docker_repos', docsSync: 'docs_sync', helpSearch: 'help_search', diff --git a/platform-hub-web/src/app/app.routes.js b/platform-hub-web/src/app/app.routes.js index 0e509abc..a692ada0 100644 --- a/platform-hub-web/src/app/app.routes.js +++ b/platform-hub-web/src/app/app.routes.js @@ -721,6 +721,7 @@ export const appRoutes = function ($stateProvider, $urlRouterProvider, $location component: AnnouncementsEditorList, data: { authenticate: true, + featureFlags: [featureFlagKeys.announcements], rolesPermitted: ['admin'] } }) @@ -732,6 +733,7 @@ export const appRoutes = function ($stateProvider, $urlRouterProvider, $location }, data: { authenticate: true, + featureFlags: [featureFlagKeys.announcements], rolesPermitted: ['admin'] }, params: { @@ -746,6 +748,7 @@ export const appRoutes = function ($stateProvider, $urlRouterProvider, $location }, data: { authenticate: true, + featureFlags: [featureFlagKeys.announcements], rolesPermitted: ['admin'] } }) @@ -753,7 +756,8 @@ export const appRoutes = function ($stateProvider, $urlRouterProvider, $location url: '/global', component: GlobalAnnouncements, data: { - authenticate: true + authenticate: true, + featureFlags: [featureFlagKeys.announcements] } }) .state('announcements.templates', { @@ -766,6 +770,7 @@ export const appRoutes = function ($stateProvider, $urlRouterProvider, $location component: AnnouncementTemplatesList, data: { authenticate: true, + featureFlags: [featureFlagKeys.announcements], rolesPermitted: ['admin'] } }) @@ -777,6 +782,7 @@ export const appRoutes = function ($stateProvider, $urlRouterProvider, $location }, data: { authenticate: true, + featureFlags: [featureFlagKeys.announcements], rolesPermitted: ['admin'] } }) @@ -785,6 +791,7 @@ export const appRoutes = function ($stateProvider, $urlRouterProvider, $location component: AnnouncementTemplatesForm, data: { authenticate: true, + featureFlags: [featureFlagKeys.announcements], rolesPermitted: ['admin'] } }) @@ -796,6 +803,7 @@ export const appRoutes = function ($stateProvider, $urlRouterProvider, $location }, data: { authenticate: true, + featureFlags: [featureFlagKeys.announcements], rolesPermitted: ['admin'] } }) diff --git a/platform-hub-web/src/app/help/faq/faq-entries.html b/platform-hub-web/src/app/help/faq/faq-entries.html index 51531ca4..04ca3a71 100644 --- a/platform-hub-web/src/app/help/faq/faq-entries.html +++ b/platform-hub-web/src/app/help/faq/faq-entries.html @@ -95,7 +95,7 @@ -
  • +
  • You can view global announcements about the platform
  • @@ -191,7 +191,7 @@
      -
    • +
    • You can mark all global announcements as read by clicking on the "Mark all read" button on the top right hand side of the Global Announcements page.
    • diff --git a/platform-hub-web/src/app/layout/shell.component.js b/platform-hub-web/src/app/layout/shell.component.js index 67fa46fa..d6181e15 100644 --- a/platform-hub-web/src/app/layout/shell.component.js +++ b/platform-hub-web/src/app/layout/shell.component.js @@ -109,13 +109,15 @@ function ShellController($scope, $mdSidenav, authService, roleCheckerService, ev title: 'Announcements', state: 'announcements.editor.list', activeState: 'announcements.editor', - icon: ctrl.announcementsIcon + icon: ctrl.announcementsIcon, + featureFlags: [featureFlagKeys.announcements] }, { title: 'Announcement Templates', state: 'announcements.templates.list', activeState: 'announcements.templates', - icon: ctrl.announcementsIcon + icon: ctrl.announcementsIcon, + featureFlags: [featureFlagKeys.announcements] }, { title: 'Costs Reports', diff --git a/platform-hub-web/src/app/layout/shell.html b/platform-hub-web/src/app/layout/shell.html index d6b6dfd1..d86ef596 100644 --- a/platform-hub-web/src/app/layout/shell.html +++ b/platform-hub-web/src/app/layout/shell.html @@ -53,7 +53,7 @@

      {{$ctrl.AppSettings.getAppTitle()}}

      - + @@ -65,6 +65,7 @@

      {{$ctrl.AppSettings.getAppTitle()}}