mirror of
https://github.com/discourse/discourse.git
synced 2026-08-06 13:08:40 +08:00
Livestream topics need as much space as possible because they have an added chat sidebar. This change adds a transformer that allows the plugin to use the progress bar instead of the timeline, which saves a good amount of space while still allowing navigation through many posts. This also solves a minor issue when entering 20+ posts deep into a livestream topic would prevent you from getting the livestream layout (hidden avatar) when viewing OP. <img width="3012" height="1724" alt="image" src="https://github.com/user-attachments/assets/2576ce2b-b900-4c58-bf25-9c611f9659e4" />
280 lines
8 KiB
Ruby
Vendored
280 lines
8 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
|
|
|
|
describe "#event_watching_invitee_status" do
|
|
fab!(:viewer, :user)
|
|
|
|
def parsed_json_for(user)
|
|
JSON.parse(
|
|
described_class.new(TopicView.new(topic), scope: Guardian.new(user), root: false).to_json,
|
|
)
|
|
end
|
|
|
|
def create_event
|
|
DiscoursePostEvent::Event.create!(
|
|
id: first_post.id,
|
|
original_starts_at: 1.hour.from_now,
|
|
original_ends_at: 2.hours.from_now,
|
|
)
|
|
end
|
|
|
|
it "returns the status the current user answered with" do
|
|
event = create_event
|
|
DiscoursePostEvent::Invitee.create_attendance!(viewer.id, event.id, :going)
|
|
|
|
expect(parsed_json_for(viewer)["event_watching_invitee_status"]).to eq("going")
|
|
end
|
|
|
|
it "is null when the current user has not answered" do
|
|
create_event
|
|
|
|
expect(parsed_json_for(viewer)["event_watching_invitee_status"]).to be_nil
|
|
end
|
|
|
|
it "is not included when the topic has no event" do
|
|
first_post
|
|
|
|
expect(parsed_json_for(viewer)).not_to have_key("event_watching_invitee_status")
|
|
end
|
|
|
|
it "is not included for anonymous users" do
|
|
create_event
|
|
|
|
expect(parsed_json_for(nil)).not_to have_key("event_watching_invitee_status")
|
|
end
|
|
|
|
it "is not affected by other users' answers" do
|
|
event = create_event
|
|
DiscoursePostEvent::Invitee.create_attendance!(Fabricate(:user).id, event.id, :going)
|
|
|
|
expect(parsed_json_for(viewer)["event_watching_invitee_status"]).to be_nil
|
|
end
|
|
end
|
|
|
|
describe "#chat_channel_id" do
|
|
fab!(:category)
|
|
fab!(:viewer, :user)
|
|
let(:topic) { Fabricate(:topic, category:) }
|
|
|
|
before do
|
|
SiteSetting.chat_enabled = true
|
|
# Don't do onebox-warming job so it doesn't make a real request
|
|
Jobs.run_later!
|
|
first_post
|
|
end
|
|
|
|
def create_event(livestream:, status: :public, raw_invitees: nil)
|
|
DiscoursePostEvent::Event.create!(
|
|
id: first_post.id,
|
|
original_starts_at: 1.hour.from_now,
|
|
original_ends_at: 2.hours.from_now,
|
|
location: "https://example.com/live",
|
|
status: DiscoursePostEvent::Event.statuses[status],
|
|
raw_invitees:,
|
|
livestream:,
|
|
)
|
|
end
|
|
|
|
def parsed_json_for(user)
|
|
JSON.parse(
|
|
described_class.new(TopicView.new(topic), scope: Guardian.new(user), root: false).to_json,
|
|
)
|
|
end
|
|
|
|
it "is included while the event is a livestream" do
|
|
create_event(livestream: true)
|
|
|
|
expect(topic.topic_chat_channel).to be_present
|
|
expect(parsed_json_for(viewer)["chat_channel_id"]).to eq(
|
|
topic.topic_chat_channel.chat_channel_id,
|
|
)
|
|
end
|
|
|
|
it "is not included once livestream is disabled, even if the channel row remains" do
|
|
event = create_event(livestream: true)
|
|
event.update!(livestream: false)
|
|
|
|
expect(topic.reload.topic_chat_channel).to be_present
|
|
expect(parsed_json_for(viewer)).not_to have_key("chat_channel_id")
|
|
end
|
|
|
|
it "is not included for users who cannot join the event" do
|
|
create_event(livestream: true, status: :private, raw_invitees: ["some_group"])
|
|
|
|
expect(parsed_json_for(viewer)).not_to have_key("chat_channel_id")
|
|
end
|
|
|
|
it "is not included for anonymous users on private events" do
|
|
create_event(livestream: true, status: :private, raw_invitees: ["some_group"])
|
|
|
|
expect(parsed_json_for(nil)).not_to have_key("chat_channel_id")
|
|
end
|
|
|
|
it "is included for anonymous users on public events" do
|
|
create_event(livestream: true)
|
|
|
|
expect(parsed_json_for(nil)["chat_channel_id"]).to eq(
|
|
topic.topic_chat_channel.chat_channel_id,
|
|
)
|
|
end
|
|
|
|
it "is still included once the event is expired" do
|
|
create_event(livestream: true)
|
|
|
|
freeze_time(3.hours.from_now)
|
|
|
|
expect(parsed_json_for(viewer)["chat_channel_id"]).to eq(
|
|
topic.topic_chat_channel.chat_channel_id,
|
|
)
|
|
end
|
|
|
|
it "is included for users in a group that can join the event" do
|
|
group = Fabricate(:group)
|
|
group.add(viewer)
|
|
create_event(livestream: true, status: :private, raw_invitees: [group.name])
|
|
|
|
expect(parsed_json_for(viewer)["chat_channel_id"]).to eq(
|
|
topic.topic_chat_channel.chat_channel_id,
|
|
)
|
|
end
|
|
|
|
it "is included for admins even when they cannot join the event" do
|
|
create_event(livestream: true, status: :private, raw_invitees: ["some_group"])
|
|
|
|
expect(parsed_json_for(Fabricate(:admin))["chat_channel_id"]).to eq(
|
|
topic.topic_chat_channel.chat_channel_id,
|
|
)
|
|
end
|
|
end
|
|
end
|