import { describe, it, expect } from 'vitest';
import { redactErrMsg } from './redact-error.js';

describe('redactErrMsg', () => {
  it('redacts user:password from a postgres:// URL embedded in an error message', () => {
    const msg = 'connect ECONNREFUSED postgres://admin:s3cr3t@db.example.com:5432/mosaic';
    expect(redactErrMsg(msg)).toBe(
      'connect ECONNREFUSED postgres://***@db.example.com:5432/mosaic',
    );
  });

  it('redacts user:password from a postgresql:// URL', () => {
    const msg = 'connection failed: postgresql://myuser:mypass@localhost:5432/testdb';
    expect(redactErrMsg(msg)).toBe('connection failed: postgresql://***@localhost:5432/testdb');
  });

  it('handles URLs with no password (user only) — still redacts userinfo', () => {
    const msg = 'error postgres://justuser@host:5432/db';
    expect(redactErrMsg(msg)).toBe('error postgres://***@host:5432/db');
  });

  it('returns the original message unchanged when no connection URL is present', () => {
    const msg = 'connection timed out after 5 seconds';
    expect(redactErrMsg(msg)).toBe('connection timed out after 5 seconds');
  });

  it('is case-insensitive for the scheme (scheme is normalized to lowercase in output)', () => {
    // The regex replacement uses a lowercase literal, so the matched scheme is
    // replaced with the lowercase form regardless of the original casing.
    const msg = 'POSTGRES://admin:pass@host:5432/db';
    expect(redactErrMsg(msg)).toBe('postgres://***@host:5432/db');
  });

  it('redacts multiple URLs in a single message', () => {
    const msg = 'src postgres://u:p@host1/db1 dst postgresql://v:q@host2/db2';
    expect(redactErrMsg(msg)).toBe('src postgres://***@host1/db1 dst postgresql://***@host2/db2');
  });

  it('does not alter a message with a postgres URL that has no userinfo', () => {
    // No userinfo component — pattern does not match, message unchanged.
    const msg = 'error at postgres://host:5432/db';
    expect(redactErrMsg(msg)).toBe('error at postgres://host:5432/db');
  });

  it('redacts user:password from a redis:// URL', () => {
    const msg = 'connect ECONNREFUSED redis://user:pass@host:6379';
    expect(redactErrMsg(msg)).toBe('connect ECONNREFUSED redis://***@host:6379');
  });

  it('redacts user:password from a rediss:// URL (TLS)', () => {
    const msg = 'connect ECONNREFUSED rediss://user:pass@host:6379';
    expect(redactErrMsg(msg)).toBe('connect ECONNREFUSED rediss://***@host:6379');
  });

  it('redacts both a postgres URL and a redis URL in the same message', () => {
    const msg =
      'primary postgres://admin:s3cr3t@db:5432/mosaic cache redis://cacheuser:cachepass@cache:6379';
    expect(redactErrMsg(msg)).toBe(
      'primary postgres://***@db:5432/mosaic cache redis://***@cache:6379',
    );
  });
});
