DEV: Use Notice API for mention warnings (#23238)
This PR swaps out the custom pathway to publishing and rendering mention warnings after a message is sent. ChatPublisher#publish_notice is used, and expanded. Now, instead of only accepting text_content as an argument, component and component_args are accepted and there is a renderer for these components. Translations moved to server, as notices expect text to be passed in unless a component is rendered The warnings are rendered at the top now, outside of the scope of the single message that sent it. I entirely removed the jit_messages_spec b/c it's duplicate testing of other parts of the app. IMO we don't need a backend test for a feature, a component test for the feature AND a system test (that is slow and potentially even flakey due to timing issues with wait) to test the same thing. So jit_messages_spec is gone.
This commit is contained in:
parent
ed35ae4dcd
commit
9c65e2140a
|
@ -387,31 +387,6 @@ module Chat
|
|||
end
|
||||
end
|
||||
|
||||
def self.publish_inaccessible_mentions(
|
||||
user_id,
|
||||
chat_message,
|
||||
cannot_chat_users,
|
||||
without_membership,
|
||||
too_many_members,
|
||||
mentions_disabled,
|
||||
global_mentions_disabled
|
||||
)
|
||||
MessageBus.publish(
|
||||
"/chat/#{chat_message.chat_channel_id}",
|
||||
{
|
||||
type: :mention_warning,
|
||||
chat_message_id: chat_message.id,
|
||||
cannot_see: cannot_chat_users.map { |u| { username: u.username, id: u.id } }.as_json,
|
||||
without_membership:
|
||||
without_membership.map { |u| { username: u.username, id: u.id } }.as_json,
|
||||
groups_with_too_many_members: too_many_members.map(&:name).as_json,
|
||||
group_mentions_disabled: mentions_disabled.map(&:name).as_json,
|
||||
global_mentions_disabled: global_mentions_disabled,
|
||||
},
|
||||
user_ids: [user_id],
|
||||
)
|
||||
end
|
||||
|
||||
def self.publish_kick_users(channel_id, user_ids)
|
||||
MessageBus.publish(
|
||||
kick_users_message_bus_channel(channel_id),
|
||||
|
@ -478,8 +453,19 @@ module Chat
|
|||
)
|
||||
end
|
||||
|
||||
def self.publish_notice(user_id:, channel_id:, text_content:)
|
||||
payload = { type: "notice", text_content: text_content, channel_id: channel_id }
|
||||
def self.publish_notice(user_id:, channel_id:, text_content: nil, type: nil, data: nil)
|
||||
# Notices are either plain text sent to the client, or a "type" with data. The
|
||||
# client will then translate that type and data into a front-end component.
|
||||
if text_content.blank? && type.blank? && data.blank?
|
||||
raise "Cannot publish notice without text content or a type"
|
||||
end
|
||||
payload = { type: "notice", channel_id: channel_id }
|
||||
if text_content
|
||||
payload[:text_content] = text_content
|
||||
else
|
||||
payload[:notice_type] = type
|
||||
payload[:data] = data
|
||||
end
|
||||
|
||||
MessageBus.publish("/chat/#{channel_id}", payload, user_ids: [user_id])
|
||||
end
|
||||
|
|
|
@ -118,7 +118,6 @@
|
|||
@message={{@message}}
|
||||
@onRetry={{@resendStagedMessage}}
|
||||
/>
|
||||
<Chat::Message::MentionWarning @message={{@message}} />
|
||||
</div>
|
||||
|
||||
{{#if this.showThreadIndicator}}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<div class="chat-notices__notice">
|
||||
|
||||
{{#if @notice.textContent}}
|
||||
<p class="chat-notices__notice__content">
|
||||
{{@notice.textContent}}
|
||||
</p>
|
||||
{{else}}
|
||||
<this.component
|
||||
@channel={{@channel}}
|
||||
@notice={{@notice}}
|
||||
@clearNotice={{this.clearNotice}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
<DButton
|
||||
@icon="times"
|
||||
@action={{this.clearNotice}}
|
||||
class="btn-flat chat-notices__notice__clear"
|
||||
/>
|
||||
</div>
|
|
@ -0,0 +1,21 @@
|
|||
import Component from "@glimmer/component";
|
||||
import MentionWithoutMembership from "discourse/plugins/chat/discourse/components/chat/notices/mention_without_membership";
|
||||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
const COMPONENT_DICT = {
|
||||
mention_without_membership: MentionWithoutMembership,
|
||||
};
|
||||
|
||||
export default class ChatNotices extends Component {
|
||||
@service("chat-channel-pane-subscriptions-manager") subscriptionsManager;
|
||||
|
||||
@action
|
||||
clearNotice() {
|
||||
this.subscriptionsManager.clearNotice(this.args.notice);
|
||||
}
|
||||
|
||||
get component() {
|
||||
return COMPONENT_DICT[this.args.notice.type];
|
||||
}
|
||||
}
|
|
@ -2,16 +2,6 @@
|
|||
<ChatRetentionReminder @channel={{@channel}} />
|
||||
|
||||
{{#each this.noticesForChannel as |notice|}}
|
||||
<div class="chat-notices__notice">
|
||||
<p class="chat-notices__notice__content">
|
||||
{{notice.textContent}}
|
||||
</p>
|
||||
|
||||
<DButton
|
||||
@icon="times"
|
||||
@action={{fn this.clearNotice notice}}
|
||||
class="btn-flat chat-notices__notice__clear"
|
||||
/>
|
||||
</div>
|
||||
<ChatNotice @notice={{notice}} @channel={{@channel}} />
|
||||
{{/each}}
|
||||
</div>
|
|
@ -1,6 +1,5 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { action } from "@ember/object";
|
||||
|
||||
export default class ChatNotices extends Component {
|
||||
@service("chat-channel-pane-subscriptions-manager") subscriptionsManager;
|
||||
|
@ -10,9 +9,4 @@ export default class ChatNotices extends Component {
|
|||
(notice) => notice.channelId === this.args.channel.id
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
clearNotice(notice) {
|
||||
this.subscriptionsManager.clearNotice(notice);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
{{#if this.shouldRender}}
|
||||
<div class="chat-message-mention-warning alert alert-info">
|
||||
{{#if this.mentionWarning.invitationSent}}
|
||||
<span
|
||||
class="chat-message-mention-warning__invitation-sent"
|
||||
{{chat/later-fn this.onDismissInvitationSent 3000}}
|
||||
>
|
||||
{{d-icon "check"}}
|
||||
<span>
|
||||
{{i18n
|
||||
"chat.mention_warning.invitations_sent"
|
||||
count=this.mentionWarning.withoutMembership.length
|
||||
}}
|
||||
</span>
|
||||
</span>
|
||||
{{else}}
|
||||
<DButton
|
||||
class="chat-message-mention-warning__dismiss-btn btn-flat"
|
||||
title={{i18n "chat.mention_warning.dismiss"}}
|
||||
@action={{this.onDismissMentionWarning}}
|
||||
@icon="times"
|
||||
/>
|
||||
|
||||
{{#if this.mentionWarning.cannotSee}}
|
||||
<p class="chat-message-mention-warning__text -cannot-see">
|
||||
{{this.mentionedCannotSeeText}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.mentionWarning.withoutMembership}}
|
||||
<p class="chat-message-mention-warning__text -without-membership">
|
||||
<span>{{this.mentionedWithoutMembershipText}}</span>
|
||||
<a href {{on "click" this.onSendInvite bubbles=false}}>
|
||||
{{i18n "chat.mention_warning.invite"}}
|
||||
</a>
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.mentionWarning.groupWithMentionsDisabled}}
|
||||
<p
|
||||
class="chat-message-mention-warning__text -groups-with-mentions-disabled"
|
||||
>
|
||||
{{this.groupsWithDisabledMentions}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.mentionWarning.groupsWithTooManyMembers}}
|
||||
<p
|
||||
class="chat-message-mention-warning__text -groups-with-too-many-members"
|
||||
>
|
||||
{{this.groupsWithTooManyMembers}}
|
||||
</p>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.mentionWarning.globalMentionsDisabled}}
|
||||
<p class="chat-message-mention-warning__text -global-mentions-disabled">
|
||||
{{i18n "chat.mention_warning.channel_wide_mentions_disallowed"}}
|
||||
</p>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
|
@ -1,99 +0,0 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { action } from "@ember/object";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { inject as service } from "@ember/service";
|
||||
import I18n from "I18n";
|
||||
|
||||
export default class ChatMessageMentionWarning extends Component {
|
||||
@service("chat-api") api;
|
||||
|
||||
@action
|
||||
async onSendInvite() {
|
||||
const userIds = this.mentionWarning.withoutMembership.mapBy("id");
|
||||
|
||||
try {
|
||||
await this.api.invite(this.args.message.channel.id, userIds, {
|
||||
messageId: this.args.message.id,
|
||||
});
|
||||
|
||||
this.mentionWarning.invitationSent = true;
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
onDismissInvitationSent() {
|
||||
this.mentionWarning.invitationSent = false;
|
||||
}
|
||||
|
||||
@action
|
||||
onDismissMentionWarning() {
|
||||
this.args.message.mentionWarning = null;
|
||||
}
|
||||
|
||||
get shouldRender() {
|
||||
return (
|
||||
this.mentionWarning &&
|
||||
(this.mentionWarning.groupWithMentionsDisabled?.length ||
|
||||
this.mentionWarning.cannotSee?.length ||
|
||||
this.mentionWarning.withoutMembership?.length ||
|
||||
this.mentionWarning.groupsWithTooManyMembers?.length ||
|
||||
this.mentionWarning.globalMentionsDisabled)
|
||||
);
|
||||
}
|
||||
|
||||
get mentionWarning() {
|
||||
return this.args.message.mentionWarning;
|
||||
}
|
||||
|
||||
get mentionedCannotSeeText() {
|
||||
return this.#findTranslatedWarning(
|
||||
"chat.mention_warning.cannot_see",
|
||||
"chat.mention_warning.cannot_see_multiple",
|
||||
{
|
||||
username: this.mentionWarning?.cannotSee?.[0]?.username,
|
||||
count: this.mentionWarning?.cannotSee?.length,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get mentionedWithoutMembershipText() {
|
||||
return this.#findTranslatedWarning(
|
||||
"chat.mention_warning.without_membership",
|
||||
"chat.mention_warning.without_membership_multiple",
|
||||
{
|
||||
username: this.mentionWarning?.withoutMembership?.[0]?.username,
|
||||
count: this.mentionWarning?.withoutMembership?.length,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get groupsWithDisabledMentions() {
|
||||
return this.#findTranslatedWarning(
|
||||
"chat.mention_warning.group_mentions_disabled",
|
||||
"chat.mention_warning.group_mentions_disabled_multiple",
|
||||
{
|
||||
group_name: this.mentionWarning?.groupWithMentionsDisabled?.[0],
|
||||
count: this.mentionWarning?.groupWithMentionsDisabled?.length,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
get groupsWithTooManyMembers() {
|
||||
return this.#findTranslatedWarning(
|
||||
"chat.mention_warning.too_many_members",
|
||||
"chat.mention_warning.too_many_members_multiple",
|
||||
{
|
||||
group_name: this.mentionWarning.groupsWithTooManyMembers?.[0],
|
||||
count: this.mentionWarning.groupsWithTooManyMembers?.length,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#findTranslatedWarning(oneKey, multipleKey, args) {
|
||||
const translationKey = args.count === 1 ? oneKey : multipleKey;
|
||||
args.count--;
|
||||
return I18n.t(translationKey, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
<div class="mention-without-membership-notice">
|
||||
{{#if this.invitationsSent}}
|
||||
<span
|
||||
class="mention-without-membership-notice__invitation-sent"
|
||||
{{chat/later-fn @clearNotice 3000}}
|
||||
>
|
||||
{{d-icon "check"}}
|
||||
<span>
|
||||
{{i18n
|
||||
"chat.mention_warning.invitations_sent"
|
||||
count=this.userIds.length
|
||||
}}
|
||||
</span>
|
||||
</span>
|
||||
{{else}}
|
||||
<p class="mention-without-membership-notice__body -without-membership">
|
||||
<span
|
||||
class="mention-without-membership-notice__body__text"
|
||||
>{{@notice.data.text}}</span>
|
||||
<a
|
||||
class="mention-without-membership-notice__body__link"
|
||||
href
|
||||
{{on "click" this.sendInvitations}}
|
||||
>
|
||||
{{i18n "chat.mention_warning.invite"}}
|
||||
</a>
|
||||
</p>
|
||||
{{/if}}
|
||||
</div>
|
|
@ -0,0 +1,31 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { action } from "@ember/object";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { inject as service } from "@ember/service";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
|
||||
export default class MentionWithoutMembership extends Component {
|
||||
@service("chat-api") chatApi;
|
||||
|
||||
@tracked invitationsSent = false;
|
||||
|
||||
get userIds() {
|
||||
return this.args.notice.data.user_ids;
|
||||
}
|
||||
|
||||
@action
|
||||
async sendInvitations(event) {
|
||||
// preventDefault to avoid a refresh
|
||||
event.preventDefault();
|
||||
|
||||
try {
|
||||
await this.chatApi.invite(this.args.channel.id, this.userIds, {
|
||||
messageId: this.args.notice.data.messageId,
|
||||
});
|
||||
|
||||
this.invitationsSent = true;
|
||||
} catch (error) {
|
||||
popupAjaxError(error);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
<StyleguideExample @title="<Chat::Message::MentionWarning>">
|
||||
<Styleguide::Component>
|
||||
<Chat::Message::MentionWarning @message={{this.message}} />
|
||||
</Styleguide::Component>
|
||||
<Styleguide::Controls::Row @name="Cannot see">
|
||||
<DToggleSwitch
|
||||
@state={{gt this.message.mentionWarning.cannotSee.length 0}}
|
||||
{{on "click" this.toggleCannotSee}}
|
||||
/>
|
||||
</Styleguide::Controls::Row>
|
||||
<Styleguide::Controls::Row @name="Group with mentions disabled">
|
||||
<DToggleSwitch
|
||||
@state={{gt
|
||||
this.message.mentionWarning.groupWithMentionsDisabled.length
|
||||
0
|
||||
}}
|
||||
{{on "click" this.toggleGroupWithMentionsDisabled}}
|
||||
/>
|
||||
</Styleguide::Controls::Row>
|
||||
<Styleguide::Controls::Row @name="Group with too many members">
|
||||
<DToggleSwitch
|
||||
@state={{gt
|
||||
this.message.mentionWarning.groupsWithTooManyMembers.length
|
||||
0
|
||||
}}
|
||||
{{on "click" this.toggleGroupsWithTooManyMembers}}
|
||||
/>
|
||||
</Styleguide::Controls::Row>
|
||||
<Styleguide::Controls::Row @name="Without membership">
|
||||
<DToggleSwitch
|
||||
@state={{gt this.message.mentionWarning.withoutMembership.length 0}}
|
||||
{{on "click" this.toggleWithoutMembership}}
|
||||
/>
|
||||
</Styleguide::Controls::Row>
|
||||
</StyleguideExample>
|
|
@ -1,75 +0,0 @@
|
|||
import Component from "@glimmer/component";
|
||||
import fabricators from "discourse/plugins/chat/discourse/lib/fabricators";
|
||||
import { action } from "@ember/object";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
export default class ChatMessageMentionWarning extends Component {
|
||||
@service currentUser;
|
||||
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.message = fabricators.message({ user: this.currentUser });
|
||||
}
|
||||
|
||||
@action
|
||||
toggleCannotSee() {
|
||||
if (this.message.mentionWarning?.cannotSee) {
|
||||
this.message.mentionWarning = null;
|
||||
} else {
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
cannot_see: [fabricators.user({ username: "bob" })].map((u) => {
|
||||
return { username: u.username, id: u.id };
|
||||
}),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
toggleGroupWithMentionsDisabled() {
|
||||
if (this.message.mentionWarning?.groupWithMentionsDisabled) {
|
||||
this.message.mentionWarning = null;
|
||||
} else {
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
group_mentions_disabled: [fabricators.group()].mapBy("name"),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
toggleGroupsWithTooManyMembers() {
|
||||
if (this.message.mentionWarning?.groupsWithTooManyMembers) {
|
||||
this.message.mentionWarning = null;
|
||||
} else {
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
groups_with_too_many_members: [
|
||||
fabricators.group(),
|
||||
fabricators.group({ name: "Moderators" }),
|
||||
].mapBy("name"),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@action
|
||||
toggleWithoutMembership() {
|
||||
if (this.message.mentionWarning?.withoutMembership) {
|
||||
this.message.mentionWarning = null;
|
||||
} else {
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
without_membership: [fabricators.user()].map((u) => {
|
||||
return { username: u.username, id: u.id };
|
||||
}),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,7 +13,6 @@ import ChatMessage from "discourse/plugins/chat/discourse/models/chat-message";
|
|||
import ChatThread from "discourse/plugins/chat/discourse/models/chat-thread";
|
||||
import ChatThreadPreview from "discourse/plugins/chat/discourse/models/chat-thread-preview";
|
||||
import ChatDirectMessage from "discourse/plugins/chat/discourse/models/chat-direct-message";
|
||||
import ChatMessageMentionWarning from "discourse/plugins/chat/discourse/models/chat-message-mention-warning";
|
||||
import ChatMessageReaction from "discourse/plugins/chat/discourse/models/chat-message-reaction";
|
||||
import User from "discourse/models/user";
|
||||
import Bookmark from "discourse/models/bookmark";
|
||||
|
@ -157,10 +156,6 @@ function groupFabricator(args = {}) {
|
|||
});
|
||||
}
|
||||
|
||||
function messageMentionWarningFabricator(message, args = {}) {
|
||||
return ChatMessageMentionWarning.create(message, args);
|
||||
}
|
||||
|
||||
function uploadFabricator() {
|
||||
return {
|
||||
extension: "jpeg",
|
||||
|
@ -191,6 +186,5 @@ export default {
|
|||
upload: uploadFabricator,
|
||||
category: categoryFabricator,
|
||||
directMessage: directMessageFabricator,
|
||||
messageMentionWarning: messageMentionWarningFabricator,
|
||||
group: groupFabricator,
|
||||
};
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
import { tracked } from "@glimmer/tracking";
|
||||
|
||||
export default class ChatMessageMentionWarning {
|
||||
static create(message, args = {}) {
|
||||
return new ChatMessageMentionWarning(message, args);
|
||||
}
|
||||
|
||||
@tracked invitationSent = false;
|
||||
@tracked cannotSee;
|
||||
@tracked withoutMembership;
|
||||
@tracked groupsWithTooManyMembers;
|
||||
@tracked groupWithMentionsDisabled;
|
||||
@tracked globalMentionsDisabled;
|
||||
|
||||
constructor(message, args = {}) {
|
||||
this.message = args.message;
|
||||
this.cannotSee = args.cannot_see;
|
||||
this.withoutMembership = args.without_membership;
|
||||
this.groupsWithTooManyMembers = args.groups_with_too_many_members;
|
||||
this.groupWithMentionsDisabled = args.group_mentions_disabled;
|
||||
this.globalMentionsDisabled = args.global_mentions_disabled;
|
||||
}
|
||||
}
|
|
@ -11,5 +11,7 @@ export default class ChatNotice {
|
|||
constructor(args = {}) {
|
||||
this.channelId = args.channel_id;
|
||||
this.textContent = args.text_content;
|
||||
this.type = args.notice_type;
|
||||
this.data = args.data;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,11 @@ export default class ChatChannelPaneSubscriptionsManager extends ChatPaneBaseSub
|
|||
}
|
||||
|
||||
handleNotice(data) {
|
||||
this.notices.push(ChatNotice.create(data));
|
||||
this.notices.pushObject(ChatNotice.create(data));
|
||||
}
|
||||
|
||||
clearNotice(notice) {
|
||||
const index = this.notices.indexOf(notice);
|
||||
if (index > -1) {
|
||||
this.notices.splice(index, 1);
|
||||
}
|
||||
this.notices.removeObject(notice);
|
||||
}
|
||||
|
||||
handleThreadOriginalMessageUpdate(data) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import Service, { inject as service } from "@ember/service";
|
||||
import ChatMessage from "discourse/plugins/chat/discourse/models/chat-message";
|
||||
import ChatMessageMentionWarning from "discourse/plugins/chat/discourse/models/chat-message-mention-warning";
|
||||
import { cloneJSON } from "discourse-common/lib/object";
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
|
||||
|
@ -105,9 +104,6 @@ export default class ChatPaneBaseSubscriptionsManager extends Service {
|
|||
case "restore":
|
||||
this.handleRestoreMessage(busData);
|
||||
break;
|
||||
case "mention_warning":
|
||||
this.handleMentionWarning(busData);
|
||||
break;
|
||||
case "self_flagged":
|
||||
this.handleSelfFlaggedMessage(busData);
|
||||
break;
|
||||
|
@ -203,13 +199,6 @@ export default class ChatPaneBaseSubscriptionsManager extends Service {
|
|||
}
|
||||
}
|
||||
|
||||
handleMentionWarning(data) {
|
||||
const message = this.messagesManager.findMessage(data.chat_message_id);
|
||||
if (message) {
|
||||
message.mentionWarning = ChatMessageMentionWarning.create(message, data);
|
||||
}
|
||||
}
|
||||
|
||||
handleSelfFlaggedMessage(data) {
|
||||
const message = this.messagesManager.findMessage(data.chat_message_id);
|
||||
if (message) {
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
.chat-message-mention-warning {
|
||||
position: relative;
|
||||
margin-top: 0.25rem;
|
||||
font-size: var(--font-down-1);
|
||||
|
||||
&__dismiss-btn {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
&__text {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
|
||||
&__invite-sent {
|
||||
color: var(--tertiary);
|
||||
}
|
||||
}
|
|
@ -52,7 +52,6 @@
|
|||
@import "chat-thread-list-header";
|
||||
@import "chat-thread-unread-indicator";
|
||||
@import "chat-thread-participants";
|
||||
@import "chat-message-mention-warning";
|
||||
@import "chat-message-error";
|
||||
@import "chat-message-creator";
|
||||
@import "chat-user-avatar";
|
||||
|
|
|
@ -129,28 +129,11 @@ en:
|
|||
one: "Last hour"
|
||||
other: "Last %{count} hours"
|
||||
mention_warning:
|
||||
dismiss: "dismiss"
|
||||
cannot_see: "%{username} can't access this channel and was not notified."
|
||||
cannot_see_multiple:
|
||||
one: "%{username} and %{count} other user cannot access this channel and were not notified."
|
||||
other: "%{username} and %{count} other users cannot access this channel and were not notified."
|
||||
invitations_sent:
|
||||
one: "Invitation sent"
|
||||
other: "Invitations sent"
|
||||
invite: "Invite to channel"
|
||||
without_membership: "%{username} has not joined this channel."
|
||||
without_membership_multiple:
|
||||
one: "%{username} and %{count} other user have not joined this channel."
|
||||
other: "%{username} and %{count} other users have not joined this channel."
|
||||
group_mentions_disabled: "%{group_name} doesn't allow mentions."
|
||||
group_mentions_disabled_multiple:
|
||||
one: "%{group_name} and %{count} other group don't allow mentions."
|
||||
other: "%{group_name} and %{count} other groups don't allow mentions."
|
||||
channel_wide_mentions_disallowed: "@here and @all mentions are disabled in this channel."
|
||||
too_many_members: "%{group_name} has too many members. No one was notified."
|
||||
too_many_members_multiple:
|
||||
one: "%{group_name} and %{count} other group have too many members. No one was notified."
|
||||
other: "%{group_name} and %{count} other groups have too many members. No one was notified."
|
||||
groups:
|
||||
header:
|
||||
some: "Some users won't be notified"
|
||||
|
|
|
@ -138,6 +138,29 @@ en:
|
|||
multi_user_truncated:
|
||||
one: "%{comma_separated_usernames} and %{count} other"
|
||||
other: "%{comma_separated_usernames} and %{count} others"
|
||||
mention_warning:
|
||||
dismiss: "dismiss"
|
||||
cannot_see: "%{first_identifier} can't access this channel and was not notified."
|
||||
cannot_see_multiple:
|
||||
one: "%{first_identifier} and %{count} other user cannot access this channel and were not notified."
|
||||
other: "%{first_identifier} and %{count} other users cannot access this channel and were not notified."
|
||||
invitations_sent:
|
||||
one: "Invitation sent"
|
||||
other: "Invitations sent"
|
||||
invite: "Invite to channel"
|
||||
without_membership: "%{first_identifier} has not joined this channel."
|
||||
without_membership_multiple:
|
||||
one: "%{first_identifier} and %{count} other user have not joined this channel."
|
||||
other: "%{first_identifier} and %{count} other users have not joined this channel."
|
||||
group_mentions_disabled: "%{first_identifier} doesn't allow mentions."
|
||||
group_mentions_disabled_multiple:
|
||||
one: "%{first_identifier} and %{count} other group don't allow mentions."
|
||||
other: "%{first_identifier} and %{count} other groups don't allow mentions."
|
||||
global_mentions_disallowed: "@here and @all mentions are disabled in this channel."
|
||||
too_many_members: "%{first_identifier} has too many members. No one was notified."
|
||||
too_many_members_multiple:
|
||||
one: "%{first_identifier} and %{count} other group have too many members. No one was notified."
|
||||
other: "%{first_identifier} and %{count} other groups have too many members. No one was notified."
|
||||
|
||||
category_channel:
|
||||
errors:
|
||||
|
|
|
@ -225,24 +225,100 @@ module Chat
|
|||
end
|
||||
|
||||
def notify_creator_of_inaccessible_mentions(inaccessible)
|
||||
group_mentions_disabled = @parsed_mentions.groups_with_disabled_mentions.to_a
|
||||
too_many_members = @parsed_mentions.groups_with_too_many_members.to_a
|
||||
if inaccessible.values.all?(&:blank?) && group_mentions_disabled.empty? &&
|
||||
too_many_members.empty? && !global_mentions_disabled
|
||||
return
|
||||
# Notify when mentioned users can join channel, but don't have a membership
|
||||
if inaccessible[:welcome_to_join].any?
|
||||
publish_inaccessible_mentions(inaccessible[:welcome_to_join])
|
||||
end
|
||||
|
||||
Chat::Publisher.publish_inaccessible_mentions(
|
||||
@user.id,
|
||||
@chat_message,
|
||||
inaccessible[:unreachable].to_a,
|
||||
inaccessible[:welcome_to_join].to_a,
|
||||
too_many_members,
|
||||
group_mentions_disabled,
|
||||
global_mentions_disabled,
|
||||
# Notify when mentioned users are not able to access the channel
|
||||
publish_unreachable_mentions(inaccessible[:unreachable]) if inaccessible[:unreachable].any?
|
||||
|
||||
# Notify when `@all` or `@here` is used when channel has global mentions disabled
|
||||
publish_global_mentions_disabled if global_mentions_disabled
|
||||
|
||||
# Notify when groups are mentioned and have mentions disabled
|
||||
group_mentions_disabled = @parsed_mentions.groups_with_disabled_mentions.to_a
|
||||
publish_group_mentions_disabled(group_mentions_disabled) if group_mentions_disabled.any?
|
||||
|
||||
# Notify when large groups are mentioned, exceeding `max_users_notified_per_group_mention`
|
||||
too_many_members = @parsed_mentions.groups_with_too_many_members.to_a
|
||||
publish_too_many_members_in_group_mention(too_many_members) if too_many_members.any?
|
||||
end
|
||||
|
||||
def publish_inaccessible_mentions(users)
|
||||
Chat::Publisher.publish_notice(
|
||||
user_id: @user.id,
|
||||
channel_id: @chat_channel.id,
|
||||
type: "mention_without_membership",
|
||||
data: {
|
||||
user_ids: users.map(&:id),
|
||||
text:
|
||||
mention_warning_text(
|
||||
single: "chat.mention_warning.without_membership",
|
||||
multiple: "chat.mention_warning.without_membership_multiple",
|
||||
first_identifier: users.first.username,
|
||||
count: users.count,
|
||||
),
|
||||
message_id: @chat_message.id,
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
def publish_group_mentions_disabled(groups)
|
||||
Chat::Publisher.publish_notice(
|
||||
user_id: @user.id,
|
||||
channel_id: @chat_channel.id,
|
||||
text_content:
|
||||
mention_warning_text(
|
||||
single: "chat.mention_warning.group_mentions_disabled",
|
||||
multiple: "chat.mention_warning.group_mentions_disabled_multiple",
|
||||
first_identifier: groups.first.name,
|
||||
count: groups.count,
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
def publish_global_mentions_disabled
|
||||
Chat::Publisher.publish_notice(
|
||||
user_id: @user.id,
|
||||
channel_id: @chat_channel.id,
|
||||
text_content: I18n.t("chat.mention_warning.global_mentions_disallowed"),
|
||||
)
|
||||
end
|
||||
|
||||
def publish_unreachable_mentions(users)
|
||||
Chat::Publisher.publish_notice(
|
||||
user_id: @user.id,
|
||||
channel_id: @chat_channel.id,
|
||||
text_content:
|
||||
mention_warning_text(
|
||||
single: "chat.mention_warning.cannot_see",
|
||||
multiple: "chat.mention_warning.cannot_see_multiple",
|
||||
first_identifier: users.first.username,
|
||||
count: users.count,
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
def publish_too_many_members_in_group_mention(groups)
|
||||
Chat::Publisher.publish_notice(
|
||||
user_id: @user.id,
|
||||
channel_id: @chat_channel.id,
|
||||
text_content:
|
||||
mention_warning_text(
|
||||
single: "chat.mention_warning.too_many_members",
|
||||
multiple: "chat.mention_warning.too_many_members_multiple",
|
||||
first_identifier: groups.first.name,
|
||||
count: groups.count,
|
||||
),
|
||||
)
|
||||
end
|
||||
|
||||
def mention_warning_text(single:, multiple:, first_identifier:, count:)
|
||||
translation_key = count == 1 ? single : multiple
|
||||
I18n.t(translation_key, first_identifier: first_identifier, count: count - 1)
|
||||
end
|
||||
|
||||
def global_mentions_disabled
|
||||
return @global_mentions_disabled if defined?(@global_mentions_disabled)
|
||||
|
||||
|
|
|
@ -488,7 +488,7 @@ describe Chat::MessageCreator do
|
|||
end
|
||||
|
||||
it "publishes inaccessible mentions when user isn't aren't a part of the channel" do
|
||||
Chat::Publisher.expects(:publish_inaccessible_mentions).once
|
||||
Chat::Publisher.expects(:publish_notice).once
|
||||
described_class.create(
|
||||
chat_channel: public_chat_channel,
|
||||
user: admin1,
|
||||
|
@ -498,7 +498,7 @@ describe Chat::MessageCreator do
|
|||
|
||||
it "publishes inaccessible mentions when user doesn't have chat access" do
|
||||
SiteSetting.chat_allowed_groups = Group::AUTO_GROUPS[:staff]
|
||||
Chat::Publisher.expects(:publish_inaccessible_mentions).once
|
||||
Chat::Publisher.expects(:publish_notice).once
|
||||
described_class.create(
|
||||
chat_channel: public_chat_channel,
|
||||
user: admin1,
|
||||
|
@ -507,7 +507,7 @@ describe Chat::MessageCreator do
|
|||
end
|
||||
|
||||
it "doesn't publish inaccessible mentions when user is following channel" do
|
||||
Chat::Publisher.expects(:publish_inaccessible_mentions).never
|
||||
Chat::Publisher.expects(:publish_notice).never
|
||||
described_class.create(
|
||||
chat_channel: public_chat_channel,
|
||||
user: admin1,
|
||||
|
|
|
@ -69,9 +69,10 @@ describe Chat::Notifier do
|
|||
|
||||
global_mentions_disabled_message = messages.first
|
||||
|
||||
expect(global_mentions_disabled_message).to be_present
|
||||
expect(global_mentions_disabled_message.data[:type].to_sym).to eq(:mention_warning)
|
||||
expect(global_mentions_disabled_message.data[:global_mentions_disabled]).to eq(true)
|
||||
expect(global_mentions_disabled_message.data[:type].to_sym).to eq(:notice)
|
||||
expect(global_mentions_disabled_message.data[:text_content]).to eq(
|
||||
I18n.t("chat.mention_warning.global_mentions_disallowed"),
|
||||
)
|
||||
end
|
||||
|
||||
it "includes all members of a channel except the sender" do
|
||||
|
@ -415,10 +416,10 @@ describe Chat::Notifier do
|
|||
|
||||
unreachable_msg = messages.first
|
||||
|
||||
expect(unreachable_msg).to be_present
|
||||
expect(unreachable_msg.data[:without_membership]).to be_empty
|
||||
unreachable_users = unreachable_msg.data[:cannot_see].map { |u| u["id"] }
|
||||
expect(unreachable_users).to contain_exactly(user_3.id)
|
||||
expect(unreachable_msg[:data][:type].to_sym).to eq(:notice)
|
||||
expect(unreachable_msg[:data][:text_content]).to eq(
|
||||
I18n.t("chat.mention_warning.cannot_see", first_identifier: user_3.username),
|
||||
)
|
||||
end
|
||||
|
||||
context "when in a personal message" do
|
||||
|
@ -452,10 +453,10 @@ describe Chat::Notifier do
|
|||
|
||||
unreachable_msg = messages.first
|
||||
|
||||
expect(unreachable_msg).to be_present
|
||||
expect(unreachable_msg.data[:without_membership]).to be_empty
|
||||
unreachable_users = unreachable_msg.data[:cannot_see].map { |u| u["id"] }
|
||||
expect(unreachable_users).to contain_exactly(user_3.id)
|
||||
expect(unreachable_msg[:data][:type].to_sym).to eq(:notice)
|
||||
expect(unreachable_msg[:data][:text_content]).to eq(
|
||||
I18n.t("chat.mention_warning.cannot_see", first_identifier: user_3.username),
|
||||
)
|
||||
end
|
||||
|
||||
it "notify posts of users who are part of the mentioned group but participating" do
|
||||
|
@ -477,10 +478,10 @@ describe Chat::Notifier do
|
|||
|
||||
unreachable_msg = messages.first
|
||||
|
||||
expect(unreachable_msg).to be_present
|
||||
expect(unreachable_msg.data[:without_membership]).to be_empty
|
||||
unreachable_users = unreachable_msg.data[:cannot_see].map { |u| u["id"] }
|
||||
expect(unreachable_users).to contain_exactly(user_3.id)
|
||||
expect(unreachable_msg[:data][:type].to_sym).to eq(:notice)
|
||||
expect(unreachable_msg[:data][:text_content]).to eq(
|
||||
I18n.t("chat.mention_warning.cannot_see", first_identifier: user_3.username),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -502,11 +503,15 @@ describe Chat::Notifier do
|
|||
|
||||
not_participating_msg = messages.first
|
||||
|
||||
expect(not_participating_msg).to be_present
|
||||
expect(not_participating_msg.data[:cannot_see]).to be_empty
|
||||
not_participating_users =
|
||||
not_participating_msg.data[:without_membership].map { |u| u["id"] }
|
||||
expect(not_participating_users).to contain_exactly(user_3.id)
|
||||
expect(not_participating_msg[:data][:type].to_sym).to eq(:notice)
|
||||
expect(not_participating_msg[:data][:text_content]).to be_nil
|
||||
expect(not_participating_msg[:data][:notice_type].to_sym).to eq(:mention_without_membership)
|
||||
expect(not_participating_msg[:data][:data]).to eq(
|
||||
user_ids: [user_3.id],
|
||||
text:
|
||||
I18n.t("chat.mention_warning.without_membership", first_identifier: user_3.username),
|
||||
message_id: msg.id,
|
||||
)
|
||||
end
|
||||
|
||||
it "cannot invite chat user without channel membership if they are ignoring the user who created the message" do
|
||||
|
@ -555,11 +560,15 @@ describe Chat::Notifier do
|
|||
|
||||
not_participating_msg = messages.first
|
||||
|
||||
expect(not_participating_msg).to be_present
|
||||
expect(not_participating_msg.data[:cannot_see]).to be_empty
|
||||
not_participating_users =
|
||||
not_participating_msg.data[:without_membership].map { |u| u["id"] }
|
||||
expect(not_participating_users).to contain_exactly(user_3.id)
|
||||
expect(not_participating_msg[:data][:type].to_sym).to eq(:notice)
|
||||
expect(not_participating_msg[:data][:text_content]).to be_nil
|
||||
expect(not_participating_msg[:data][:notice_type].to_sym).to eq(:mention_without_membership)
|
||||
expect(not_participating_msg[:data][:data]).to eq(
|
||||
user_ids: [user_3.id],
|
||||
text:
|
||||
I18n.t("chat.mention_warning.without_membership", first_identifier: user_3.username),
|
||||
message_id: msg.id,
|
||||
)
|
||||
end
|
||||
|
||||
it "can invite other group members to channel" do
|
||||
|
@ -580,11 +589,15 @@ describe Chat::Notifier do
|
|||
|
||||
not_participating_msg = messages.first
|
||||
|
||||
expect(not_participating_msg).to be_present
|
||||
expect(not_participating_msg.data[:cannot_see]).to be_empty
|
||||
not_participating_users =
|
||||
not_participating_msg.data[:without_membership].map { |u| u["id"] }
|
||||
expect(not_participating_users).to contain_exactly(user_3.id)
|
||||
expect(not_participating_msg[:data][:type].to_sym).to eq(:notice)
|
||||
expect(not_participating_msg[:data][:text_content]).to be_nil
|
||||
expect(not_participating_msg[:data][:notice_type].to_sym).to eq(:mention_without_membership)
|
||||
expect(not_participating_msg[:data][:data]).to eq(
|
||||
user_ids: [user_3.id],
|
||||
text:
|
||||
I18n.t("chat.mention_warning.without_membership", first_identifier: user_3.username),
|
||||
message_id: msg.id,
|
||||
)
|
||||
end
|
||||
|
||||
it "cannot invite a member of a group who is ignoring the user who created the message" do
|
||||
|
@ -650,9 +663,11 @@ describe Chat::Notifier do
|
|||
end
|
||||
|
||||
too_many_members_msg = messages.first
|
||||
expect(too_many_members_msg).to be_present
|
||||
too_many_members = too_many_members_msg.data[:groups_with_too_many_members]
|
||||
expect(too_many_members).to contain_exactly(group.name)
|
||||
|
||||
expect(too_many_members_msg[:data][:type].to_sym).to eq(:notice)
|
||||
expect(too_many_members_msg[:data][:text_content]).to eq(
|
||||
I18n.t("chat.mention_warning.too_many_members", first_identifier: group.name),
|
||||
)
|
||||
end
|
||||
|
||||
it "sends a message to the client signaling the group doesn't allow mentions" do
|
||||
|
@ -667,9 +682,11 @@ describe Chat::Notifier do
|
|||
end
|
||||
|
||||
mentions_disabled_msg = messages.first
|
||||
expect(mentions_disabled_msg).to be_present
|
||||
mentions_disabled = mentions_disabled_msg.data[:group_mentions_disabled]
|
||||
expect(mentions_disabled).to contain_exactly(group.name)
|
||||
|
||||
expect(mentions_disabled_msg[:data][:type].to_sym).to eq(:notice)
|
||||
expect(mentions_disabled_msg[:data][:text_content]).to eq(
|
||||
I18n.t("chat.mention_warning.group_mentions_disabled", first_identifier: group.name),
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe "JIT messages", type: :system do
|
||||
fab!(:channel_1) { Fabricate(:chat_channel) }
|
||||
fab!(:current_user) { Fabricate(:user) }
|
||||
fab!(:other_user) { Fabricate(:user) }
|
||||
|
||||
let(:chat) { PageObjects::Pages::Chat.new }
|
||||
let(:channel) { PageObjects::Pages::ChatChannel.new }
|
||||
|
||||
before do
|
||||
channel_1.add(current_user)
|
||||
chat_system_bootstrap
|
||||
sign_in(current_user)
|
||||
end
|
||||
|
||||
context "when mentioning a user" do
|
||||
context "when user is not on the channel" do
|
||||
it "displays a mention warning" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
chat.visit_channel(channel_1)
|
||||
channel.send_message("hi @#{other_user.username}")
|
||||
|
||||
expect(page).to have_content(
|
||||
I18n.t("js.chat.mention_warning.without_membership", username: other_user.username),
|
||||
wait: 5,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when user can’t access the channel" do
|
||||
fab!(:group_1) { Fabricate(:group) }
|
||||
fab!(:private_channel_1) { Fabricate(:private_category_channel, group: group_1) }
|
||||
|
||||
before do
|
||||
group_1.add(current_user)
|
||||
private_channel_1.add(current_user)
|
||||
end
|
||||
|
||||
it "displays a mention warning" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
chat.visit_channel(private_channel_1)
|
||||
channel.send_message("hi @#{other_user.username}")
|
||||
|
||||
expect(page).to have_content(
|
||||
I18n.t("js.chat.mention_warning.cannot_see", username: other_user.username),
|
||||
wait: 5,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when category channel permission is readonly for everyone" do
|
||||
fab!(:group_1) { Fabricate(:group) }
|
||||
fab!(:private_channel_1) { Fabricate(:private_category_channel, group: group_1) }
|
||||
|
||||
before do
|
||||
group_1.add(current_user)
|
||||
private_channel_1.add(current_user)
|
||||
end
|
||||
|
||||
it "displays a mention warning" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
chat.visit_channel(private_channel_1)
|
||||
channel.send_message("hi @#{other_user.username}")
|
||||
|
||||
expect(page).to have_content(
|
||||
I18n.t("js.chat.mention_warning.cannot_see", username: other_user.username),
|
||||
wait: 5,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context "when mention a group" do
|
||||
context "when group can't be mentioned" do
|
||||
fab!(:group_1) { Fabricate(:group, mentionable_level: Group::ALIAS_LEVELS[:nobody]) }
|
||||
|
||||
it "displays a mention warning" do
|
||||
Jobs.run_immediately!
|
||||
|
||||
chat.visit_channel(channel_1)
|
||||
channel.send_message("hi @#{group_1.name}")
|
||||
|
||||
expect(page).to have_content(
|
||||
I18n.t("js.chat.mention_warning.group_mentions_disabled", group_name: group_1.name),
|
||||
wait: 5,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,118 +0,0 @@
|
|||
import { render } from "@ember/test-helpers";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import hbs from "htmlbars-inline-precompile";
|
||||
import { module, test } from "qunit";
|
||||
import fabricators from "discourse/plugins/chat/discourse/lib/fabricators";
|
||||
|
||||
module(
|
||||
"Discourse Chat | Component | Chat::Message::MentionWarning",
|
||||
function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
const template = hbs`
|
||||
<Chat::Message::MentionWarning @message={{this.message}} />
|
||||
`;
|
||||
|
||||
test("without memberships", async function (assert) {
|
||||
this.message = fabricators.message();
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
without_membership: [fabricators.user()].map((u) => {
|
||||
return { username: u.username, id: u.id };
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
await render(template);
|
||||
|
||||
assert
|
||||
.dom(".chat-message-mention-warning__text.-without-membership")
|
||||
.exists();
|
||||
});
|
||||
|
||||
test("cannot see channel", async function (assert) {
|
||||
this.message = fabricators.message();
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
cannot_see: [fabricators.user()].map((u) => {
|
||||
return { username: u.username, id: u.id };
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
await render(template);
|
||||
|
||||
assert.dom(".chat-message-mention-warning__text.-cannot-see").exists();
|
||||
});
|
||||
|
||||
test("cannot see channel", async function (assert) {
|
||||
this.message = fabricators.message();
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
cannot_see: [fabricators.user()].map((u) => {
|
||||
return { username: u.username, id: u.id };
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
await render(template);
|
||||
|
||||
assert.dom(".chat-message-mention-warning__text.-cannot-see").exists();
|
||||
});
|
||||
|
||||
test("too many groups", async function (assert) {
|
||||
this.message = fabricators.message();
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
groups_with_too_many_members: [fabricators.group()].mapBy("name"),
|
||||
}
|
||||
);
|
||||
|
||||
await render(template);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
".chat-message-mention-warning__text.-groups-with-too-many-members"
|
||||
)
|
||||
.exists();
|
||||
});
|
||||
|
||||
test("groups with mentions disabled", async function (assert) {
|
||||
this.message = fabricators.message();
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
group_mentions_disabled: [fabricators.group()].mapBy("name"),
|
||||
}
|
||||
);
|
||||
|
||||
await render(template);
|
||||
|
||||
assert
|
||||
.dom(
|
||||
".chat-message-mention-warning__text.-groups-with-mentions-disabled"
|
||||
)
|
||||
.exists();
|
||||
});
|
||||
|
||||
test("displays a warning when global mentions are disabled", async function (assert) {
|
||||
this.message = fabricators.message();
|
||||
this.message.mentionWarning = fabricators.messageMentionWarning(
|
||||
this.message,
|
||||
{
|
||||
global_mentions_disabled: true,
|
||||
}
|
||||
);
|
||||
|
||||
await render(template);
|
||||
|
||||
assert
|
||||
.dom(".chat-message-mention-warning__text.-global-mentions-disabled")
|
||||
.exists();
|
||||
});
|
||||
}
|
||||
);
|
|
@ -1,3 +1,5 @@
|
|||
import I18n from "I18n";
|
||||
import pretender from "discourse/tests/helpers/create-pretender";
|
||||
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||
import hbs from "htmlbars-inline-precompile";
|
||||
import fabricators from "discourse/plugins/chat/discourse/lib/fabricators";
|
||||
|
@ -62,4 +64,52 @@ module("Discourse Chat | Component | chat-notice", function (hooks) {
|
|||
"Notice was cleared"
|
||||
);
|
||||
});
|
||||
test("MentionWithoutMembership notice renders", async function (assert) {
|
||||
this.channel = fabricators.channel();
|
||||
this.manager = this.container.lookup(
|
||||
"service:chatChannelPaneSubscriptionsManager"
|
||||
);
|
||||
const text = "Joffrey can't chat, hermano";
|
||||
this.manager.handleNotice({
|
||||
channel_id: this.channel.id,
|
||||
notice_type: "mention_without_membership",
|
||||
data: { user_ids: [1], message_id: 1, text },
|
||||
});
|
||||
|
||||
await render(hbs`<ChatNotices @channel={{this.channel}} />`);
|
||||
|
||||
assert.strictEqual(
|
||||
queryAll(
|
||||
".chat-notices .chat-notices__notice .mention-without-membership-notice"
|
||||
).length,
|
||||
1,
|
||||
"Notice is present"
|
||||
);
|
||||
|
||||
assert.dom(".mention-without-membership-notice__body__text").hasText(text);
|
||||
assert
|
||||
.dom(".mention-without-membership-notice__body__link")
|
||||
.hasText(I18n.t("chat.mention_warning.invite"));
|
||||
|
||||
pretender.put(`/chat/${this.channel.id}/invite`, () => {
|
||||
return [200, { "Content-Type": "application/json" }, {}];
|
||||
});
|
||||
|
||||
await click(
|
||||
query(".mention-without-membership-notice__body__link"),
|
||||
"Invites the user"
|
||||
);
|
||||
|
||||
// I would love to test that the invitation sent text is present here but
|
||||
// dismiss is called right away instead of waiting 3 seconds.. Not much we can
|
||||
// do about this - at least we are testing that nothing broke all the way through
|
||||
// clearing the notice
|
||||
assert.strictEqual(
|
||||
queryAll(
|
||||
".chat-notices .chat-notices__notice .mention-without-membership-notice"
|
||||
).length,
|
||||
0,
|
||||
"Notice has been cleared"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue