208 lines
7.3 KiB
Ruby
208 lines
7.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
# Test: Agent Availability and Status
|
|
# Run with: bundle exec rails runner script/assignment_v2/test_agent_availability.rb
|
|
#
|
|
# Tests:
|
|
# - Only online agents receive assignments
|
|
# - Offline agents are excluded from assignment pool
|
|
# - When agents go offline mid-assignment, remaining conversations go to online agents
|
|
# - When agents come online, they become eligible for new assignments
|
|
#
|
|
# Key Implementation Details:
|
|
# - inbox.available_agents filters by online status via OnlineStatusTracker
|
|
# - OnlineStatusTracker.update_presence(account_id, 'User', user_id) marks agent as online
|
|
# - OnlineStatusTracker.remove_presence(account_id, 'User', user_id) marks agent as offline
|
|
# - Availability is checked for EACH conversation assignment (not cached for the batch)
|
|
# - This ensures real-time status changes affect assignment within a single job run
|
|
|
|
require_relative 'test_helpers'
|
|
|
|
class TestAgentAvailability
|
|
include AssignmentV2TestHelpers
|
|
|
|
def run
|
|
section('TEST: Agent Availability and Status')
|
|
|
|
account = get_test_account
|
|
inbox = nil
|
|
|
|
begin
|
|
# Setup test inbox and policy
|
|
inbox = create_test_inbox(account, name: 'Availability Test Inbox')
|
|
policy = create_test_policy(account, name: 'Availability Test Policy')
|
|
link_policy_to_inbox(inbox, policy)
|
|
|
|
# Test 1: Only online agents receive assignments
|
|
section('Test 1: Only Online Agents Get Assigned')
|
|
|
|
# Create 3 agents: 2 online, 1 offline
|
|
agent_online_1 = create_test_agent(account, inbox, name: 'Agent Online 1', online: true)
|
|
agent_online_2 = create_test_agent(account, inbox, name: 'Agent Online 2', online: true)
|
|
agent_offline = create_test_agent(account, inbox, name: 'Agent Offline', online: false)
|
|
|
|
info("Online agents: #{agent_online_1.name}, #{agent_online_2.name}")
|
|
info("Offline agent: #{agent_offline.name}")
|
|
|
|
# Create 6 conversations (should be split between 2 online agents only)
|
|
create_bulk_conversations(inbox, count: 6)
|
|
|
|
# Run assignment
|
|
assigned_count = run_assignment(inbox)
|
|
|
|
# Verify only online agents got assignments
|
|
log('Verifying only online agents assigned...', color: :blue)
|
|
|
|
# Should assign all 6 conversations (2 online agents available)
|
|
all_assigned = assert_equal(
|
|
assigned_count,
|
|
6,
|
|
'All 6 conversations assigned'
|
|
)
|
|
|
|
# Each online agent should have 3 conversations (round-robin between 2)
|
|
online_1_count = inbox.conversations.where(assignee: agent_online_1).count
|
|
online_2_count = inbox.conversations.where(assignee: agent_online_2).count
|
|
offline_count = inbox.conversations.where(assignee: agent_offline).count
|
|
|
|
distribution_ok = assert_equal(
|
|
online_1_count,
|
|
3,
|
|
"#{agent_online_1.name} has 3 conversations"
|
|
)
|
|
|
|
distribution_ok &= assert_equal(
|
|
online_2_count,
|
|
3,
|
|
"#{agent_online_2.name} has 3 conversations"
|
|
)
|
|
|
|
# Offline agent should have 0
|
|
offline_excluded = assert_equal(
|
|
offline_count,
|
|
0,
|
|
"#{agent_offline.name} has 0 conversations (offline)"
|
|
)
|
|
|
|
test1_ok = all_assigned && distribution_ok && offline_excluded
|
|
|
|
# Test 2: When agent goes offline, new assignments skip them
|
|
section('Test 2: Agent Goes Offline Mid-Test')
|
|
|
|
# Take agent_online_2 offline by setting status to 'offline'
|
|
OnlineStatusTracker.set_status(account.id, agent_online_2.id, 'offline')
|
|
info("Took #{agent_online_2.name} offline")
|
|
|
|
# Create 3 more conversations
|
|
create_bulk_conversations(inbox, count: 3)
|
|
|
|
# Run assignment again
|
|
assigned_count_2 = run_assignment(inbox)
|
|
|
|
# Verify only agent_online_1 gets the new assignments
|
|
log('Verifying offline agent excluded...', color: :blue)
|
|
|
|
# Should assign all 3 new conversations
|
|
all_assigned_2 = assert_equal(
|
|
assigned_count_2,
|
|
3,
|
|
'All 3 new conversations assigned'
|
|
)
|
|
|
|
# Agent_online_1 should now have 6 total (3 + 3 new)
|
|
online_1_new_count = inbox.conversations.where(assignee: agent_online_1).count
|
|
online_1_got_all = assert_equal(
|
|
online_1_new_count,
|
|
6,
|
|
"#{agent_online_1.name} has 6 conversations (got all new ones)"
|
|
)
|
|
|
|
# Agent_online_2 should still have 3 (no new assignments)
|
|
online_2_still_count = inbox.conversations.where(assignee: agent_online_2).count
|
|
online_2_unchanged = assert_equal(
|
|
online_2_still_count,
|
|
3,
|
|
"#{agent_online_2.name} still has 3 conversations (offline, no new ones)"
|
|
)
|
|
|
|
test2_ok = all_assigned_2 && online_1_got_all && online_2_unchanged
|
|
|
|
# Test 3: When agent comes online, they become eligible
|
|
section('Test 3: Agent Comes Online')
|
|
|
|
# Bring agent_online_2 back online by updating presence and setting status
|
|
OnlineStatusTracker.update_presence(account.id, 'User', agent_online_2.id)
|
|
OnlineStatusTracker.set_status(account.id, agent_online_2.id, 'online')
|
|
info("Brought #{agent_online_2.name} back online")
|
|
|
|
# Bring offline agent online too
|
|
OnlineStatusTracker.update_presence(account.id, 'User', agent_offline.id)
|
|
OnlineStatusTracker.set_status(account.id, agent_offline.id, 'online')
|
|
info("Brought #{agent_offline.name} online")
|
|
|
|
# Create 6 more conversations (should distribute across all 3 now)
|
|
create_bulk_conversations(inbox, count: 6)
|
|
|
|
# Run assignment
|
|
assigned_count_3 = run_assignment(inbox)
|
|
|
|
# Verify all 3 agents get assignments
|
|
log('Verifying all online agents get assignments...', color: :blue)
|
|
|
|
# Should assign all 6 conversations
|
|
all_assigned_3 = assert_equal(
|
|
assigned_count_3,
|
|
6,
|
|
'All 6 final conversations assigned'
|
|
)
|
|
|
|
# Each agent should get 2 more (round-robin across 3)
|
|
agent_online_1_final = inbox.conversations.where(assignee: agent_online_1).count
|
|
agent_online_2_final = inbox.conversations.where(assignee: agent_online_2).count
|
|
agent_offline_final = inbox.conversations.where(assignee: agent_offline).count
|
|
|
|
online_1_increased = assert_equal(
|
|
agent_online_1_final,
|
|
8, # 6 + 2
|
|
"#{agent_online_1.name} has 8 conversations (6 + 2 new)"
|
|
)
|
|
|
|
online_2_increased = assert_equal(
|
|
agent_online_2_final,
|
|
5, # 3 + 2
|
|
"#{agent_online_2.name} has 5 conversations (3 + 2 new)"
|
|
)
|
|
|
|
# Previously offline agent should now have assignments
|
|
previously_offline_assigned = assert_equal(
|
|
agent_offline_final,
|
|
2, # 0 + 2
|
|
"#{agent_offline.name} has 2 conversations (came online, got 2 new)"
|
|
)
|
|
|
|
test3_ok = all_assigned_3 && online_1_increased && online_2_increased && previously_offline_assigned
|
|
|
|
# Show final distribution
|
|
show_assignment_distribution(inbox, [agent_online_1, agent_online_2, agent_offline])
|
|
|
|
# Final result
|
|
if test1_ok && test2_ok && test3_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(TestAgentAvailability.new.run ? 0 : 1)
|