FIX: prevents user to restore message deleted by staff (#22571)
It could only occur on message created by the user itself and deleted while the user was looking at the channel. It more generally fix the trash service which was not correctly setting the author of the delete.
This commit is contained in:
parent
c996e5502f
commit
32e32f43b5
|
@ -174,6 +174,7 @@ module Chat
|
||||||
type: "delete",
|
type: "delete",
|
||||||
deleted_id: chat_message.id,
|
deleted_id: chat_message.id,
|
||||||
deleted_at: chat_message.deleted_at,
|
deleted_at: chat_message.deleted_at,
|
||||||
|
deleted_by_id: chat_message.deleted_by_id,
|
||||||
latest_not_deleted_message_id: latest_not_deleted_message_id,
|
latest_not_deleted_message_id: latest_not_deleted_message_id,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,8 +50,8 @@ module Chat
|
||||||
guardian.can_delete_chat?(message, message.chat_channel.chatable)
|
guardian.can_delete_chat?(message, message.chat_channel.chatable)
|
||||||
end
|
end
|
||||||
|
|
||||||
def trash_message(message:, **)
|
def trash_message(message:, guardian:, **)
|
||||||
message.trash!
|
message.trash!(guardian.user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy_notifications(message:, **)
|
def destroy_notifications(message:, **)
|
||||||
|
|
|
@ -96,8 +96,10 @@ export default class ChatMessageInteractor {
|
||||||
|
|
||||||
get canRestoreMessage() {
|
get canRestoreMessage() {
|
||||||
return (
|
return (
|
||||||
this.canDelete &&
|
|
||||||
this.message?.deletedAt &&
|
this.message?.deletedAt &&
|
||||||
|
(this.currentUser.staff ||
|
||||||
|
(this.message?.user?.id === this.currentUser.id &&
|
||||||
|
this.message?.deletedById === this.currentUser.id)) &&
|
||||||
this.message.channel?.canModifyMessages?.(this.currentUser)
|
this.message.channel?.canModifyMessages?.(this.currentUser)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -118,7 +120,7 @@ export default class ChatMessageInteractor {
|
||||||
|
|
||||||
get canFlagMessage() {
|
get canFlagMessage() {
|
||||||
return (
|
return (
|
||||||
this.currentUser?.id !== this.message?.user?.id &&
|
this.currentUser.id !== this.message?.user?.id &&
|
||||||
this.message?.userFlagStatus === undefined &&
|
this.message?.userFlagStatus === undefined &&
|
||||||
this.message.channel?.canFlag &&
|
this.message.channel?.canFlag &&
|
||||||
!this.message?.chatWebhookEvent &&
|
!this.message?.chatWebhookEvent &&
|
||||||
|
@ -128,7 +130,7 @@ export default class ChatMessageInteractor {
|
||||||
|
|
||||||
get canRebakeMessage() {
|
get canRebakeMessage() {
|
||||||
return (
|
return (
|
||||||
this.currentUser?.staff &&
|
this.currentUser.staff &&
|
||||||
this.message.channel?.canModifyMessages?.(this.currentUser)
|
this.message.channel?.canModifyMessages?.(this.currentUser)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +144,7 @@ export default class ChatMessageInteractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
get canDelete() {
|
get canDelete() {
|
||||||
return this.currentUser?.id === this.message.user.id
|
return this.currentUser.id === this.message.user.id
|
||||||
? this.message.channel?.canDeleteSelf
|
? this.message.channel?.canDeleteSelf
|
||||||
: this.message.channel?.canDeleteOthers;
|
: this.message.channel?.canDeleteOthers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ export default class ChatMessage {
|
||||||
@tracked thread;
|
@tracked thread;
|
||||||
@tracked manager;
|
@tracked manager;
|
||||||
@tracked threadTitle;
|
@tracked threadTitle;
|
||||||
|
@tracked deletedById;
|
||||||
|
|
||||||
@tracked _deletedAt;
|
@tracked _deletedAt;
|
||||||
@tracked _cooked;
|
@tracked _cooked;
|
||||||
|
@ -69,6 +70,7 @@ export default class ChatMessage {
|
||||||
this.hidden = args.hidden || false;
|
this.hidden = args.hidden || false;
|
||||||
this.chatWebhookEvent = args.chatWebhookEvent || args.chat_webhook_event;
|
this.chatWebhookEvent = args.chatWebhookEvent || args.chat_webhook_event;
|
||||||
this.createdAt = args.createdAt || args.created_at;
|
this.createdAt = args.createdAt || args.created_at;
|
||||||
|
this.deletedById = args.deletedById || args.deleted_by_id;
|
||||||
this._deletedAt = args.deletedAt || args.deleted_at;
|
this._deletedAt = args.deletedAt || args.deleted_at;
|
||||||
this.expanded =
|
this.expanded =
|
||||||
this.hidden || this._deletedAt ? false : args.expanded || true;
|
this.hidden || this._deletedAt ? false : args.expanded || true;
|
||||||
|
|
|
@ -177,6 +177,7 @@ export default class ChatPaneBaseSubscriptionsManager extends Service {
|
||||||
|
|
||||||
if (this.currentUser.staff || this.currentUser.id === targetMsg.user.id) {
|
if (this.currentUser.staff || this.currentUser.id === targetMsg.user.id) {
|
||||||
targetMsg.deletedAt = data.deleted_at;
|
targetMsg.deletedAt = data.deleted_at;
|
||||||
|
targetMsg.deletedById = data.deleted_by_id;
|
||||||
targetMsg.expanded = false;
|
targetMsg.expanded = false;
|
||||||
} else {
|
} else {
|
||||||
this.messagesManager.removeMessage(targetMsg);
|
this.messagesManager.removeMessage(targetMsg);
|
||||||
|
|
|
@ -172,9 +172,9 @@ module Chat
|
||||||
if message.user_id == current_user.id
|
if message.user_id == current_user.id
|
||||||
case chatable
|
case chatable
|
||||||
when Category
|
when Category
|
||||||
return can_see_category?(chatable)
|
return message.deleted_by_id == current_user.id || can_see_category?(chatable)
|
||||||
when Chat::DirectMessage
|
when Chat::DirectMessage
|
||||||
return true
|
return message.deleted_by_id == current_user.id || is_staff?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -236,10 +236,16 @@ RSpec.describe Chat::GuardianExtensions do
|
||||||
context "when chatable is a direct message" do
|
context "when chatable is a direct message" do
|
||||||
fab!(:chatable) { Chat::DirectMessage.create! }
|
fab!(:chatable) { Chat::DirectMessage.create! }
|
||||||
|
|
||||||
it "allows owner to restore" do
|
it "allows owner to restore when deleted by owner" do
|
||||||
|
message.trash!(guardian.user)
|
||||||
expect(guardian.can_restore_chat?(message, chatable)).to eq(true)
|
expect(guardian.can_restore_chat?(message, chatable)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "disallow owner to restore when deleted by staff" do
|
||||||
|
message.trash!(staff_guardian.user)
|
||||||
|
expect(guardian.can_restore_chat?(message, chatable)).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
it "allows staff to restore" do
|
it "allows staff to restore" do
|
||||||
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
|
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
|
||||||
end
|
end
|
||||||
|
@ -323,9 +329,15 @@ RSpec.describe Chat::GuardianExtensions do
|
||||||
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
|
expect(staff_guardian.can_restore_chat?(message, chatable)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows owner to restore" do
|
it "allows owner to restore when deleted by owner" do
|
||||||
|
message.trash!(guardian.user)
|
||||||
expect(guardian.can_restore_chat?(message, chatable)).to eq(true)
|
expect(guardian.can_restore_chat?(message, chatable)).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "disallow owner to restore when deleted by staff" do
|
||||||
|
message.trash!(staff_guardian.user)
|
||||||
|
expect(guardian.can_restore_chat?(message, chatable)).to eq(false)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -110,91 +110,91 @@ RSpec.describe Chat::Api::ChannelMessagesController do
|
||||||
describe "#restore" do
|
describe "#restore" do
|
||||||
RSpec.shared_examples "chat_message_restoration" do
|
RSpec.shared_examples "chat_message_restoration" do
|
||||||
it "doesn't allow a user to restore another user's message" do
|
it "doesn't allow a user to restore another user's message" do
|
||||||
sign_in(other_user)
|
another_user = Fabricate(:user)
|
||||||
|
message = Fabricate(:chat_message, chat_channel: chat_channel, user: another_user)
|
||||||
|
message.trash!(another_user)
|
||||||
|
|
||||||
put "/chat/api/channels/#{chat_channel.id}/messages/#{deleted_message.id}/restore.json"
|
sign_in(current_user)
|
||||||
|
|
||||||
|
put "/chat/api/channels/#{chat_channel.id}/messages/#{message.id}/restore.json"
|
||||||
expect(response.status).to eq(403)
|
expect(response.status).to eq(403)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows a user to restore their own messages" do
|
it "allows a user to restore their own messages" do
|
||||||
|
message = Fabricate(:chat_message, chat_channel: chat_channel, user: current_user)
|
||||||
|
message.trash!(current_user)
|
||||||
|
|
||||||
sign_in(current_user)
|
sign_in(current_user)
|
||||||
|
|
||||||
put "/chat/api/channels/#{chat_channel.id}/messages/#{deleted_message.id}/restore.json"
|
put "/chat/api/channels/#{chat_channel.id}/messages/#{message.id}/restore.json"
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
expect(deleted_message.reload.deleted_at).to be_nil
|
expect(message.reload.deleted_at).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "allows admin to restore others' messages" do
|
it "allows admin to restore others' messages" do
|
||||||
|
message = Fabricate(:chat_message, chat_channel: chat_channel, user: current_user)
|
||||||
|
message.trash!(current_user)
|
||||||
|
|
||||||
sign_in(admin)
|
sign_in(admin)
|
||||||
|
|
||||||
put "/chat/api/channels/#{chat_channel.id}/messages/#{deleted_message.id}/restore.json"
|
put "/chat/api/channels/#{chat_channel.id}/messages/#{message.id}/restore.json"
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
expect(deleted_message.reload.deleted_at).to be_nil
|
expect(message.reload.deleted_at).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not allow message restore when channel is read_only" do
|
it "does not allow message restore when channel is read_only" do
|
||||||
|
message = Fabricate(:chat_message, chat_channel: chat_channel, user: current_user)
|
||||||
|
message.trash!(current_user)
|
||||||
|
|
||||||
sign_in(current_user)
|
sign_in(current_user)
|
||||||
|
|
||||||
chat_channel.update!(status: :read_only)
|
chat_channel.update!(status: :read_only)
|
||||||
|
|
||||||
put "/chat/api/channels/#{chat_channel.id}/messages/#{deleted_message.id}/restore.json"
|
put "/chat/api/channels/#{chat_channel.id}/messages/#{message.id}/restore.json"
|
||||||
expect(response.status).to eq(403)
|
expect(response.status).to eq(403)
|
||||||
expect(deleted_message.reload.deleted_at).not_to be_nil
|
expect(message.reload.deleted_at).not_to be_nil
|
||||||
|
|
||||||
sign_in(admin)
|
sign_in(admin)
|
||||||
put "/chat/api/channels/#{chat_channel.id}/messages/#{deleted_message.id}/restore.json"
|
put "/chat/api/channels/#{chat_channel.id}/messages/#{message.id}/restore.json"
|
||||||
expect(response.status).to eq(403)
|
expect(response.status).to eq(403)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "only allows admin to restore when channel is closed" do
|
it "only allows admin to restore when channel is closed" do
|
||||||
|
message = Fabricate(:chat_message, chat_channel: chat_channel, user: current_user)
|
||||||
|
message.trash!(current_user)
|
||||||
|
|
||||||
sign_in(admin)
|
sign_in(admin)
|
||||||
|
|
||||||
chat_channel.update!(status: :read_only)
|
chat_channel.update!(status: :read_only)
|
||||||
|
|
||||||
put "/chat/api/channels/#{chat_channel.id}/messages/#{deleted_message.id}/restore.json"
|
put "/chat/api/channels/#{chat_channel.id}/messages/#{message.id}/restore.json"
|
||||||
expect(response.status).to eq(403)
|
expect(response.status).to eq(403)
|
||||||
expect(deleted_message.reload.deleted_at).not_to be_nil
|
expect(message.reload.deleted_at).not_to be_nil
|
||||||
|
|
||||||
chat_channel.update!(status: :closed)
|
chat_channel.update!(status: :closed)
|
||||||
put "/chat/api/channels/#{chat_channel.id}/messages/#{deleted_message.id}/restore.json"
|
put "/chat/api/channels/#{chat_channel.id}/messages/#{message.id}/restore.json"
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
expect(deleted_message.reload.deleted_at).to be_nil
|
expect(message.reload.deleted_at).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
fab!(:admin) { Fabricate(:admin) }
|
fab!(:admin) { Fabricate(:admin) }
|
||||||
fab!(:second_user) { Fabricate(:user) }
|
fab!(:another_user) { Fabricate(:user) }
|
||||||
|
|
||||||
before do
|
|
||||||
message =
|
|
||||||
Chat::Message.create(
|
|
||||||
user: current_user,
|
|
||||||
message: "this is a message",
|
|
||||||
chat_channel: chat_channel,
|
|
||||||
)
|
|
||||||
message.trash!
|
|
||||||
end
|
|
||||||
|
|
||||||
let(:deleted_message) do
|
|
||||||
Chat::Message.unscoped.where(user: current_user, chat_channel: chat_channel).last
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "for category" do
|
describe "for category" do
|
||||||
fab!(:category) { Fabricate(:category) }
|
fab!(:category) { Fabricate(:category) }
|
||||||
fab!(:chat_channel) { Fabricate(:category_channel, chatable: category) }
|
fab!(:chat_channel) { Fabricate(:category_channel, chatable: category) }
|
||||||
|
|
||||||
it_behaves_like "chat_message_restoration" do
|
it_behaves_like "chat_message_restoration"
|
||||||
let(:other_user) { second_user }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "for dm channel" do
|
describe "for dm channel" do
|
||||||
fab!(:user_2) { Fabricate(:user) }
|
fab!(:user_2) { Fabricate(:user) }
|
||||||
fab!(:chat_channel) { Fabricate(:direct_message_channel, users: [current_user, user_2]) }
|
fab!(:chat_channel) do
|
||||||
|
Fabricate(:direct_message_channel, users: [current_user, another_user])
|
||||||
it_behaves_like "chat_message_restoration" do
|
|
||||||
let(:other_user) { user_2 }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it_behaves_like "chat_message_restoration"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,7 @@ describe Chat::Publisher do
|
||||||
MessageBus.track_publish { described_class.publish_delete!(channel, message_2) }[0].data
|
MessageBus.track_publish { described_class.publish_delete!(channel, message_2) }[0].data
|
||||||
|
|
||||||
expect(data["deleted_at"]).to eq(message_2.deleted_at.iso8601(3))
|
expect(data["deleted_at"]).to eq(message_2.deleted_at.iso8601(3))
|
||||||
|
expect(data["deleted_by_id"]).to eq(message_2.deleted_by_id)
|
||||||
expect(data["deleted_id"]).to eq(message_2.id)
|
expect(data["deleted_id"]).to eq(message_2.id)
|
||||||
expect(data["latest_not_deleted_message_id"]).to eq(message_1.id)
|
expect(data["latest_not_deleted_message_id"]).to eq(message_1.id)
|
||||||
expect(data["type"]).to eq("delete")
|
expect(data["type"]).to eq("delete")
|
||||||
|
|
|
@ -41,6 +41,10 @@ RSpec.describe Chat::TrashMessage do
|
||||||
it "trashes the message" do
|
it "trashes the message" do
|
||||||
result
|
result
|
||||||
expect(Chat::Message.find_by(id: message.id)).to be_nil
|
expect(Chat::Message.find_by(id: message.id)).to be_nil
|
||||||
|
|
||||||
|
deleted_message = Chat::Message.unscoped.find_by(id: message.id)
|
||||||
|
expect(deleted_message.deleted_by_id).to eq(current_user.id)
|
||||||
|
expect(deleted_message.deleted_at).to be_within(1.minute).of(Time.zone.now)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "destroys notifications for mentions" do
|
it "destroys notifications for mentions" do
|
||||||
|
@ -65,6 +69,7 @@ RSpec.describe Chat::TrashMessage do
|
||||||
{
|
{
|
||||||
"type" => "delete",
|
"type" => "delete",
|
||||||
"deleted_id" => message.id,
|
"deleted_id" => message.id,
|
||||||
|
"deleted_by_id" => current_user.id,
|
||||||
"deleted_at" => message.reload.deleted_at.iso8601(3),
|
"deleted_at" => message.reload.deleted_at.iso8601(3),
|
||||||
"latest_not_deleted_message_id" => nil,
|
"latest_not_deleted_message_id" => nil,
|
||||||
},
|
},
|
||||||
|
|
|
@ -120,6 +120,12 @@ module PageObjects
|
||||||
find("[data-value='delete']").click
|
find("[data-value='delete']").click
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def restore_message(message)
|
||||||
|
hover_message(message)
|
||||||
|
click_more_button
|
||||||
|
find("[data-value='restore']").click
|
||||||
|
end
|
||||||
|
|
||||||
def open_edit_message(message)
|
def open_edit_message(message)
|
||||||
hover_message(message)
|
hover_message(message)
|
||||||
click_more_button
|
click_more_button
|
||||||
|
|
|
@ -18,7 +18,16 @@ module PageObjects
|
||||||
end
|
end
|
||||||
|
|
||||||
def hover
|
def hover
|
||||||
message_by_id(message.id).hover
|
component.hover
|
||||||
|
end
|
||||||
|
|
||||||
|
def open_more_menu
|
||||||
|
hover
|
||||||
|
click_more_button
|
||||||
|
end
|
||||||
|
|
||||||
|
def expand
|
||||||
|
component.find(".chat-message-expand").click
|
||||||
end
|
end
|
||||||
|
|
||||||
def select(shift: false)
|
def select(shift: false)
|
||||||
|
@ -37,7 +46,7 @@ module PageObjects
|
||||||
component.click(delay: 0.6)
|
component.click(delay: 0.6)
|
||||||
page.find(".chat-message-actions [data-id=\"select\"]").click
|
page.find(".chat-message-actions [data-id=\"select\"]").click
|
||||||
else
|
else
|
||||||
component.hover
|
hover
|
||||||
click_more_button
|
click_more_button
|
||||||
page.find("[data-value='select']").click
|
page.find("[data-value='select']").click
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,22 @@ module PageObjects
|
||||||
page.find(context)
|
page.find(context)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def has_action?(action, **args)
|
||||||
|
message = find(args)
|
||||||
|
message.open_more_menu
|
||||||
|
page.has_css?("[data-value='#{action}']")
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_no_action?(action, **args)
|
||||||
|
message = find(args)
|
||||||
|
message.open_more_menu
|
||||||
|
page.has_no_css?("[data-value='#{action}']")
|
||||||
|
end
|
||||||
|
|
||||||
|
def expand(**args)
|
||||||
|
find(args).expand
|
||||||
|
end
|
||||||
|
|
||||||
def select(args)
|
def select(args)
|
||||||
find(args).select
|
find(args).select
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
RSpec.describe "Restore message", type: :system do
|
||||||
|
fab!(:admin_user) { Fabricate(:admin) }
|
||||||
|
fab!(:regular_user) { Fabricate(:user) }
|
||||||
|
fab!(:another_user) { Fabricate(:user) }
|
||||||
|
fab!(:channel_1) { Fabricate(:category_channel) }
|
||||||
|
|
||||||
|
let(:chat_page) { PageObjects::Pages::Chat.new }
|
||||||
|
let(:chat_channel_page) { PageObjects::Pages::ChatChannel.new }
|
||||||
|
|
||||||
|
before do
|
||||||
|
chat_system_bootstrap
|
||||||
|
channel_1.add(admin_user)
|
||||||
|
channel_1.add(regular_user)
|
||||||
|
channel_1.add(another_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when user deletes its own message" do
|
||||||
|
fab!(:message_1) { Fabricate(:chat_message, chat_channel: channel_1, user: regular_user) }
|
||||||
|
|
||||||
|
it "can be restored by the owner" do
|
||||||
|
sign_in(regular_user)
|
||||||
|
chat_page.visit_channel(channel_1)
|
||||||
|
|
||||||
|
chat_channel_page.delete_message(message_1)
|
||||||
|
|
||||||
|
expect(chat_channel_page.messages).to have_deleted_message(message_1, count: 1)
|
||||||
|
expect(chat_channel_page.messages).to have_action("restore", id: message_1.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can't be restored by another user" do
|
||||||
|
using_session(:another_user) do
|
||||||
|
sign_in(another_user)
|
||||||
|
chat_page.visit_channel(channel_1)
|
||||||
|
end
|
||||||
|
|
||||||
|
using_session(:regular_user) do |session|
|
||||||
|
sign_in(regular_user)
|
||||||
|
chat_page.visit_channel(channel_1)
|
||||||
|
chat_channel_page.delete_message(message_1)
|
||||||
|
session.quit
|
||||||
|
end
|
||||||
|
|
||||||
|
using_session(:another_user) do |session|
|
||||||
|
expect(chat_channel_page.messages).to have_no_message(id: message_1.id)
|
||||||
|
session.quit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when staff deletes user message" do
|
||||||
|
fab!(:message_1) { Fabricate(:chat_message, chat_channel: channel_1, user: regular_user) }
|
||||||
|
|
||||||
|
it "can't be restored by owner" do
|
||||||
|
using_session(:regular_user) do
|
||||||
|
sign_in(regular_user)
|
||||||
|
chat_page.visit_channel(channel_1)
|
||||||
|
end
|
||||||
|
|
||||||
|
using_session(:admin_user) do |session|
|
||||||
|
sign_in(admin_user)
|
||||||
|
chat_page.visit_channel(channel_1)
|
||||||
|
chat_channel_page.delete_message(message_1)
|
||||||
|
session.quit
|
||||||
|
end
|
||||||
|
|
||||||
|
using_session(:regular_user) do |session|
|
||||||
|
expect(chat_channel_page.messages).to have_deleted_message(message_1, count: 1)
|
||||||
|
chat_channel_page.messages.expand(id: message_1.id)
|
||||||
|
expect(chat_channel_page.messages).to have_no_action("restore", id: message_1.id)
|
||||||
|
session.quit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue