discourse/plugins/discourse-calendar/spec/serializers/topic_view_serializer_spec.rb
Bannon Tanner c557cafe43
FEAT: add all_day option to calendar events (#38511)
This feature adds all day functionality to discourse-calendar post event
events, and fixes the display across different timezones.

There are many smaller changes in here to get the date to display
correctly across timezones, including on the event topic itself, the
upcoming events block in right-sidebar-blocks, the upcoming events page
(calendar), and the badge on topics in list view.

####  A bit more detailed:
- Adds new column `all_day` to `discourse_post_event_events` and wires
that up through the model, serializer, and controller
- Modifies existing methods for formatting time to account for `all_day`
flag
- Modifies the frontend components to check for the `all_day` flag and,
if present, display the dates without times and ignoring timezones
- The post event builder form will now snap the times to 00:00 and 23:59
if all day is checked, and then hide the time entry input boxes
- Adds the all day flag to the webhook payload and parses start/end
times based on that flag
- Tests for all of the new functionality

#### Demo video


https://github.com/user-attachments/assets/b4067764-d2e6-48df-b95e-5b8c717f8716
2026-03-18 11:29:30 -05:00

134 lines
3.6 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe TopicViewSerializer do
subject(:serializer) do
described_class.new(TopicView.new(topic), scope: Guardian.new, root: false)
end
let(:topic) { Fabricate(:topic) }
let(:first_post) { Fabricate(:post, topic:) }
let(:parsed_json) { JSON.parse(serializer.to_json) }
before do
freeze_time(Time.utc(2020, 4, 24, 14, 10))
Jobs.run_immediately!
SiteSetting.calendar_enabled = true
SiteSetting.discourse_post_event_enabled = true
end
context "without timezone" do
before do
DiscoursePostEvent::Event.create!(
id: first_post.id,
original_starts_at: 1.hour.from_now,
original_ends_at: 2.hours.from_now,
)
end
describe "#event_starts_at" do
it "returns the start time of the event in proper format" do
expect(parsed_json["event_starts_at"]).to eq("2020-04-24T15:10:00.000Z")
end
end
describe "#event_ends_at" do
it "returns the end time of the event in proper format" do
expect(parsed_json["event_ends_at"]).to eq("2020-04-24T16:10:00.000Z")
end
end
describe "#event_timezone" do
it "is not included when event has no timezone" do
expect(parsed_json).not_to have_key("event_timezone")
end
end
describe "#event_show_local_time" do
it "returns false when show_local_time is not set" do
expect(parsed_json["event_show_local_time"]).to eq(false)
end
end
end
context "with timezone and show_local_time true" do
before do
DiscoursePostEvent::Event.create!(
id: first_post.id,
original_starts_at: 1.hour.from_now,
original_ends_at: 2.hours.from_now,
timezone: "Australia/Sydney",
show_local_time: true,
)
end
describe "#event_timezone" do
it "returns the timezone of the event" do
expect(parsed_json["event_timezone"]).to eq("Australia/Sydney")
end
end
describe "#event_show_local_time" do
it "returns true when show_local_time is set" do
expect(parsed_json["event_show_local_time"]).to eq(true)
end
end
end
context "with timezone and show_local_time false" do
before do
DiscoursePostEvent::Event.create!(
id: first_post.id,
original_starts_at: 1.hour.from_now,
original_ends_at: 2.hours.from_now,
timezone: "Australia/Sydney",
show_local_time: false,
)
end
describe "#event_timezone" do
it "returns the timezone of the event" do
expect(parsed_json["event_timezone"]).to eq("Australia/Sydney")
end
end
describe "#event_show_local_time" do
it "returns false when show_local_time is explicitly false" do
expect(parsed_json["event_show_local_time"]).to eq(false)
end
end
end
context "with all-day event" do
before do
SiteSetting.display_post_event_date_on_topic_title = true
DiscoursePostEvent::Event.create!(
id: first_post.id,
original_starts_at: Time.utc(2020, 4, 25),
original_ends_at: Time.utc(2020, 4, 27),
all_day: true,
)
end
describe "#event_all_day" do
it "returns true" do
expect(parsed_json["event_all_day"]).to eq(true)
end
end
end
context "without all-day event" do
before do
DiscoursePostEvent::Event.create!(
id: first_post.id,
original_starts_at: 1.hour.from_now,
original_ends_at: 2.hours.from_now,
)
end
describe "#event_all_day" do
it "is not included" do
expect(parsed_json).not_to have_key("event_all_day")
end
end
end
end