wulf-pulse/lib/services/triage-note-format.test.ts
lorentz b4e05eb6ad test(21-01): add failing tests for triage-note formatter
- Cover verdict/confidence rendering, reasons/summary sections
- Cover both BlastRadiusResult branches (ok and unavailable)
- Cover remediation-state rendering (empty and populated)
- Cover URL sanitization and null-verdict graceful handling
2026-07-16 12:05:59 -04:00

104 lines
4.1 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { formatTriageNote, type TriageNoteEvidence } from './triage-note-format';
import type { BlastRadiusResult } from './mimecast-blast-radius';
function baseEvidence(overrides: Partial<TriageNoteEvidence> = {}): TriageNoteEvidence {
return {
campaignId: 'campaign-1',
reportCount: 3,
companyName: 'Acme Corp',
subject: 'Your invoice is ready',
verdict: 'THREAT',
confidence: 0.85,
summary: 'Credential-harvesting link found in message body.',
reasons: ['Sender domain not in allowlist', 'URL matches known phishing indicator'],
recommendedActions: ['block_sender', 'purge_message'],
requiresApproval: true,
blastRadius: { status: 'unavailable', reason: 'not_configured' },
remediationActions: [],
urls: [],
...overrides,
};
}
describe('formatTriageNote', () => {
it('includes the verdict label and confidence value', () => {
const output = formatTriageNote(baseEvidence());
expect(output).toContain('THREAT');
expect(output).toContain('0.85');
});
it('includes a Summary line and a Reasons section listing each reason', () => {
const output = formatTriageNote(baseEvidence());
expect(output).toContain('Credential-harvesting link found in message body.');
expect(output).toContain('Sender domain not in allowlist');
expect(output).toContain('URL matches known phishing indicator');
});
it('shows delivered/held/rejected/clicked counts when blast radius is ok', () => {
const ok: BlastRadiusResult = {
status: 'ok',
matched: 5,
delivered: 3,
held: 1,
rejected: 1,
clicked: 2,
perRecipient: [{ recipient: 'user@acme.example', status: 'delivered' }],
source: 'fan-out',
};
const output = formatTriageNote(baseEvidence({ blastRadius: ok }));
expect(output).toContain('3');
expect(output).toContain('1');
expect(output).toContain('2');
});
it('shows an explicit unavailable reason when blast radius is unavailable', () => {
const output = formatTriageNote(
baseEvidence({ blastRadius: { status: 'unavailable', reason: 'not_configured' } })
);
expect(output).toContain('unavailable');
expect(output).toContain('not_configured');
});
it('states no action taken when remediationActions is empty', () => {
const output = formatTriageNote(baseEvidence({ remediationActions: [] }));
expect(output.toLowerCase()).toMatch(/proposed|no action/);
});
it('lists each remediation action with status and approver when present', () => {
const output = formatTriageNote(
baseEvidence({
remediationActions: [
{ actionType: 'block_sender', status: 'approved', approvedBy: 'operator@example.com', approvedAt: '2026-07-01T00:00:00Z' },
{ actionType: 'purge_message', status: 'completed', approvedBy: 'operator@example.com', approvedAt: '2026-07-01T00:00:00Z' },
],
})
);
expect(output).toContain('block_sender');
expect(output).toContain('approved');
expect(output).toContain('purge_message');
expect(output).toContain('completed');
expect(output).toContain('operator@example.com');
});
it('renders indicator URLs in sanitized form, dropping query strings', () => {
const output = formatTriageNote(baseEvidence({ urls: ['http://evil.example/p?token=leak'] }));
expect(output).not.toContain('token=leak');
expect(output).toContain('http://evil.example/p');
});
it('never leaks a secret embedded in free-text fields (sanitizeNoteText applied to whole output)', () => {
const output = formatTriageNote(
baseEvidence({ summary: 'Found link http://evil.example/x?access_token=SECRETVALUE in body' })
);
expect(output).not.toContain('access_token=SECRETVALUE');
});
it('handles null verdict/confidence gracefully without throwing', () => {
expect(() =>
formatTriageNote(baseEvidence({ verdict: null, confidence: null }))
).not.toThrow();
const output = formatTriageNote(baseEvidence({ verdict: null, confidence: null }));
expect(output.toLowerCase()).toContain('not yet classified');
});
});