mirror of
https://github.com/discourse/discourse.git
synced 2024-12-11 18:53:40 +08:00
12a18d4d55
This commit main goal was to comply with Zeitwerk and properly rely on autoloading. To achieve this, most resources have been namespaced under the `Chat` module. - Given all models are now namespaced with `Chat::` and would change the stored types in DB when using polymorphism or STI (single table inheritance), this commit uses various Rails methods to ensure proper class is loaded and the stored name in DB is unchanged, eg: `Chat::Message` model will be stored as `"ChatMessage"`, and `"ChatMessage"` will correctly load `Chat::Message` model. - Jobs are now using constants only, eg: `Jobs::Chat::Foo` and should only be enqueued this way Notes: - This commit also used this opportunity to limit the number of registered css files in plugin.rb - `discourse_dev` support has been removed within this commit and will be reintroduced later <!-- NOTE: All pull requests should have tests (rspec in Ruby, qunit in JavaScript). If your code does not include test coverage, please include an explanation of why it was omitted. -->
282 lines
9.7 KiB
Ruby
282 lines
9.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
RSpec.describe "Create channel", type: :system, js: true do
|
|
fab!(:category_1) { Fabricate(:category) }
|
|
|
|
let(:chat_page) { PageObjects::Pages::Chat.new }
|
|
let(:channel_modal) { PageObjects::Modals::ChatChannelCreate.new }
|
|
|
|
before { chat_system_bootstrap }
|
|
|
|
context "when user cannot create channel" do
|
|
fab!(:current_user) { Fabricate(:user) }
|
|
before { sign_in(current_user) }
|
|
|
|
it "does not show the create channel button" do
|
|
chat_page.visit_browse
|
|
expect(chat_page).not_to have_new_channel_button
|
|
end
|
|
end
|
|
|
|
context "when can create channel" do
|
|
fab!(:current_admin_user) { Fabricate(:admin) }
|
|
before { sign_in(current_admin_user) }
|
|
|
|
context "when selecting a category" do
|
|
it "shows access hint" do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.select_category(category_1)
|
|
|
|
expect(channel_modal).to have_create_hint(Group[:everyone].name)
|
|
end
|
|
|
|
it "does not override channel name if that was already specified" do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.fill_name("My Cool Channel")
|
|
channel_modal.select_category(category_1)
|
|
|
|
expect(channel_modal).to have_name_prefilled("My Cool Channel")
|
|
end
|
|
|
|
context "when category is private" do
|
|
fab!(:group_1) { Fabricate(:group) }
|
|
fab!(:private_category_1) { Fabricate(:private_category, group: group_1) }
|
|
|
|
it "shows access hint when selecting the category" do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.select_category(private_category_1)
|
|
|
|
expect(channel_modal).to have_create_hint(group_1.name)
|
|
end
|
|
|
|
context "when category is a child" do
|
|
fab!(:group_2) { Fabricate(:group) }
|
|
fab!(:child_category) do
|
|
Fabricate(:private_category, parent_category_id: private_category_1.id, group: group_2)
|
|
end
|
|
|
|
it "shows access hint when selecting the category" do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.select_category(child_category)
|
|
|
|
expect(channel_modal).to have_create_hint(group_2.name)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when category has a malicious group name" do
|
|
fab!(:group_1) do
|
|
group = Group.new(name: "<script>e</script>")
|
|
group.save(validate: false)
|
|
group
|
|
end
|
|
fab!(:private_category_1) { Fabricate(:private_category, group: group_1) }
|
|
|
|
it "escapes the group name" do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.select_category(private_category_1)
|
|
expect(page).to have_no_css(".loading-permissions")
|
|
|
|
expect(channel_modal.create_channel_hint["innerHTML"].strip).to include(
|
|
"<script>e</script>",
|
|
)
|
|
end
|
|
end
|
|
|
|
it "autogenerates slug from name and changes slug placeholder" do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
name = "Cats & Dogs"
|
|
channel_modal.select_category(category_1)
|
|
channel_modal.fill_name(name)
|
|
channel_modal.fill_description("All kind of cute cats")
|
|
|
|
wait_for_attribute(channel_modal.slug_input, :placeholder, "cats-dogs")
|
|
|
|
channel_modal.click_primary_button
|
|
|
|
expect(page).to have_content(name)
|
|
created_channel = Chat::Channel.find_by(chatable_id: category_1.id)
|
|
expect(created_channel.slug).to eq("cats-dogs")
|
|
expect(page).to have_current_path(chat.channel_path(created_channel.slug, created_channel.id))
|
|
end
|
|
|
|
it "allows the user to set a slug independently of name" do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
name = "Cats & Dogs"
|
|
channel_modal.select_category(category_1)
|
|
channel_modal.fill_name(name)
|
|
channel_modal.fill_description("All kind of cute cats")
|
|
channel_modal.fill_slug("pets-everywhere")
|
|
channel_modal.click_primary_button
|
|
|
|
expect(page).to have_content(name)
|
|
created_channel = Chat::Channel.find_by(chatable_id: category_1.id)
|
|
expect(created_channel.slug).to eq("pets-everywhere")
|
|
expect(page).to have_current_path(chat.channel_path(created_channel.slug, created_channel.id))
|
|
end
|
|
|
|
context "when saving" do
|
|
context "when user has chosen to automatically add users" do
|
|
let(:dialog) { PageObjects::Components::Dialog.new }
|
|
let(:name) { "Cats & Dogs" }
|
|
|
|
before do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.fill_name(name)
|
|
end
|
|
|
|
context "for a public category" do
|
|
before do
|
|
channel_modal.select_category(category_1)
|
|
find(".auto-join-channel__label").click
|
|
channel_modal.click_primary_button
|
|
end
|
|
|
|
it "displays the correct warning" do
|
|
expect(dialog).to have_content(
|
|
I18n.t(
|
|
"js.chat.create_channel.auto_join_users.public_category_warning",
|
|
category: category_1.name,
|
|
),
|
|
)
|
|
end
|
|
|
|
it "allows the user to proceed with channel creation" do
|
|
dialog.click_yes
|
|
expect(page).to have_content(name)
|
|
created_channel = Chat::Channel.find_by(chatable_id: category_1.id)
|
|
expect(page).to have_current_path(
|
|
chat.channel_path(created_channel.slug, created_channel.id),
|
|
)
|
|
end
|
|
|
|
it "does nothing if no is clicked" do
|
|
dialog.click_no
|
|
expect(page).to have_css(".create-channel-modal")
|
|
expect(Chat::Channel.exists?(chatable_id: category_1.id)).to eq(false)
|
|
end
|
|
end
|
|
|
|
context "for a private category" do
|
|
fab!(:group_1) { Fabricate(:group) }
|
|
fab!(:user_1) { Fabricate(:user) }
|
|
fab!(:private_category) { Fabricate(:private_category, group: group_1) }
|
|
|
|
before do
|
|
group_1.add(user_1)
|
|
channel_modal.select_category(private_category)
|
|
find(".auto-join-channel__label").click
|
|
channel_modal.click_primary_button
|
|
end
|
|
|
|
context "when only 1 group can access the category" do
|
|
it "displays the correct warning" do
|
|
expect(dialog).to have_content(
|
|
I18n.t(
|
|
"js.chat.create_channel.auto_join_users.warning_1_group",
|
|
count: 1,
|
|
group: "@#{group_1.name}",
|
|
),
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when 2 groups can access the category" do
|
|
fab!(:group_2) { Fabricate(:group) }
|
|
fab!(:category_group_2) do
|
|
CategoryGroup.create(group: group_2, category: private_category)
|
|
end
|
|
|
|
it "displays the correct warning" do
|
|
expect(dialog).to have_content(
|
|
I18n.t(
|
|
"js.chat.create_channel.auto_join_users.warning_2_groups",
|
|
count: 1,
|
|
group1: "@#{group_1.name}",
|
|
group2: "@#{group_2.name}",
|
|
),
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when > 2 groups can access the category" do
|
|
fab!(:group_2) { Fabricate(:group) }
|
|
fab!(:category_group_2) do
|
|
CategoryGroup.create(group: group_2, category: private_category)
|
|
end
|
|
|
|
fab!(:group_3) { Fabricate(:group) }
|
|
fab!(:category_group_3) do
|
|
CategoryGroup.create(group: group_3, category: private_category)
|
|
end
|
|
|
|
it "displays the correct warning" do
|
|
# NOTE: This has to be hardcoded because the I18n module in ruby
|
|
# does not support messageFormat.
|
|
expect(dialog).to have_content(
|
|
"Automatically add 1 user from @#{group_1.name} and 2 other groups?",
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context "when error" do
|
|
it "displays the error" do
|
|
existing_channel = Fabricate(:chat_channel)
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.select_category(existing_channel.chatable)
|
|
channel_modal.fill_name(existing_channel.name)
|
|
channel_modal.click_primary_button
|
|
|
|
expect(page).to have_content(I18n.t("chat.errors.channel_exists_for_category"))
|
|
end
|
|
end
|
|
|
|
context "when slug is already being used" do
|
|
it "displays the error" do
|
|
Fabricate(:chat_channel, slug: "pets-everywhere")
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.select_category(category_1)
|
|
channel_modal.fill_name("Testing")
|
|
channel_modal.fill_slug("pets-everywhere")
|
|
channel_modal.click_primary_button
|
|
|
|
expect(page).to have_content(
|
|
"Slug " + I18n.t("chat.category_channel.errors.is_already_in_use"),
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when successful" do
|
|
it "redirects to created channel" do
|
|
chat_page.visit_browse
|
|
chat_page.new_channel_button.click
|
|
channel_modal.select_category(category_1)
|
|
expect(channel_modal).to have_name_prefilled(category_1.name)
|
|
|
|
channel_modal.fill_description("All kind of cute cats")
|
|
channel_modal.click_primary_button
|
|
|
|
expect(page).to have_content(category_1.name)
|
|
created_channel = Chat::Channel.find_by(chatable_id: category_1.id)
|
|
expect(page).to have_current_path(
|
|
chat.channel_path(created_channel.slug, created_channel.id),
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|