Files
claw3d/tests/unit/execApprovalEvents.test.ts
Luke The Dev 4fa4f13558 First Release of Claw3D (#11)
Co-authored-by: iamlukethedev <iamlukethedev@users.noreply.github.com>
2026-03-19 23:14:04 -05:00

214 lines
5.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { AgentState } from "@/features/agents/state/store";
import {
parseExecApprovalRequested,
parseExecApprovalResolved,
resolveExecApprovalAgentId,
} from "@/features/agents/approvals/execApprovalEvents";
import type { EventFrame } from "@/lib/gateway/GatewayClient";
const createAgent = (agentId: string, sessionKey: string): AgentState => ({
agentId,
name: agentId,
sessionKey,
status: "idle",
sessionCreated: true,
awaitingUserInput: false,
hasUnseenActivity: false,
outputLines: [],
lastResult: null,
lastDiff: null,
runId: null,
runStartedAt: null,
streamText: null,
thinkingTrace: null,
latestOverride: null,
latestOverrideKind: null,
lastAssistantMessageAt: null,
lastActivityAt: null,
latestPreview: null,
lastUserMessage: null,
draft: "",
sessionSettingsSynced: true,
historyLoadedAt: null,
historyFetchLimit: null,
historyFetchedCount: null,
historyMaybeTruncated: false,
toolCallingEnabled: true,
showThinkingTraces: true,
model: "openai/gpt-5",
thinkingLevel: "medium",
avatarSeed: agentId,
avatarUrl: null,
});
describe("execApprovalEvents", () => {
it("parses exec.approval.requested payload", () => {
const event: EventFrame = {
type: "event",
event: "exec.approval.requested",
payload: {
id: "approval-1",
request: {
command: "npm run test",
cwd: "/repo",
host: "gateway",
security: "allowlist",
ask: "always",
agentId: "agent-1",
resolvedPath: "/bin/npm",
sessionKey: "agent:agent-1:main",
},
createdAtMs: 123,
expiresAtMs: 456,
},
};
expect(parseExecApprovalRequested(event)).toEqual({
id: "approval-1",
request: {
command: "npm run test",
cwd: "/repo",
host: "gateway",
security: "allowlist",
ask: "always",
agentId: "agent-1",
resolvedPath: "/bin/npm",
sessionKey: "agent:agent-1:main",
},
createdAtMs: 123,
expiresAtMs: 456,
});
});
it("returns null for invalid requested payload", () => {
const event: EventFrame = {
type: "event",
event: "exec.approval.requested",
payload: {
id: "approval-1",
request: { command: "" },
createdAtMs: 0,
expiresAtMs: 0,
},
};
expect(parseExecApprovalRequested(event)).toBeNull();
});
it("parses exec.approval.resolved payload", () => {
const event: EventFrame = {
type: "event",
event: "exec.approval.resolved",
payload: {
id: "approval-1",
decision: "allow-once",
resolvedBy: "studio",
ts: 987,
},
};
expect(parseExecApprovalResolved(event)).toEqual({
id: "approval-1",
decision: "allow-once",
resolvedBy: "studio",
ts: 987,
});
});
it("returns null for unknown resolved decision", () => {
const event: EventFrame = {
type: "event",
event: "exec.approval.resolved",
payload: {
id: "approval-1",
decision: "approve",
ts: 987,
},
};
expect(parseExecApprovalResolved(event)).toBeNull();
});
it("resolves approval agent by explicit agent id", () => {
const requested = {
id: "approval-1",
request: {
command: "pwd",
cwd: null,
host: "gateway",
security: null,
ask: null,
agentId: "agent-2",
resolvedPath: null,
sessionKey: "agent:agent-2:main",
},
createdAtMs: 1,
expiresAtMs: 2,
};
const agents = [
createAgent("agent-1", "agent:agent-1:main"),
createAgent("agent-2", "agent:agent-2:main"),
];
expect(resolveExecApprovalAgentId({ requested, agents })).toBe("agent-2");
});
it("trusts explicit agent id even when the local agent list has not hydrated it yet", () => {
const requested = {
id: "approval-1",
request: {
command: "pwd",
cwd: null,
host: "gateway",
security: null,
ask: null,
agentId: "agent-prehydration",
resolvedPath: null,
sessionKey: "agent:agent-prehydration:main",
},
createdAtMs: 1,
expiresAtMs: 2,
};
const agents = [createAgent("agent-1", "agent:agent-1:main")];
expect(resolveExecApprovalAgentId({ requested, agents })).toBe("agent-prehydration");
});
it("falls back to session key when agent id missing", () => {
const requested = {
id: "approval-1",
request: {
command: "pwd",
cwd: null,
host: "gateway",
security: null,
ask: null,
agentId: null,
resolvedPath: null,
sessionKey: "agent:agent-3:main",
},
createdAtMs: 1,
expiresAtMs: 2,
};
const agents = [createAgent("agent-3", "agent:agent-3:main")];
expect(resolveExecApprovalAgentId({ requested, agents })).toBe("agent-3");
});
it("returns null when no agent mapping matches", () => {
const requested = {
id: "approval-1",
request: {
command: "pwd",
cwd: null,
host: "gateway",
security: null,
ask: null,
agentId: null,
resolvedPath: null,
sessionKey: "agent:missing:main",
},
createdAtMs: 1,
expiresAtMs: 2,
};
const agents = [createAgent("agent-1", "agent:agent-1:main")];
expect(resolveExecApprovalAgentId({ requested, agents })).toBeNull();
});
});