Completes the escalation-event repository/service changes from the prior
commit: normalizes the exactOptionalPropertyTypes mismatch in the
findFirst fallback lookup, and updates every existing unit test
(sla-pause-resume, sla-breach-detection, sla-compliance-metric,
escalation-rule-match) to the new SlaRunRepository.updateWithVersion and
EscalationEventRepository.create({event, wasNewlyCreated}) signatures.
Full typecheck/lint/architecture-check clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
75 lines
3.2 KiB
TypeScript
75 lines
3.2 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
|
|
|
vi.mock('@/modules/ticketing/tickets', () => ({
|
|
ticketsService: { getById: vi.fn().mockResolvedValue({ id: 't1', productId: 'prod-1' }) },
|
|
}));
|
|
|
|
import { EscalationService } from '@/modules/orchestration/escalation/service/escalation.service';
|
|
|
|
describe('EscalationService.handleBreach', () => {
|
|
it('fires one EscalationEvent and a scoped re-assignment per active matching rule', async () => {
|
|
const rule = {
|
|
id: 'rule-1',
|
|
policyId: 'policy-1',
|
|
triggerType: 'resolution_breach',
|
|
targetNodeId: 'node-1',
|
|
active: true,
|
|
};
|
|
const policies = {
|
|
findApplicable: vi.fn().mockResolvedValue({ id: 'policy-1', productId: 'prod-1' }),
|
|
} as never;
|
|
const rules = { findActiveRules: vi.fn().mockResolvedValue([rule]) } as never;
|
|
const events = {
|
|
create: vi.fn().mockResolvedValue({ event: { id: 'event-1' }, wasNewlyCreated: true }),
|
|
} as never;
|
|
const assignmentEngine = {
|
|
assignToSpecificNode: vi.fn().mockResolvedValue(undefined),
|
|
} as never;
|
|
|
|
const service = new EscalationService(policies, rules, events, assignmentEngine);
|
|
await service.handleBreach('t1', 'resolution_breach');
|
|
|
|
expect(
|
|
(rules as { findActiveRules: ReturnType<typeof vi.fn> }).findActiveRules,
|
|
).toHaveBeenCalledWith('policy-1', 'resolution_breach');
|
|
expect((events as { create: ReturnType<typeof vi.fn> }).create).toHaveBeenCalledWith(
|
|
expect.objectContaining({ ticketId: 't1', ruleId: 'rule-1', toNodeId: 'node-1' }),
|
|
);
|
|
expect(
|
|
(assignmentEngine as { assignToSpecificNode: ReturnType<typeof vi.fn> }).assignToSpecificNode,
|
|
).toHaveBeenCalledWith('t1', 'node-1', 'system', expect.stringContaining('resolution_breach'));
|
|
});
|
|
|
|
it('records nothing when no escalation policy matches the ticket product', async () => {
|
|
const policies = { findApplicable: vi.fn().mockResolvedValue(null) } as never;
|
|
const rules = { findActiveRules: vi.fn() } as never;
|
|
const events = { create: vi.fn() } as never;
|
|
const assignmentEngine = { assignToSpecificNode: vi.fn() } as never;
|
|
|
|
const service = new EscalationService(policies, rules, events, assignmentEngine);
|
|
await service.handleBreach('t1', 'resolution_breach');
|
|
|
|
expect(
|
|
(rules as { findActiveRules: ReturnType<typeof vi.fn> }).findActiveRules,
|
|
).not.toHaveBeenCalled();
|
|
expect((events as { create: ReturnType<typeof vi.fn> }).create).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('records nothing when a policy matches but no active rule matches the trigger type', async () => {
|
|
const policies = {
|
|
findApplicable: vi.fn().mockResolvedValue({ id: 'policy-1', productId: 'prod-1' }),
|
|
} as never;
|
|
const rules = { findActiveRules: vi.fn().mockResolvedValue([]) } as never;
|
|
const events = { create: vi.fn() } as never;
|
|
const assignmentEngine = { assignToSpecificNode: vi.fn() } as never;
|
|
|
|
const service = new EscalationService(policies, rules, events, assignmentEngine);
|
|
await service.handleBreach('t1', 'resolution_breach');
|
|
|
|
expect((events as { create: ReturnType<typeof vi.fn> }).create).not.toHaveBeenCalled();
|
|
expect(
|
|
(assignmentEngine as { assignToSpecificNode: ReturnType<typeof vi.fn> }).assignToSpecificNode,
|
|
).not.toHaveBeenCalled();
|
|
});
|
|
});
|