discourse/spec/services/user_notification_schedule_...

157 lines
6.7 KiB
Ruby

# frozen_string_literal: true
RSpec.describe UserNotificationScheduleProcessor do
include ActiveSupport::Testing::TimeHelpers
fab!(:user) { Fabricate(:user) }
let(:standard_schedule) {
schedule = UserNotificationSchedule.create({
user: user
}.merge(UserNotificationSchedule::DEFAULT))
schedule.enabled = true
schedule.save
schedule
}
describe "#create_do_not_disturb_timings" do
[
{ timezone: "UTC", offset: "+00:00" },
{ timezone: "America/Chicago", offset: "-06:00" },
{ timezone: "Australia/Sydney", offset: "+11:00" },
].each do |timezone_info|
it 'creates dnd timings correctly for each timezone' do
user.user_option.update(timezone: timezone_info[:timezone])
travel_to Time.new(2020, 1, 4, 12, 0, 0, "+00:00") do
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(standard_schedule)
# The default schedule is 8am - 5pm.
# Expect DND timings to fill gaps before/after those times for 3 days.
dnd_timings = user.do_not_disturb_timings
offset = timezone_info[:offset]
expect(dnd_timings[0].starts_at).to eq_time(Time.new(2020, 1, 4, 0, 0, 0, offset))
expect(dnd_timings[0].ends_at).to eq_time(Time.new(2020, 1, 4, 7, 59, 0, offset))
expect(dnd_timings[1].starts_at).to eq_time(Time.new(2020, 1, 4, 17, 0, 0, offset))
expect(dnd_timings[1].ends_at).to eq_time(Time.new(2020, 1, 5, 7, 59, 0, offset))
expect(dnd_timings[2].starts_at).to eq_time(Time.new(2020, 1, 5, 17, 0, 0, offset))
expect(dnd_timings[2].ends_at).to eq_time(Time.new(2020, 1, 6, 7, 59, 0, offset))
expect(dnd_timings[3].starts_at).to eq_time(Time.new(2020, 1, 6, 17, 0, 0, offset))
expect(dnd_timings[3].ends_at).to be_within(1.second).of Time.new(2020, 1, 6, 23, 59, 59, offset)
end
end
end
it 'does not create duplicate record, but ensures the correct records exist' do
user.user_option.update(timezone: "UTC")
travel_to Time.new(2020, 1, 4, 12, 0, 0, "+00:00") do
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(standard_schedule)
expect(user.do_not_disturb_timings.count).to eq(4)
# All duplicates, so no new timings should be created
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(standard_schedule)
expect(user.do_not_disturb_timings.count).to eq(4)
end
travel_to Time.new(2020, 1, 5, 12, 0, 0, "+00:00") do
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(standard_schedule)
# There is 1 overlap, so expect only 3 more to be created
expect(user.do_not_disturb_timings.count).to eq(7)
end
travel_to Time.new(2020, 1, 10, 12, 0, 0, "+00:00") do
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(standard_schedule)
# There is no overlap, so expect only 4 more to be created
expect(user.do_not_disturb_timings.count).to eq(11)
end
end
it 'extends previously scheduled dnd timings to remove gaps' do
user.user_option.update(timezone: "UTC")
travel_to Time.new(2020, 1, 4, 12, 0, 0, "+00:00") do
existing_timing = user.do_not_disturb_timings.create(
scheduled: true,
starts_at: 1.day.ago,
ends_at: Time.new(2020, 1, 03, 11, 0, 0, "+00:00").end_of_day
)
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(standard_schedule)
expect(existing_timing.reload.ends_at).to eq_time(Time.new(2020, 1, 4, 7, 59, 0, "+00:00"))
end
end
it 'creates the correct timings when the whole schedule is DND (-1)' do
user.user_option.update(timezone: "UTC")
schedule = standard_schedule
schedule.update(
day_0_start_time: -1,
day_1_start_time: -1,
day_2_start_time: -1,
day_3_start_time: -1,
day_4_start_time: -1,
day_5_start_time: -1,
day_6_start_time: -1,
)
travel_to Time.new(2020, 1, 4, 12, 0, 0, "+00:00") do
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(schedule)
expect(user.do_not_disturb_timings.count).to eq(1)
expect(user.do_not_disturb_timings.first.starts_at).to eq_time(Time.new(2020, 1, 4, 0, 0, 0, "+00:00"))
expect(user.do_not_disturb_timings.first.ends_at).to be_within(1.second).of Time.new(2020, 1, 6, 23, 59, 59, "+00:00")
end
end
it 'creates the correct timings at the end of a month and year' do
user.user_option.update(timezone: "UTC")
schedule = standard_schedule
schedule.update(
day_3_start_time: -1, # December 31, 2020 was a thursday. testing more cases.
)
travel_to Time.new(2020, 12, 31, 12, 0, 0, "+00:00") do
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(schedule)
expect(user.do_not_disturb_timings[0].starts_at).to eq_time(Time.new(2020, 12, 31, 0, 0, 0, "+00:00"))
expect(user.do_not_disturb_timings[0].ends_at).to eq_time(Time.new(2021, 1, 1, 7, 59, 0, "+00:00"))
expect(user.do_not_disturb_timings[1].starts_at).to eq_time(Time.new(2021, 1, 1, 17, 0, 0, "+00:00"))
expect(user.do_not_disturb_timings[1].ends_at).to eq_time(Time.new(2021, 1, 2, 7, 59, 0, "+00:00"))
expect(user.do_not_disturb_timings[2].starts_at).to eq_time(Time.new(2021, 1, 2, 17, 0, 0, "+00:00"))
expect(user.do_not_disturb_timings[2].ends_at).to be_within(1.second).of Time.new(2021, 1, 2, 23, 59, 59, "+00:00")
end
end
it 'handles midnight to midnight for multiple days (no timings created)' do
user.user_option.update(timezone: "UTC")
schedule = standard_schedule
schedule.update(
day_0_start_time: 0,
day_0_end_time: 1440,
day_1_start_time: 0,
day_1_end_time: 1440,
day_2_start_time: 0,
day_2_end_time: 1440,
)
travel_to Time.new(2021, 1, 4, 12, 0, 0, "+00:00") do
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(schedule)
expect(user.do_not_disturb_timings.count).to eq(0)
end
end
it 'publishes to message bus when the user should enter DND' do
user.user_option.update(timezone: "UTC")
schedule = standard_schedule
travel_to Time.new(2020, 12, 31, 1, 0, 0, "+00:00") do
messages = MessageBus.track_publish("/do-not-disturb/#{user.id}") do
UserNotificationScheduleProcessor.create_do_not_disturb_timings_for(schedule)
end
expect(messages.size).to eq(1)
expect(messages[0].data[:ends_at]).to eq(Time.new(2020, 12, 31, 7, 59, 0, "+00:00").httpdate)
expect(messages[0].user_ids).to contain_exactly(user.id)
end
end
end
end