From bf4c7f7c65982ed2a0a8e28e6bd77230f6787ab1 Mon Sep 17 00:00:00 2001 From: Nikita Ashikhmin Date: Thu, 27 Aug 2026 16:54:43 +0400 Subject: [PATCH] test: align approval e2e with permission modes --- .../e2e/acp-e2e-file-approval.test.ts | 28 ---------------- .../e2e/acp-e2e-mcp-approval.test.ts | 7 ++-- .../e2e/acp-e2e-shell-approval.test.ts | 32 +++++++++++++------ 3 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/__tests__/CodexACPAgent/e2e/acp-e2e-file-approval.test.ts b/src/__tests__/CodexACPAgent/e2e/acp-e2e-file-approval.test.ts index b80920d0..190418fa 100644 --- a/src/__tests__/CodexACPAgent/e2e/acp-e2e-file-approval.test.ts +++ b/src/__tests__/CodexACPAgent/e2e/acp-e2e-file-approval.test.ts @@ -3,14 +3,11 @@ import fs from "node:fs"; import path from "node:path"; import {afterEach, beforeEach, expect, it, onTestFinished, vi} from "vitest"; import {AgentMode} from "../../../AgentMode"; -import {ApprovalOptionId} from "../../../permissions/option-ids"; import { createAuthenticatedFixture, - createPermissionResponder, describeE2E, expectEndTurn, expectNoPermissionRequests, - expectPermissionRequests, generateFileNameForTest, type SpawnedAgentFixture, } from "./acp-e2e-test-utils"; @@ -19,31 +16,6 @@ const FILE_CONTENT = "file approval e2e"; // The edit lands before the turn ends, so this only absorbs filesystem visibility lag. const FILE_APPEARS_TIMEOUT_MS = 5_000; -describeE2E("E2E file approval tests", () => { - let fixture: SpawnedAgentFixture; - - beforeEach(async () => { - fixture = await createAuthenticatedFixture(AgentMode.ReadOnly); - }); - - afterEach(async () => { - await fixture.dispose(); - }); - - it("applies approved file edits", async () => { - fixture.setPermissionResponder(createPermissionResponder("edit", ApprovalOptionId.AllowOnce)); - const sessionId = await expectFileEditApplied(fixture, newFilePathIn(fixture.workspaceDir)); - expectPermissionRequests(fixture, sessionId, {edit: 1, execute: 0}); - }); - - it("does not apply rejected file edits", async () => { - fixture.setPermissionResponder(createPermissionResponder("edit", ApprovalOptionId.Cancel)); - const sessionId = await expectFileEditBlocked(fixture, newFilePathIn(fixture.workspaceDir)); - expect(fixture.readPermissionRequests(sessionId, "edit").length).toBeGreaterThanOrEqual(1); - expect(fixture.readPermissionRequests(sessionId, "execute")).toHaveLength(0); - }); -}); - describeE2E("E2E read-only mode file permission tests", () => { let fixture: SpawnedAgentFixture; diff --git a/src/__tests__/CodexACPAgent/e2e/acp-e2e-mcp-approval.test.ts b/src/__tests__/CodexACPAgent/e2e/acp-e2e-mcp-approval.test.ts index 0cdb7fb3..49fcf034 100644 --- a/src/__tests__/CodexACPAgent/e2e/acp-e2e-mcp-approval.test.ts +++ b/src/__tests__/CodexACPAgent/e2e/acp-e2e-mcp-approval.test.ts @@ -2,6 +2,7 @@ import type * as acp from "@agentclientprotocol/sdk"; import fs from "node:fs"; import path from "node:path"; import {afterEach, beforeEach, expect, it} from "vitest"; +import {AgentMode} from "../../../AgentMode"; import {McpApprovalOptionId, type McpApprovalOptionId as McpApprovalOptionIdValue} from "../../../permissions/option-ids"; import { createAuthenticatedFixture, @@ -67,7 +68,7 @@ describeE2E("E2E MCP approval tests (configured in session)", () => { let fixture: SpawnedAgentFixture; beforeEach(async () => { - fixture = await createAuthenticatedFixture(); + fixture = await createAuthenticatedFixture(AgentMode.ReadOnly); }); afterEach(async () => { @@ -139,7 +140,7 @@ describeE2E("E2E MCP approval tests (configured in toml)", () => { let fixture: SpawnedAgentFixture; beforeEach(async () => { - fixture = await createAuthenticatedFixture(); + fixture = await createAuthenticatedFixture(AgentMode.ReadOnly); invocationMarkerPath = path.join(os.tmpdir(), `mcp-tool-invocation-${crypto.randomUUID()}.txt`) }); @@ -151,7 +152,7 @@ describeE2E("E2E MCP approval tests (configured in toml)", () => { beforeEach(async () => { await fixture.dispose(); - fixture = await createAuthenticatedFixture(undefined, [createMcpServer(invocationMarkerPath)]); + fixture = await createAuthenticatedFixture(AgentMode.ReadOnly, [createMcpServer(invocationMarkerPath)]); }); it("skips subsequent approvals in the same session when allow_always is selected", async () => { diff --git a/src/__tests__/CodexACPAgent/e2e/acp-e2e-shell-approval.test.ts b/src/__tests__/CodexACPAgent/e2e/acp-e2e-shell-approval.test.ts index b0c087d7..ca5d0646 100644 --- a/src/__tests__/CodexACPAgent/e2e/acp-e2e-shell-approval.test.ts +++ b/src/__tests__/CodexACPAgent/e2e/acp-e2e-shell-approval.test.ts @@ -8,6 +8,7 @@ import { createPermissionResponder, createPermissionResponse, describeE2E, + expectCancelled, expectEndTurn, expectNoPermissionRequests, expectPermissionRequests, @@ -38,15 +39,23 @@ describeE2E("E2E shell approval tests", () => { await fixture.dispose(); }); - async function promptShellCommandTwice(): Promise { - for (const text of [ + async function promptShellCommandTwice( + expectedStopReasons: ["end_turn" | "cancelled", "end_turn" | "cancelled"], + ): Promise { + const prompts = [ `Use your shell tool to run exactly \`${command}\`.`, `Use your shell tool to run exactly the same command again: \`${command}\`.`, - ]) { - expectEndTurn(await fixture.connection.prompt({ + ]; + for (const [index, text] of prompts.entries()) { + const response = await fixture.connection.prompt({ sessionId, prompt: [{type: "text", text}], - })); + }); + if (expectedStopReasons[index] === "cancelled") { + expectCancelled(response); + } else { + expectEndTurn(response); + } } } @@ -57,15 +66,18 @@ describeE2E("E2E shell approval tests", () => { ? responses.shift() ?? ApprovalOptionId.Cancel : null )); - await promptShellCommandTwice(); + await promptShellCommandTwice(["end_turn", "cancelled"]); expect(fs.existsSync(firstFilePath)).toBe(true); expect(fs.existsSync(secondFilePath)).toBe(false); expectPermissionRequests(fixture, sessionId, {execute: 2, edit: 0}); }); - it("skips subsequent approvals when allow_for_session is selected", async () => { - fixture.setPermissionResponder(createPermissionResponder("execute", ApprovalOptionId.AllowForSession)); - await promptShellCommandTwice(); + it("skips subsequent approvals when the exec-policy amendment is accepted", async () => { + fixture.setPermissionResponder(createPermissionResponder( + "execute", + ApprovalOptionId.AcceptWithExecpolicyAmendment, + )); + await promptShellCommandTwice(["end_turn", "end_turn"]); expect(fs.existsSync(firstFilePath)).toBe(true); expect(fs.existsSync(secondFilePath)).toBe(true); expectPermissionRequests(fixture, sessionId, {execute: 1, edit: 0}); @@ -73,7 +85,7 @@ describeE2E("E2E shell approval tests", () => { it("cancels every command when cancel is selected", async () => { fixture.setPermissionResponder(createPermissionResponder("execute", ApprovalOptionId.Cancel)); - await promptShellCommandTwice(); + await promptShellCommandTwice(["cancelled", "cancelled"]); expect(fs.existsSync(firstFilePath)).toBe(false); expect(fs.existsSync(secondFilePath)).toBe(false); expectPermissionRequests(fixture, sessionId, {execute: 2, edit: 0});