98 lines
2.9 KiB
TypeScript
98 lines
2.9 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
import { MemberWorkSyncTeamChangeRouter } from '@features/member-work-sync/main/adapters/input/MemberWorkSyncTeamChangeRouter';
|
|
|
|
function createRouter(activeMembers: string[] = ['alice', 'bob']) {
|
|
const queue = {
|
|
enqueue: vi.fn(),
|
|
dropTeam: vi.fn(),
|
|
};
|
|
const router = new MemberWorkSyncTeamChangeRouter(
|
|
{
|
|
loadActiveMemberNames: async () => activeMembers,
|
|
},
|
|
queue as never
|
|
);
|
|
return { queue, router };
|
|
}
|
|
|
|
describe('MemberWorkSyncTeamChangeRouter', () => {
|
|
it('routes task and config events to all active members', async () => {
|
|
const { queue, router } = createRouter();
|
|
|
|
router.noteTeamChange({ type: 'task', teamName: 'team-a', detail: 'task-1.json' });
|
|
await Promise.resolve();
|
|
|
|
expect(queue.enqueue).toHaveBeenCalledWith({
|
|
teamName: 'team-a',
|
|
memberName: 'alice',
|
|
triggerReason: 'task_changed',
|
|
runAfterMs: undefined,
|
|
});
|
|
expect(queue.enqueue).toHaveBeenCalledWith({
|
|
teamName: 'team-a',
|
|
memberName: 'bob',
|
|
triggerReason: 'task_changed',
|
|
runAfterMs: undefined,
|
|
});
|
|
});
|
|
|
|
it('routes inbox and tool-finish events to the addressed member only', () => {
|
|
const { queue, router } = createRouter();
|
|
|
|
router.noteTeamChange({ type: 'inbox', teamName: 'team-a', detail: 'inboxes/bob.json' });
|
|
router.noteTeamChange({
|
|
type: 'tool-activity',
|
|
teamName: 'team-a',
|
|
detail: JSON.stringify({ action: 'finish', memberName: 'alice', toolUseId: 'tool-1' }),
|
|
});
|
|
|
|
expect(queue.enqueue).toHaveBeenCalledWith({
|
|
teamName: 'team-a',
|
|
memberName: 'bob',
|
|
triggerReason: 'inbox_changed',
|
|
});
|
|
expect(queue.enqueue).toHaveBeenCalledWith({
|
|
teamName: 'team-a',
|
|
memberName: 'alice',
|
|
triggerReason: 'tool_finished',
|
|
});
|
|
});
|
|
|
|
it('drops queued work when the team goes offline', () => {
|
|
const { queue, router } = createRouter();
|
|
|
|
router.noteTeamChange({ type: 'lead-activity', teamName: 'team-a', detail: 'offline' });
|
|
|
|
expect(queue.dropTeam).toHaveBeenCalledWith('team-a');
|
|
expect(queue.enqueue).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('routes member-turn-settled events to one member reconcile', () => {
|
|
const { queue, router } = createRouter();
|
|
|
|
router.noteTeamChange({
|
|
type: 'member-turn-settled',
|
|
teamName: 'team-a',
|
|
detail: JSON.stringify({ memberName: 'alice', sourceId: 'source-1', provider: 'claude' }),
|
|
});
|
|
|
|
expect(queue.enqueue).toHaveBeenCalledWith({
|
|
teamName: 'team-a',
|
|
memberName: 'alice',
|
|
triggerReason: 'turn_settled',
|
|
});
|
|
});
|
|
|
|
it('ignores malformed member-turn-settled details', () => {
|
|
const { queue, router } = createRouter();
|
|
|
|
router.noteTeamChange({
|
|
type: 'member-turn-settled',
|
|
teamName: 'team-a',
|
|
detail: 'not-json',
|
|
});
|
|
|
|
expect(queue.enqueue).not.toHaveBeenCalled();
|
|
});
|
|
});
|