const { test } = require('node:test'); const assert = require('node:assert/strict'); const { buildContextFingerprint, stableStringify } = require('./hash'); const { normalizeGlpiText } = require('./normalize'); function baseTicket(overrides) { return Object.assign({ status: 2, tecnico_atribuido: 'Wagner', categoria: 'Rede', entidade: 'Matriz', titulo: 'Nobreak desligando', descricao: 'Nobreak do servidor desligando sozinho', followups: [{ id: 1, date: '2026-08-20 10:00:00', texto: 'Aguardando peca' }], tasks: [{ id: 1, status: 1, date: '2026-08-19 09:00:00', texto: 'Verificado no local' }], dias_aberto: 10, dias_sem_interacao: 3, }, overrides); } test('alterar apenas dias_aberto/dias_sem_interacao NAO muda o hash', () => { const a = buildContextFingerprint(baseTicket({ dias_aberto: 10, dias_sem_interacao: 3 })); const b = buildContextFingerprint(baseTicket({ dias_aberto: 11, dias_sem_interacao: 4 })); assert.equal(a, b); }); test('novo followup MUDA o hash', () => { const a = buildContextFingerprint(baseTicket({})); const b = buildContextFingerprint(baseTicket({ followups: [{ id: 1, date: '2026-08-20 10:00:00', texto: 'Aguardando peca' }, { id: 2, date: '2026-08-21 08:00:00', texto: 'Peca chegou' }] })); assert.notEqual(a, b); }); test('mudanca de tecnico MUDA o hash', () => { const a = buildContextFingerprint(baseTicket({ tecnico_atribuido: 'Wagner' })); const b = buildContextFingerprint(baseTicket({ tecnico_atribuido: 'Eric' })); assert.notEqual(a, b); }); test('mesmo conteudo normalizado de fontes com encoding HTML diferente gera o MESMO hash', () => { const textoHtml = normalizeGlpiText('

Aguardando cliente

'); const textoEscapado = normalizeGlpiText('<p>Aguardando cliente</p>'); assert.equal(textoHtml, textoEscapado, 'pre-condicao: normalizacao deve produzir o mesmo texto'); const a = buildContextFingerprint(baseTicket({ followups: [{ id: 1, date: '2026-08-20 10:00:00', texto: textoHtml }] })); const b = buildContextFingerprint(baseTicket({ followups: [{ id: 1, date: '2026-08-20 10:00:00', texto: textoEscapado }] })); assert.equal(a, b); }); test('edicao real do conteudo de um followup (mesmo id/date) MUDA o hash', () => { const a = buildContextFingerprint(baseTicket({ followups: [{ id: 1, date: '2026-08-20 10:00:00', texto: 'Aguardando peca' }] })); const b = buildContextFingerprint(baseTicket({ followups: [{ id: 1, date: '2026-08-20 10:00:00', texto: 'Peca instalada, testando' }] })); assert.notEqual(a, b); }); test('stableStringify ignora ordem de chaves', () => { assert.equal(stableStringify({ b: 1, a: 2 }), stableStringify({ a: 2, b: 1 })); });