/** * test/sanitize.test.ts * * Testes unitários para a sanitização recursiva de respostas. */ import { describe, it } from "node:test"; import assert from "node:assert/strict"; import { REDACTED, isSensitiveField, sanitizeRecursively, sanitizeText, } from "../src/diagnostics/sanitize.js"; describe("isSensitiveField", () => { it("reconhece nomes de campos sensíveis ignorando maiúsculas/minúsculas", () => { assert.equal(isSensitiveField("name"), true); assert.equal(isSensitiveField("patientName"), true); assert.equal(isSensitiveField("NOME"), true); assert.equal(isSensitiveField("phone"), true); assert.equal(isSensitiveField("telefone"), true); assert.equal(isSensitiveField("email"), true); assert.equal(isSensitiveField("cpf"), true); assert.equal(isSensitiveField("document"), true); assert.equal(isSensitiveField("documento"), true); assert.equal(isSensitiveField("token"), true); assert.equal(isSensitiveField("authorization"), true); assert.equal(isSensitiveField("password"), true); assert.equal(isSensitiveField("senha"), true); assert.equal(isSensitiveField("address"), true); assert.equal(isSensitiveField("endereco"), true); }); it("não reconhece campos não sensíveis", () => { assert.equal(isSensitiveField("id"), false); assert.equal(isSensitiveField("appointmentId"), false); assert.equal(isSensitiveField("startAt"), false); assert.equal(isSensitiveField("status"), false); assert.equal(isSensitiveField("page"), false); }); }); describe("sanitizeRecursively", () => { it("mascara valores de campos sensíveis", () => { const sanitized = sanitizeRecursively({ name: "Maria dos Santos", phone: "75999999999", email: "maria@example.com", }); assert.equal(sanitized.name, REDACTED); assert.equal(sanitized.phone, REDACTED); assert.equal(sanitized.email, REDACTED); }); it("percorre objetos e arrays aninhados", () => { const sanitized = sanitizeRecursively({ data: [ { patient: { name: "João", cpf: "12345678900" }, appointmentId: "abc-123", }, ], }); assert.equal(sanitized.data[0].patient.name, REDACTED); assert.equal(sanitized.data[0].patient.cpf, REDACTED); assert.equal(sanitized.data[0].appointmentId, "abc-123"); }); it("mantém campos não sensíveis intactos", () => { const sanitized = sanitizeRecursively({ id: "app-1", status: "confirmed", page: 1, }); assert.equal(sanitized.id, "app-1"); assert.equal(sanitized.status, "confirmed"); assert.equal(sanitized.page, 1); }); it("redige ocorrências de segredos mesmo em campos não sensíveis", () => { const token = "segredo-super-secreto"; const sanitized = sanitizeRecursively( { message: `token=${token}`, data: "x", }, [token], ); assert.ok(!JSON.stringify(sanitized).includes(token)); assert.ok(JSON.stringify(sanitized).includes(REDACTED)); }); it("não vaza o token na saída sanitizada", () => { const token = "token-real-xyz"; const sanitized = sanitizeRecursively( { data: [{ patient: { name: "Maria", phone: "75999999999" }, token }], }, [token], ); assert.ok(!JSON.stringify(sanitized).includes(token)); assert.ok(!JSON.stringify(sanitized).includes("75999999999")); assert.ok(!JSON.stringify(sanitized).includes("Maria")); }); it("lida com valores primitivos e null", () => { assert.equal(sanitizeRecursively(null), null); assert.equal(sanitizeRecursively("texto", ["zzz"]), "texto"); assert.equal(sanitizeRecursively(42), 42); }); }); describe("sanitizeText", () => { it("redige segredos e limita o comprimento", () => { const long = "a".repeat(700); const result = sanitizeText(`token=${long}`, [long]); assert.ok(!result.includes(long)); assert.ok(result.length <= 500); assert.ok(result.includes(REDACTED)); }); });