0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-08 17:53:55 +08:00
discourse/plugins/chat/spec/system/drawer_spec.rb
Chris Alberti c863228004
FIX: Don't double subfolder when clicking chat icon after opening chat in drawer (#42030)
Fixes a corner case where the chat URL was stored including prefix when
opening a chat channel in drawer mode, and then the prefix was doubled
when clicking the chat icon in the header.

The URL with the subfolder is stored by storeChatURL() when opening a
chat channel in drawer mode. Then after navigating away, if the user
clicked the chat icon in the header, it would prepend the subfolder
again.

Now we strip the subfolder away in lastKnownChatURL(), mirroring the fix
in lastKnownAppURL().

Adds a system spec reproducing the issue which fails before the fix.

Reported in Meta /t/401446
2026-07-27 09:12:40 -05:00

356 lines
11 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe "Drawer" do
fab!(:current_user, :user)
let(:chat_page) { PageObjects::Pages::Chat.new }
let(:channel_page) { PageObjects::Pages::ChatChannel.new }
let(:drawer_page) { PageObjects::Pages::ChatDrawer.new }
before do
chat_system_bootstrap
sign_in(current_user)
chat_page.prefers_drawer
end
it "handles transitions between drawer and full page and applies appropriate classes" do
visit("/")
chat_page.open_from_header
expect(page).to have_css(
"body.has-drawer-chat.has-chat.chat-drawer-active.chat-drawer-expanded",
)
expect(page).to have_css("html.has-drawer-chat.has-chat")
expect(page).to have_no_css("body.has-full-page-chat")
drawer_page.maximize
expect(page).to have_css("body.has-chat.has-full-page-chat")
expect(page).to have_css("html.has-chat.has-full-page-chat")
expect(page).to have_no_css("body.has-drawer-chat")
expect(page).to have_no_css("html.has-drawer-chat")
end
it "respects drawer preference after page refresh" do
visit("/")
chat_page.open_from_header
expect(page).to have_css("body.has-drawer-chat")
drawer_page.close
expect(page).to have_no_css("body.chat-drawer-active")
refresh
chat_page.open_from_header
expect(page).to have_css("body.has-drawer-chat")
expect(page).to have_no_css("body.has-full-page-chat")
end
context "when on channel" do
fab!(:channel, :chat_channel)
fab!(:membership) do
Fabricate(:user_chat_channel_membership, user: current_user, chat_channel: channel)
end
context "when clicking channel title" do
before do
visit("/")
chat_page.open_from_header
drawer_page.open_channel(channel)
page.find(".c-navbar__channel-title").click
end
it "opens channel settings page" do
expect(drawer_page).to have_channel_settings
end
it "has tabs for settings and members" do
expect(drawer_page).to have_css(".c-channel-info__nav li a", text: "Settings")
expect(drawer_page).to have_css(".c-channel-info__nav li a", text: "Members")
end
it "opens correct tab when clicked" do
page.find(".c-channel-info__nav li a", text: "Members").click
expect(drawer_page).to have_channel_members
page.find(".c-channel-info__nav li a", text: "Settings").click
expect(drawer_page).to have_channel_settings
end
it "has a back button" do
expect(drawer_page).to have_css(".c-navbar__back-button")
end
end
end
context "when opening" do
it "uses stored size" do
visit("/") # we need to visit the page first to set the local storage
page.execute_script "window.localStorage.setItem('discourse_chat_drawer_size_width','500');"
page.execute_script "window.localStorage.setItem('discourse_chat_drawer_size_height','500');"
visit("/")
chat_page.open_from_header
chat_drawer = page.find(".chat-drawer")
expect(chat_drawer).to have_computed_style(width: "500px")
expect(chat_drawer).to have_computed_style(height: "500px")
end
it "has a default size" do
visit("/")
chat_page.open_from_header
chat_drawer = page.find(".chat-drawer")
expect(chat_drawer).to have_computed_style(width: "400px")
expect(chat_drawer).to have_computed_style(height: "530px")
end
end
context "when toggling open/close" do
it "toggles a css class on body" do
visit("/")
chat_page.open_from_header
expect(page.find("body.chat-drawer-active")).to be_visible
drawer_page.close
expect(page.find("body:not(.chat-drawer-active)")).to be_visible
end
end
context "when closing the drawer" do
fab!(:channel_1, :chat_channel)
fab!(:message_1) { Fabricate(:chat_message, chat_channel: channel_1) }
before { channel_1.add(current_user) }
it "resets the active message" do
visit("/")
chat_page.open_from_header
drawer_page.open_channel(channel_1)
channel_page.hover_message(message_1)
expect(page).to have_css(".chat-message-actions-container", visible: :all)
drawer_page.close
expect(page).to have_no_css(".chat-message-actions-container")
end
end
context "when clicking the drawer's header" do
it "collapses the drawer" do
visit("/")
chat_page.open_from_header
expect(page).to have_selector(".chat-drawer.is-expanded")
expect(page).to have_selector("body.chat-drawer-expanded")
page.find(".c-navbar").click
expect(page).to have_selector(".chat-drawer:not(.is-expanded)")
expect(page).to have_selector("body:not(.chat-drawer-expanded)")
end
end
context "when going from drawer to full page" do
fab!(:channel_1, :chat_channel)
fab!(:channel_2, :chat_channel)
fab!(:user_1, :user)
before do
current_user.upsert_custom_fields(::Chat::LAST_CHAT_CHANNEL_ID => channel_1.id)
channel_1.add(current_user)
channel_2.add(current_user)
channel_1.add(user_1)
channel_2.add(user_1)
end
it "correctly resets subscriptions" do
visit("/")
chat_page.open_from_header
drawer_page.maximize
chat_page.minimize_full_page
drawer_page.maximize
expect(page).to have_css(".chat-channel.--loaded[data-id='#{channel_1.id}']")
Fabricate(
:chat_message,
chat_channel: channel_1,
user: user_1,
use_service: true,
message: "onlyonce",
)
expect(page).to have_content("onlyonce", count: 1)
chat_page.visit_channel(channel_2)
expect(page).to have_content("onlyonce", count: 0)
end
end
context "when subfolder install" do
fab!(:channel, :chat_channel)
before do
current_user.upsert_custom_fields(::Chat::LAST_CHAT_CHANNEL_ID => channel.id)
channel.add(current_user)
set_subfolder "/discuss"
end
it "works to go from full page to drawer" do
visit("/discuss/chat")
chat_page.minimize_full_page
expect(drawer_page).to have_open_channel(channel)
end
it "returns to the homepage when toggling chat icon after expanding drawer to full page" do
SiteSetting.chat_separate_sidebar_mode = "fullscreen"
SiteSetting.top_menu = "categories|latest|new"
visit("/discuss/")
chat_page.open_from_header
expect(page).to have_css("body.has-drawer-chat")
drawer_page.maximize
expect(page).to have_css("body.has-full-page-chat")
find(".chat-header-icon").click
expect(page).to have_current_path("/discuss/categories")
expect(page).to have_no_css("body.has-full-page-chat")
end
it "does not double the subfolder when returning to a chat channel via the header icon after a programmatic navigation" do
visit("/discuss/chat")
expect(page).to have_css("html.has-chat")
find(".title a").click
expect(page).to have_current_path("/discuss/")
find(".sidebar-section-link.channel-#{channel.id}").click
expect(page).to have_css("body.has-drawer-chat")
drawer_page.close
find(".chat-header-icon").click
expect(page).to have_current_path("/discuss/")
expect(page).to have_css("body.has-drawer-chat")
expect(page).to have_css(".chat-channel.--loaded[data-id='#{channel.id}']")
end
end
context "when sending a message from a thread while viewing a topic" do
fab!(:post1, :post)
fab!(:post2) { Fabricate(:post, topic: post1.topic) }
fab!(:channel) { Fabricate(:chat_channel, threading_enabled: true) }
fab!(:thread) { Fabricate(:chat_thread, channel: channel, with_replies: 1, use_service: true) }
fab!(:membership) do
Fabricate(:user_chat_channel_membership, user: current_user, chat_channel: channel)
end
let(:topic_page) { PageObjects::Pages::Topic.new }
let(:thread_list_page) { PageObjects::Components::Chat::ThreadList.new }
let(:thread_page) { PageObjects::Pages::ChatThread.new }
before { Jobs.run_immediately! }
it "has topic context" do
tested_context = {}
blk = ->(*, context) { tested_context = context }
DiscourseEvent.on(:chat_message_created, &blk)
topic_page.visit_topic(post1.topic)
chat_page.open_from_header
drawer_page.open_channel(channel)
drawer_page.open_thread_list
thread_list_page.open_thread(thread)
thread_page.send_message
try_until_success do
expect(tested_context.dig(:context, :post_ids)).to eq([post1.id, post2.id])
expect(tested_context.dig(:context, :topic_id)).to eq(post1.topic_id)
end
ensure
DiscourseEvent.off(:chat_message_created, &blk)
end
end
describe "with chat footer" do
it "opens channels list by default" do
visit("/")
chat_page.open_from_header
expect(drawer_page).to have_open_channels
end
it "shows footer nav when 2 or more tabs are accessible" do
visit("/")
chat_page.open_from_header
expect(page).to have_css(".chat-drawer .c-footer")
expect(page).to have_css(".chat-drawer .c-footer__item", count: 3)
end
it "hides footer nav when only channels are accessible" do
SiteSetting.direct_message_enabled_groups = Group::AUTO_GROUPS[:staff]
visit("/")
chat_page.open_from_header
expect(page).to have_no_css(".chat-drawer .c-footer")
end
context "when clicking footer nav items" do
fab!(:channel) { Fabricate(:chat_channel, threading_enabled: true) }
fab!(:other_user, :user)
before do
SiteSetting.chat_threads_enabled = true
channel.add(current_user)
channel.add(other_user)
end
it "shows active state" do
visit("/")
chat_page.open_from_header
drawer_page.click_direct_messages
expect(page).to have_css("#c-footer-direct-messages.--active")
end
context "with viewable threads" do
before do
message = Fabricate(:chat_message, chat_channel: channel, user: current_user)
thread = Fabricate(:chat_thread, channel: channel, original_message: message)
thread.add(current_user)
Fabricate(:chat_message, chat_channel: channel, thread: thread, user: other_user)
thread.set_replies_count_cache(1, update_db: true)
end
it "redirects to correct route" do
visit("/")
chat_page.open_from_header
drawer_page.click_direct_messages
expect(drawer_page).to have_open_direct_messages
drawer_page.click_channels
expect(drawer_page).to have_open_channels
drawer_page.click_user_threads
expect(drawer_page).to have_open_user_threads
end
end
end
end
end