import { afterEach, beforeEach, describe, expect, it } from "bun:test"; import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { ResultReferenceResolver } from "../../src/results/resolver.js"; import { RESULT_REFERENCE_KIND, RESULT_REFERENCE_SOURCE, ResultReferenceStore, } from "../../src/results/store.js"; describe("ResultReferenceResolver", () => { let tempDir: string; let store: ResultReferenceStore; let resolver: ResultReferenceResolver; beforeEach(async () => { tempDir = await mkdtemp(join(tmpdir(), "tjwater-result-ref-")); store = new ResultReferenceStore(tempDir, 60_000); resolver = new ResultReferenceResolver(store); await store.initialize(); }); afterEach(async () => { await rm(tempDir, { force: true, recursive: true }); }); it("stores metadata for render refs and resolves them", async () => { const record = await resolver.register({ actorKey: "actor-1", clientSessionId: "client-1", data: { node_area_map: { J1: "DMA-1", J2: "DMA-2", }, }, kind: RESULT_REFERENCE_KIND.renderJunctionsPayload, projectId: "project-1", projectKey: "project-key-1", schemaVersion: 1, sessionId: "session-1", source: RESULT_REFERENCE_SOURCE.agentGenerated, traceId: "trace-1", }); expect(record.kind).toBe(RESULT_REFERENCE_KIND.renderJunctionsPayload); expect(record.schemaVersion).toBe(1); expect(record.source).toBe(RESULT_REFERENCE_SOURCE.agentGenerated); const result = await resolver.getFullAuthorized( record.resultRef, { actorKey: "actor-1", projectId: "project-1", }, ); expect(result).not.toBeNull(); expect(result?.kind).toBe(RESULT_REFERENCE_KIND.renderJunctionsPayload); expect(result?.schema_version).toBe(1); expect(result?.source).toBe(RESULT_REFERENCE_SOURCE.agentGenerated); expect(result?.data).toEqual({ node_area_map: { J1: "DMA-1", J2: "DMA-2", }, }); }); it("rejects malformed refs and auth mismatches", async () => { const malformedRef = "res-bbbbbbbbbbbbbbbb"; await writeFile( join(tempDir, `${malformedRef}.json`), JSON.stringify( { resultRef: malformedRef, createdAt: "2026-05-21T00:00:00.000Z", data: { value: 1 }, preview: { count: 1, fields: ["value"], sample: { value: 1 }, summary: "object<1 fields>", }, projectId: "project-1", projectKey: "project-key-1", sessionId: "session-1", sizeBytes: 10, traceId: "trace-1", }, null, 2, ), "utf8", ); const malformed = await store.getAuthorizedRecord(malformedRef, { actorKey: "actor-1", projectId: "project-1", }); expect(malformed).toBeNull(); const renderRecord = await resolver.register({ actorKey: "actor-2", clientSessionId: "client-2", data: { node_area_map: { J1: "DMA-1", }, }, kind: RESULT_REFERENCE_KIND.renderJunctionsPayload, projectId: "project-2", projectKey: "project-key-2", schemaVersion: 1, sessionId: "session-2", source: RESULT_REFERENCE_SOURCE.agentGenerated, traceId: "trace-2", }); const wrongActor = await resolver.getFullAuthorized(renderRecord.resultRef, { actorKey: "actor-other", projectId: "project-2", }); expect(wrongActor).toBeNull(); }); it("registers render refs from local wrapper files and normalizes payloads", async () => { const filePath = join(tempDir, "render-wrapper.json"); await writeFile( filePath, JSON.stringify( { metadata: { createdAt: "2026-05-21T00:00:00.000Z", projectId: "project-3", }, location: { file_path: filePath, }, data: { node_area_map: { J1: "DMA-1", J2: 2, }, area_ids: ["DMA-1", " DMA-2 "], area_colors: { "DMA-1": "#ff0000", "DMA-2": "#00ff00", }, }, createdAt: "2026-05-21T00:00:00.000Z", }, null, 2, ), "utf8", ); const record = await resolver.registerRenderPayloadFile(filePath, { actorKey: "actor-3", clientSessionId: "client-3", projectId: "project-3", projectKey: "project-key-3", sessionId: "session-3", source: RESULT_REFERENCE_SOURCE.migration, traceId: "trace-3", }); expect(record.kind).toBe(RESULT_REFERENCE_KIND.renderJunctionsPayload); expect(record.source).toBe(RESULT_REFERENCE_SOURCE.migration); const result = await resolver.getFullAuthorized( record.resultRef, { actorKey: "actor-3", projectId: "project-3", }, { expectedKind: RESULT_REFERENCE_KIND.renderJunctionsPayload, }, ); expect(result?.data).toEqual({ node_area_map: { J1: "DMA-1", J2: "2", }, area_ids: ["DMA-1", "DMA-2"], area_colors: { "DMA-1": "#ff0000", "DMA-2": "#00ff00", }, }); }); it("repairs wrapper files that omit metadata and location", async () => { const filePath = join(tempDir, "render-wrapper-missing-fields.json"); await writeFile( filePath, JSON.stringify( { data: { node_area_map: { J1: "DMA-1", }, }, createdAt: "2026-05-21T00:00:00.000Z", }, null, 2, ), "utf8", ); const record = await resolver.registerRenderPayloadFile(filePath, { actorKey: "actor-4", clientSessionId: "client-4", projectId: "project-4", projectKey: "project-key-4", sessionId: "session-4", source: RESULT_REFERENCE_SOURCE.migration, traceId: "trace-4", }); expect(record.kind).toBe(RESULT_REFERENCE_KIND.renderJunctionsPayload); const repaired = JSON.parse(await readFile(filePath, "utf8")) as { metadata?: Record; location?: Record; }; expect(repaired.metadata).toEqual({ createdAt: "2026-05-21T00:00:00.000Z", projectId: "project-4", }); expect(repaired.location).toEqual({ file_path: filePath, }); }); it("repairs wrapper files whose location points elsewhere", async () => { const filePath = join(tempDir, "render-wrapper-wrong-location.json"); await writeFile( filePath, JSON.stringify( { metadata: { createdAt: "2026-05-21T00:00:00.000Z", }, location: { file_path: "/tmp/elsewhere.json", source: "legacy", }, data: { node_area_map: { J1: "DMA-1", }, }, }, null, 2, ), "utf8", ); await resolver.registerRenderPayloadFile(filePath, { actorKey: "actor-4", clientSessionId: "client-4", projectId: "project-4", projectKey: "project-key-4", sessionId: "session-4", source: RESULT_REFERENCE_SOURCE.migration, traceId: "trace-4", }); const repaired = JSON.parse(await readFile(filePath, "utf8")) as { metadata?: Record; location?: Record; }; expect(repaired.metadata).toEqual({ createdAt: "2026-05-21T00:00:00.000Z", projectId: "project-4", }); expect(repaired.location).toEqual({ file_path: filePath, source: "legacy", }); }); it("resolves legacy render payload files when callers include the json suffix", async () => { const legacyRef = "res-c2fcee33-577e"; await writeFile( join(tempDir, `${legacyRef}.json`), JSON.stringify( { data: { node_area_map: { J1: "DMA-1", J2: 2, }, area_ids: ["DMA-1"], }, createdAt: "2026-05-21T00:00:00.000Z", projectId: "project-legacy-render", }, null, 2, ), "utf8", ); const result = await resolver.getFullAuthorized( `${legacyRef}.json`, { actorKey: "actor-legacy-render", clientSessionId: "chat-legacy-render", projectId: "project-legacy-render", }, { expectedKind: RESULT_REFERENCE_KIND.renderJunctionsPayload, }, ); expect(result?.result_ref).toBe(legacyRef); expect(result?.kind).toBe(RESULT_REFERENCE_KIND.renderJunctionsPayload); expect(result?.source).toBe(RESULT_REFERENCE_SOURCE.legacy); expect(result?.data).toEqual({ node_area_map: { J1: "DMA-1", J2: "2", }, area_ids: ["DMA-1"], }); }); it("keeps legacy render payload files scoped to their project", async () => { const legacyRef = "res-dddddddddddddddd"; await writeFile( join(tempDir, `${legacyRef}.json`), JSON.stringify( { data: { node_area_map: { J1: "DMA-1", }, }, projectId: "project-allowed", }, null, 2, ), "utf8", ); const result = await resolver.getFullAuthorized( legacyRef, { actorKey: "actor-legacy-render", clientSessionId: "chat-legacy-render", projectId: "project-denied", }, { expectedKind: RESULT_REFERENCE_KIND.renderJunctionsPayload, }, ); expect(result).toBeNull(); }); });