test(21-01): add failing tests for triage-note sanitizer

- Cover URL query/fragment stripping, malformed-URL no-throw
- Cover Bearer token and credential query-param redaction
- Cover email/hash preservation (evidence, not secrets)
This commit is contained in:
lorentz 2026-07-16 12:04:58 -04:00
parent 235bc49810
commit cc93707e41

View file

@ -0,0 +1,58 @@
import { describe, it, expect } from 'vitest';
import { sanitizeUrl, sanitizeNoteText } from './triage-note-sanitize';
describe('sanitizeUrl', () => {
it('strips query string and fragment, keeping scheme+host+path', () => {
expect(sanitizeUrl('https://evil.example/login?token=abc123&next=/x#frag')).toBe(
'https://evil.example/login'
);
});
it('returns exactly the scheme+host+path for a token+fragment URL', () => {
expect(sanitizeUrl('https://evil.example/a?token=abc#f')).toBe('https://evil.example/a');
});
it('does not throw on a malformed/non-URL string and strips any ?/# tail', () => {
expect(() => sanitizeUrl('not a url')).not.toThrow();
expect(sanitizeUrl('not a url')).toBe('not a url');
expect(() => sanitizeUrl('')).not.toThrow();
expect(sanitizeUrl('not-a-url?foo=bar#baz')).toBe('not-a-url');
});
it('always strips query even for benign params (not selective)', () => {
expect(sanitizeUrl('https://good.example/path?utm_source=newsletter')).toBe(
'https://good.example/path'
);
});
});
describe('sanitizeNoteText', () => {
it('redacts an Authorization/Bearer token', () => {
const input = 'Header seen: Bearer eyJabc.def.ghi in the request';
const output = sanitizeNoteText(input);
expect(output).not.toContain('eyJabc.def.ghi');
expect(output).toContain('[REDACTED]');
});
it('redacts credential-style query-param values inside free text', () => {
const input = 'see http://x/y?access_token=SECRET&password=p';
const output = sanitizeNoteText(input);
expect(output).not.toContain('access_token=SECRET');
expect(output).not.toContain('password=p');
});
it('preserves a bare sender email and a 64-char hex attachment hash unchanged', () => {
const hash = 'a'.repeat(64);
const input = `Reported by attacker@evil.example with attachment hash ${hash}`;
const output = sanitizeNoteText(input);
expect(output).toContain('attacker@evil.example');
expect(output).toContain(hash);
});
it('is pure and deterministic', () => {
const input = 'plain text with no secrets';
expect(sanitizeNoteText(input)).toBe(sanitizeNoteText(input));
});
});