mirror of
https://github.com/discourse/discourse.git
synced 2024-12-22 21:46:08 +08:00
79d2eb5beb
Support threads in DMs and group chats so members can keep their conversations organized. This change adds a new toggle switch for threads within the Chat Channel Settings screen. For new direct message channels threading is enabled by default. We have made a decision to exclude direct message threads from the My Threads screen for now.
319 lines
10 KiB
Ruby
319 lines
10 KiB
Ruby
# frozen_string_literal: true
|
||
|
||
RSpec.describe "Channel - Info - Settings page", type: :system do
|
||
fab!(:current_user) { Fabricate(:user) }
|
||
fab!(:channel_1) { Fabricate(:category_channel) }
|
||
|
||
let(:chat_page) { PageObjects::Pages::Chat.new }
|
||
let(:toasts) { PageObjects::Components::Toasts.new }
|
||
let(:channel_settings_page) { PageObjects::Pages::ChatChannelSettings.new }
|
||
|
||
before do
|
||
chat_system_bootstrap
|
||
sign_in(current_user)
|
||
end
|
||
|
||
context "when visiting from browse page" do
|
||
context "when clicking back button" do
|
||
it "redirects to browse page" do
|
||
chat_page.visit_browse
|
||
find(".c-navbar__back-button").click
|
||
|
||
expect(page).to have_current_path("/chat/browse/open")
|
||
end
|
||
end
|
||
end
|
||
|
||
context "when visiting from channel page" do
|
||
context "when clicking back button" do
|
||
it "redirects to channel page" do
|
||
chat_page.visit_channel(channel_1)
|
||
find(".c-navbar__channel-title").click
|
||
find(".c-navbar__back-button").click
|
||
|
||
expect(page).to have_current_path(chat.channel_path(channel_1.slug, channel_1.id))
|
||
end
|
||
end
|
||
end
|
||
|
||
context "as unauthorized user" do
|
||
before { SiteSetting.chat_allowed_groups = Fabricate(:group).id }
|
||
|
||
it "redirects to home page" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page).to have_current_path("/latest")
|
||
end
|
||
end
|
||
|
||
context "as not allowed to see the channel" do
|
||
fab!(:channel_1) { Fabricate(:private_category_channel) }
|
||
|
||
it "redirects to browse page" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page).to have_current_path("/chat/browse/open")
|
||
end
|
||
end
|
||
|
||
context "as not member of channel" do
|
||
it "shows settings page" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
|
||
end
|
||
end
|
||
|
||
context "as regular user of channel" do
|
||
before { channel_1.add(current_user) }
|
||
|
||
it "shows settings page" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
|
||
end
|
||
|
||
it "shows channel info" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page.find(".badge-category__name")).to have_content(channel_1.chatable.name)
|
||
expect(page.find(".c-channel-settings__name")).to have_content(channel_1.title)
|
||
expect(page.find(".c-channel-settings__slug")).to have_content(channel_1.slug)
|
||
end
|
||
|
||
it "can’t edit name or slug" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page).to have_no_selector(".edit-name-slug-btn")
|
||
end
|
||
|
||
it "can’t edit description" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page).to have_no_selector(".edit-description-btn")
|
||
end
|
||
|
||
it "escapes channel title" do
|
||
channel_1.update!(name: "<script>alert('hello')</script>")
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page.find(".c-channel-settings__name")["innerHTML"].strip).to eq(
|
||
"<script>alert('hello')</script>",
|
||
)
|
||
expect(page.find(".chat-channel-name__label")["innerHTML"].strip).to include(
|
||
"<script>alert('hello')</script>",
|
||
)
|
||
end
|
||
|
||
it "is not showing admin section" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page).to have_no_css("[data-section='admin']")
|
||
end
|
||
|
||
it "can mute channel" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
membership = channel_1.membership_for(current_user)
|
||
|
||
expect {
|
||
PageObjects::Components::DToggleSwitch.new(".c-channel-settings__mute-switch").toggle
|
||
|
||
expect(toasts).to have_success(I18n.t("js.saved"))
|
||
}.to change { membership.reload.muted }.from(false).to(true)
|
||
end
|
||
|
||
it "can change notification level" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
membership = channel_1.membership_for(current_user)
|
||
|
||
expect {
|
||
select_kit =
|
||
PageObjects::Components::SelectKit.new(".c-channel-settings__notifications-selector")
|
||
select_kit.expand
|
||
select_kit.select_row_by_name("Never")
|
||
|
||
expect(toasts).to have_success(I18n.t("js.saved"))
|
||
}.to change { membership.reload.notification_level }.from("mention").to("never")
|
||
end
|
||
|
||
it "can unfollow channel" do
|
||
membership = channel_1.membership_for(current_user)
|
||
|
||
chat_page.visit_channel_settings(channel_1)
|
||
click_button(I18n.t("js.chat.channel_settings.leave_channel"))
|
||
|
||
expect(page).to have_current_path("/chat/browse/open")
|
||
expect(membership.reload.following).to eq(false)
|
||
end
|
||
|
||
context "when group channel" do
|
||
fab!(:channel_1) do
|
||
Fabricate(:direct_message_channel, group: true, users: [current_user, Fabricate(:user)])
|
||
end
|
||
|
||
before { channel_1.add(current_user) }
|
||
|
||
it "can leave channel" do
|
||
membership = channel_1.membership_for(current_user)
|
||
|
||
chat_page.visit_channel_settings(channel_1)
|
||
click_button(I18n.t("js.chat.channel_settings.leave_channel"))
|
||
|
||
expect(page).to have_current_path("/chat/browse/open")
|
||
expect(Chat::UserChatChannelMembership.exists?(membership.id)).to eq(false)
|
||
expect(
|
||
channel_1.chatable.direct_message_users.where(user_id: current_user.id).exists?,
|
||
).to eq(false)
|
||
end
|
||
end
|
||
|
||
context "when direct message channel" do
|
||
fab!(:channel_1) do
|
||
Fabricate(:direct_message_channel, users: [current_user, Fabricate(:user)])
|
||
end
|
||
|
||
before { channel_1.add(current_user) }
|
||
|
||
it "can toggle threading" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect {
|
||
PageObjects::Components::DToggleSwitch.new(".c-channel-settings__threading-switch").toggle
|
||
expect(toasts).to have_success(I18n.t("js.saved"))
|
||
}.to change { channel_1.reload.threading_enabled }.from(true).to(false)
|
||
end
|
||
end
|
||
end
|
||
|
||
context "as staff" do
|
||
fab!(:current_user) { Fabricate(:admin) }
|
||
|
||
before { channel_1.add(current_user) }
|
||
|
||
it "can edit name" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
edit_modal = channel_settings_page.open_edit_modal
|
||
|
||
expect(edit_modal).to have_name_input(channel_1.title)
|
||
|
||
name = "A new name"
|
||
|
||
edit_modal.fill_and_save_name(name)
|
||
|
||
expect(page).to have_content(name)
|
||
end
|
||
|
||
it "can edit description" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
find(".edit-description-btn").click
|
||
|
||
expect(page).to have_selector(
|
||
".chat-modal-edit-channel-description__description-input",
|
||
text: channel_1.description,
|
||
)
|
||
|
||
description = "A new description"
|
||
find(".chat-modal-edit-channel-description__description-input").fill_in(with: description)
|
||
find(".create").click
|
||
|
||
expect(page).to have_content(description)
|
||
end
|
||
|
||
it "can edit slug" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
edit_modal = channel_settings_page.open_edit_modal
|
||
|
||
slug = "gonzo-slug"
|
||
|
||
expect(edit_modal).to have_slug_input(channel_1.slug)
|
||
|
||
edit_modal.fill_and_save_slug(slug)
|
||
|
||
expect(page).to have_current_path("/chat/c/gonzo-slug/#{channel_1.id}")
|
||
end
|
||
|
||
it "can clear the slug to use the autogenerated version based on the name" do
|
||
channel_1.update!(name: "test channel")
|
||
chat_page.visit_channel_settings(channel_1)
|
||
edit_modal = channel_settings_page.open_edit_modal
|
||
|
||
expect(edit_modal).to have_slug_input(channel_1.slug)
|
||
|
||
edit_modal.fill_in_slug_input("")
|
||
edit_modal.wait_for_auto_generated_slug
|
||
edit_modal.save_changes
|
||
|
||
expect(page).to have_current_path("/chat/c/test-channel/#{channel_1.id}")
|
||
end
|
||
|
||
it "shows settings page" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
|
||
end
|
||
|
||
it "can change auto join setting" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect {
|
||
PageObjects::Components::DToggleSwitch.new(".c-channel-settings__auto-join-switch").toggle
|
||
find("#dialog-holder .btn-primary").click
|
||
|
||
expect(toasts).to have_success(I18n.t("js.saved"))
|
||
}.to change { channel_1.reload.auto_join_users }.from(false).to(true)
|
||
end
|
||
|
||
it "can change allow channel wide mentions" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect {
|
||
PageObjects::Components::DToggleSwitch.new(
|
||
".c-channel-settings__channel-wide-mentions",
|
||
).toggle
|
||
|
||
expect(toasts).to have_success(I18n.t("js.saved"))
|
||
}.to change { channel_1.reload.allow_channel_wide_mentions }.from(true).to(false)
|
||
end
|
||
|
||
it "can close channel" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect {
|
||
click_button(I18n.t("js.chat.channel_settings.close_channel"))
|
||
find("#chat-channel-toggle-btn").click
|
||
|
||
expect(page).to have_content(I18n.t("js.chat.channel_status.closed_header"))
|
||
}.to change { channel_1.reload.status }.from("open").to("closed")
|
||
end
|
||
|
||
it "can enable threading" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
expect {
|
||
PageObjects::Components::DToggleSwitch.new(".c-channel-settings__threading-switch").toggle
|
||
|
||
expect(toasts).to have_success(I18n.t("js.saved"))
|
||
}.to change { channel_1.reload.threading_enabled }.from(false).to(true)
|
||
end
|
||
|
||
it "can delete channel" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
|
||
click_button(I18n.t("js.chat.channel_settings.delete_channel"))
|
||
fill_in("channel-delete-confirm-name", with: channel_1.title)
|
||
find_button("chat-confirm-delete-channel", disabled: false).click
|
||
expect(page).to have_content(I18n.t("js.chat.channel_delete.process_started"))
|
||
end
|
||
|
||
it "doesn’t delete when confirmation is wrong" do
|
||
chat_page.visit_channel_settings(channel_1)
|
||
find(".delete-btn").click
|
||
fill_in("channel-delete-confirm-name", with: channel_1.title + "wrong")
|
||
|
||
expect(page).to have_button("chat-confirm-delete-channel", disabled: true)
|
||
end
|
||
end
|
||
end
|