Skip to content

Commit e839bad

Browse files
committed
Add e2e test for gateway auth type
1 parent 5b8c4b2 commit e839bad

2 files changed

Lines changed: 74 additions & 18 deletions

File tree

src/__tests__/CodexACPAgent/e2e/acp-e2e-test-utils.ts

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,64 @@ export async function createAuthenticatedFixture(
7171
runtimePaths = createTemporaryRuntimePaths()
7272
): Promise<SpawnedAgentFixture> {
7373
const apiKey = requireLiveApiKey();
74+
return await createSpawnedFixture(async (connection, authMethods) => {
75+
if (!authMethods.some((method) => method.id === "api-key")) {
76+
throw new Error("API key authentication is not available.");
77+
}
78+
79+
await connection.authenticate({
80+
methodId: "api-key",
81+
_meta: {
82+
"api-key": {
83+
apiKey,
84+
},
85+
},
86+
});
87+
88+
const authenticationStatus = await getAuthenticationStatus(connection);
89+
if (authenticationStatus["type"] !== "api-key") {
90+
throw new Error(`Unexpected authentication status: ${JSON.stringify(authenticationStatus)}`);
91+
}
92+
}, runtimePaths);
93+
}
94+
95+
export interface GatewayFixtureOptions {
96+
readonly baseUrl: string;
97+
readonly headers?: Record<string, string>;
98+
}
99+
100+
export async function createGatewayFixture(
101+
options: GatewayFixtureOptions,
102+
runtimePaths = createTemporaryRuntimePaths(),
103+
): Promise<SpawnedAgentFixture> {
104+
return await createSpawnedFixture(async (connection, authMethods) => {
105+
if (!authMethods.some((method) => method.id === "gateway")) {
106+
throw new Error("Gateway authentication is not available.");
107+
}
108+
109+
await connection.authenticate({
110+
methodId: "gateway",
111+
_meta: {
112+
gateway: {
113+
baseUrl: options.baseUrl,
114+
headers: options.headers ?? {},
115+
},
116+
},
117+
});
118+
119+
const authenticationStatus = await getAuthenticationStatus(connection);
120+
if (authenticationStatus["type"] !== "gateway" || authenticationStatus["name"] !== "custom-gateway") {
121+
throw new Error(`Unexpected authentication status: ${JSON.stringify(authenticationStatus)}`);
122+
}
123+
}, runtimePaths);
124+
}
125+
126+
type Authenticator = (connection: acp.ClientSideConnection, authMethods: acp.AuthMethod[]) => Promise<void>;
127+
128+
async function createSpawnedFixture(
129+
authenticate: Authenticator,
130+
runtimePaths: RuntimePaths,
131+
): Promise<SpawnedAgentFixture> {
74132
const agentProcess = spawn("npm", ["run", "--silent", "start"], {
75133
cwd: process.cwd(),
76134
env: {
@@ -101,23 +159,7 @@ export async function createAuthenticatedFixture(
101159
throw new Error(`Unexpected protocol version: ${initializeResponse.protocolVersion}`);
102160
}
103161

104-
if (!initializeResponse.authMethods?.some((method) => method.id === "api-key")) {
105-
throw new Error("API key authentication is not available.");
106-
}
107-
108-
await connection.authenticate({
109-
methodId: "api-key",
110-
_meta: {
111-
"api-key": {
112-
apiKey,
113-
},
114-
},
115-
});
116-
117-
const authenticationStatus = await getAuthenticationStatus(connection);
118-
if (authenticationStatus["type"] !== "api-key") {
119-
throw new Error(`Unexpected authentication status: ${JSON.stringify(authenticationStatus)}`);
120-
}
162+
await authenticate(connection, initializeResponse.authMethods ?? []);
121163

122164
const createSession = async (): Promise<SpawnedSessionFixture> => {
123165
const newSessionResponse = await connection.newSession({
@@ -153,7 +195,7 @@ export async function createAuthenticatedFixture(
153195
};
154196
}
155197

156-
function requireLiveApiKey(): string {
198+
export function requireLiveApiKey(): string {
157199
const apiKey = process.env["CODEX_API_KEY"] ?? process.env["OPENAI_API_KEY"];
158200
if (!apiKey) {
159201
throw new Error("Live integration test requires CODEX_API_KEY or OPENAI_API_KEY.");

src/__tests__/CodexACPAgent/e2e/acp-e2e.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import {afterEach, expect, it} from "vitest";
22
import {
33
createAuthenticatedFixture,
44
createFixtureWithSkill,
5+
createGatewayFixture,
56
describeE2E,
7+
requireLiveApiKey,
68
type SpawnedAgentFixture,
79
} from "./acp-e2e-test-utils";
810

@@ -24,6 +26,18 @@ describeE2E("E2E tests", () => {
2426
});
2527
});
2628

29+
it('returns model response when authenticated via gateway', async () => {
30+
const apiKey = requireLiveApiKey();
31+
fixture = await createGatewayFixture({
32+
baseUrl: "https://api.openai.com/v1",
33+
headers: {Authorization: `Bearer ${apiKey}`},
34+
});
35+
const session = await fixture.createSession();
36+
await session.expectPromptText("Reply with exactly integration-ok and nothing else.", (text) => {
37+
expect(text.toLowerCase()).toContain("integration-ok");
38+
});
39+
});
40+
2741
it("uses the selected session model for subsequent prompts", async () => {
2842
fixture = await createAuthenticatedFixture();
2943
const session = await fixture.createSession();

0 commit comments

Comments
 (0)