From b5fa02bf3339f73d2a3a4bc3e2b02aa0147790b7 Mon Sep 17 00:00:00 2001 From: Mac Siri Date: Thu, 2 Apr 2020 17:24:39 -0400 Subject: [PATCH] Create Broadcasts.rake (#7010) --- .rubocop.yml | 1 + app/models/site_config.rb | 3 ++ lib/tasks/broadcasts.rake | 16 ++++++ .../welcome_notification/generator_spec.rb | 49 ++++++++++++------ spec/tasks/broadcasts_spec.rb | 51 +++++++++++++++++++ 5 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 lib/tasks/broadcasts.rake create mode 100644 spec/tasks/broadcasts_spec.rb diff --git a/.rubocop.yml b/.rubocop.yml index 486722f3e..c10b74b1c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -11,6 +11,7 @@ RSpec/DescribeClass: Exclude: - spec/requests/**/* - spec/system/**/* + - spec/tasks/**/* RSpec/ExampleLength: Max: 15 diff --git a/app/models/site_config.rb b/app/models/site_config.rb index 6369ff448..1cf074f16 100644 --- a/app/models/site_config.rb +++ b/app/models/site_config.rb @@ -25,6 +25,9 @@ class SiteConfig < RailsSettings::Base # Authentication field :authentication_providers, type: :array, default: %w[twitter github] + # Broadcast + field :welcome_notifications_live_at, type: :date + # campaign field :campaign_hero_html_variant_name, type: :string, default: "" field :campaign_featured_tags, type: :array, default: %w[] diff --git a/lib/tasks/broadcasts.rake b/lib/tasks/broadcasts.rake new file mode 100644 index 000000000..2e6455ff4 --- /dev/null +++ b/lib/tasks/broadcasts.rake @@ -0,0 +1,16 @@ +namespace :broadcasts do + desc "Send Welcome Notifications once a day" + task send_welcome_notification_flow: :environment do + # In order to prevent new users from receiving multiple welcome notifications in a day, + # a feature_live_date is required. The script will only be effective after feature_live_date + # and will ultimately be superseded by 7.days.ago when it's larger than feature_live_date. + next unless SiteConfig.welcome_notifications_live_at + + notifications_live_at = SiteConfig.welcome_notifications_live_at + week_ago = 7.days.ago + latest_date = notifications_live_at > week_ago ? notifications_live_at : week_ago + User.select(:id).where("created_at > ?", latest_date).find_each do |user| + Broadcasts::WelcomeNotification::Generator.call(user.id) + end + end +end diff --git a/spec/services/broadcasts/welcome_notification/generator_spec.rb b/spec/services/broadcasts/welcome_notification/generator_spec.rb index 293699be2..b74518ac7 100644 --- a/spec/services/broadcasts/welcome_notification/generator_spec.rb +++ b/spec/services/broadcasts/welcome_notification/generator_spec.rb @@ -1,9 +1,15 @@ require "rails_helper" RSpec.describe Broadcasts::WelcomeNotification::Generator, type: :service do - let(:mascot_account) { create(:user) } - let!(:welcome_thread) { create(:article, user: mascot_account, published: true, tags: "welcome") } - let!(:welcome_broadcast) { create(:welcome_broadcast) } + let(:mascot_account) { create(:user) } + let!(:welcome_thread) { create(:article, user: mascot_account, published: true, tags: "welcome") } + + let_it_be_readonly(:welcome_broadcast) { create(:welcome_broadcast) } + let_it_be_readonly(:twitter_connect_broadcast) { create(:twitter_connect_broadcast) } + let_it_be_readonly(:github_connect_broadcast) { create(:github_connect_broadcast) } + let_it_be_readonly(:customize_feed_broadcast) { create(:customize_feed_broadcast) } + let_it_be_readonly(:discuss_and_ask_broadcast) { create(:discuss_and_ask_broadcast) } + let_it_be_readonly(:customize_ux_broadcast) { create(:customize_ux_broadcast) } before do allow(Notification).to receive(:send_welcome_notification).and_call_original @@ -28,11 +34,27 @@ RSpec.describe Broadcasts::WelcomeNotification::Generator, type: :service do end.to not_change(user.notifications, :count) end - it "sends only 1 notification at a time" do - user = create(:user, :with_identity, identities: ["github"], created_at: 1.week.ago) - expect do - sidekiq_perform_enqueued_jobs { described_class.call(user.id) } - end.to change(user.notifications, :count).by(1) + it "sends only 1 notification at a time, in the correct order" do # rubocop:disable RSpec/MultipleExpectations, RSpec/ExampleLength + user = create(:user, :with_identity, identities: ["github"], created_at: 1.day.ago) + expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect(user.notifications.last.notifiable).to eq(welcome_broadcast) + + Timecop.travel(1.day.since) + expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect(user.notifications.last.notifiable).to eq(twitter_connect_broadcast) + + Timecop.travel(1.day.since) + expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect(user.notifications.last.notifiable).to eq(customize_feed_broadcast) + + Timecop.travel(2.days.since) + expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect(user.notifications.last.notifiable).to eq(customize_ux_broadcast) + + Timecop.travel(1.day.since) + expect { sidekiq_perform_enqueued_jobs { described_class.call(user.id) } }.to change(user.notifications, :count).by(1) + expect(user.notifications.last.notifiable).to eq(discuss_and_ask_broadcast) + Timecop.return end end @@ -64,9 +86,6 @@ RSpec.describe Broadcasts::WelcomeNotification::Generator, type: :service do end describe "#send_authentication_notification" do - let!(:twitter_connect_broadcast) { create(:twitter_connect_broadcast) } - let!(:github_connect_broadcast) { create(:github_connect_broadcast) } - it "does not send notification if user is created less than a day ago" do user = create(:user, :with_identity, identities: ["github"]) sidekiq_perform_enqueued_jobs { described_class.new(user.id).send(:send_authentication_notification) } @@ -110,7 +129,6 @@ RSpec.describe Broadcasts::WelcomeNotification::Generator, type: :service do describe "#send_feed_customization_notification" do let!(:user) { create(:user, :with_identity, identities: %w[twitter github], created_at: 3.days.ago) } - let!(:customize_feed_broadcast) { create(:customize_feed_broadcast) } it "does not send a notification to a newly-created user" do user.update!(created_at: Time.zone.now) @@ -140,7 +158,6 @@ RSpec.describe Broadcasts::WelcomeNotification::Generator, type: :service do describe "#send_ux_customization_notification" do let!(:user) { create(:user, :with_identity, identities: %w[twitter github], created_at: 5.days.ago) } - let!(:customize_ux_broadcast) { create(:customize_ux_broadcast) } it "does not send a notification to a newly-created user" do user.update!(created_at: Time.zone.now) @@ -164,9 +181,9 @@ RSpec.describe Broadcasts::WelcomeNotification::Generator, type: :service do describe "#send_discuss_and_ask_notification" do let!(:user) { create(:user, :with_identity, identities: %w[twitter github], created_at: 6.days.ago) } - let!(:ask_question_broadcast) { create(:ask_question_broadcast) } - let!(:start_discussion_broadcast) { create(:start_discussion_broadcast) } - let!(:discuss_and_ask_broadcast) { create(:discuss_and_ask_broadcast) } + + let_it_be_readonly(:ask_question_broadcast) { create(:ask_question_broadcast) } + let_it_be_readonly(:start_discussion_broadcast) { create(:start_discussion_broadcast) } context "with a user who has asked a question" do it "generates the correct broadcast type and sends the notification to the user" do diff --git a/spec/tasks/broadcasts_spec.rb b/spec/tasks/broadcasts_spec.rb new file mode 100644 index 000000000..cb2dc6528 --- /dev/null +++ b/spec/tasks/broadcasts_spec.rb @@ -0,0 +1,51 @@ +require "rails_helper" + +RSpec.describe "Broadcasts tasks", type: :task do + let(:service) { Broadcasts::WelcomeNotification::Generator } + let(:one_week_from_today) { 1.week.since } + + let_it_be_readonly(:default_config_date) { SiteConfig.welcome_notifications_live_at } + + before do + # Set date to a week from today + SiteConfig.welcome_notifications_live_at = one_week_from_today + allow(service).to receive(:call) + Rake::Task.clear + PracticalDeveloper::Application.load_tasks + end + + after do + SiteConfig.welcome_notifications_live_at = default_config_date + end + + describe "#broadcast_welcome_notification_flow" do + it "does nothing if SiteConfig.welcome_notifications_live_at is nil" do + SiteConfig.welcome_notifications_live_at = nil + create(:user, created_at: 1.day.ago) + Rake::Task["broadcasts:send_welcome_notification_flow"].invoke + expect(service).not_to have_received(:call) + end + + it "does not call upon users created before the start_date" do + # Travel forward one week, and test that a user created 8 days ago does not receive notifications. + Timecop.travel(one_week_from_today) do + create(:user, created_at: 1.day.ago) + Rake::Task["broadcasts:send_welcome_notification_flow"].invoke + expect(service).not_to have_received(:call) + end + end + + it "call upon users created less than a week ago" do + # Travel forward one week (7) + # then travel another week further (14 days) + # On day 14, pressume user is created 6 days ago (created on day 8) + # At this point notifications_live_at < week_ago is true and notifications_live_at is ignored. + Timecop.travel(one_week_from_today + 1.week) do + create_list(:user, 3, created_at: 6.days.ago) + create_list(:user, 1, created_at: 10.days.ago) + Rake::Task["broadcasts:send_welcome_notification_flow"].invoke + expect(service).to have_received(:call).exactly(3) + end + end + end +end