mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 04:41:25 +08:00
FEATURE: introduces group channels (#24288)
Group channels will allow users to create channels with a name and invite people. It's possible to add people even after creation of the channel. Removing users is not yet possible but will be added in the near future. Technically a group channel is `direct_message_channel` with a group attribute set to true on its direct message (chatable). This model might evolve in the future but offers much flexibility for now without having to rely on a complex migration. The commit essentially consists of: - a migration to set existing direct message channels with more than 2 users to a group - a new message creator which allows to search, add members, and create groups - a new `AddUsersToChannel` service - a modified `SearchChatable` service
This commit is contained in:
@ -33,9 +33,13 @@ Fabricator(:private_category_channel, from: :category_channel) do
|
||||
end
|
||||
|
||||
Fabricator(:direct_message_channel, from: :chat_channel) do
|
||||
transient :users, following: true, with_membership: true
|
||||
transient :users, :group, following: true, with_membership: true
|
||||
chatable do |attrs|
|
||||
Fabricate(:direct_message, users: attrs[:users] || [Fabricate(:user), Fabricate(:user)])
|
||||
Fabricate(
|
||||
:direct_message,
|
||||
users: attrs[:users] || [Fabricate(:user), Fabricate(:user)],
|
||||
group: attrs[:group] || false,
|
||||
)
|
||||
end
|
||||
status { :open }
|
||||
name nil
|
||||
|
@ -46,9 +46,39 @@ RSpec.describe Chat::GuardianExtensions do
|
||||
expect(staff_guardian.can_create_chat_channel?).to eq(true)
|
||||
end
|
||||
|
||||
it "only staff can edit chat channels" do
|
||||
expect(guardian.can_edit_chat_channel?).to eq(false)
|
||||
expect(staff_guardian.can_edit_chat_channel?).to eq(true)
|
||||
context "when category channel" do
|
||||
it "allows staff to edit chat channels" do
|
||||
expect(guardian.can_edit_chat_channel?(channel)).to eq(false)
|
||||
expect(staff_guardian.can_edit_chat_channel?(channel)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when direct message channel" do
|
||||
context "when member of channel" do
|
||||
context "when group" do
|
||||
before do
|
||||
dm_channel.chatable.update!(group: true)
|
||||
add_users_to_channel(user, dm_channel)
|
||||
end
|
||||
|
||||
it "allows to edit the channel" do
|
||||
expect(user.guardian.can_edit_chat_channel?(dm_channel)).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when not group" do
|
||||
it "doesn’t allow to edit the channel" do
|
||||
Chat::DirectMessageUser.create(user: user, direct_message: dm_channel.chatable)
|
||||
expect(user.guardian.can_edit_chat_channel?(dm_channel)).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when not member of channel" do
|
||||
it "doesn’t allow to edit the channel" do
|
||||
expect(user.guardian.can_edit_chat_channel?(dm_channel)).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "only staff can close chat channels" do
|
||||
|
@ -102,6 +102,17 @@ module ChatSpecHelpers
|
||||
service_failed!(result) if result.failure?
|
||||
result
|
||||
end
|
||||
|
||||
def add_users_to_channel(users, channel, user: Discourse.system_user)
|
||||
result =
|
||||
::Chat::AddUsersToChannel.call(
|
||||
guardian: user.guardian,
|
||||
channel_id: channel.id,
|
||||
usernames: Array(users).map(&:username),
|
||||
)
|
||||
service_failed!(result) if result.failure?
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
|
@ -0,0 +1,55 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Chat::Api::ChannelsMembershipsController do
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
fab!(:channel_1) do
|
||||
Fabricate(:direct_message_channel, group: true, users: [current_user, Fabricate(:user)])
|
||||
end
|
||||
|
||||
before do
|
||||
SiteSetting.chat_enabled = true
|
||||
SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:everyone]
|
||||
channel_1.add(current_user)
|
||||
sign_in(current_user)
|
||||
end
|
||||
|
||||
describe "#create" do
|
||||
describe "success" do
|
||||
it "works" do
|
||||
add_users_to_channel(current_user, channel_1)
|
||||
post "/chat/api/channels/#{channel_1.id}/memberships",
|
||||
params: {
|
||||
usernames: [Fabricate(:user).username],
|
||||
}
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
context "when users can't be added" do
|
||||
before { channel_1.chatable.update(group: false) }
|
||||
|
||||
it "returns a 422" do
|
||||
post "/chat/api/channels/#{channel_1.id}/memberships",
|
||||
params: {
|
||||
usernames: [Fabricate(:user).username],
|
||||
}
|
||||
|
||||
expect(response.status).to eq(422)
|
||||
expect(response.parsed_body["errors"].first).to eq(
|
||||
I18n.t("chat.errors.users_cant_be_added_to_channel"),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when channel is not found" do
|
||||
before { channel_1.chatable.update!(group: false) }
|
||||
|
||||
it "returns a 404" do
|
||||
get "/chat/api/channels/-999/messages", params: { usernames: [Fabricate(:user).username] }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -14,13 +14,16 @@ RSpec.describe Chat::Api::ChatablesController do
|
||||
describe "without chat permissions" do
|
||||
it "errors errors for anon" do
|
||||
get "/chat/api/chatables"
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
|
||||
it "errors when user cannot chat" do
|
||||
SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:staff]
|
||||
sign_in(current_user)
|
||||
|
||||
get "/chat/api/chatables"
|
||||
|
||||
expect(response.status).to eq(403)
|
||||
end
|
||||
end
|
||||
@ -28,9 +31,11 @@ RSpec.describe Chat::Api::ChatablesController do
|
||||
describe "with chat permissions" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
|
||||
before { sign_in(current_user) }
|
||||
before { channel_1.add(current_user) }
|
||||
|
||||
it "returns results" do
|
||||
sign_in(current_user)
|
||||
|
||||
get "/chat/api/chatables", params: { term: channel_1.name }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
|
@ -23,7 +23,10 @@ RSpec.describe Chat::Api::DirectMessagesController do
|
||||
describe "#create" do
|
||||
before { Group.refresh_automatic_groups! }
|
||||
|
||||
shared_examples "creating dms" do
|
||||
describe "dm with one other user" do
|
||||
let(:usernames) { user1.username }
|
||||
let(:direct_message_user_ids) { [current_user.id, user1.id] }
|
||||
|
||||
it "creates a new dm channel with username(s) provided" do
|
||||
expect {
|
||||
post "/chat/api/direct-message-channels.json", params: { target_usernames: [usernames] }
|
||||
@ -35,31 +38,55 @@ RSpec.describe Chat::Api::DirectMessagesController do
|
||||
|
||||
it "returns existing dm channel if one exists for username(s)" do
|
||||
create_dm_channel(direct_message_user_ids)
|
||||
|
||||
expect {
|
||||
post "/chat/api/direct-message-channels.json", params: { target_usernames: [usernames] }
|
||||
}.not_to change { Chat::DirectMessage.count }
|
||||
end
|
||||
end
|
||||
|
||||
describe "dm with one other user" do
|
||||
let(:usernames) { user1.username }
|
||||
let(:direct_message_user_ids) { [current_user.id, user1.id] }
|
||||
|
||||
include_examples "creating dms"
|
||||
end
|
||||
|
||||
describe "dm with myself" do
|
||||
let(:usernames) { [current_user.username] }
|
||||
let(:direct_message_user_ids) { [current_user.id] }
|
||||
|
||||
include_examples "creating dms"
|
||||
it "creates a new dm channel with username(s) provided" do
|
||||
expect {
|
||||
post "/chat/api/direct-message-channels.json", params: { target_usernames: [usernames] }
|
||||
}.to change { Chat::DirectMessage.count }.by(1)
|
||||
expect(Chat::DirectMessage.last.direct_message_users.map(&:user_id)).to match_array(
|
||||
direct_message_user_ids,
|
||||
)
|
||||
end
|
||||
|
||||
it "returns existing dm channel if one exists for username(s)" do
|
||||
create_dm_channel(direct_message_user_ids)
|
||||
|
||||
expect {
|
||||
post "/chat/api/direct-message-channels.json", params: { target_usernames: [usernames] }
|
||||
}.not_to change { Chat::DirectMessage.count }
|
||||
end
|
||||
end
|
||||
|
||||
describe "dm with two other users" do
|
||||
let(:usernames) { [user1, user2, user3].map(&:username) }
|
||||
let(:direct_message_user_ids) { [current_user.id, user1.id, user2.id, user3.id] }
|
||||
|
||||
include_examples "creating dms"
|
||||
it "creates a new dm channel with username(s) provided" do
|
||||
expect {
|
||||
post "/chat/api/direct-message-channels.json", params: { target_usernames: [usernames] }
|
||||
}.to change { Chat::DirectMessage.count }.by(1)
|
||||
expect(Chat::DirectMessage.last.direct_message_users.map(&:user_id)).to match_array(
|
||||
direct_message_user_ids,
|
||||
)
|
||||
end
|
||||
|
||||
it "createsa new dm channel" do
|
||||
create_dm_channel(direct_message_user_ids)
|
||||
|
||||
expect {
|
||||
post "/chat/api/direct-message-channels.json", params: { target_usernames: [usernames] }
|
||||
}.to change { Chat::DirectMessage.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
it "creates Chat::UserChatChannelMembership records" do
|
||||
|
@ -611,6 +611,7 @@ RSpec.describe Chat::ChatController do
|
||||
expect(response.status).to eq(403)
|
||||
|
||||
Chat::DirectMessageUser.create(user: user, direct_message: dm_channel.chatable)
|
||||
|
||||
expect {
|
||||
post "/chat/drafts.json", params: { chat_channel_id: dm_channel.id, data: "{}" }
|
||||
}.to change { Chat::Draft.count }.by(1)
|
||||
|
104
plugins/chat/spec/services/chat/add_users_to_channel_spec.rb
Normal file
104
plugins/chat/spec/services/chat/add_users_to_channel_spec.rb
Normal file
@ -0,0 +1,104 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Chat::AddUsersToChannel do
|
||||
describe described_class::Contract, type: :model do
|
||||
subject(:contract) { described_class.new(usernames: [], channel_id: nil) }
|
||||
|
||||
it { is_expected.to validate_presence_of :channel_id }
|
||||
it { is_expected.to validate_presence_of :usernames }
|
||||
end
|
||||
|
||||
describe ".call" do
|
||||
subject(:result) { described_class.call(params) }
|
||||
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
fab!(:users) { Fabricate.times(5, :user) }
|
||||
fab!(:direct_message) { Fabricate(:direct_message, users: [current_user], group: true) }
|
||||
fab!(:channel) { Fabricate(:direct_message_channel, chatable: direct_message) }
|
||||
|
||||
let(:guardian) { Guardian.new(current_user) }
|
||||
let(:params) do
|
||||
{ guardian: guardian, channel_id: channel.id, usernames: users.map(&:username) }
|
||||
end
|
||||
|
||||
context "when all steps pass" do
|
||||
before { channel.add(current_user) }
|
||||
|
||||
it "fetches users to add" do
|
||||
expect(result.users.map(&:username)).to contain_exactly(*users.map(&:username))
|
||||
end
|
||||
|
||||
it "doesn't include existing direct message users" do
|
||||
Chat::DirectMessageUser.create!(user: users.first, direct_message: direct_message)
|
||||
|
||||
expect(result.users.map(&:username)).to contain_exactly(*users[1..-1].map(&:username))
|
||||
end
|
||||
|
||||
it "creates memberships" do
|
||||
expect { result }.to change { channel.user_chat_channel_memberships.count }.by(
|
||||
users.count + 1,
|
||||
) # +1 for system user creating the notice message and added to the channel
|
||||
end
|
||||
|
||||
it "creates direct messages users" do
|
||||
expect { result }.to change { ::Chat::DirectMessageUser.count }.by(users.count + 1) # +1 for system user creating the notice message and added to the channel
|
||||
end
|
||||
|
||||
it "updates users count" do
|
||||
expect { result }.to change { channel.reload.user_count }.by(users.count + 1) # +1 for system user creating the notice message and added to the channel
|
||||
end
|
||||
|
||||
it "creates a chat message to show added users" do
|
||||
added_users = result.users
|
||||
|
||||
channel.chat_messages.last.tap do |message|
|
||||
expect(message.message).to eq(
|
||||
I18n.t(
|
||||
"chat.channel.users_invited_to_channel",
|
||||
invited_users: added_users.map { |u| "@#{u.username}" }.join(", "),
|
||||
inviting_user: "@#{current_user.username}",
|
||||
count: added_users.count,
|
||||
),
|
||||
)
|
||||
expect(message.user).to eq(Discourse.system_user)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when there are too many usernames" do
|
||||
before { SiteSetting.chat_max_direct_message_users = 2 }
|
||||
|
||||
it { is_expected.to fail_a_contract }
|
||||
end
|
||||
|
||||
context "when channel is not found" do
|
||||
before { params[:channel_id] = -999 }
|
||||
|
||||
it { is_expected.to fail_to_find_a_model(:channel) }
|
||||
end
|
||||
|
||||
context "when user don't have access to channel" do
|
||||
fab!(:channel) { Fabricate(:private_category_channel, group: Fabricate(:group)) }
|
||||
|
||||
it { is_expected.to fail_a_policy(:can_add_users_to_channel) }
|
||||
end
|
||||
|
||||
context "when channel is not a group" do
|
||||
before { direct_message.update!(group: false) }
|
||||
|
||||
it { is_expected.to fail_a_policy(:can_add_users_to_channel) }
|
||||
end
|
||||
|
||||
context "when channel is not a direct message channel" do
|
||||
fab!(:channel) { Fabricate(:chat_channel) }
|
||||
|
||||
it { is_expected.to fail_a_policy(:can_add_users_to_channel) }
|
||||
end
|
||||
|
||||
context "when user is not admin and not a member of the channel" do
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
|
||||
it { is_expected.to fail_a_policy(:can_add_users_to_channel) }
|
||||
end
|
||||
end
|
||||
end
|
@ -26,7 +26,9 @@ RSpec.describe Chat::CreateDirectMessageChannel do
|
||||
fab!(:user_2) { Fabricate(:user, username: "elaine") }
|
||||
|
||||
let(:guardian) { Guardian.new(current_user) }
|
||||
let(:params) { { guardian: guardian, target_usernames: %w[lechuck elaine] } }
|
||||
let(:target_usernames) { [user_1.username, user_2.username] }
|
||||
let(:name) { "" }
|
||||
let(:params) { { guardian: guardian, target_usernames: target_usernames, name: name } }
|
||||
|
||||
before { Group.refresh_automatic_groups! }
|
||||
|
||||
@ -35,6 +37,10 @@ RSpec.describe Chat::CreateDirectMessageChannel do
|
||||
expect(result).to be_a_success
|
||||
end
|
||||
|
||||
it "updates user count" do
|
||||
expect(result.channel.user_count).to eq(3) # current user + user_1 + user_2
|
||||
end
|
||||
|
||||
it "creates the channel" do
|
||||
expect { result }.to change { Chat::Channel.count }
|
||||
expect(result.channel.chatable).to have_attributes(
|
||||
@ -58,16 +64,59 @@ RSpec.describe Chat::CreateDirectMessageChannel do
|
||||
end
|
||||
|
||||
context "when there is an existing direct message channel for the target users" do
|
||||
before { described_class.call(params) }
|
||||
context "when a name has been given" do
|
||||
let(:target_usernames) { [user_1.username] }
|
||||
let(:name) { "Monkey Island" }
|
||||
|
||||
it "does not create a channel" do
|
||||
expect { result }.to not_change { Chat::Channel.count }.and not_change {
|
||||
Chat::DirectMessage.count
|
||||
}
|
||||
it "creates a second channel" do
|
||||
described_class.call(params)
|
||||
|
||||
expect { result }.to change { Chat::Channel.count }.and change {
|
||||
Chat::DirectMessage.count
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
it "does not double-insert the channel memberships" do
|
||||
expect { result }.not_to change { Chat::UserChatChannelMembership.count }
|
||||
context "when the channel has more than one user" do
|
||||
let(:target_usernames) { [user_1.username, user_2.username] }
|
||||
|
||||
it "creates a second channel" do
|
||||
described_class.call(params)
|
||||
|
||||
expect { result }.to change { Chat::Channel.count }.and change {
|
||||
Chat::DirectMessage.count
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context "when the channel has one user and no name" do
|
||||
let(:target_usernames) { [user_1.username] }
|
||||
|
||||
it "reuses the existing channel" do
|
||||
existing_channel = described_class.call(params).channel
|
||||
|
||||
expect(result.channel.id).to eq(existing_channel.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "when theres also a group channel with same users" do
|
||||
let(:target_usernames) { [user_1.username] }
|
||||
|
||||
it "returns the non group existing channel" do
|
||||
group_channel = described_class.call(params.merge(name: "cats")).channel
|
||||
channel = described_class.call(params).channel
|
||||
|
||||
expect(result.channel.id).to_not eq(group_channel.id)
|
||||
expect(result.channel.id).to eq(channel.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when a name is given" do
|
||||
let(:name) { "Monkey Island" }
|
||||
|
||||
it "sets it as the channel name" do
|
||||
expect(result.channel.name).to eq(name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -7,20 +7,34 @@ RSpec.describe Chat::SearchChatable do
|
||||
fab!(:current_user) { Fabricate(:user, username: "bob-user") }
|
||||
fab!(:sam) { Fabricate(:user, username: "sam-user") }
|
||||
fab!(:charlie) { Fabricate(:user, username: "charlie-user") }
|
||||
fab!(:alain) { Fabricate(:user, username: "alain-user") }
|
||||
fab!(:channel_1) { Fabricate(:chat_channel, name: "bob-channel") }
|
||||
fab!(:channel_2) { Fabricate(:direct_message_channel, users: [current_user, sam]) }
|
||||
fab!(:channel_3) { Fabricate(:direct_message_channel, users: [current_user, sam, charlie]) }
|
||||
fab!(:channel_4) { Fabricate(:direct_message_channel, users: [sam, charlie]) }
|
||||
fab!(:channel_5) { Fabricate(:direct_message_channel, users: [current_user, charlie, alain]) }
|
||||
|
||||
let(:guardian) { Guardian.new(current_user) }
|
||||
let(:params) { { guardian: guardian, term: term } }
|
||||
let(:term) { "" }
|
||||
let(:include_users) { false }
|
||||
let(:include_category_channels) { false }
|
||||
let(:include_direct_message_channels) { false }
|
||||
let(:excluded_memberships_channel_id) { nil }
|
||||
let(:params) do
|
||||
{
|
||||
guardian: guardian,
|
||||
term: term,
|
||||
include_users: include_users,
|
||||
include_category_channels: include_category_channels,
|
||||
include_direct_message_channels: include_direct_message_channels,
|
||||
excluded_memberships_channel_id: excluded_memberships_channel_id,
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
SiteSetting.direct_message_enabled_groups = Group::AUTO_GROUPS[:everyone]
|
||||
# simpler user search without having to worry about user search data
|
||||
SiteSetting.enable_names = false
|
||||
return unless guardian.can_create_direct_message?
|
||||
channel_1.add(current_user)
|
||||
end
|
||||
|
||||
@ -29,118 +43,144 @@ RSpec.describe Chat::SearchChatable do
|
||||
expect(result).to be_a_success
|
||||
end
|
||||
|
||||
it "returns chatables" do
|
||||
it "cleans the term" do
|
||||
params[:term] = "#bob"
|
||||
expect(result.term).to eq("bob")
|
||||
|
||||
params[:term] = "@bob"
|
||||
expect(result.term).to eq("bob")
|
||||
end
|
||||
|
||||
it "fetches user memberships" do
|
||||
expect(result.memberships).to contain_exactly(
|
||||
channel_1.membership_for(current_user),
|
||||
channel_2.membership_for(current_user),
|
||||
channel_3.membership_for(current_user),
|
||||
channel_5.membership_for(current_user),
|
||||
)
|
||||
expect(result.category_channels).to contain_exactly(channel_1)
|
||||
expect(result.direct_message_channels).to contain_exactly(channel_2, channel_3)
|
||||
expect(result.users).to include(current_user, sam)
|
||||
end
|
||||
|
||||
it "doesn’t return direct message of other users" do
|
||||
expect(result.direct_message_channels).to_not include(channel_4)
|
||||
end
|
||||
context "when including users" do
|
||||
let(:include_users) { true }
|
||||
|
||||
context "with private channel" do
|
||||
fab!(:private_channel_1) { Fabricate(:private_category_channel, name: "private") }
|
||||
let(:term) { "#private" }
|
||||
it "fetches users" do
|
||||
expect(result.users).to include(current_user, sam, charlie, alain)
|
||||
end
|
||||
|
||||
it "doesn’t return category channels you can't access" do
|
||||
expect(result.category_channels).to_not include(private_channel_1)
|
||||
it "can filter usernames" do
|
||||
params[:term] = "sam"
|
||||
|
||||
expect(result.users).to contain_exactly(sam)
|
||||
end
|
||||
|
||||
it "can filter users with a membership to a specific channel" do
|
||||
params[:excluded_memberships_channel_id] = channel_1.id
|
||||
|
||||
expect(result.users).to_not include(current_user)
|
||||
end
|
||||
end
|
||||
|
||||
context "when public channels are disabled" do
|
||||
it "does not return category channels" do
|
||||
SiteSetting.enable_public_channels = false
|
||||
context "when not including users" do
|
||||
let(:include_users) { false }
|
||||
|
||||
expect(described_class.call(params).category_channels).to be_blank
|
||||
it "doesn’t fetch users" do
|
||||
expect(result.users).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when term is prefixed with #" do
|
||||
let(:term) { "#" }
|
||||
context "when including category channels" do
|
||||
let(:include_category_channels) { true }
|
||||
|
||||
it "doesn’t return users" do
|
||||
expect(result.users).to be_blank
|
||||
expect(result.category_channels).to contain_exactly(channel_1)
|
||||
expect(result.direct_message_channels).to contain_exactly(channel_2, channel_3)
|
||||
end
|
||||
end
|
||||
it "fetches category channels" do
|
||||
expect(result.category_channels).to include(channel_1)
|
||||
end
|
||||
|
||||
context "when term is prefixed with @" do
|
||||
let(:term) { "@" }
|
||||
it "can filter titles" do
|
||||
searched_channel = Fabricate(:chat_channel, name: "beaver")
|
||||
params[:term] = "beaver"
|
||||
|
||||
it "doesn’t return channels" do
|
||||
expect(result.users).to include(current_user, sam)
|
||||
expect(result.category_channels).to be_blank
|
||||
expect(result.direct_message_channels).to be_blank
|
||||
end
|
||||
end
|
||||
expect(result.category_channels).to contain_exactly(searched_channel)
|
||||
end
|
||||
|
||||
context "when filtering" do
|
||||
context "with full match" do
|
||||
let(:term) { "bob" }
|
||||
it "can filter slugs" do
|
||||
searched_channel = Fabricate(:chat_channel, name: "beaver", slug: "something")
|
||||
params[:term] = "something"
|
||||
|
||||
expect(result.category_channels).to contain_exactly(searched_channel)
|
||||
end
|
||||
|
||||
it "doesn’t include category channels you can't access" do
|
||||
Fabricate(:private_category_channel)
|
||||
|
||||
it "returns matching channels" do
|
||||
expect(result.users).to contain_exactly(current_user)
|
||||
expect(result.category_channels).to contain_exactly(channel_1)
|
||||
expect(result.direct_message_channels).to contain_exactly(channel_2, channel_3)
|
||||
end
|
||||
end
|
||||
|
||||
context "with partial match" do
|
||||
let(:term) { "cha" }
|
||||
context "when not including category channels" do
|
||||
let(:include_category_channels) { false }
|
||||
|
||||
it "returns matching channels" do
|
||||
expect(result.users).to contain_exactly(charlie)
|
||||
expect(result.category_channels).to contain_exactly(channel_1)
|
||||
expect(result.direct_message_channels).to contain_exactly(channel_3)
|
||||
it "doesn’t fetch category channels" do
|
||||
expect(result.category_channels).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when filtering with non existing term" do
|
||||
let(:term) { "xxxxxxxxxx" }
|
||||
context "when including direct message channels" do
|
||||
let(:include_direct_message_channels) { true }
|
||||
|
||||
it "returns matching channels" do
|
||||
expect(result.users).to be_blank
|
||||
expect(result.category_channels).to be_blank
|
||||
expect(result.direct_message_channels).to be_blank
|
||||
it "fetches direct message channels" do
|
||||
expect(result.direct_message_channels).to contain_exactly(channel_2, channel_3, channel_5)
|
||||
end
|
||||
|
||||
it "doesn’t fetches inaccessible direct message channels" do
|
||||
expect(result.direct_message_channels).to_not include(channel_4)
|
||||
end
|
||||
|
||||
it "can filter by title" do
|
||||
searched_channel =
|
||||
Fabricate(:direct_message_channel, users: [current_user, sam, charlie], name: "koala")
|
||||
params[:term] = "koala"
|
||||
|
||||
expect(result.direct_message_channels).to contain_exactly(searched_channel)
|
||||
end
|
||||
|
||||
it "can filter by slug" do
|
||||
searched_channel =
|
||||
Fabricate(
|
||||
:direct_message_channel,
|
||||
users: [current_user, sam, charlie],
|
||||
slug: "capybara",
|
||||
)
|
||||
params[:term] = "capybara"
|
||||
|
||||
expect(result.direct_message_channels).to contain_exactly(searched_channel)
|
||||
end
|
||||
|
||||
it "can filter by users" do
|
||||
cedric = Fabricate(:user, username: "cedric")
|
||||
searched_channel =
|
||||
Fabricate(:direct_message_channel, users: [current_user, cedric], slug: "capybara")
|
||||
searched_channel.add(cedric)
|
||||
params[:term] = "cedric"
|
||||
|
||||
expect(result.direct_message_channels).to contain_exactly(searched_channel)
|
||||
end
|
||||
|
||||
context "when also includes users" do
|
||||
let(:include_users) { true }
|
||||
|
||||
it "excludes one to one direct message channels with user" do
|
||||
expect(result.users).to include(sam)
|
||||
expect(result.direct_message_channels).to contain_exactly(channel_3, channel_5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when filtering with @prefix" do
|
||||
let(:term) { "@bob" }
|
||||
context "when not including direct message channels" do
|
||||
let(:include_direct_message_channels) { false }
|
||||
|
||||
it "returns matching channels" do
|
||||
expect(result.users).to contain_exactly(current_user)
|
||||
expect(result.category_channels).to be_blank
|
||||
expect(result.direct_message_channels).to be_blank
|
||||
end
|
||||
end
|
||||
|
||||
context "when filtering with #prefix" do
|
||||
let(:term) { "#bob" }
|
||||
|
||||
it "returns matching channels" do
|
||||
expect(result.users).to be_blank
|
||||
expect(result.category_channels).to contain_exactly(channel_1)
|
||||
expect(result.direct_message_channels).to contain_exactly(channel_2, channel_3)
|
||||
end
|
||||
end
|
||||
|
||||
context "when current user can't created direct messages" do
|
||||
let(:term) { "@bob" }
|
||||
|
||||
before { SiteSetting.direct_message_enabled_groups = Group::AUTO_GROUPS[:staff] }
|
||||
|
||||
it "doesn’t return users" do
|
||||
expect(result.users).to be_blank
|
||||
it "doesn’t fetch direct message channels" do
|
||||
expect(result.direct_message_channels).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -23,12 +23,6 @@ RSpec.describe Chat::UpdateChannel do
|
||||
it { is_expected.to fail_a_policy(:check_channel_permission) }
|
||||
end
|
||||
|
||||
context "when the user tries to edit a DM channel" do
|
||||
fab!(:channel) { Fabricate(:direct_message_channel, users: [current_user, Fabricate(:user)]) }
|
||||
|
||||
it { is_expected.to fail_a_policy(:no_direct_message_channel) }
|
||||
end
|
||||
|
||||
context "when channel is a category one" do
|
||||
context "when a valid user provides valid params" do
|
||||
let(:message) do
|
||||
|
@ -15,7 +15,6 @@
|
||||
"muted": { "type": "boolean" },
|
||||
"desktop_notification_level": { "type": "string" },
|
||||
"mobile_notification_level": { "type": "string" },
|
||||
"last_viewed_at": { "type": "string" },
|
||||
"following": { "type": "boolean" },
|
||||
"user": {
|
||||
"type": ["object", "null"],
|
||||
@ -24,7 +23,9 @@
|
||||
"id": { "type": "number" },
|
||||
"name": { "type": "string" },
|
||||
"avatar_template": { "type": "string" },
|
||||
"username": { "type": "string" }
|
||||
"username": { "type": "string" },
|
||||
"can_chat": { "type": "boolean" },
|
||||
"has_chat_enabled": { "type": "boolean" }
|
||||
}
|
||||
},
|
||||
"last_viewed_at": { "type": "datetime" }
|
||||
|
@ -26,7 +26,7 @@ RSpec.describe "Channel - Info - Members page", type: :system do
|
||||
it "redirects to settings page" do
|
||||
chat_page.visit_channel_members(channel_1)
|
||||
|
||||
expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/settings")
|
||||
expect(page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}/info/members")
|
||||
end
|
||||
end
|
||||
|
||||
@ -64,4 +64,42 @@ RSpec.describe "Channel - Info - Members page", type: :system do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when category channel" do
|
||||
it "doesn’t allow to add members" do
|
||||
chat_page.visit_channel_members(channel_1)
|
||||
|
||||
expect(chat_page).to have_no_css(".chat-channel-members__list-item.-add-member")
|
||||
end
|
||||
end
|
||||
|
||||
context "when category channel" do
|
||||
fab!(:channel_1) do
|
||||
Fabricate(
|
||||
:direct_message_channel,
|
||||
slug: "test-channel",
|
||||
users: [current_user, Fabricate(:user), Fabricate(:user)],
|
||||
group: true,
|
||||
)
|
||||
end
|
||||
|
||||
it "allows to add members" do
|
||||
new_user = Fabricate(:user)
|
||||
chat_page.visit_channel_members(channel_1)
|
||||
chat_page.find(".chat-channel-members__list-item.-add-member").click
|
||||
chat_page.find(".chat-message-creator__members-input").fill_in(with: new_user.username)
|
||||
chat_page.find(".chat-message-creator__list-item").click
|
||||
chat_page.find(".add-to-channel").click
|
||||
|
||||
expect(chat_page).to have_current_path("/chat/c/#{channel_1.slug}/#{channel_1.id}")
|
||||
expect(chat_page).to have_content(
|
||||
I18n.t(
|
||||
"chat.channel.users_invited_to_channel",
|
||||
invited_users: "@#{new_user.username}",
|
||||
inviting_user: "@#{current_user.username}",
|
||||
count: 1,
|
||||
),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -159,6 +159,8 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
||||
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)
|
||||
|
||||
@ -170,7 +172,7 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
||||
|
||||
edit_modal.fill_and_save_name(name)
|
||||
|
||||
expect(channel_settings_page).to have_name(name)
|
||||
expect(page).to have_content(name)
|
||||
end
|
||||
|
||||
it "can edit description" do
|
||||
@ -191,6 +193,7 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
||||
|
||||
it "can edit slug" do
|
||||
chat_page.visit_channel_settings(channel_1)
|
||||
|
||||
edit_modal = channel_settings_page.open_edit_modal
|
||||
|
||||
slug = "gonzo-slug"
|
||||
@ -199,7 +202,7 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
||||
|
||||
edit_modal.fill_and_save_slug(slug)
|
||||
|
||||
expect(channel_settings_page).to have_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
|
||||
@ -213,7 +216,7 @@ RSpec.describe "Channel - Info - Settings page", type: :system do
|
||||
edit_modal.wait_for_auto_generated_slug
|
||||
edit_modal.save_changes
|
||||
|
||||
expect(channel_settings_page).to have_slug("test-channel")
|
||||
expect(page).to have_current_path("/chat/c/test-channel/#{channel_1.id}")
|
||||
end
|
||||
|
||||
it "shows settings page" do
|
||||
|
82
plugins/chat/spec/system/chat_message_creator_spec.rb
Normal file
82
plugins/chat/spec/system/chat_message_creator_spec.rb
Normal file
@ -0,0 +1,82 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "Flag message", type: :system do
|
||||
let(:chat_page) { PageObjects::Pages::Chat.new }
|
||||
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
chat_system_bootstrap
|
||||
sign_in(current_user)
|
||||
end
|
||||
|
||||
it "lists preloaded channels by default" do
|
||||
channel_1 = Fabricate(:chat_channel)
|
||||
channel_1.add(current_user)
|
||||
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_1)
|
||||
end
|
||||
|
||||
it "can filter channels" do
|
||||
channel_1 = Fabricate(:chat_channel)
|
||||
channel_2 = Fabricate(:chat_channel)
|
||||
channel_1.add(current_user)
|
||||
channel_2.add(current_user)
|
||||
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.filter(channel_2.title)
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_2)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_1)
|
||||
end
|
||||
|
||||
it "can filter users" do
|
||||
user_1 = Fabricate(:user)
|
||||
user_2 = Fabricate(:user)
|
||||
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.filter(user_2.username)
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(user_2)
|
||||
expect(chat_page.message_creator).to be_not_listing(user_1)
|
||||
end
|
||||
|
||||
it "can filter direct message channels" do
|
||||
channel_1 = Fabricate(:direct_message_channel, users: [current_user])
|
||||
channel_2 =
|
||||
Fabricate(
|
||||
:direct_message_channel,
|
||||
users: [current_user, Fabricate(:user), Fabricate(:user, username: "user_1")],
|
||||
)
|
||||
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.filter("user_1")
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_2)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_1)
|
||||
end
|
||||
|
||||
it "can create a new group message" do
|
||||
user_1 = Fabricate(:user)
|
||||
user_2 = Fabricate(:user)
|
||||
|
||||
visit("/")
|
||||
chat_page.prefers_full_page
|
||||
chat_page.open_new_message
|
||||
chat_page.find("#new-group-chat").click
|
||||
chat_page.find(".chat-message-creator__new-group-header__input").fill_in(with: "cats")
|
||||
chat_page.find(".chat-message-creator__members-input").fill_in(with: user_1.username)
|
||||
chat_page.message_creator.click_row(user_1)
|
||||
chat_page.find(".chat-message-creator__members-input").fill_in(with: user_2.username)
|
||||
chat_page.message_creator.click_row(user_2)
|
||||
page.find(".create-chat-group").click
|
||||
|
||||
expect(page).to have_current_path(%r{/chat/c/cats/\d+})
|
||||
end
|
||||
end
|
@ -24,7 +24,7 @@ RSpec.describe "Drawer", type: :system do
|
||||
drawer_page.open_channel(channel)
|
||||
page.find(".chat-channel-title").click
|
||||
|
||||
expect(page).to have_current_path("/chat/c/#{channel.slug}/#{channel.id}/info/settings")
|
||||
expect(page).to have_current_path("/chat/c/#{channel.slug}/#{channel.id}/info/members")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,470 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "New message", type: :system do
|
||||
fab!(:current_user) { Fabricate(:admin) }
|
||||
|
||||
let(:chat_page) { PageObjects::Pages::Chat.new }
|
||||
|
||||
before do
|
||||
# simpler user search without having to worry about user search data
|
||||
SiteSetting.enable_names = false
|
||||
|
||||
chat_system_bootstrap
|
||||
sign_in(current_user)
|
||||
end
|
||||
|
||||
it "cmd + k opens new message" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
expect(chat_page.message_creator).to be_opened
|
||||
end
|
||||
|
||||
context "when public channels are disabled" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
|
||||
before do
|
||||
SiteSetting.enable_public_channels = false
|
||||
channel_1.add(current_user)
|
||||
end
|
||||
|
||||
it "doesn’t list public channels" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_1)
|
||||
end
|
||||
|
||||
it "has a correct placeholder" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
expect(chat_page.message_creator.input["placeholder"]).to eq(
|
||||
I18n.t("js.chat.new_message_modal.default_user_search_placeholder"),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when selecting more users than allowed" do
|
||||
fab!(:current_user) { Fabricate(:trust_level_1) }
|
||||
fab!(:user_1) { Fabricate(:user) }
|
||||
fab!(:user_2) { Fabricate(:user) }
|
||||
|
||||
before { SiteSetting.chat_max_direct_message_users = 1 }
|
||||
|
||||
it "shows an error" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.filter(user_1.username)
|
||||
chat_page.message_creator.shift_click_row(user_1)
|
||||
chat_page.message_creator.filter(user_2.username)
|
||||
chat_page.message_creator.shift_click_row(user_2)
|
||||
chat_page.message_creator.click_cta
|
||||
|
||||
expect(page).to have_content(
|
||||
I18n.t(
|
||||
"chat.errors.over_chat_max_direct_message_users",
|
||||
count: SiteSetting.chat_max_direct_message_users,
|
||||
),
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when public channels are disabled and user can't create direct message" do
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
SiteSetting.enable_public_channels = false
|
||||
SiteSetting.direct_message_enabled_groups = Group::AUTO_GROUPS[:staff]
|
||||
end
|
||||
|
||||
it "doesn’t list public channels" do
|
||||
visit("/")
|
||||
chat_page.open_new_message(ensure_open: false)
|
||||
|
||||
expect(chat_page.message_creator).to be_closed
|
||||
end
|
||||
end
|
||||
|
||||
context "when the content is not filtered" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
fab!(:channel_2) { Fabricate(:chat_channel) }
|
||||
fab!(:user_1) { Fabricate(:user) }
|
||||
fab!(:user_2) { Fabricate(:user) }
|
||||
fab!(:direct_message_channel_1) do
|
||||
Fabricate(:direct_message_channel, users: [current_user, user_1])
|
||||
end
|
||||
fab!(:direct_message_channel_2) { Fabricate(:direct_message_channel, users: [user_1, user_2]) }
|
||||
|
||||
before { channel_1.add(current_user) }
|
||||
|
||||
it "lists channels the user is following" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_2)
|
||||
expect(chat_page.message_creator).to be_not_listing(direct_message_channel_2)
|
||||
expect(chat_page.message_creator).to be_listing(user_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(user_2)
|
||||
end
|
||||
end
|
||||
|
||||
context "with no selection" do
|
||||
context "with unread state" do
|
||||
fab!(:user_1) { Fabricate(:user) }
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
fab!(:channel_2) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||
|
||||
before do
|
||||
channel_1.add(user_1)
|
||||
channel_1.add(current_user)
|
||||
Fabricate(:chat_message, chat_channel: channel_1, user: user_1)
|
||||
Fabricate(:chat_message, chat_channel: channel_2, user: user_1)
|
||||
end
|
||||
|
||||
it "shows the correct state" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
expect(chat_page.message_creator).to have_unread_row(channel_1, urgent: false)
|
||||
expect(chat_page.message_creator).to have_unread_row(user_1, urgent: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when clicking a row" do
|
||||
context "when the row is a channel" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
|
||||
before { channel_1.add(current_user) }
|
||||
|
||||
it "opens the channel" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.click_row(channel_1)
|
||||
|
||||
expect(chat_page).to have_drawer(channel_id: channel_1.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the row is a user" do
|
||||
fab!(:user_1) { Fabricate(:user) }
|
||||
fab!(:channel_1) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||
|
||||
it "opens the channel" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.click_row(user_1)
|
||||
|
||||
expect(chat_page).to have_drawer(channel_id: channel_1.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when shift clicking a row" do
|
||||
context "when the row is a channel" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
|
||||
before { channel_1.add(current_user) }
|
||||
|
||||
it "opens the channel" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.shift_click_row(channel_1)
|
||||
|
||||
expect(chat_page).to have_drawer(channel_id: channel_1.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the row is a user" do
|
||||
fab!(:user_1) { Fabricate(:user) }
|
||||
fab!(:channel_1) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||
|
||||
it "adds the user" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.shift_click_row(user_1)
|
||||
|
||||
expect(chat_page.message_creator).to be_selecting(user_1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when pressing enter" do
|
||||
context "when the row is a channel" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
|
||||
before { channel_1.add(current_user) }
|
||||
|
||||
it "opens the channel" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.click_row(channel_1)
|
||||
|
||||
expect(chat_page).to have_drawer(channel_id: channel_1.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the row is a user" do
|
||||
fab!(:user_1) { Fabricate(:user) }
|
||||
fab!(:channel_1) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||
|
||||
it "opens the channel" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.click_row(user_1)
|
||||
|
||||
expect(chat_page).to have_drawer(channel_id: channel_1.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when pressing shift+enter" do
|
||||
context "when the row is a channel" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
|
||||
before { channel_1.add(current_user) }
|
||||
|
||||
it "opens the channel" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.shift_enter_shortcut
|
||||
|
||||
expect(chat_page).to have_drawer(channel_id: channel_1.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "when the row is a user" do
|
||||
fab!(:user_1) { Fabricate(:user) }
|
||||
fab!(:channel_1) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||
|
||||
it "adds the user" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.shift_enter_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_selecting(user_1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when navigating content with arrows" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel, name: "channela") }
|
||||
fab!(:channel_2) { Fabricate(:chat_channel, name: "channelb") }
|
||||
|
||||
before do
|
||||
channel_1.add(current_user)
|
||||
channel_2.add(current_user)
|
||||
end
|
||||
|
||||
it "changes active content" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_1, active: true)
|
||||
|
||||
chat_page.message_creator.arrow_down_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_2, active: true)
|
||||
|
||||
chat_page.message_creator.arrow_down_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_1, active: true)
|
||||
|
||||
chat_page.message_creator.arrow_up_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_2, active: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "with disabled content" do
|
||||
fab!(:user_1) { Fabricate(:user) }
|
||||
fab!(:channel_1) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||
|
||||
before { user_1.user_option.update!(chat_enabled: false) }
|
||||
|
||||
it "doesn’t make the content active" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(user_1, inactive: true, disabled: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when filtering" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel, name: "bob-channel") }
|
||||
fab!(:user_1) { Fabricate(:user, username: "bob-user") }
|
||||
fab!(:user_2) { Fabricate(:user) }
|
||||
fab!(:channel_2) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||
fab!(:channel_3) { Fabricate(:direct_message_channel, users: [current_user, user_1, user_2]) }
|
||||
|
||||
before { channel_1.add(current_user) }
|
||||
|
||||
context "when query is the name of the category" do
|
||||
fab!(:category) { Fabricate(:category, name: "dev") }
|
||||
fab!(:channel_1) { Fabricate(:category_channel, chatable: category, name: "something dev") }
|
||||
fab!(:channel_2) { Fabricate(:category_channel, chatable: category, name: "something else") }
|
||||
|
||||
it "favors the channel name" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
chat_page.message_creator.filter("dev")
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_2)
|
||||
end
|
||||
end
|
||||
|
||||
context "with no prefix" do
|
||||
it "lists all matching content" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
chat_page.message_creator.filter("bob")
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_2)
|
||||
expect(chat_page.message_creator).to be_listing(channel_3)
|
||||
expect(chat_page.message_creator).to be_listing(user_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(user_2)
|
||||
end
|
||||
end
|
||||
|
||||
context "with channel prefix" do
|
||||
it "lists matching channel" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
chat_page.message_creator.filter("#bob")
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(channel_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_2)
|
||||
expect(chat_page.message_creator).to be_listing(channel_3)
|
||||
expect(chat_page.message_creator).to be_not_listing(user_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(user_2)
|
||||
end
|
||||
end
|
||||
|
||||
context "with user prefix" do
|
||||
it "lists matching users" do
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
|
||||
chat_page.message_creator.filter("@bob")
|
||||
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_2)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_3)
|
||||
expect(chat_page.message_creator).to be_listing(user_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(user_2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "with selection" do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel, name: "bob-channel") }
|
||||
fab!(:user_1) { Fabricate(:user, username: "bob-user") }
|
||||
fab!(:user_2) { Fabricate(:user, username: "bobby-user") }
|
||||
fab!(:user_3) { Fabricate(:user, username: "sam-user") }
|
||||
fab!(:channel_2) { Fabricate(:direct_message_channel, users: [current_user, user_1]) }
|
||||
fab!(:channel_3) { Fabricate(:direct_message_channel, users: [current_user, user_2]) }
|
||||
|
||||
before do
|
||||
channel_1.add(current_user)
|
||||
visit("/")
|
||||
chat_page.open_new_message
|
||||
chat_page.message_creator.shift_click_row(user_1)
|
||||
end
|
||||
|
||||
context "when pressing enter" do
|
||||
it "opens the channel" do
|
||||
chat_page.message_creator.enter_shortcut
|
||||
|
||||
expect(chat_page).to have_drawer(channel_id: channel_2.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "when clicking cta" do
|
||||
it "opens the channel" do
|
||||
chat_page.message_creator.click_cta
|
||||
|
||||
expect(chat_page).to have_drawer(channel_id: channel_2.id)
|
||||
end
|
||||
end
|
||||
|
||||
context "when filtering" do
|
||||
it "shows only matching users regardless of prefix" do
|
||||
chat_page.message_creator.filter("#bob")
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(user_1)
|
||||
expect(chat_page.message_creator).to be_listing(user_2)
|
||||
expect(chat_page.message_creator).to be_not_listing(user_3)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_1)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_2)
|
||||
expect(chat_page.message_creator).to be_not_listing(channel_3)
|
||||
end
|
||||
|
||||
it "shows selected user as selected in content" do
|
||||
chat_page.message_creator.filter("@bob")
|
||||
|
||||
expect(chat_page.message_creator).to be_listing(user_1, selected: true)
|
||||
expect(chat_page.message_creator).to be_listing(user_2, selected: false)
|
||||
end
|
||||
end
|
||||
|
||||
context "when clicking another user" do
|
||||
it "adds it to the selection" do
|
||||
chat_page.message_creator.filter("@bob")
|
||||
chat_page.message_creator.click_row(user_2)
|
||||
|
||||
expect(chat_page.message_creator).to be_selecting(user_1)
|
||||
expect(chat_page.message_creator).to be_selecting(user_2)
|
||||
end
|
||||
end
|
||||
|
||||
context "when pressing backspace" do
|
||||
it "removes it" do
|
||||
chat_page.message_creator.backspace_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_selecting(user_1, active: true)
|
||||
|
||||
chat_page.message_creator.backspace_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_not_selecting(user_1)
|
||||
end
|
||||
end
|
||||
|
||||
context "when navigating selection with arrow left/right" do
|
||||
it "changes active item" do
|
||||
chat_page.message_creator.filter("@bob")
|
||||
chat_page.message_creator.click_row(user_2)
|
||||
|
||||
chat_page.message_creator.arrow_left_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_selecting(user_2, active: true)
|
||||
|
||||
chat_page.message_creator.arrow_left_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_selecting(user_1, active: true)
|
||||
|
||||
chat_page.message_creator.arrow_left_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_selecting(user_2, active: true)
|
||||
|
||||
chat_page.message_creator.arrow_right_shortcut
|
||||
|
||||
expect(chat_page.message_creator).to be_selecting(user_1, active: true)
|
||||
end
|
||||
end
|
||||
|
||||
context "when clicking selection" do
|
||||
it "removes it" do
|
||||
chat_page.message_creator.click_item(user_1)
|
||||
|
||||
expect(chat_page.message_creator).to be_not_selecting(user_1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -13,7 +13,7 @@ module PageObjects
|
||||
end
|
||||
|
||||
def input
|
||||
component.find(".chat-message-creator__input")
|
||||
component.find(".chat-message-creator__search-input__input")
|
||||
end
|
||||
|
||||
def filter(query = "")
|
||||
@ -104,7 +104,7 @@ module PageObjects
|
||||
end
|
||||
|
||||
def build_row_selector(chatable, **args)
|
||||
selector = ".chat-message-creator__row"
|
||||
selector = ".chat-message-creator__list-item"
|
||||
selector += content_selector(**args)
|
||||
selector += chatable_selector(chatable, **args)
|
||||
selector
|
||||
@ -116,9 +116,9 @@ module PageObjects
|
||||
selector = ".-selected" if args[:selected]
|
||||
selector = ":not(.-disabled)" if args[:enabled]
|
||||
if args[:active]
|
||||
selector += ".-active"
|
||||
selector += ".-highlighted"
|
||||
elsif args[:inactive]
|
||||
selector += ":not(.-active)"
|
||||
selector += ":not(.-highlighted)"
|
||||
end
|
||||
selector
|
||||
end
|
||||
@ -126,14 +126,11 @@ module PageObjects
|
||||
def chatable_selector(chatable, **args)
|
||||
selector = ""
|
||||
if chatable.try(:category_channel?)
|
||||
selector += ".-channel"
|
||||
selector += "[data-id='c-#{chatable.id}']"
|
||||
selector += "[data-identifier='c-#{chatable.id}']"
|
||||
elsif chatable.try(:direct_message_channel?)
|
||||
selector += ".-channel"
|
||||
selector += "[data-id='c-#{chatable.id}']"
|
||||
selector += "[data-identifier='c-#{chatable.id}']"
|
||||
else
|
||||
selector += ".-user"
|
||||
selector += "[data-id='u-#{chatable.id}']"
|
||||
selector += "[data-identifier='u-#{chatable.id}']"
|
||||
end
|
||||
selector
|
||||
end
|
||||
|
@ -16,8 +16,6 @@ RSpec.describe "User status | sidebar", type: :system do
|
||||
end
|
||||
|
||||
it "shows user status" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
visit("/")
|
||||
|
||||
expect(find(".user-status-message .emoji")["alt"]).to eq("heart")
|
||||
@ -26,8 +24,6 @@ RSpec.describe "User status | sidebar", type: :system do
|
||||
|
||||
context "when changing status" do
|
||||
it "updates status" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
visit("/")
|
||||
current_user.set_status!("offline", "tooth")
|
||||
|
||||
@ -38,8 +34,6 @@ RSpec.describe "User status | sidebar", type: :system do
|
||||
|
||||
context "when removing status" do
|
||||
it "removes status" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
visit("/")
|
||||
current_user.clear_status!
|
||||
|
||||
|
Reference in New Issue
Block a user