Files
camino-package-runtime/test/queries.test.mjs
T
Timothy J. Aveni 6a17cd1ae0 Add checked workspace-interface query roots
Implement scoped interface extents across QX, generated bindings, SDK,
Orch, Camino and browser queries. Preserve native projection, aggregation,
pagination and watch invalidation without synthetic persisted objects.
Validate exact query grants and scope freshness on execution and replay.
Add local PostgreSQL, transport, browser and code-generation coverage.

C1 implementation slice only: full-text indexes and Studio search adoption
(C2/C3) remain tracked in the implementation handoff. No publication or deployment.
2026-09-19 10:18:47 -07:00

103 lines
3.7 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import { create } from "@bufbuild/protobuf";
import { QueryResponseSchema } from "../dist/camino/api_pb.js";
import { InjectedDependencySchema } from "../dist/quixos/refs_pb.js";
import { createRuntimeContext, decodeQuerySnapshot, jsToProtoValue, protoValueToJs } from "../dist/index.js";
test("private relational captures cannot be decoded as a completed public query", () => {
const response = create(QueryResponseSchema, { relationalCaptures: [{ rootObjectId: "obj:private" }] });
assert.throws(
() => decodeQuerySnapshot(response, { kind: "record", fields: {} }, "run", 1n),
/QUERY_RESULT_UNFINISHED/,
);
});
test("query ports carry only an injected query identity and root", async () => {
let seen;
const context = createRuntimeContext(
{},
{
executeQuery: async (request) => {
seen = request;
return create(QueryResponseSchema);
},
},
{
objectId: "obj:receiver",
input: {},
dependencies: [
create(InjectedDependencySchema, {
portId: "list",
objectId: "obj:collection",
binding: { case: "queryId", value: "pkg@1:upcoming" },
}),
],
},
);
await context.query("list").execute({ first: jsToProtoValue(30) }, "checked-definition");
assert.equal(seen.expectedDefinitionDigest, "checked-definition");
assert.deepEqual(seen.root, { case: "objectId", value: "obj:collection" });
assert.equal(seen.queryId, "pkg@1:upcoming");
assert.equal(protoValueToJs(seen.variables.first), 30);
assert.throws(() => context.query("not-injected"), /Missing/);
});
test("workspace query ports carry explicit scoped evidence, never their receiver", async () => {
let seen;
const dependency = create(InjectedDependencySchema, {
portId: "search",
binding: {
case: "workspaceQuery",
value: {
queryId: "pkg@1:search",
scope: {
workspaceId: "ws",
workspaceRevisionId: "ws@1",
workspaceEpoch: "1",
interfaceRevisionId: "searchable",
bindingDigest: "digest",
},
},
},
});
const context = createRuntimeContext(
{},
{
executeQuery: async (request) => {
seen = request;
return create(QueryResponseSchema);
},
},
{ objectId: "obj:receiver", input: {}, dependencies: [dependency] },
);
await context.query("search").execute({});
assert.equal(seen.root.case, "workspaceScope");
assert.equal(seen.root.value.workspaceId, "ws");
assert.equal(seen.objectId, undefined);
dependency.binding.value.scope = undefined;
assert.throws(
() => createRuntimeContext({}, {}, { objectId: "obj:receiver", input: {}, dependencies: [dependency] }),
/has no scope/,
);
});
test("query snapshots distinguish an unavailable scalar from a successful null", () => {
const output = {
kind: "record",
fields: { title: { kind: "scalar", name: "string" }, score: { kind: "scalar", name: "int64" } },
};
const response = create(QueryResponseSchema, {
value: jsToProtoValue({ title: "Native title", score: null }),
pending: [{ path: [{ part: { case: "field", value: "score" } }] }],
});
const snapshot = decodeQuerySnapshot(response, output, "run1", 1n);
assert.equal(snapshot.status, "partial");
assert.deepEqual(snapshot.data, { title: "Native title" });
assert.deepEqual(snapshot.fields, [{ path: ["score"], status: "pending" }]);
assert.equal(output.fields.score.kind, "scalar");
response.pending = [];
response.value = jsToProtoValue({ title: "Native title", score: 9007199254740993n });
assert.equal(decodeQuerySnapshot(response, output, "run1", 2n).data.score, 9007199254740993n);
});