feat(conversations): add message creation limit lock
This commit is contained in:
@@ -104,6 +104,53 @@ RSpec.describe Conversation do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'message creation lock' do
|
||||
let(:conversation) { create(:conversation) }
|
||||
let(:message_params) { { conversation: conversation, account: conversation.account, inbox: conversation.inbox } }
|
||||
|
||||
it 'detects when the message limit has been reached' do
|
||||
with_modified_env 'CONVERSATION_MESSAGE_LIMIT': '2' do
|
||||
create(:message, **message_params)
|
||||
|
||||
expect(conversation.reload.message_limit).to eq(2)
|
||||
expect(conversation.message_limit_reached?).to be false
|
||||
|
||||
create(:message, **message_params)
|
||||
|
||||
expect(conversation.reload.message_limit_reached?).to be true
|
||||
expect(conversation.message_creation_locked?).to be true
|
||||
expect(conversation.message_creation_lock_reason).to eq('message_limit')
|
||||
end
|
||||
end
|
||||
|
||||
it 'stores and clears manual lock metadata' do
|
||||
freeze_time do
|
||||
conversation.lock_message_creation!(reason: 'maintenance')
|
||||
|
||||
lock_data = conversation.reload.additional_attributes['message_creation_lock']
|
||||
expect(lock_data).to include(
|
||||
'locked' => true,
|
||||
'reason' => 'maintenance',
|
||||
'locked_at' => Time.current.iso8601
|
||||
)
|
||||
expect(conversation.manual_message_creation_locked?).to be true
|
||||
expect(conversation.message_creation_locked?).to be true
|
||||
expect(conversation.message_creation_lock_reason).to eq('manual')
|
||||
|
||||
conversation.unlock_message_creation!
|
||||
|
||||
expect(conversation.reload.additional_attributes).not_to have_key('message_creation_lock')
|
||||
expect(conversation.message_creation_locked?).to be false
|
||||
end
|
||||
end
|
||||
|
||||
it 'fails loudly when the message limit config is invalid' do
|
||||
with_modified_env 'CONVERSATION_MESSAGE_LIMIT': 'invalid' do
|
||||
expect { conversation.message_limit }.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.after_update' do
|
||||
let!(:account) { create(:account) }
|
||||
let!(:old_assignee) do
|
||||
@@ -620,6 +667,10 @@ RSpec.describe Conversation do
|
||||
contact_inbox: conversation.contact_inbox,
|
||||
timestamp: conversation.last_activity_at.to_i,
|
||||
can_reply: true,
|
||||
message_limit: conversation.message_limit,
|
||||
message_limit_reached: conversation.message_limit_reached?,
|
||||
message_creation_locked: conversation.message_creation_locked?,
|
||||
message_creation_lock_reason: conversation.message_creation_lock_reason,
|
||||
channel: 'Channel::WebWidget',
|
||||
snoozed_until: conversation.snoozed_until,
|
||||
custom_attributes: conversation.custom_attributes,
|
||||
|
||||
@@ -141,6 +141,10 @@ RSpec.describe Message do
|
||||
source_id: message.conversation.contact_inbox.source_id
|
||||
},
|
||||
last_activity_at: message.conversation.last_activity_at.to_i,
|
||||
message_limit: message.conversation.message_limit,
|
||||
message_limit_reached: message.conversation.message_limit_reached?,
|
||||
message_creation_locked: message.conversation.message_creation_locked?,
|
||||
message_creation_lock_reason: message.conversation.message_creation_lock_reason,
|
||||
unread_count: message.conversation.unread_incoming_messages.count
|
||||
},
|
||||
sentiment: {},
|
||||
@@ -154,6 +158,47 @@ RSpec.describe Message do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'message creation lock' do
|
||||
let(:conversation) { create(:conversation) }
|
||||
let(:message_params) { { conversation: conversation, account: conversation.account, inbox: conversation.inbox } }
|
||||
let(:locked_error_name) { 'CustomExceptions::ConversationMessageCreationLocked' }
|
||||
|
||||
it 'allows the capped message and blocks the next message' do
|
||||
with_modified_env 'CONVERSATION_MESSAGE_LIMIT': '2' do
|
||||
create(:message, **message_params)
|
||||
|
||||
expect { create(:message, **message_params) }.to change(described_class, :count).by(1)
|
||||
expect { create(:message, **message_params) }
|
||||
.to raise_error(StandardError) { |error| expect(error.class.name).to eq(locked_error_name) }
|
||||
end
|
||||
end
|
||||
|
||||
it 'counts incoming, outgoing, template, private, and activity messages' do
|
||||
with_modified_env 'CONVERSATION_MESSAGE_LIMIT': '5' do
|
||||
create(:message, message_type: :incoming, **message_params)
|
||||
create(:message, message_type: :outgoing, **message_params)
|
||||
create(:message, message_type: :template, **message_params)
|
||||
create(:message, message_type: :outgoing, private: true, **message_params)
|
||||
create(:message, message_type: :activity, **message_params)
|
||||
|
||||
expect(conversation.reload.message_limit_reached?).to be true
|
||||
expect { create(:message, **message_params) }
|
||||
.to raise_error(StandardError) { |error| expect(error.class.name).to eq(locked_error_name) }
|
||||
end
|
||||
end
|
||||
|
||||
it 'blocks message creation when manually locked and allows it after unlock' do
|
||||
conversation.lock_message_creation!(reason: 'ops')
|
||||
|
||||
expect { create(:message, **message_params) }
|
||||
.to raise_error(StandardError) { |error| expect(error.class.name).to eq(locked_error_name) }
|
||||
|
||||
conversation.unlock_message_creation!
|
||||
|
||||
expect { create(:message, **message_params) }.to change(described_class, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'message create event' do
|
||||
let!(:conversation) { create(:conversation) }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user