Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 0 additions & 105 deletions packages/access-tools/src/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import {
AccessForbiddenError,
AccessNotFoundError,
grantAccess,
listGrants,
listPrincipals,
revokeAccess,
type AccessToolClientConfig,
} from "./client";
Expand All @@ -19,92 +17,6 @@ function testConfig(fetchImpl: typeof fetch): AccessToolClientConfig {
};
}

test("listPrincipals sends sidecar auth and parses the response", async () => {
let seenUrl: string | undefined;
let seenHeaders: Record<string, string> | undefined;
const fetchImpl = (async (url: string | URL, init?: RequestInit) => {
seenUrl = String(url);
seenHeaders = init?.headers as Record<string, string>;
return new Response(
JSON.stringify({
principals: [
{ id: "prin_1", kind: "workflow", refId: "run_1", status: "active" },
],
}),
);
}) as unknown as typeof fetch;

const result = await listPrincipals(testConfig(fetchImpl));

expect(seenUrl).toBe(
"https://hub.example.com/api/workflow-access/principals",
);
expect(seenHeaders?.["authorization"]).toBe("Bearer sc-token");
expect(seenHeaders?.["x-workflow-run-address"]).toBe("run_1@workflow");
expect(result).toEqual([
{ id: "prin_1", kind: "workflow", refId: "run_1", status: "active" },
]);
});

test("listGrants filters by principalId and resource", async () => {
let seenUrl: string | undefined;
const fetchImpl = (async (url: string | URL) => {
seenUrl = String(url);
return new Response(JSON.stringify({ grants: [] }));
}) as unknown as typeof fetch;

await listGrants(testConfig(fetchImpl), {
principalId: "prin_1",
resource: "workflow-run:*",
});

const parsed = new URL(seenUrl ?? "");
expect(parsed.searchParams.get("principalId")).toBe("prin_1");
expect(parsed.searchParams.get("resource")).toBe("workflow-run:*");
});

test("grantAccess round-trips the created grants", async () => {
let seenBody: unknown;
const fetchImpl = (async (_url: string | URL, init?: RequestInit) => {
seenBody = JSON.parse(String(init?.body));
return new Response(
JSON.stringify({
grants: [
{
id: "grant_1",
principalId: "prin_2",
resource: "workflow-run:*",
action: "read",
effect: "allow",
},
],
}),
{ status: 201 },
);
}) as unknown as typeof fetch;

const result = await grantAccess(testConfig(fetchImpl), {
principalId: "prin_2",
resource: "workflow-run:*",
actions: ["read"],
});

expect(seenBody).toEqual({
principalId: "prin_2",
resource: "workflow-run:*",
actions: ["read"],
});
expect(result).toEqual([
{
id: "grant_1",
principalId: "prin_2",
resource: "workflow-run:*",
action: "read",
effect: "allow",
},
]);
});

test("a 403 from grantAccess surfaces as AccessForbiddenError with the hub's userMessage", async () => {
const fetchImpl = (async () =>
new Response(
Expand Down Expand Up @@ -139,20 +51,3 @@ test("a 404 from revokeAccess surfaces as AccessNotFoundError", async () => {
revokeAccess(testConfig(fetchImpl), "grant_missing"),
).rejects.toThrow(AccessNotFoundError);
});

test("revokeAccess sends a DELETE to the grant's own path", async () => {
let seenUrl: string | undefined;
let seenMethod: string | undefined;
const fetchImpl = (async (url: string | URL, init?: RequestInit) => {
seenUrl = String(url);
seenMethod = init?.method;
return new Response(null, { status: 204 });
}) as unknown as typeof fetch;

await revokeAccess(testConfig(fetchImpl), "grant_1");

expect(seenUrl).toBe(
"https://hub.example.com/api/workflow-access/grants/grant_1",
);
expect(seenMethod).toBe("DELETE");
});
29 changes: 0 additions & 29 deletions packages/access-tools/src/tool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import {
accessTools,
GRANT_ACCESS_TOOL,
LIST_GRANTS_TOOL,
LIST_PRINCIPALS_TOOL,
REVOKE_ACCESS_TOOL,
type WorkflowAccessEnv,
} from "./tool";

Expand All @@ -22,33 +20,6 @@ function callFor(name: string, args: Record<string, unknown>): ToolCall {
return { id: "call_1", name, arguments: args };
}

test("declares exactly the four access tools", () => {
const bundle = accessTools(testEnv());
expect(bundle.definitions.map((d) => d.name)).toEqual([
LIST_PRINCIPALS_TOOL,
LIST_GRANTS_TOOL,
GRANT_ACCESS_TOOL,
REVOKE_ACCESS_TOOL,
]);
});

test("requires the sanctioned env keys", () => {
expect(accessTools.requires).toEqual([
"hubAccessUrl",
"sidecarToken",
"address",
]);
});

test("grant_access and revoke_access declare approval: ask; the reads do not", () => {
expect(accessTools.definitions).toEqual([
{ name: LIST_PRINCIPALS_TOOL },
{ name: LIST_GRANTS_TOOL },
{ name: GRANT_ACCESS_TOOL, approval: "ask" },
{ name: REVOKE_ACCESS_TOOL, approval: "ask" },
]);
});

test("list_grants rejects invalid input before ever calling fetch", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = (async () => {
Expand Down
51 changes: 0 additions & 51 deletions packages/catalog-tools/src/tool.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,39 +74,6 @@ function stubbing(body: unknown): void {
})) as unknown as typeof fetch;
}

describe("the bundle's shape", () => {
test("declares three tools, none gated behind approval", () => {
expect(catalogTools.definitions).toEqual([
{ name: LIST_MODEL_CONCEPTS_TOOL },
{ name: PICK_MODELS_TOOL },
{ name: ESTIMATE_RUN_COST_TOOL },
]);
});

test("requires the sanctioned workflow-run env keys", () => {
expect(catalogTools.requires).toEqual([
"hubCatalogUrl",
"sidecarToken",
"address",
]);
});

test("no tool takes a model name, and the capability list is the real vocabulary", () => {
const definitions = catalogTools(env()).definitions;
for (const definition of definitions) {
const schema = definition.inputSchema as {
properties: Record<string, { items?: { enum?: string[] } }>;
};
expect(Object.keys(schema.properties)).not.toContain("model");
const capabilities = schema.properties["capabilities"];
if (capabilities !== undefined) {
expect(capabilities.items?.enum).toContain("plain-text");
expect(capabilities.items?.enum).not.toContain("telepathy");
}
}
});
});

describe("pick_models", () => {
test("naming both a concept and capabilities is refused, and says why", async () => {
const result = await catalogTools(env()).run(
Expand Down Expand Up @@ -326,24 +293,6 @@ function forbidden(): Response {
);
}

describe("the offering bundle's shape", () => {
test("gates create_offering and disable_offering behind approval, not set_offering_priority", () => {
expect(catalogOfferingTools.definitions).toEqual([
{ name: CREATE_OFFERING_TOOL, approval: "ask" },
{ name: SET_OFFERING_PRIORITY_TOOL },
{ name: DISABLE_OFFERING_TOOL, approval: "ask" },
]);
});

test("requires only the sanctioned workflow-run env keys", () => {
expect(catalogOfferingTools.requires).toEqual([
"hubCatalogUrl",
"sidecarToken",
"address",
]);
});
});

describe("create_offering", () => {
test("resolves both names to ids, then creates the offering", async () => {
globalThis.fetch = routedFetch({
Expand Down
Loading