Skip to content

Commit b93d4fd

Browse files
committed
test(rest): conform the fixture store to the double-limit and where-matcher gates
The fixture find double now holds the caller's limit bound by presence and filters through one hand-written matcher that supports equality and the $in shape the shared resolver actually issues, refusing every other shape loudly. check:objectql-double-limit graded the new double (301 graded, bound applied) and check:where-matcher counts the matcher among the refusing conformers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015YPiiDdw96RGS25WLctCQP
1 parent 63e7535 commit b93d4fd

1 file changed

Lines changed: 52 additions & 21 deletions

File tree

packages/rest/src/execctx-authz-input-seam-reachability.test.ts

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -230,34 +230,65 @@ const RAW_MEMBER_KEY = 'osk_member_key_fixture';
230230
const RAW_EXMEMBER_KEY = 'osk_exmember_key_fixture';
231231
const RAW_ORGLESS_KEY = 'osk_orgless_key_fixture';
232232

233+
/**
234+
* The fixture's ONE hand-written where-matcher: equality plus `$in` — the two
235+
* shapes the shared resolver actually issues — and it REFUSES every other
236+
* shape loudly instead of silently matching (the check:where-matcher
237+
* convention: a combinator or operator this fixture does not implement must
238+
* never read as a field that happened not to match).
239+
*/
240+
function matchesWhere(row: any, where: any): boolean {
241+
for (const [field, cond] of Object.entries(where ?? {})) {
242+
if (field.startsWith('$')) {
243+
throw new Error(`fixture where-matcher: unsupported combinator '${field}'`);
244+
}
245+
if (cond !== null && typeof cond === 'object') {
246+
const ops = Object.keys(cond as object);
247+
if (ops.length !== 1 || ops[0] !== '$in' || !Array.isArray((cond as any).$in)) {
248+
throw new Error(`fixture where-matcher: unsupported operator shape on '${field}'`);
249+
}
250+
if (!(cond as any).$in.includes(row[field])) return false;
251+
continue;
252+
}
253+
if (row[field] !== cond) return false;
254+
}
255+
return true;
256+
}
257+
233258
/**
234259
* A permission store with the SHIPPED aggregation shapes: API keys in
235260
* `sys_api_key`, memberships in `sys_member`, capabilities through
236-
* `sys_user_permission_set` → `sys_permission_set`. Filters honour the
237-
* `where` keys the resolver actually sends, so the two `sys_member` reads
238-
* (by user, by org) answer differently, as a real engine does.
261+
* `sys_user_permission_set` → `sys_permission_set`. Every read filters
262+
* through the one refusing matcher above, and the caller's `limit` bound is
263+
* held BY PRESENCE (check:objectql-double-limit).
239264
*/
240265
function qlWith(opts: { memberships: Array<{ user_id: string; organization_id: string }> }) {
241-
const apiKeys = [
242-
{ key: hashApiKey(RAW_MEMBER_KEY), user_id: 'u_member', active_organization_id: 'org_A', revoked: false },
243-
{ key: hashApiKey(RAW_EXMEMBER_KEY), user_id: 'u_exmember', active_organization_id: 'org_A', revoked: false },
244-
{ key: hashApiKey(RAW_ORGLESS_KEY), user_id: 'u_orgless', revoked: false },
245-
];
266+
const tables: Record<string, any[]> = {
267+
sys_api_key: [
268+
{ key: hashApiKey(RAW_MEMBER_KEY), user_id: 'u_member', active_organization_id: 'org_A', revoked: false },
269+
{ key: hashApiKey(RAW_EXMEMBER_KEY), user_id: 'u_exmember', active_organization_id: 'org_A', revoked: false },
270+
{ key: hashApiKey(RAW_ORGLESS_KEY), user_id: 'u_orgless', revoked: false },
271+
],
272+
sys_member: opts.memberships,
273+
sys_user: [
274+
{ id: 'u_member', email: 'u_member@example.com' },
275+
{ id: 'u_exmember', email: 'u_exmember@example.com' },
276+
{ id: 'u_orgless', email: 'u_orgless@example.com' },
277+
{ id: 'u_gated', email: 'u_gated@example.com' },
278+
],
279+
sys_user_permission_set: [
280+
{ user_id: 'u_member', permission_set_id: 'ps_pkg' },
281+
{ user_id: 'u_exmember', permission_set_id: 'ps_pkg' },
282+
{ user_id: 'u_orgless', permission_set_id: 'ps_pkg' },
283+
],
284+
sys_permission_set: [
285+
{ id: 'ps_pkg', name: 'pkg_admin', system_permissions: ['manage_metadata', 'studio.access'] },
286+
],
287+
};
246288
return {
247289
find: async (object: string, q: any = {}) => {
248-
const where = q?.where ?? {};
249-
if (object === 'sys_api_key') return apiKeys.filter((r) => r.key === where.key);
250-
if (object === 'sys_member') {
251-
if (where.user_id) return opts.memberships.filter((m) => m.user_id === where.user_id);
252-
if (where.organization_id) return opts.memberships.filter((m) => m.organization_id === where.organization_id);
253-
return [];
254-
}
255-
if (object === 'sys_user') return [{ id: where.id, email: `${where.id}@example.com` }];
256-
if (object === 'sys_user_permission_set') return [{ permission_set_id: 'ps_pkg' }];
257-
if (object === 'sys_permission_set') {
258-
return [{ id: 'ps_pkg', name: 'pkg_admin', system_permissions: ['manage_metadata', 'studio.access'] }];
259-
}
260-
return [];
290+
const rows = (tables[object] ?? []).filter((row: any) => matchesWhere(row, q?.where));
291+
return typeof q?.limit === 'number' ? rows.slice(0, q.limit) : rows;
261292
},
262293
};
263294
}

0 commit comments

Comments
 (0)