53 lines
2.4 KiB
TypeScript
53 lines
2.4 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
import { MindDB, FrameStore, SessionStore } from '@waggle/core';
|
|
import { normalizeToMemory } from '../../src/local/routes/memory-center.js';
|
|
|
|
/**
|
|
* normalizeToMemory.hasOriginalSource — the gate for the #7 "View original source"
|
|
* affordance. It must reflect ACTUAL archive availability (readArchiveUids), not the
|
|
* presence of a sourceId: an auto-synced harvest summary carries sourceId but no
|
|
* raw_archive link, so offering "View original" would always 404. This pins the
|
|
* derivation so the EvidencePanel button can gate on it instead of sourceId.
|
|
*/
|
|
describe('normalizeToMemory — hasOriginalSource (Art.17 View-original gate)', () => {
|
|
let db: MindDB;
|
|
let frames: FrameStore;
|
|
beforeEach(() => {
|
|
db = new MindDB(':memory:');
|
|
new SessionStore(db).ensure('harvest', 'harvest', 'test');
|
|
frames = new FrameStore(db);
|
|
});
|
|
afterEach(() => db.close());
|
|
|
|
function normalize(metadata: Record<string, unknown>) {
|
|
// Unique content per case so createIFrame's content-dedup never collides.
|
|
const f = frames.createIFrame('harvest', `[Harvest:claude-code] s\n\n${JSON.stringify(metadata)}`, 'normal', 'import');
|
|
frames.setMetadata(f.id, JSON.stringify(metadata));
|
|
return normalizeToMemory(frames.getById(f.id)!, 'personal');
|
|
}
|
|
|
|
it('is TRUE when the frame links a raw_archive row (archiveUids present)', () => {
|
|
expect(normalize({ sourceId: 's1', archiveUids: ['u1'] }).hasOriginalSource).toBe(true);
|
|
});
|
|
|
|
it('tolerates the legacy scalar archiveUid', () => {
|
|
expect(normalize({ sourceId: 's2', archiveUid: 'u2' }).hasOriginalSource).toBe(true);
|
|
});
|
|
|
|
it('is FALSE for a sourceId-only frame (auto-synced summary — no archive to view)', () => {
|
|
const m = normalize({ sourceId: 'sess-abc' });
|
|
expect(m.sourceId).toBe('sess-abc'); // provenance id still exposed (chip)
|
|
expect(m.hasOriginalSource).toBe(false); // but no viewable source → button hidden
|
|
});
|
|
|
|
it('is FALSE for a frame with no provenance metadata', () => {
|
|
expect(normalize({ kind: 'fact' }).hasOriginalSource).toBe(false);
|
|
});
|
|
|
|
it('marks temporary agent-inferred frames as needing review', () => {
|
|
const f = frames.createIFrame('harvest', 'Assistant example only.', 'temporary', 'agent_inferred');
|
|
const m = normalizeToMemory(frames.getById(f.id)!, 'personal');
|
|
expect(m.status).toBe('unreviewed');
|
|
});
|
|
});
|