Files
chatwoot/spec/enterprise/builders/notification_builder_spec.rb
6c67eb9ba0 fix(notifications): Respect conversation access when notifying agents (#14412)
Agents with limited custom roles were receiving notifications (creation,
assignment, mentions, new messages, SLA) for conversations they couldn't
actually open. For example, an agent whose custom role only grants
`conversation_unassigned_manage` was getting notified about
conversations assigned to other agents.

Notifications now go through the same `ConversationPolicy#show?` check
that gates the conversation view itself, so an agent only gets notified
for conversations they're permitted to see. Administrators and agents
without custom roles are unaffected.

---------

Co-authored-by: Sojan Jose <sojan@pepalo.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2026-05-12 10:57:29 +04:00

107 lines
4.4 KiB
Ruby

require 'rails_helper'
describe NotificationBuilder do
describe '#perform with custom role permissions' do
let!(:account) { create(:account) }
let!(:agent) { create(:user, account: account, role: :agent) }
let!(:inbox) { create(:inbox, account: account) }
let!(:account_user) { agent.account_users.find_by(account: account) }
before do
create(:inbox_member, user: agent, inbox: inbox)
notification_setting = agent.notification_settings.find_by(account_id: account.id)
notification_setting.selected_email_flags = [:email_conversation_creation]
notification_setting.selected_push_flags = [:push_conversation_creation]
notification_setting.save!
end
def build_notification(conversation, type: 'conversation_creation')
described_class.new(
notification_type: type,
user: agent,
account: account,
primary_actor: conversation
).perform
end
context 'when the agent has conversation_manage permission' do
before do
custom_role = create(:custom_role, account: account, permissions: ['conversation_manage'])
account_user.update!(custom_role: custom_role)
end
it 'creates a notification for any inbox conversation' do
conversation = create(:conversation, account: account, inbox: inbox)
expect { build_notification(conversation) }.to change { agent.notifications.count }.by(1)
end
end
context 'when the agent has conversation_unassigned_manage permission' do
before do
custom_role = create(:custom_role, account: account, permissions: ['conversation_unassigned_manage'])
account_user.update!(custom_role: custom_role)
end
it 'creates a notification for unassigned conversations' do
conversation = create(:conversation, account: account, inbox: inbox, assignee: nil)
expect { build_notification(conversation) }.to change { agent.notifications.count }.by(1)
end
it 'creates a notification for conversations assigned to the agent' do
conversation = create(:conversation, account: account, inbox: inbox, assignee: agent)
expect { build_notification(conversation) }.to change { agent.notifications.count }.by(1)
end
it 'does not create a notification for conversations assigned to someone else' do
other_agent = create(:user, account: account, role: :agent)
create(:inbox_member, user: other_agent, inbox: inbox)
conversation = create(:conversation, account: account, inbox: inbox, assignee: other_agent)
expect { build_notification(conversation) }.not_to(change { agent.notifications.count })
end
end
context 'when the agent has conversation_participating_manage permission' do
before do
custom_role = create(:custom_role, account: account, permissions: ['conversation_participating_manage'])
account_user.update!(custom_role: custom_role)
end
it 'creates a notification for conversations assigned to the agent' do
conversation = create(:conversation, account: account, inbox: inbox, assignee: agent)
expect { build_notification(conversation) }.to change { agent.notifications.count }.by(1)
end
it 'creates a notification for conversations the agent participates in' do
conversation = create(:conversation, account: account, inbox: inbox, assignee: nil)
create(:conversation_participant, conversation: conversation, account: account, user: agent)
expect { build_notification(conversation) }.to change { agent.notifications.count }.by(1)
end
it 'does not create a notification for unassigned conversations the agent does not participate in' do
conversation = create(:conversation, account: account, inbox: inbox, assignee: nil)
expect { build_notification(conversation) }.not_to(change { agent.notifications.count })
end
end
context 'when the custom role grants no conversation permissions' do
before do
custom_role = create(:custom_role, account: account, permissions: ['contact_manage'])
account_user.update!(custom_role: custom_role)
end
it 'does not create a notification' do
conversation = create(:conversation, account: account, inbox: inbox, assignee: agent)
expect { build_notification(conversation) }.not_to(change { agent.notifications.count })
end
end
end
end