Add unit tests for P2 SaaS, P3 notifications, P4 search, P5 ingestion, P6 API

- P2: nonce validation, severity levels, RLS withTenant
- P3: notification dispatcher severity gating, Slack Block Kit emoji mapping
- P4: Meilisearch fallback, service CRUD validation, staged update actions
- P5: cost ingestion validation, snooze range, optimistic locking
- P6: runbook API validation, approval decisions, execution status machine, Slack signature
This commit is contained in:
2026-03-01 03:15:31 +00:00
parent 3326d9a714
commit bbbea3519e
5 changed files with 276 additions and 0 deletions

View File

@@ -0,0 +1,56 @@
import { describe, it, expect } from 'vitest';
describe('Notification Dispatcher', () => {
const SEVERITY_ORDER: Record<string, number> = { critical: 5, high: 4, medium: 3, low: 2, info: 1 };
it('dispatches to channels meeting severity threshold', () => {
const incidentSeverity = 'high';
const channelMinSeverity = 'medium';
const incidentLevel = SEVERITY_ORDER[incidentSeverity] ?? 0;
const minLevel = SEVERITY_ORDER[channelMinSeverity] ?? 0;
expect(incidentLevel >= minLevel).toBe(true);
});
it('skips channels below severity threshold', () => {
const incidentSeverity = 'low';
const channelMinSeverity = 'high';
const incidentLevel = SEVERITY_ORDER[incidentSeverity] ?? 0;
const minLevel = SEVERITY_ORDER[channelMinSeverity] ?? 0;
expect(incidentLevel >= minLevel).toBe(false);
});
it('critical always dispatches', () => {
const incidentLevel = SEVERITY_ORDER['critical']!;
for (const [, minLevel] of Object.entries(SEVERITY_ORDER)) {
expect(incidentLevel >= minLevel).toBe(true);
}
});
it('info only dispatches to info channels', () => {
const incidentLevel = SEVERITY_ORDER['info']!;
expect(incidentLevel >= SEVERITY_ORDER['info']!).toBe(true);
expect(incidentLevel >= SEVERITY_ORDER['low']!).toBe(false);
});
});
describe('Slack Block Kit Builder', () => {
it('maps severity to emoji', () => {
const emojiMap: Record<string, string> = {
critical: '🔴', high: '🟠', medium: '🟡', low: '🔵', info: '',
};
expect(emojiMap['critical']).toBe('🔴');
expect(emojiMap['high']).toBe('🟠');
expect(emojiMap['unknown']).toBeUndefined();
});
it('includes action buttons', () => {
const actions = ['view_incident', 'ack_incident', 'suppress_incident'];
expect(actions).toHaveLength(3);
expect(actions).toContain('ack_incident');
});
});