4fa4f13558
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
136 lines
4.0 KiB
TypeScript
136 lines
4.0 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { GatewayResponseError, type GatewayClient } from "@/lib/gateway/GatewayClient";
|
|
import { upsertGatewayAgentExecApprovals } from "@/lib/gateway/execApprovals";
|
|
|
|
describe("upsertGatewayAgentExecApprovals", () => {
|
|
it("writes per-agent policy with base hash", async () => {
|
|
const client = {
|
|
call: vi.fn(async (method: string, params?: unknown) => {
|
|
if (method === "exec.approvals.get") {
|
|
return {
|
|
exists: true,
|
|
hash: "hash-1",
|
|
file: {
|
|
version: 1,
|
|
agents: {
|
|
main: {
|
|
security: "allowlist",
|
|
ask: "always",
|
|
allowlist: [{ pattern: "/bin/main" }],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|
|
if (method === "exec.approvals.set") {
|
|
const payload = params as {
|
|
baseHash?: string;
|
|
file?: {
|
|
agents?: Record<string, { security?: string; ask?: string; allowlist?: Array<{ pattern: string }> }>;
|
|
};
|
|
};
|
|
expect(payload.baseHash).toBe("hash-1");
|
|
expect(payload.file?.agents?.["agent-2"]).toEqual({
|
|
security: "allowlist",
|
|
ask: "always",
|
|
allowlist: [{ pattern: "/usr/bin/git" }],
|
|
});
|
|
return { ok: true };
|
|
}
|
|
throw new Error(`unexpected method: ${method}`);
|
|
}),
|
|
} as unknown as GatewayClient;
|
|
|
|
await upsertGatewayAgentExecApprovals({
|
|
client,
|
|
agentId: "agent-2",
|
|
policy: {
|
|
security: "allowlist",
|
|
ask: "always",
|
|
allowlist: [{ pattern: "/usr/bin/git" }],
|
|
},
|
|
});
|
|
});
|
|
|
|
it("removes per-agent policy when policy is null", async () => {
|
|
const client = {
|
|
call: vi.fn(async (method: string, params?: unknown) => {
|
|
if (method === "exec.approvals.get") {
|
|
return {
|
|
exists: true,
|
|
hash: "hash-2",
|
|
file: {
|
|
version: 1,
|
|
agents: {
|
|
"agent-1": {
|
|
security: "allowlist",
|
|
ask: "always",
|
|
allowlist: [{ pattern: "/bin/echo" }],
|
|
},
|
|
},
|
|
},
|
|
};
|
|
}
|
|
if (method === "exec.approvals.set") {
|
|
const payload = params as {
|
|
file?: { agents?: Record<string, unknown> };
|
|
};
|
|
expect(payload.file?.agents?.["agent-1"]).toBeUndefined();
|
|
return { ok: true };
|
|
}
|
|
throw new Error(`unexpected method: ${method}`);
|
|
}),
|
|
} as unknown as GatewayClient;
|
|
|
|
await upsertGatewayAgentExecApprovals({
|
|
client,
|
|
agentId: "agent-1",
|
|
policy: null,
|
|
});
|
|
});
|
|
|
|
it("retries once when gateway reports stale base hash", async () => {
|
|
let setAttempts = 0;
|
|
const client = {
|
|
call: vi.fn(async (method: string, params?: unknown) => {
|
|
if (method === "exec.approvals.get") {
|
|
return {
|
|
exists: true,
|
|
hash: setAttempts === 0 ? "hash-old" : "hash-new",
|
|
file: {
|
|
version: 1,
|
|
agents: {},
|
|
},
|
|
};
|
|
}
|
|
if (method === "exec.approvals.set") {
|
|
setAttempts += 1;
|
|
const payload = params as { baseHash?: string };
|
|
if (setAttempts === 1) {
|
|
expect(payload.baseHash).toBe("hash-old");
|
|
throw new GatewayResponseError({
|
|
code: "INVALID_REQUEST",
|
|
message: "exec approvals changed since last load; re-run exec.approvals.get and retry",
|
|
});
|
|
}
|
|
expect(payload.baseHash).toBe("hash-new");
|
|
return { ok: true };
|
|
}
|
|
throw new Error(`unexpected method: ${method}`);
|
|
}),
|
|
} as unknown as GatewayClient;
|
|
|
|
await upsertGatewayAgentExecApprovals({
|
|
client,
|
|
agentId: "agent-3",
|
|
policy: {
|
|
security: "full",
|
|
ask: "off",
|
|
allowlist: [],
|
|
},
|
|
});
|
|
|
|
expect(setAttempts).toBe(2);
|
|
});
|
|
});
|