import { afterEach, beforeEach, describe, expect, it } from "bun:test"; import { mkdtemp, rm, stat, 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, tempDir, 1024 * 1024); 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.agentGenerated, traceId: "trace-3", }); expect(record.kind).toBe(RESULT_REFERENCE_KIND.renderJunctionsPayload); expect(record.source).toBe(RESULT_REFERENCE_SOURCE.agentGenerated); 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", }, }); await expect(stat(filePath)).rejects.toThrow(); }); it("rejects render payload files outside the configured import directory", async () => { const outsideDir = await mkdtemp(join(tmpdir(), "tjwater-result-outside-")); const filePath = join(outsideDir, "render-wrapper.json"); await writeFile( filePath, JSON.stringify({ metadata: {}, location: { file_path: filePath }, data: { node_area_map: { J1: "DMA-1" } }, }), "utf8", ); try { await expect( resolver.registerRenderPayloadFile(filePath, { actorKey: "actor-4", clientSessionId: "client-4", projectKey: "project-key-4", sessionId: "session-4", source: RESULT_REFERENCE_SOURCE.agentGenerated, traceId: "trace-4", }), ).rejects.toThrow("RESULT_REF_IMPORT_DIR"); } finally { await rm(outsideDir, { force: true, recursive: true }); } }); it("rejects oversized render payload files before parsing", async () => { const filePath = join(tempDir, "oversized.json"); await writeFile(filePath, "x".repeat(128), "utf8"); const sizeLimitedResolver = new ResultReferenceResolver(store, tempDir, 64); await expect( sizeLimitedResolver.registerRenderPayloadFile(filePath, { actorKey: "actor-5", clientSessionId: "client-5", projectKey: "project-key-5", sessionId: "session-5", source: RESULT_REFERENCE_SOURCE.agentGenerated, traceId: "trace-5", }), ).rejects.toThrow("RESULT_REF_IMPORT_MAX_BYTES"); }); });