mirror of
https://github.com/discourse/discourse.git
synced 2026-08-08 17:53:55 +08:00
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
356 lines
11 KiB
Ruby
Vendored
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
|