Files
support_backend/tests/unit/orchestration/strategies.test.ts
T
saqib mirandClaude Sonnet 5 40687f68fa feat(010-identity-auth): real staff login, session verification, and role gating
Replaces the no-op fastify.authenticate stub and the never-implemented
identity/auth login with real bcrypt password verification, JWT session
issuance/verification (reusing the existing JWT_SECRET), and a Redis-backed
revocation denylist for logout. Adds requireRole('ADMIN') to admin-only
configuration writes across 002-009 that previously relied on a decorator
that never actually checked anything. Adds self-identity (GET /auth/me,
re-validated against live account state) and admin-provisioned accounts
(POST /admin/users).

Making the auth check genuinely reject invalid/missing tokens exposed that
~18 pre-existing integration test files called already-gated routes with no
Authorization header (safe against the old no-op stub, broken against a real
one) — fixed via a shared tests/helpers/auth.ts (loginAs/authHeader) and a
file-by-file pass, plus two related SLA-run cleanup races exposed once admin
setup calls in those files' own beforeAll blocks started actually succeeding.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 12:45:37 +05:30

117 lines
3.7 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { roundRobinSelectIndex } from '@/modules/orchestration/assignments/strategies/round-robin.strategy';
import {
lowestLoadCandidates,
AgentWithLoad,
} from '@/modules/orchestration/assignments/calculators/workload.calculator';
import {
highestSkillScoreCandidates,
withSkillScores,
AgentWithSkillScore,
} from '@/modules/orchestration/assignments/calculators/skill-match.calculator';
function fakeAgent(id: string) {
return {
id,
teamId: 't',
name: id,
active: true,
userId: null,
createdAt: new Date(),
updatedAt: new Date(),
skills: [],
};
}
describe('roundRobinSelectIndex', () => {
it('cycles through indices 0..length-1 as the count increases', () => {
expect(roundRobinSelectIndex(1, 3)).toBe(0);
expect(roundRobinSelectIndex(2, 3)).toBe(1);
expect(roundRobinSelectIndex(3, 3)).toBe(2);
expect(roundRobinSelectIndex(4, 3)).toBe(0); // wraps back to the first agent
});
it('never produces the same index for two different, sequential counter values within one cycle', () => {
const seen = new Set<number>();
for (let count = 1; count <= 5; count++) {
seen.add(roundRobinSelectIndex(count, 5));
}
expect(seen.size).toBe(5);
});
});
describe('lowestLoadCandidates', () => {
it('picks the single lowest-load agent when there is no tie', () => {
const withLoads: AgentWithLoad[] = [
{ agent: fakeAgent('a'), currentLoad: 5 },
{ agent: fakeAgent('b'), currentLoad: 2 },
{ agent: fakeAgent('c'), currentLoad: 8 },
];
expect(lowestLoadCandidates(withLoads).map((a) => a.id)).toEqual(['b']);
});
it('returns every agent tied for the lowest load', () => {
const withLoads: AgentWithLoad[] = [
{ agent: fakeAgent('a'), currentLoad: 2 },
{ agent: fakeAgent('b'), currentLoad: 2 },
{ agent: fakeAgent('c'), currentLoad: 8 },
];
expect(
lowestLoadCandidates(withLoads)
.map((a) => a.id)
.sort(),
).toEqual(['a', 'b']);
});
it('returns an empty array for an empty input', () => {
expect(lowestLoadCandidates([])).toEqual([]);
});
});
describe('withSkillScores', () => {
it('sums proficiency level only across the required skills, ignoring extras', () => {
const eligible = [
{
...fakeAgent('a'),
skills: [
{ id: '1', agentId: 'a', skillTag: 'x', level: 3 },
{ id: '2', agentId: 'a', skillTag: 'y', level: 10 }, // not required — ignored
],
},
{
...fakeAgent('b'),
skills: [
{ id: '3', agentId: 'b', skillTag: 'x', level: 1 },
{ id: '4', agentId: 'b', skillTag: 'z', level: 1 },
],
},
];
const scored = withSkillScores(eligible, ['x', 'z']);
expect(scored.find((s) => s.agent.id === 'a')?.totalLevel).toBe(3); // only x counts
expect(scored.find((s) => s.agent.id === 'b')?.totalLevel).toBe(2); // x + z
});
});
describe('highestSkillScoreCandidates', () => {
it('picks the single highest-scoring agent when there is no tie', () => {
const scored: AgentWithSkillScore[] = [
{ agent: fakeAgent('a'), totalLevel: 3 },
{ agent: fakeAgent('b'), totalLevel: 7 },
];
expect(highestSkillScoreCandidates(scored).map((a) => a.id)).toEqual(['b']);
});
it('returns every agent tied for the highest score', () => {
const scored: AgentWithSkillScore[] = [
{ agent: fakeAgent('a'), totalLevel: 5 },
{ agent: fakeAgent('b'), totalLevel: 5 },
{ agent: fakeAgent('c'), totalLevel: 1 },
];
expect(
highestSkillScoreCandidates(scored)
.map((a) => a.id)
.sort(),
).toEqual(['a', 'b']);
});
});