/** * Test helper: pre-seed `localStorage` with an active session that holds * one document + one representation, so an integration test can skip * the empty-state + upload flow and mount straight into a populated * Review/Forms layout. * * Pre-CE-WP-0005 integration tests clicked a "fixture button" in the * `CollectionList` to load a sample PDF; after the session refactor * there is no fixture list directly in the active-session UI. These * legacy tests now call `seedSessionWithDoc` in `beforeEach` instead. * * The seed bypasses `SessionService.create()` (which mints a random * id) so tests can reference the resulting `documentId` / * `representationId` synchronously, before the app boots. */ import type { Document, DocumentRepresentation } from "@shared/document"; import type { DocumentId, RepresentationId, SessionId } from "@shared/ids"; import type { Session } from "@shared/session"; export interface SeedOptions { readonly sessionName?: string; readonly documentTitle?: string; readonly canonicalText: string; readonly mode?: "review" | "forms"; } export interface SeedResult { readonly sessionId: SessionId; readonly documentId: DocumentId; readonly representationId: RepresentationId; } function rid(prefix: string): string { return `${prefix}_seed_${Math.random().toString(36).slice(2, 10)}`; } export function seedSessionWithDoc(opts: SeedOptions): SeedResult { const sessionId = rid("sess") as SessionId; const documentId = rid("doc") as DocumentId; const representationId = rid("rep") as RepresentationId; const now = "2026-05-25T00:00:00.000Z"; const session: Session = { id: sessionId, name: opts.sessionName ?? "Test Session", createdAt: now, updatedAt: now, lastOpenedAt: now, }; const document: Document = { id: documentId, mediaType: "application/pdf", ...(opts.documentTitle ? { title: opts.documentTitle } : {}), fingerprint: "seed-fingerprint", createdAt: now, updatedAt: now, }; const representation: DocumentRepresentation = { id: representationId, documentId, representationType: "pdf-text", contentHash: "seed-fingerprint", canonicalText: opts.canonicalText, pageMap: [{ page: 1, width: 595, height: 842 }], offsetMap: [ { page: 1, globalStart: 0, globalEnd: opts.canonicalText.length, pageLength: opts.canonicalText.length, }, ], generatedAt: now, }; const snapshot = { version: 1, documents: [document], representations: [representation], annotations: [], evidenceItems: [], }; const sessionsFile = { version: 1, sessions: [session], activeSessionId: sessionId, }; localStorage.setItem("citation-evidence:sessions:v1", JSON.stringify(sessionsFile)); localStorage.setItem("citation-evidence:active-session-id:v1", sessionId); localStorage.setItem( `citation-evidence:session:${sessionId}:engine-snapshot:v1`, JSON.stringify(snapshot), ); localStorage.setItem( `citation-evidence:session:${sessionId}:active-document-id:v1`, documentId, ); // Set the hash so the App routes straight into the session. const hash = opts.mode === "forms" ? `#/s/${sessionId}/forms/demo` : `#/s/${sessionId}`; history.replaceState( null, "", window.location.pathname + window.location.search + hash, ); return { sessionId, documentId, representationId }; }