gapmind/test/dedup.test.ts
2026-09-11 23:59:05 -04:00

57 lines
1.8 KiB
TypeScript

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import {
dedupFavicons,
dedupObservations,
dedupPeersByInfoHash,
} from '../src/services/dedup.util.js';
describe('dedupObservations', () => {
it('keeps newest row per port', () => {
const rows = [
{ port: 80, banner: 'old', observedAt: new Date('2024-01-01') },
{ port: 80, banner: 'new', observedAt: new Date('2024-06-01') },
{ port: 443, banner: 'tls', observedAt: new Date('2024-01-01') },
];
const out = dedupObservations(rows);
assert.equal(out.length, 2);
assert.equal(out.find((r) => r.port === 80)?.banner, 'new');
});
it('is order-independent', () => {
const rows = [
{ port: 22, banner: 'new', observedAt: new Date('2024-06-01') },
{ port: 22, banner: 'old', observedAt: new Date('2024-01-01') },
];
assert.equal(dedupObservations(rows)[0]?.banner, 'new');
});
it('handles empty input', () => {
assert.deepEqual(dedupObservations([]), []);
});
});
describe('dedupFavicons', () => {
it('collapses identical perceptual hashes', () => {
const rows = [
{ perceptualHash: 'ab', createdAt: new Date('2024-01-01') },
{ perceptualHash: 'ab', createdAt: new Date('2024-02-01') },
{ perceptualHash: 'cd', createdAt: new Date('2024-01-01') },
];
const out = dedupFavicons(rows);
assert.equal(out.length, 2);
});
});
describe('dedupPeersByInfoHash', () => {
it('dedups case-insensitively, keeps first (newest)', () => {
const rows = [
{ infoHash: 'AABB', address: '1.1.1.1' },
{ infoHash: 'aabb', address: '2.2.2.2' },
{ infoHash: 'ccdd', address: '3.3.3.3' },
];
const out = dedupPeersByInfoHash(rows);
assert.equal(out.length, 2);
assert.equal(out[0]?.address, '1.1.1.1');
});
});