diff --git a/app/models/calendar_event.rb b/app/models/calendar_event.rb index 5510b6b3..59ac2f16 100644 --- a/app/models/calendar_event.rb +++ b/app/models/calendar_event.rb @@ -5,7 +5,15 @@ class CalendarEvent < ActiveRecord::Base belongs_to :post belongs_to :user - after_destroy :clear_holiday_user_status + after_save do + if SiteSetting.enable_user_status && underway? + DiscourseCalendar::HolidayStatus.set!(user, ends_at) + end + end + + after_destroy do + DiscourseCalendar::HolidayStatus.clear!(user) if SiteSetting.enable_user_status + end def ends_at end_date || (start_date + 24.hours) @@ -65,14 +73,6 @@ class CalendarEvent < ActiveRecord::Base private - def clear_holiday_user_status - return if user.blank? || user.user_status.blank? - - if DiscourseCalendar::HolidayStatus.is_holiday_status?(user.user_status) - user.clear_status! - end - end - def self.convert_to_date_time(value) return if value.blank? diff --git a/jobs/scheduled/update_holiday_usernames.rb b/jobs/scheduled/update_holiday_usernames.rb index b914f6d7..b7c4b9a2 100644 --- a/jobs/scheduled/update_holiday_usernames.rb +++ b/jobs/scheduled/update_holiday_usernames.rb @@ -47,21 +47,7 @@ module Jobs User .where(id: users_on_holiday.keys) .includes(:user_status) - .each { |u| set_holiday_status(u, users_on_holiday[u.id][:ends_at]) } - end - - def set_holiday_status(user, ends_at) - status = user.user_status - - if status.blank? || - status.expired? || - (DiscourseCalendar::HolidayStatus.is_holiday_status?(status) && status.ends_at != ends_at) - - user.set_status!( - I18n.t("discourse_calendar.holiday_status.description"), - DiscourseCalendar::HolidayStatus::EMOJI, - ends_at) - end + .each { |u| DiscourseCalendar::HolidayStatus.set!(u, users_on_holiday[u.id][:ends_at]) } end end end diff --git a/lib/holiday_status.rb b/lib/holiday_status.rb index d07a2719..fb7940a3 100644 --- a/lib/holiday_status.rb +++ b/lib/holiday_status.rb @@ -4,6 +4,28 @@ module DiscourseCalendar class HolidayStatus EMOJI = 'desert_island' + def self.set!(user, ends_at) + status = user.user_status + + if status.blank? || + status.expired? || + (is_holiday_status?(status) && status.ends_at != ends_at) + + user.set_status!( + I18n.t("discourse_calendar.holiday_status.description"), + EMOJI, + ends_at) + end + end + + def self.clear!(user) + if user.user_status && is_holiday_status?(user.user_status) + user.clear_status! + end + end + + private + def self.is_holiday_status?(status) status.emoji == EMOJI && status.description == I18n.t("discourse_calendar.holiday_status.description") end diff --git a/spec/integration/post_spec.rb b/spec/integration/post_spec.rb index 1423763b..cfedd810 100644 --- a/spec/integration/post_spec.rb +++ b/spec/integration/post_spec.rb @@ -610,14 +610,97 @@ describe Post do before do SiteSetting.holiday_calendar_topic_id = calendar_post.topic_id + SiteSetting.enable_user_status = true + end + + context "when adding a post with an event" do + it "sets holiday user status" do + freeze_time Time.utc(2018, 6, 5, 10, 30) + + raw = 'Vacation [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' + post = create_post(raw: raw, topic: calendar_post.topic) + + status = post.user.user_status + expect(status).to be_present + expect(status.description).to eq(I18n.t("discourse_calendar.holiday_status.description")) + expect(status.emoji).to eq(DiscourseCalendar::HolidayStatus::EMOJI) + expect(status.ends_at).to eq_time(Time.utc(2018, 6, 6, 10, 20)) + end + + it "doesn't set holiday user status if user already has custom user status" do + freeze_time Time.utc(2018, 6, 5, 10, 30) + + # user sets a custom status + custom_status = { + description: "I am working on holiday", + emoji: "construction_worker_man" + } + user.set_status!(custom_status[:description], custom_status[:emoji]) + + raw = 'Vacation [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' + post = create_post(raw: raw, topic: calendar_post.topic, user: user) + + # a holiday status wasn't set: + status = post.user.user_status + expect(status).to be_present + expect(status.description).to eq(custom_status[:description]) + expect(status.emoji).to eq(custom_status[:emoji]) + end + end + + context "when updating event dates" do + it "sets holiday user status" do + freeze_time Time.utc(2018, 6, 5, 10, 30) + today = "2018-06-05" + tomorrow = "2018-06-06" + + raw = "Vacation [date='#{tomorrow}']" + post = create_post(raw: raw, topic: calendar_post.topic) + expect(post.user.user_status).to be_blank + + PostRevisor.new(post).revise!(post.user, { raw: "Vacation [date='#{today}']" }) + post.reload + + status = post.user.user_status + expect(status).to be_present + expect(status.description).to eq(I18n.t("discourse_calendar.holiday_status.description")) + expect(status.emoji).to eq(DiscourseCalendar::HolidayStatus::EMOJI) + expect(status.ends_at).to eq_time(Time.utc(2018, 6, 6, 0, 0)) + end + + it "doesn't set holiday user status if user already has custom user status" do + freeze_time Time.utc(2018, 6, 5, 10, 30) + today = "2018-06-05" + tomorrow = "2018-06-06" + + raw = "Vacation [date='#{tomorrow}']" + post = create_post(raw: raw, topic: calendar_post.topic) + expect(post.user.user_status).to be_blank + + # user sets a custom status + custom_status = { + description: "I am working on holiday", + emoji: "construction_worker_man" + } + post.user.set_status!(custom_status[:description], custom_status[:emoji]) + + PostRevisor.new(post).revise!(post.user, { raw: "Vacation [date='#{today}']" }) + post.reload + + # a holiday status wasn't set: + status = post.user.user_status + expect(status).to be_present + expect(status.description).to eq(custom_status[:description]) + expect(status.emoji).to eq(custom_status[:emoji]) + end end context "when deleting a post with an event" do it "clears user status that was previously set by the calendar plugin" do - SiteSetting.enable_user_status = true + freeze_time Time.utc(2018, 6, 5, 10, 30) + raw = 'Vacation [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' post = create_post(raw: raw, topic: calendar_post.topic) - freeze_time Time.utc(2018, 6, 5, 10, 30) DiscourseCalendar::UpdateHolidayUsernames.new.execute(nil) # the job has set the holiday status: @@ -635,10 +718,10 @@ describe Post do end it "doesn't clear user status that wasn't set by the calendar plugin" do - SiteSetting.enable_user_status = true + freeze_time Time.utc(2018, 6, 5, 10, 30) + raw = 'Vacation [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' post = create_post(raw: raw, topic: calendar_post.topic) - freeze_time Time.utc(2018, 6, 5, 10, 30) DiscourseCalendar::UpdateHolidayUsernames.new.execute(nil) # the job has set the holiday status: @@ -648,7 +731,7 @@ describe Post do expect(status.emoji).to eq(DiscourseCalendar::HolidayStatus::EMOJI) expect(status.ends_at).to eq_time(Time.utc(2018, 6, 6, 10, 20)) - # user set their own status + # user sets a custom status custom_status = { description: "I am working on holiday", emoji: "construction_worker_man" diff --git a/spec/jobs/scheduled/update_holiday_usernames_spec.rb b/spec/jobs/scheduled/update_holiday_usernames_spec.rb index c90a8dd1..202f28ff 100644 --- a/spec/jobs/scheduled/update_holiday_usernames_spec.rb +++ b/spec/jobs/scheduled/update_holiday_usernames_spec.rb @@ -12,10 +12,11 @@ describe DiscourseCalendar::UpdateHolidayUsernames do end it "adds users on holiday to the users_on_holiday list" do + freeze_time Time.utc(2018, 6, 5, 18, 40) + raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' post = create_post(raw: raw, topic: calendar_post.topic) - freeze_time Time.utc(2018, 6, 5, 18, 40) subject.execute(nil) expect(DiscourseCalendar.users_on_holiday).to eq([post.user.username]) @@ -27,13 +28,14 @@ describe DiscourseCalendar::UpdateHolidayUsernames do end it "adds custom field to users on holiday" do + freeze_time Time.utc(2018, 6, 5, 10, 30) + raw1 = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' post1 = create_post(raw: raw1, topic: calendar_post.topic) raw2 = 'Rome [date="2018-06-05"]' # the whole day post2 = create_post(raw: raw2, topic: calendar_post.topic) - freeze_time Time.utc(2018, 6, 5, 10, 30) subject.execute(nil) expect(UserCustomField.exists?(name: DiscourseCalendar::HOLIDAY_CUSTOM_FIELD, user_id: post1.user.id)).to be_truthy expect(UserCustomField.exists?(name: DiscourseCalendar::HOLIDAY_CUSTOM_FIELD, user_id: post2.user.id)).to be_truthy @@ -51,10 +53,11 @@ describe DiscourseCalendar::UpdateHolidayUsernames do it "sets status of users on holiday" do SiteSetting.enable_user_status = true + freeze_time Time.utc(2018, 6, 5, 10, 30) + raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' post = create_post(raw: raw, topic: calendar_post.topic) - freeze_time Time.utc(2018, 6, 5, 10, 30) subject.execute(nil) post.user.reload @@ -67,10 +70,11 @@ describe DiscourseCalendar::UpdateHolidayUsernames do it "doesn't set status of users on holiday if user status is disabled in site settings" do SiteSetting.enable_user_status = false + freeze_time Time.utc(2018, 6, 5, 10, 30) + raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' post = create_post(raw: raw, topic: calendar_post.topic) - freeze_time Time.utc(2018, 6, 5, 10, 30) subject.execute(nil) post.user.reload @@ -79,16 +83,16 @@ describe DiscourseCalendar::UpdateHolidayUsernames do it "holiday status doesn't override status that was set by a user themselves" do SiteSetting.enable_user_status = true + freeze_time Time.utc(2018, 6, 5, 10, 30) + raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' post = create_post(raw: raw, topic: calendar_post.topic) - custom_status = { description: "I am working on holiday", emoji: "construction_worker_man" } post.user.set_status!(custom_status[:description], custom_status[:emoji]) - freeze_time Time.utc(2018, 6, 5, 10, 30) subject.execute(nil) post.user.reload @@ -128,10 +132,11 @@ describe DiscourseCalendar::UpdateHolidayUsernames do it "updates status' ends_at date when user edits a holiday post" do SiteSetting.enable_user_status = true + freeze_time Time.utc(2018, 6, 5, 10, 30) + raw = 'Rome [date="2018-06-05" time="10:20:00"] to [date="2018-06-06" time="10:20:00"]' post = create_post(raw: raw, topic: calendar_post.topic) - freeze_time Time.utc(2018, 6, 5, 10, 30) subject.execute(nil) post.user.reload