chore: add scripts to test
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Test: Real-Time Assignment Trigger
|
||||
# Run with: bundle exec rails runner script/assignment_v2/test_real_time_trigger.rb
|
||||
#
|
||||
# Tests:
|
||||
# - Assignment triggered when conversation status changes to 'open'
|
||||
# - Assignment triggered when new conversation created
|
||||
# - Assignment only runs when assignee is blank
|
||||
# - Assignment respects enable_auto_assignment flag
|
||||
#
|
||||
# Key Implementation Details:
|
||||
# - AutoAssignmentHandler is a concern included in Conversation model
|
||||
# - Triggers after_save when conversation_status_changed_to_open?
|
||||
# - Checks inbox.auto_assignment_v2_enabled? to use v2 vs legacy system
|
||||
# - NOTE: auto_assignment_v2_enabled? not yet implemented, so this test simulates expected behavior
|
||||
# - When implemented, it will call: AutoAssignment::AssignmentJob.perform_later(inbox_id: inbox.id)
|
||||
#
|
||||
# This test manually triggers assignment to simulate real-time behavior
|
||||
|
||||
require_relative 'test_helpers'
|
||||
|
||||
class TestRealTimeTrigger
|
||||
include AssignmentV2TestHelpers
|
||||
|
||||
def run
|
||||
section('TEST: Real-Time Assignment Trigger')
|
||||
|
||||
account = get_test_account
|
||||
inbox = nil
|
||||
|
||||
begin
|
||||
# Setup test inbox and policy
|
||||
inbox = create_test_inbox(account, name: 'Real-Time Trigger Test Inbox')
|
||||
policy = create_test_policy(account, name: 'Real-Time Policy')
|
||||
link_policy_to_inbox(inbox, policy)
|
||||
|
||||
# Create agent
|
||||
agent = create_test_agent(account, inbox, name: 'Agent Real-Time', online: true)
|
||||
|
||||
# Test 1: Assignment triggered when conversation status changes to open
|
||||
section('Test 1: Status Change to Open Triggers Assignment')
|
||||
|
||||
# Create conversation with status 'pending' (not open)
|
||||
conv = create_test_conversation(inbox, contact_name: 'Pending Customer', status: 'pending')
|
||||
info('Created conversation with status: pending')
|
||||
|
||||
# Conversation should not be assigned (status is not open)
|
||||
conv.reload
|
||||
pending_unassigned = assert(
|
||||
conv.assignee_id.nil?,
|
||||
'Pending conversation not assigned',
|
||||
'Pending conversation was assigned (should not be)'
|
||||
)
|
||||
|
||||
# Change status to 'open' and manually trigger assignment (simulating handler)
|
||||
conv.update!(status: 'open')
|
||||
info('Changed status to: open')
|
||||
|
||||
# Simulate real-time trigger: run assignment job
|
||||
# In production, AutoAssignmentHandler would call: AutoAssignment::AssignmentJob.perform_later
|
||||
assigned_count = run_assignment(inbox)
|
||||
|
||||
# Verify assignment happened
|
||||
log('Verifying assignment after status change...', color: :blue)
|
||||
|
||||
assigned_ok = assert_equal(
|
||||
assigned_count,
|
||||
1,
|
||||
'Conversation assigned after status changed to open'
|
||||
)
|
||||
|
||||
conv.reload
|
||||
has_assignee = assert(
|
||||
conv.assignee_id.present?,
|
||||
'Conversation has assignee',
|
||||
'Conversation not assigned'
|
||||
)
|
||||
|
||||
test1_ok = pending_unassigned && assigned_ok && has_assignee
|
||||
|
||||
# Test 2: New conversation created as 'open' triggers assignment
|
||||
section('Test 2: New Open Conversation Triggers Assignment')
|
||||
|
||||
# Create conversation directly as 'open'
|
||||
conv2 = create_test_conversation(inbox, contact_name: 'Open Customer', status: 'open')
|
||||
info('Created conversation with status: open')
|
||||
|
||||
# Simulate real-time trigger
|
||||
assigned_count_2 = run_assignment(inbox)
|
||||
|
||||
# Verify assignment
|
||||
log('Verifying assignment for new open conversation...', color: :blue)
|
||||
|
||||
assigned_ok_2 = assert_equal(
|
||||
assigned_count_2,
|
||||
1,
|
||||
'New open conversation assigned'
|
||||
)
|
||||
|
||||
conv2.reload
|
||||
has_assignee_2 = assert(
|
||||
conv2.assignee_id.present?,
|
||||
'New conversation has assignee',
|
||||
'New conversation not assigned'
|
||||
)
|
||||
|
||||
test2_ok = assigned_ok_2 && has_assignee_2
|
||||
|
||||
# Test 3: Already assigned conversation not re-assigned
|
||||
section('Test 3: Already Assigned Conversation Not Re-Assigned')
|
||||
|
||||
# Create and assign a conversation
|
||||
conv3 = create_test_conversation(inbox, contact_name: 'Customer 3', status: 'open')
|
||||
run_assignment(inbox)
|
||||
conv3.reload
|
||||
original_assignee = conv3.assignee
|
||||
info("Conversation initially assigned to: #{original_assignee.name}")
|
||||
|
||||
# Update something else (not status, not assignee)
|
||||
conv3.update!(additional_attributes: { test: 'value' })
|
||||
|
||||
# Simulate real-time trigger
|
||||
assigned_count_3 = run_assignment(inbox)
|
||||
|
||||
# Verify no re-assignment
|
||||
log('Verifying already-assigned conversation not re-assigned...', color: :blue)
|
||||
|
||||
# Should assign 0 (conversation already has assignee)
|
||||
no_reassign = assert_equal(
|
||||
assigned_count_3,
|
||||
0,
|
||||
'No conversations re-assigned'
|
||||
)
|
||||
|
||||
conv3.reload
|
||||
same_assignee = assert(
|
||||
conv3.assignee_id == original_assignee.id,
|
||||
'Conversation keeps original assignee',
|
||||
'Conversation was re-assigned (should not be)'
|
||||
)
|
||||
|
||||
test3_ok = no_reassign && same_assignee
|
||||
|
||||
# Test 4: Resolved conversation changing to open triggers assignment
|
||||
section('Test 4: Resolved → Open Triggers Assignment')
|
||||
|
||||
# Create and resolve a conversation
|
||||
conv4 = create_test_conversation(inbox, contact_name: 'Returning Customer', status: 'open')
|
||||
run_assignment(inbox)
|
||||
conv4.reload
|
||||
conv4.update!(status: 'resolved', assignee: nil)
|
||||
info('Conversation resolved and unassigned')
|
||||
|
||||
# Reopen conversation
|
||||
conv4.update!(status: 'open')
|
||||
info('Conversation reopened (status: open)')
|
||||
|
||||
# Simulate real-time trigger
|
||||
assigned_count_4 = run_assignment(inbox)
|
||||
|
||||
# Verify re-assignment
|
||||
log('Verifying reopened conversation assigned...', color: :blue)
|
||||
|
||||
assigned_ok_4 = assert_equal(
|
||||
assigned_count_4,
|
||||
1,
|
||||
'Reopened conversation assigned'
|
||||
)
|
||||
|
||||
conv4.reload
|
||||
has_assignee_4 = assert(
|
||||
conv4.assignee_id.present?,
|
||||
'Reopened conversation has assignee',
|
||||
'Reopened conversation not assigned'
|
||||
)
|
||||
|
||||
test4_ok = assigned_ok_4 && has_assignee_4
|
||||
|
||||
# Test 5: Assignment respects online status in real-time
|
||||
section('Test 5: Real-Time Assignment Respects Agent Availability')
|
||||
|
||||
# Take agent offline
|
||||
OnlineStatusTracker.set_status(account.id, agent.id, 'offline')
|
||||
info("Took #{agent.name} offline")
|
||||
|
||||
# Create new conversation
|
||||
conv5 = create_test_conversation(inbox, contact_name: 'Customer During Offline', status: 'open')
|
||||
|
||||
# Simulate real-time trigger
|
||||
assigned_count_5 = run_assignment(inbox)
|
||||
|
||||
# Verify no assignment (agent offline)
|
||||
log('Verifying no assignment when agent offline...', color: :blue)
|
||||
|
||||
no_assign_offline = assert_equal(
|
||||
assigned_count_5,
|
||||
0,
|
||||
'No assignment when agent offline'
|
||||
)
|
||||
|
||||
conv5.reload
|
||||
unassigned_offline = assert(
|
||||
conv5.assignee_id.nil?,
|
||||
'Conversation remains unassigned when agent offline',
|
||||
'Conversation was assigned despite agent being offline'
|
||||
)
|
||||
|
||||
# Bring agent back online
|
||||
OnlineStatusTracker.update_presence(account.id, 'User', agent.id)
|
||||
OnlineStatusTracker.set_status(account.id, agent.id, 'online')
|
||||
info("Brought #{agent.name} back online")
|
||||
|
||||
# Simulate real-time trigger (next conversation triggers assignment for backlog)
|
||||
assigned_count_6 = run_assignment(inbox)
|
||||
|
||||
# Now should assign
|
||||
assigned_after_online = assert_equal(
|
||||
assigned_count_6,
|
||||
1,
|
||||
'Assignment happens when agent comes online'
|
||||
)
|
||||
|
||||
test5_ok = no_assign_offline && unassigned_offline && assigned_after_online
|
||||
|
||||
# Final result
|
||||
if test1_ok && test2_ok && test3_ok && test4_ok && test5_ok
|
||||
section('✓ ALL TESTS PASSED')
|
||||
true
|
||||
else
|
||||
section('✗ SOME TESTS FAILED')
|
||||
false
|
||||
end
|
||||
rescue StandardError => e
|
||||
error("Test failed with error: #{e.message}")
|
||||
puts e.backtrace.first(5).join("\n")
|
||||
false
|
||||
ensure
|
||||
cleanup_test_data(account, inbox: inbox) if inbox
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Run test and exit with appropriate code
|
||||
exit(TestRealTimeTrigger.new.run ? 0 : 1)
|
||||
Reference in New Issue
Block a user