import { describe, expect, it } from "vitest"; import { indexInvalidationRegistry } from "../../src/contracts/query-invalidation.ts"; import { createBoundQueryKey, createQueryInvalidationPrefix, defineQueryNamespaceIdentity, queryNamespaceIdentityKey, } from "../../src/contracts/query-keys.ts"; describe("query namespace identity", () => { it("uses a canonical JSON tuple as the namespace identity key", () => { const namespace = defineQueryNamespaceIdentity("reference-resource", 1); expect(queryNamespaceIdentityKey(namespace)).toBe( '["reference-resource",1]', ); }); it("creates one namespace-first prefix for invalidation and bound keys", () => { const namespace = defineQueryNamespaceIdentity("reference-resource", 1); const prefix = createQueryInvalidationPrefix(namespace); const key = createBoundQueryKey( namespace, "scope-fingerprint-0001", 3, "identity-token-0001", ); expect(prefix).toEqual(["query", 2, "reference-resource", 1]); expect(key).toEqual([ "query", 2, "reference-resource", 1, "scope-fingerprint-0001", 3, "identity-token-0001", ]); expect(key.slice(0, 4)).toEqual(prefix); expect(Object.isFrozen(prefix)).toBe(true); expect(Object.isFrozen(key)).toBe(true); }); it.each([ ["empty", ""], ["C0 control", "orders\u0000private"], ["DEL control", "orders\u007fprivate"], ["81 UTF-8 bytes", "가".repeat(27)], ])("rejects a $0 namespace ID", (_label, namespaceId) => { expect(() => defineQueryNamespaceIdentity(namespaceId, 1)).toThrow( /namespace identity is invalid/u, ); }); it.each([0, -1, 1.5, Number.MAX_SAFE_INTEGER + 1])( "rejects the non-positive-safe namespace version %s", (namespaceVersion) => { expect(() => defineQueryNamespaceIdentity("reference-resource", namespaceVersion), ).toThrow(/namespace identity is invalid/u); }, ); it("rejects a non-positive definition version before creating a bound key", () => { const namespace = defineQueryNamespaceIdentity("reference-resource", 1); expect(() => createBoundQueryKey( namespace, "scope-fingerprint-0001", 0, "identity-token-0001", ), ).toThrow(/definition version is invalid/u); }); }); describe("query invalidation registry", () => { it.each([ { label: "topic", registry: { topics: ["orders\u0000private"], namespaces: ["orders"], edges: [{ topicId: "orders\u0000private", namespace: "orders" }], }, }, { label: "namespace", registry: { topics: ["orders"], namespaces: ["orders\u001fprivate"], edges: [{ topicId: "orders", namespace: "orders\u001fprivate" }], }, }, ])("rejects control characters in a registry $label", ({ registry }) => { expect(() => indexInvalidationRegistry(registry)).toThrow(/is invalid/u); }); });