Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Flaky schedule date alerts notifications job spec #15040

Merged
merged 4 commits into from
Mar 20, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,24 @@
# See docs/COPYRIGHT.rdoc for more details.
#++

require 'spec_helper'
require "spec_helper"

RSpec.describe Notifications::ScheduleDateAlertsNotificationsJob, type: :job, with_ee: %i[date_alerts] do
include ActiveSupport::Testing::TimeHelpers

shared_let(:project) { create(:project, name: 'main') }
shared_let(:project) { create(:project, name: "main") }
# Paris and Berlin are both UTC+01:00 (CET) or UTC+02:00 (CEST)
shared_let(:timezone_paris) { ActiveSupport::TimeZone['Europe/Paris'] }
shared_let(:timezone_paris) { ActiveSupport::TimeZone["Europe/Paris"] }
# Kathmandu is UTC+05:45 (no DST)
shared_let(:timezone_kathmandu) { ActiveSupport::TimeZone['Asia/Kathmandu'] }
shared_let(:timezone_kathmandu) { ActiveSupport::TimeZone["Asia/Kathmandu"] }
shared_let(:user_paris) do
create(:user,
firstname: 'Paris',
firstname: "Paris",
preferences: { time_zone: timezone_paris.name })
end
shared_let(:user_kathmandu) do
create(:user,
firstname: 'Kathmandu',
firstname: "Kathmandu",
preferences: { time_zone: timezone_kathmandu.name })
end

Expand All @@ -60,14 +60,14 @@ def set_scheduled_time(scheduled_at)

# Converts "hh:mm" into { hour: h, min: m }
def time_hash(time)
%i[hour min].zip(time.split(':', 2).map(&:to_i)).to_h
%i[hour min].zip(time.split(":", 2).map(&:to_i)).to_h
end

def timezone_time(time, timezone)
timezone.now.change(time_hash(time))
end

def run_job(scheduled_at: '1:00', local_time: '1:04', timezone: timezone_paris)
def run_job(scheduled_at:, local_time:, timezone:)
set_scheduled_time(timezone_time(scheduled_at, timezone))
travel_to(timezone_time(local_time, timezone)) do
GoodJob.perform_inline
Expand All @@ -86,104 +86,95 @@ def deserialize_job(job)

def expect_job(job, *arguments)
job_data = deserialize_job(job)
expect(job_data['job_class']).to eql(job.job_class)
expect(job_data['arguments']).to match_array arguments
expect(job_data['executions']).to eq 0
expect(job_data["job_class"]).to eql(job.job_class)
expect(job_data["arguments"]).to match_array arguments
expect(job_data["executions"]).to eq 0
end

shared_examples_for 'job execution creates date alerts creation job' do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:04' }
let(:user) { user_paris }

it 'creates the job for the user' do
shared_examples_for "job execution creates date alerts creation job" do
it "creates the job for the user" do
expect do
run_job(timezone:, scheduled_at:, local_time:) do
j = GoodJob::Job.where(job_class: "Notifications::CreateDateAlertsNotificationsJob")
.order(created_at: :desc)
.last
expect_job(j, user)
end
end.to change(GoodJob::Job, :count).by 1
end.to change { GoodJob::Job.where(job_class: "Notifications::CreateDateAlertsNotificationsJob").count }.by 1
toy marked this conversation as resolved.
Show resolved Hide resolved
end
end

shared_examples_for 'job execution creates no date alerts creation job' do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:04' }

it 'creates no job' do
shared_examples_for "job execution creates no date alerts creation job" do
it "creates no job" do
expect do
run_job(timezone:, scheduled_at:, local_time:)
end.not_to change(GoodJob::Job, :count)
end
end

describe '#perform' do
context 'for users whose local time is 1:00 am (UTC+1) when the job is executed' do
it_behaves_like 'job execution creates date alerts creation job' do
describe "#perform" do
context "for users whose local time is 1:00 am (UTC+1) when the job is executed" do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:04' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:04" }
let(:user) { user_paris }
end
end

context 'for users whose local time is 1:00 am (UTC+05:45) when the job is executed' do
it_behaves_like 'job execution creates date alerts creation job' do
context "for users whose local time is 1:00 am (UTC+05:45) when the job is executed" do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_kathmandu }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:04' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:04" }
let(:user) { user_kathmandu }
end
end

context 'without enterprise token', with_ee: false do
it_behaves_like 'job execution creates no date alerts creation job' do
context "without enterprise token", with_ee: false do
it_behaves_like "job execution creates no date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:04' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:04" }
end
end

context 'when scheduled and executed at 01:00 am local time' do
it_behaves_like 'job execution creates date alerts creation job' do
context "when scheduled and executed at 01:00 am local time" do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:00' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:00" }
let(:user) { user_paris }
end
end

context 'when scheduled and executed at 01:14 am local time' do
it_behaves_like 'job execution creates date alerts creation job' do
context "when scheduled and executed at 01:14 am local time" do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:14' }
let(:local_time) { '1:14' }
let(:scheduled_at) { "1:14" }
let(:local_time) { "1:14" }
let(:user) { user_paris }
end
end

context 'when scheduled and executed at 01:15 am local time' do
it_behaves_like 'job execution creates no date alerts creation job' do
context "when scheduled and executed at 01:15 am local time" do
it_behaves_like "job execution creates no date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:15' }
let(:local_time) { '1:15' }
let(:scheduled_at) { "1:15" }
let(:local_time) { "1:15" }
end
end

context 'when scheduled at 01:00 am local time and executed at 01:37 am local time' do
it_behaves_like 'job execution creates date alerts creation job' do
context "when scheduled at 01:00 am local time and executed at 01:37 am local time" do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:37' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:37" }
let(:user) { user_paris }
end
end

context 'with a user having only due_date active in notification settings' do
context "with a user having only due_date active in notification settings" do
before do
NotificationSetting
.where(user: user_paris)
Expand All @@ -192,15 +183,15 @@ def expect_job(job, *arguments)
overdue: nil)
end

it_behaves_like 'job execution creates date alerts creation job' do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:00' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:00" }
let(:user) { user_paris }
end
end

context 'with a user having only start_date active in notification settings' do
context "with a user having only start_date active in notification settings" do
before do
NotificationSetting
.where(user: user_paris)
Expand All @@ -209,15 +200,15 @@ def expect_job(job, *arguments)
overdue: nil)
end

it_behaves_like 'job execution creates date alerts creation job' do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:00' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:00" }
let(:user) { user_paris }
end
end

context 'with a user having only overdue active in notification settings' do
context "with a user having only overdue active in notification settings" do
before do
NotificationSetting
.where(user: user_paris)
Expand All @@ -226,15 +217,15 @@ def expect_job(job, *arguments)
overdue: 1)
end

it_behaves_like 'job execution creates date alerts creation job' do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:00' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:00" }
let(:user) { user_paris }
end
end

context 'without a user having notification settings' do
context "without a user having notification settings" do
before do
NotificationSetting
.where(user: user_paris)
Expand All @@ -243,14 +234,14 @@ def expect_job(job, *arguments)
overdue: nil)
end

it_behaves_like 'job execution creates no date alerts creation job' do
it_behaves_like "job execution creates no date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:00' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:00" }
end
end

context 'with a user having only a project active notification settings' do
context "with a user having only a project active notification settings" do
before do
NotificationSetting
.where(user: user_paris)
Expand All @@ -266,23 +257,23 @@ def expect_job(job, *arguments)
overdue: nil)
end

it_behaves_like 'job execution creates date alerts creation job' do
it_behaves_like "job execution creates date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:00' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:00" }
let(:user) { user_paris }
end
end

context 'with a locked user' do
context "with a locked user" do
before do
user_paris.locked!
end

it_behaves_like 'job execution creates no date alerts creation job' do
it_behaves_like "job execution creates no date alerts creation job" do
let(:timezone) { timezone_paris }
let(:scheduled_at) { '1:00' }
let(:local_time) { '1:00' }
let(:scheduled_at) { "1:00" }
let(:local_time) { "1:00" }
end
end
end
Expand Down
Loading