If you are the application owner check the logs for more information.
+
422
+
Request rejected
+
Your request couldn't be processed due to a security verification failure or invalid data.
+
+
+ Back to home
+
+
+
If this keeps happening, try clearing your cookies and refreshing.
diff --git a/public/500.html b/public/500.html
index 061abc587..1339c166b 100644
--- a/public/500.html
+++ b/public/500.html
@@ -1,66 +1,108 @@
-
+
-
-
-
We're sorry, but something went wrong.
-
-
If you are the application owner check the logs for more information.
+
+
500
+
Something went wrong
+
An unexpected error occurred. Please refresh the page or try again shortly.
+
+
+ Back to home
+
+
+
If the problem persists, please try again in a few minutes.
diff --git a/spec/enterprise/services/enterprise/auto_assignment/assignment_service_spec.rb b/spec/enterprise/services/enterprise/auto_assignment/assignment_service_spec.rb
index 432f397be..ba1a3eec0 100644
--- a/spec/enterprise/services/enterprise/auto_assignment/assignment_service_spec.rb
+++ b/spec/enterprise/services/enterprise/auto_assignment/assignment_service_spec.rb
@@ -16,8 +16,9 @@ RSpec.describe Enterprise::AutoAssignment::AssignmentService, type: :service do
# Link inbox to assignment policy
create(:inbox_assignment_policy, inbox: inbox, assignment_policy: assignment_policy)
- allow(account).to receive(:feature_enabled?).and_return(false)
- allow(account).to receive(:feature_enabled?).with('assignment_v2').and_return(true)
+ # Enable assignment_v2 (base) and advanced_assignment (premium) features
+ account.enable_features('assignment_v2')
+ account.save!
# Set agents as online
OnlineStatusTracker.update_presence(account.id, 'User', agent1.id)
diff --git a/spec/enterprise/services/enterprise/auto_assignment/capacity_service_spec.rb b/spec/enterprise/services/enterprise/auto_assignment/capacity_service_spec.rb
index 98d7c2172..c34eaad64 100644
--- a/spec/enterprise/services/enterprise/auto_assignment/capacity_service_spec.rb
+++ b/spec/enterprise/services/enterprise/auto_assignment/capacity_service_spec.rb
@@ -52,8 +52,9 @@ RSpec.describe Enterprise::AutoAssignment::CapacityService, type: :service do
agent_at_capacity.id.to_s => 'online'
})
- # Enable assignment_v2 feature
- allow(account).to receive(:feature_enabled?).with('assignment_v2').and_return(true)
+ # Enable assignment_v2 (base) and advanced_assignment (premium) features
+ account.enable_features('assignment_v2', 'advanced_assignment')
+ account.save!
# Create existing assignments for agent_at_capacity (at limit)
3.times do
diff --git a/spec/jobs/auto_assignment/periodic_assignment_job_spec.rb b/spec/jobs/auto_assignment/periodic_assignment_job_spec.rb
index 4b06decd0..e281f79f4 100644
--- a/spec/jobs/auto_assignment/periodic_assignment_job_spec.rb
+++ b/spec/jobs/auto_assignment/periodic_assignment_job_spec.rb
@@ -14,13 +14,13 @@ RSpec.describe AutoAssignment::PeriodicAssignmentJob, type: :job do
describe '#perform' do
context 'when account has assignment_v2 feature enabled' do
before do
- allow(account).to receive(:feature_enabled?).with('assignment_v2').and_return(true)
+ account.enable_features('assignment_v2')
+ account.save!
allow(Account).to receive(:find_in_batches).and_yield([account])
end
- context 'when inbox has auto_assignment_v2 enabled' do
+ context 'when inbox has assignment policy or auto assignment enabled' do
before do
- allow(inbox).to receive(:auto_assignment_v2_enabled?).and_return(true)
inbox_relation = instance_double(ActiveRecord::Relation)
allow(account).to receive(:inboxes).and_return(inbox_relation)
allow(inbox_relation).to receive(:joins).with(:assignment_policy).and_return(inbox_relation)
@@ -41,8 +41,8 @@ RSpec.describe AutoAssignment::PeriodicAssignmentJob, type: :job do
policy2 = create(:assignment_policy, account: account2)
create(:inbox_assignment_policy, inbox: inbox2, assignment_policy: policy2)
- allow(account2).to receive(:feature_enabled?).with('assignment_v2').and_return(true)
- allow(inbox2).to receive(:auto_assignment_v2_enabled?).and_return(true)
+ account2.enable_features('assignment_v2')
+ account2.save!
inbox_relation2 = instance_double(ActiveRecord::Relation)
allow(account2).to receive(:inboxes).and_return(inbox_relation2)
@@ -58,9 +58,10 @@ RSpec.describe AutoAssignment::PeriodicAssignmentJob, type: :job do
end
end
- context 'when inbox does not have auto_assignment_v2 enabled' do
+ context 'when inbox does not have assignment policy or auto assignment enabled' do
before do
- allow(inbox).to receive(:auto_assignment_v2_enabled?).and_return(false)
+ inbox.update!(enable_auto_assignment: false)
+ InboxAssignmentPolicy.where(inbox: inbox).destroy_all
end
it 'does not queue assignment job' do
@@ -73,7 +74,6 @@ RSpec.describe AutoAssignment::PeriodicAssignmentJob, type: :job do
context 'when account does not have assignment_v2 feature enabled' do
before do
- allow(account).to receive(:feature_enabled?).with('assignment_v2').and_return(false)
allow(Account).to receive(:find_in_batches).and_yield([account])
end
@@ -90,11 +90,11 @@ RSpec.describe AutoAssignment::PeriodicAssignmentJob, type: :job do
# Create multiple accounts
5.times do |_i|
acc = create(:account)
+ acc.enable_features('assignment_v2')
+ acc.save!
inb = create(:inbox, account: acc, enable_auto_assignment: true)
policy = create(:assignment_policy, account: acc)
create(:inbox_assignment_policy, inbox: inb, assignment_policy: policy)
- allow(acc).to receive(:feature_enabled?).with('assignment_v2').and_return(true)
- allow(inb).to receive(:auto_assignment_v2_enabled?).and_return(true)
inbox_relation = instance_double(ActiveRecord::Relation)
allow(acc).to receive(:inboxes).and_return(inbox_relation)
diff --git a/spec/lib/webhooks/trigger_spec.rb b/spec/lib/webhooks/trigger_spec.rb
index 78bf361c4..79cf92150 100644
--- a/spec/lib/webhooks/trigger_spec.rb
+++ b/spec/lib/webhooks/trigger_spec.rb
@@ -74,10 +74,11 @@ describe Webhooks::Trigger do
context 'when webhook type is agent bot' do
let(:webhook_type) { :agent_bot_webhook }
+ let!(:pending_conversation) { create(:conversation, inbox: inbox, status: :pending, account: account) }
+ let!(:pending_message) { create(:message, account: account, inbox: inbox, conversation: pending_conversation) }
it 'reopens conversation and enqueues activity message if pending' do
- conversation.update(status: :pending)
- payload = { event: 'message_created', conversation: { id: conversation.id }, id: message.id }
+ payload = { event: 'message_created', id: pending_message.id }
expect(RestClient::Request).to receive(:execute)
.with(
@@ -92,11 +93,11 @@ describe Webhooks::Trigger do
perform_enqueued_jobs do
trigger.execute(url, payload, webhook_type)
end
- end.not_to(change { message.reload.status })
+ end.not_to(change { pending_message.reload.status })
- expect(conversation.reload.status).to eq('open')
+ expect(pending_conversation.reload.status).to eq('open')
- activity_message = conversation.reload.messages.order(:created_at).last
+ activity_message = pending_conversation.reload.messages.order(:created_at).last
expect(activity_message.message_type).to eq('activity')
expect(activity_message.content).to eq(agent_bot_error_content)
end
@@ -118,9 +119,52 @@ describe Webhooks::Trigger do
end.not_to(change { message.reload.status })
expect(Conversations::ActivityMessageJob).not_to have_been_enqueued
-
expect(conversation.reload.status).to eq('open')
end
+
+ it 'keeps conversation pending when keep_pending_on_bot_failure setting is enabled' do
+ account.update(keep_pending_on_bot_failure: true)
+ payload = { event: 'message_created', id: pending_message.id }
+
+ expect(RestClient::Request).to receive(:execute)
+ .with(
+ method: :post,
+ url: url,
+ payload: payload.to_json,
+ headers: { content_type: :json, accept: :json },
+ timeout: webhook_timeout
+ ).and_raise(RestClient::ExceptionWithResponse.new('error', 500)).once
+
+ trigger.execute(url, payload, webhook_type)
+
+ expect(Conversations::ActivityMessageJob).not_to have_been_enqueued
+ expect(pending_conversation.reload.status).to eq('pending')
+ end
+
+ it 'reopens conversation when keep_pending_on_bot_failure setting is disabled' do
+ account.update(keep_pending_on_bot_failure: false)
+ payload = { event: 'message_created', id: pending_message.id }
+
+ expect(RestClient::Request).to receive(:execute)
+ .with(
+ method: :post,
+ url: url,
+ payload: payload.to_json,
+ headers: { content_type: :json, accept: :json },
+ timeout: webhook_timeout
+ ).and_raise(RestClient::ExceptionWithResponse.new('error', 500)).once
+ expect do
+ perform_enqueued_jobs do
+ trigger.execute(url, payload, webhook_type)
+ end
+ end.not_to(change { pending_message.reload.status })
+
+ expect(pending_conversation.reload.status).to eq('open')
+
+ activity_message = pending_conversation.reload.messages.order(:created_at).last
+ expect(activity_message.message_type).to eq('activity')
+ expect(activity_message.content).to eq(agent_bot_error_content)
+ end
end
end
diff --git a/spec/services/auto_assignment/assignment_service_spec.rb b/spec/services/auto_assignment/assignment_service_spec.rb
index 535277714..2139e5e78 100644
--- a/spec/services/auto_assignment/assignment_service_spec.rb
+++ b/spec/services/auto_assignment/assignment_service_spec.rb
@@ -10,8 +10,9 @@ RSpec.describe AutoAssignment::AssignmentService do
let(:conversation) { create(:conversation, inbox: inbox, assignee: nil) }
before do
- # Enable assignment_v2 feature for the account
- allow(account).to receive(:feature_enabled?).with('assignment_v2').and_return(true)
+ # Enable assignment_v2 feature for the account (basic assignment features)
+ account.enable_features('assignment_v2')
+ account.save!
# Link inbox to assignment policy
create(:inbox_assignment_policy, inbox: inbox, assignment_policy: assignment_policy)
create(:inbox_member, inbox: inbox, user: agent)
diff --git a/spec/services/auto_assignment/rate_limiter_spec.rb b/spec/services/auto_assignment/rate_limiter_spec.rb
index 48a5367e3..d5c3de047 100644
--- a/spec/services/auto_assignment/rate_limiter_spec.rb
+++ b/spec/services/auto_assignment/rate_limiter_spec.rb
@@ -59,8 +59,9 @@ RSpec.describe AutoAssignment::RateLimiter do
allow(inbox).to receive(:assignment_policy).and_return(nil)
end
- it 'does not track the assignment' do
- expect(Redis::Alfred).not_to receive(:set)
+ it 'still tracks the assignment with default window' do
+ expected_key = format(Redis::RedisKeys::ASSIGNMENT_KEY, inbox_id: inbox.id, agent_id: agent.id, conversation_id: conversation.id)
+ expect(Redis::Alfred).to receive(:set).with(expected_key, conversation.id.to_s, ex: 24.hours.to_i)
rate_limiter.track_assignment(conversation)
end
end