diff --git a/extensions/codex/src/app-server/auth-bridge.test.ts b/extensions/codex/src/app-server/auth-bridge.test.ts index ff9680b3b18..29095089df5 100644 --- a/extensions/codex/src/app-server/auth-bridge.test.ts +++ b/extensions/codex/src/app-server/auth-bridge.test.ts @@ -17,17 +17,9 @@ describe("bridgeCodexAppServerStartOptions", () => { crypto.createHash("sha256").update(profileId).digest("hex").slice(0, 16), ); - beforeAll(async () => { - ({ bridgeCodexAppServerStartOptions } = await import("./auth-bridge.js")); - }); - - afterEach(async () => { - await Promise.all( - tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })), - ); - }); - - it("bridges canonical OpenClaw oauth into an isolated CODEX_HOME", async () => { + async function createAgentDirWithDefaultProfile( + profile: Record = {}, + ): Promise { const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-codex-app-server-")); tempDirs.push(agentDir); saveAuthProfileStore( @@ -40,14 +32,31 @@ describe("bridgeCodexAppServerStartOptions", () => { access: "access-token", refresh: "refresh-token", expires: Date.now() + 60_000, - accountId: "acct-123", - idToken: "id-token", + ...profile, }, }, }, agentDir, { filterExternalAuthProfiles: false }, ); + return agentDir; + } + + beforeAll(async () => { + ({ bridgeCodexAppServerStartOptions } = await import("./auth-bridge.js")); + }); + + afterEach(async () => { + await Promise.all( + tempDirs.splice(0).map((dir) => fs.rm(dir, { recursive: true, force: true })), + ); + }); + + it("bridges canonical OpenClaw oauth into an isolated CODEX_HOME", async () => { + const agentDir = await createAgentDirWithDefaultProfile({ + accountId: "acct-123", + idToken: "id-token", + }); const result = await bridgeCodexAppServerStartOptions({ startOptions: { @@ -110,24 +119,7 @@ describe("bridgeCodexAppServerStartOptions", () => { }); it("refuses to overwrite a symlinked auth bridge file", async () => { - const agentDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-codex-app-server-")); - tempDirs.push(agentDir); - saveAuthProfileStore( - { - version: 1, - profiles: { - "openai-codex:default": { - type: "oauth", - provider: "openai-codex", - access: "access-token", - refresh: "refresh-token", - expires: Date.now() + 60_000, - }, - }, - }, - agentDir, - { filterExternalAuthProfiles: false }, - ); + const agentDir = await createAgentDirWithDefaultProfile(); const codexHome = resolveHashedCodexHome(agentDir, "openai-codex:default"); await fs.mkdir(codexHome, { recursive: true }); diff --git a/extensions/codex/src/app-server/compact.test.ts b/extensions/codex/src/app-server/compact.test.ts index 6c92f682993..3f4e69ee82b 100644 --- a/extensions/codex/src/app-server/compact.test.ts +++ b/extensions/codex/src/app-server/compact.test.ts @@ -9,6 +9,26 @@ import { writeCodexAppServerBinding } from "./session-binding.js"; let tempDir: string; +async function writeTestBinding(options: { authProfileId?: string } = {}): Promise { + const sessionFile = path.join(tempDir, "session.jsonl"); + await writeCodexAppServerBinding(sessionFile, { + threadId: "thread-1", + cwd: tempDir, + ...options, + }); + return sessionFile; +} + +function startCompaction(sessionFile: string, options: { currentTokenCount?: number } = {}) { + return maybeCompactCodexAppServerSession({ + sessionId: "session-1", + sessionKey: "agent:main:session-1", + sessionFile, + workspaceDir: tempDir, + ...options, + }); +} + describe("maybeCompactCodexAppServerSession", () => { beforeEach(async () => { tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-codex-compact-")); @@ -22,19 +42,9 @@ describe("maybeCompactCodexAppServerSession", () => { it("waits for native app-server compaction before reporting success", async () => { const fake = createFakeCodexClient(); __testing.setCodexAppServerClientFactoryForTests(async () => fake.client); - const sessionFile = path.join(tempDir, "session.jsonl"); - await writeCodexAppServerBinding(sessionFile, { - threadId: "thread-1", - cwd: tempDir, - }); + const sessionFile = await writeTestBinding(); - const pendingResult = maybeCompactCodexAppServerSession({ - sessionId: "session-1", - sessionKey: "agent:main:session-1", - sessionFile, - workspaceDir: tempDir, - currentTokenCount: 123, - }); + const pendingResult = startCompaction(sessionFile, { currentTokenCount: 123 }); await vi.waitFor(() => { expect(fake.request).toHaveBeenCalledWith("thread/compact/start", { threadId: "thread-1" }); }); @@ -70,18 +80,9 @@ describe("maybeCompactCodexAppServerSession", () => { it("accepts native context-compaction item completion as success", async () => { const fake = createFakeCodexClient(); __testing.setCodexAppServerClientFactoryForTests(async () => fake.client); - const sessionFile = path.join(tempDir, "session.jsonl"); - await writeCodexAppServerBinding(sessionFile, { - threadId: "thread-1", - cwd: tempDir, - }); + const sessionFile = await writeTestBinding(); - const pendingResult = maybeCompactCodexAppServerSession({ - sessionId: "session-1", - sessionKey: "agent:main:session-1", - sessionFile, - workspaceDir: tempDir, - }); + const pendingResult = startCompaction(sessionFile); await vi.waitFor(() => { expect(fake.request).toHaveBeenCalledWith("thread/compact/start", { threadId: "thread-1" }); }); @@ -113,19 +114,9 @@ describe("maybeCompactCodexAppServerSession", () => { seenAuthProfileId = authProfileId; return fake.client; }); - const sessionFile = path.join(tempDir, "session.jsonl"); - await writeCodexAppServerBinding(sessionFile, { - threadId: "thread-1", - cwd: tempDir, - authProfileId: "openai-codex:work", - }); + const sessionFile = await writeTestBinding({ authProfileId: "openai-codex:work" }); - const pendingResult = maybeCompactCodexAppServerSession({ - sessionId: "session-1", - sessionKey: "agent:main:session-1", - sessionFile, - workspaceDir: tempDir, - }); + const pendingResult = startCompaction(sessionFile); await vi.waitFor(() => { expect(fake.request).toHaveBeenCalledWith("thread/compact/start", { threadId: "thread-1" }); }); diff --git a/extensions/codex/src/app-server/models.test.ts b/extensions/codex/src/app-server/models.test.ts index f1d94e83579..f847a4e866c 100644 --- a/extensions/codex/src/app-server/models.test.ts +++ b/extensions/codex/src/app-server/models.test.ts @@ -4,25 +4,30 @@ import { listCodexAppServerModels } from "./models.js"; import { resetSharedCodexAppServerClientForTests } from "./shared-client.js"; import { createClientHarness } from "./test-support.js"; -const mocks = vi.hoisted(() => ({ - bridgeCodexAppServerStartOptions: vi.fn(async ({ startOptions }) => startOptions), - resolveOpenClawAgentDir: vi.fn(() => "/tmp/openclaw-agent"), -})); +const mocks = vi.hoisted(() => { + const authBridge = { + startOptions: vi.fn(async ({ startOptions }) => startOptions), + }; + const providerAuth = { + agentDir: vi.fn(() => "/tmp/openclaw-agent"), + }; + return { authBridge, providerAuth }; +}); vi.mock("./auth-bridge.js", () => ({ - bridgeCodexAppServerStartOptions: mocks.bridgeCodexAppServerStartOptions, + bridgeCodexAppServerStartOptions: mocks.authBridge.startOptions, })); vi.mock("openclaw/plugin-sdk/provider-auth", () => ({ - resolveOpenClawAgentDir: mocks.resolveOpenClawAgentDir, + resolveOpenClawAgentDir: mocks.providerAuth.agentDir, })); describe("listCodexAppServerModels", () => { afterEach(() => { resetSharedCodexAppServerClientForTests(); vi.restoreAllMocks(); - mocks.bridgeCodexAppServerStartOptions.mockClear(); - mocks.resolveOpenClawAgentDir.mockClear(); + mocks.authBridge.startOptions.mockClear(); + mocks.providerAuth.agentDir.mockClear(); }); it("lists app-server models through the typed helper", async () => {