task-routing.test.js
1 /** 2 * Task Routing Tests 3 * 4 * Verify task type to agent mapping is correct 5 */ 6 7 import { test } from 'node:test'; 8 import assert from 'node:assert/strict'; 9 import { 10 TASK_ROUTING, 11 getAgentForTaskType, 12 isValidTaskType, 13 getTaskTypesForAgent, 14 validateTaskAssignment, 15 } from '../../src/agents/utils/task-routing.js'; 16 17 test('TASK_ROUTING has all expected task types', () => { 18 const expectedTaskTypes = [ 19 // Developer 20 'fix_bug', 21 'implement_feature', 22 'refactor_code', 23 'apply_feedback', 24 'implementation_plan', 25 // QA 26 'write_test', 27 'verify_fix', 28 'check_coverage', 29 'run_tests', 30 // Security 31 'audit_code', 32 'scan_dependencies', 33 'verify_compliance', 34 'scan_secrets', 35 'threat_model', 36 'fix_security_issue', 37 'review_dependency_update', 38 // Architect 39 'design_proposal', 40 'technical_review', 41 'review_design', 42 'suggest_refactor', 43 'update_documentation', 44 'check_documentation_freshness', 45 'check_complexity', 46 'audit_documentation', 47 'check_branch_health', 48 'profile_performance', 49 'review_documentation', 50 // Triage 51 'classify_error', 52 'route_task', 53 'prioritize_tasks', 54 // Monitor 55 'scan_logs', 56 'check_agent_health', 57 'check_process_compliance', 58 'detect_anomaly', 59 'check_pipeline_health', 60 'check_slo_compliance', 61 ]; 62 63 for (const taskType of expectedTaskTypes) { 64 assert.ok(TASK_ROUTING[taskType], `Missing task type in TASK_ROUTING: ${taskType}`); 65 } 66 }); 67 68 test('getAgentForTaskType returns correct agent for developer tasks', () => { 69 assert.equal(getAgentForTaskType('fix_bug'), 'developer'); 70 assert.equal(getAgentForTaskType('implement_feature'), 'developer'); 71 assert.equal(getAgentForTaskType('refactor_code'), 'developer'); 72 }); 73 74 test('getAgentForTaskType returns correct agent for qa tasks', () => { 75 assert.equal(getAgentForTaskType('write_test'), 'qa'); 76 assert.equal(getAgentForTaskType('verify_fix'), 'qa'); 77 assert.equal(getAgentForTaskType('run_tests'), 'qa'); 78 }); 79 80 test('getAgentForTaskType returns correct agent for security tasks', () => { 81 assert.equal(getAgentForTaskType('audit_code'), 'security'); 82 assert.equal(getAgentForTaskType('scan_dependencies'), 'security'); 83 assert.equal(getAgentForTaskType('review_dependency_update'), 'security'); 84 }); 85 86 test('getAgentForTaskType returns correct agent for architect tasks', () => { 87 assert.equal(getAgentForTaskType('design_proposal'), 'architect'); 88 assert.equal(getAgentForTaskType('technical_review'), 'architect'); 89 assert.equal(getAgentForTaskType('review_documentation'), 'architect'); 90 }); 91 92 test('getAgentForTaskType returns correct agent for triage tasks', () => { 93 assert.equal(getAgentForTaskType('classify_error'), 'triage'); 94 assert.equal(getAgentForTaskType('route_task'), 'triage'); 95 }); 96 97 test('getAgentForTaskType returns correct agent for monitor tasks', () => { 98 assert.equal(getAgentForTaskType('scan_logs'), 'monitor'); 99 assert.equal(getAgentForTaskType('check_agent_health'), 'monitor'); 100 assert.equal(getAgentForTaskType('check_pipeline_health'), 'monitor'); 101 }); 102 103 test('getAgentForTaskType returns triage for unknown task types', () => { 104 assert.equal(getAgentForTaskType('unknown_task_type'), 'triage'); 105 assert.equal(getAgentForTaskType('another_unknown'), 'triage'); 106 }); 107 108 test('isValidTaskType returns true for known task types', () => { 109 assert.equal(isValidTaskType('fix_bug'), true); 110 assert.equal(isValidTaskType('implement_feature'), true); 111 assert.equal(isValidTaskType('review_documentation'), true); 112 }); 113 114 test('isValidTaskType returns false for unknown task types', () => { 115 assert.equal(isValidTaskType('unknown_task'), false); 116 assert.equal(isValidTaskType('invalid_type'), false); 117 }); 118 119 test('getTaskTypesForAgent returns all task types for developer', () => { 120 const types = getTaskTypesForAgent('developer'); 121 assert.ok(types.includes('fix_bug')); 122 assert.ok(types.includes('implement_feature')); 123 assert.ok(types.includes('refactor_code')); 124 assert.ok(types.includes('apply_feedback')); 125 assert.ok(types.includes('implementation_plan')); 126 }); 127 128 test('getTaskTypesForAgent returns all task types for qa', () => { 129 const types = getTaskTypesForAgent('qa'); 130 assert.ok(types.includes('write_test')); 131 assert.ok(types.includes('verify_fix')); 132 assert.ok(types.includes('check_coverage')); 133 assert.ok(types.includes('run_tests')); 134 }); 135 136 test('getTaskTypesForAgent returns all task types for security', () => { 137 const types = getTaskTypesForAgent('security'); 138 assert.ok(types.includes('audit_code')); 139 assert.ok(types.includes('scan_dependencies')); 140 assert.ok(types.includes('review_dependency_update')); 141 }); 142 143 test('getTaskTypesForAgent returns all task types for architect', () => { 144 const types = getTaskTypesForAgent('architect'); 145 assert.ok(types.includes('design_proposal')); 146 assert.ok(types.includes('technical_review')); 147 assert.ok(types.includes('review_documentation')); 148 }); 149 150 test('validateTaskAssignment returns valid for correct assignments', () => { 151 const result1 = validateTaskAssignment('fix_bug', 'developer'); 152 assert.equal(result1.valid, true); 153 154 const result2 = validateTaskAssignment('write_test', 'qa'); 155 assert.equal(result2.valid, true); 156 157 const result3 = validateTaskAssignment('audit_code', 'security'); 158 assert.equal(result3.valid, true); 159 }); 160 161 test('validateTaskAssignment returns invalid for incorrect assignments', () => { 162 const result = validateTaskAssignment('fix_bug', 'architect'); 163 assert.equal(result.valid, false); 164 assert.equal(result.correctAgent, 'developer'); 165 assert.ok(result.reason.includes('developer')); 166 assert.ok(result.reason.includes('architect')); 167 }); 168 169 test('validateTaskAssignment handles misrouted implement_feature', () => { 170 // Previously misrouted to monitor, triage, qa, security, architect 171 assert.equal(validateTaskAssignment('implement_feature', 'monitor').valid, false); 172 assert.equal(validateTaskAssignment('implement_feature', 'triage').valid, false); 173 assert.equal(validateTaskAssignment('implement_feature', 'qa').valid, false); 174 assert.equal(validateTaskAssignment('implement_feature', 'security').valid, false); 175 assert.equal(validateTaskAssignment('implement_feature', 'architect').valid, false); 176 177 // Should only be valid for developer 178 assert.equal(validateTaskAssignment('implement_feature', 'developer').valid, true); 179 }); 180 181 test('validateTaskAssignment handles review_documentation correctly', () => { 182 // Should route to architect 183 const result = validateTaskAssignment('review_documentation', 'architect'); 184 assert.equal(result.valid, true); 185 186 // Should be invalid for other agents 187 const wrongResult = validateTaskAssignment('review_documentation', 'developer'); 188 assert.equal(wrongResult.valid, false); 189 assert.equal(wrongResult.correctAgent, 'architect'); 190 }); 191 192 test('validateTaskAssignment handles review_dependency_update correctly', () => { 193 // Should route to security 194 const result = validateTaskAssignment('review_dependency_update', 'security'); 195 assert.equal(result.valid, true); 196 197 // Should be invalid for other agents 198 const wrongResult = validateTaskAssignment('review_dependency_update', 'developer'); 199 assert.equal(wrongResult.valid, false); 200 assert.equal(wrongResult.correctAgent, 'security'); 201 }); 202 203 test('no duplicate task types in routing', () => { 204 const taskTypes = Object.keys(TASK_ROUTING); 205 const uniqueTaskTypes = [...new Set(taskTypes)]; 206 207 assert.equal( 208 taskTypes.length, 209 uniqueTaskTypes.length, 210 'Found duplicate task types in TASK_ROUTING' 211 ); 212 }); 213 214 test('all agents have at least one task type', () => { 215 const agents = ['developer', 'qa', 'security', 'architect', 'triage', 'monitor']; 216 217 for (const agent of agents) { 218 const types = getTaskTypesForAgent(agent); 219 assert.ok(types.length > 0, `Agent '${agent}' has no task types assigned`); 220 } 221 });