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));
  });
});
