Files
waggle-os/packages/hive-mind-core/tests/harvest/set-hash.test.ts
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

51 lines
2.0 KiB
TypeScript

/**
* harvestSetHash unit tests (R3-004 — skip unchanged-content rescans).
*
* The harvest route hashes an incoming item set and, when it matches the
* source's stored last_content_hash, skips the O(nĀ·500) per-item rescan.
* The digest must be: deterministic, order-independent (adapter jitter), and
* sensitive to any id/title/content edit.
*/
import { describe, it, expect } from 'vitest';
import { harvestSetHash } from '../../src/harvest/dedup.js';
const A = { id: '1', title: 'Alpha', content: 'first body' };
const B = { id: '2', title: 'Beta', content: 'second body' };
describe('harvestSetHash', () => {
it('is deterministic for the same set', () => {
expect(harvestSetHash([A, B])).toBe(harvestSetHash([A, B]));
});
it('is order-independent (adapter ordering jitter must not change the digest)', () => {
expect(harvestSetHash([A, B])).toBe(harvestSetHash([B, A]));
});
it('changes when an item content is edited (same id)', () => {
const edited = { ...A, content: 'first body — edited' };
expect(harvestSetHash([A, B])).not.toBe(harvestSetHash([edited, B]));
});
it('changes when an item title is edited', () => {
const edited = { ...A, title: 'Alpha 2' };
expect(harvestSetHash([A, B])).not.toBe(harvestSetHash([edited, B]));
});
it('changes when an item is added or removed', () => {
expect(harvestSetHash([A, B])).not.toBe(harvestSetHash([A]));
expect(harvestSetHash([A])).not.toBe(harvestSetHash([]));
});
it('tolerates missing optional fields without throwing', () => {
expect(() => harvestSetHash([{ content: 'x' }, { id: 'y' }, {}])).not.toThrow();
});
it('distinguishes two items that swap field values (id+title+content are positional per item)', () => {
// Same multiset of strings but recombined differently → different digest.
const x = { id: '1', title: 'T', content: 'C' };
const y = { id: '1', title: 'C', content: 'T' };
expect(harvestSetHash([x])).not.toBe(harvestSetHash([y]));
});
});