Files
openclaw/extensions/openai/base-url.test.ts
Peter Steinberger 1b1cebfe42 fix(openai): align auth availability with effective routes (#104685)
* feat(openai): add provider-owned route facts

* fix(openai): harden provider route facts

* test(codex): update rebased auth fixtures

* chore: leave release notes to release workflow

* fix(openai): align route auth with current contracts

* test(openai): align route and shard expectations

* test(openai): satisfy route fixture contracts

* fix(openai): preserve direct profile forwarding

* test(models): complete route auth mocks

* test(codex): type compaction factory mock

* fix(openai): preserve provider-native model ids

* test(agents): align route auth fixtures

* style(agents): format route integrations

* test(plugin-sdk): pin current surface counts
2026-07-11 15:26:48 -07:00

119 lines
5.6 KiB
TypeScript

// Openai tests cover base url plugin behavior.
import { describe, expect, it } from "vitest";
import {
canonicalizeCodexResponsesBaseUrl,
classifyOpenAIBaseUrl,
isOpenAIApiBaseUrl,
isOpenAICodexBaseUrl,
isOpenAIHttpsApiBaseUrl,
OPENAI_API_BASE_URL,
OPENAI_CODEX_RESPONSES_BASE_URL,
resolveOpenAIDefaultBaseUrl,
} from "./base-url.js";
describe("openai base URL helpers", () => {
it("recognizes direct OpenAI API routes", () => {
expect(isOpenAIApiBaseUrl("http://api.openai.com/v1")).toBe(false);
expect(isOpenAIApiBaseUrl("https://api.openai.com")).toBe(true);
expect(isOpenAIApiBaseUrl("https://api.openai.com/v1")).toBe(true);
expect(isOpenAIApiBaseUrl("https://api.openai.com/v1/")).toBe(true);
expect(isOpenAIApiBaseUrl("https://api.openai.com:443/v1")).toBe(true);
expect(isOpenAIApiBaseUrl("https://api.openai.com./v1")).toBe(true);
});
it("rejects proxy or unrelated API routes", () => {
expect(isOpenAIApiBaseUrl("ftp://api.openai.com/v1")).toBe(false);
expect(isOpenAIApiBaseUrl("https://proxy.example.com/v1")).toBe(false);
expect(isOpenAIApiBaseUrl("https://chatgpt.com/backend-api")).toBe(false);
expect(isOpenAIApiBaseUrl(undefined)).toBe(false);
});
it("limits native transport hooks to HTTPS official routes", () => {
expect(isOpenAIHttpsApiBaseUrl("https://api.openai.com/v1")).toBe(true);
expect(isOpenAIHttpsApiBaseUrl("http://api.openai.com/v1")).toBe(false);
});
it("classifies exact HTTPS native endpoints as official", () => {
expect(classifyOpenAIBaseUrl(undefined)).toBe("unresolved");
expect(classifyOpenAIBaseUrl("https://api.openai.com/v1")).toBe("platform");
expect(classifyOpenAIBaseUrl("https://api.openai.com:443/v1")).toBe("platform");
expect(classifyOpenAIBaseUrl("https://api.openai.com./v1")).toBe("platform");
expect(classifyOpenAIBaseUrl("https://chatgpt.com/backend-api/codex/responses")).toBe(
"chatgpt",
);
expect(classifyOpenAIBaseUrl("https://proxy.example.test/v1?tenant=one")).toBe("custom");
for (const invalid of [
"ftp://api.openai.com/v1",
"http://api.openai.com/v1",
"http://chatgpt.com/backend-api/codex",
"https://api.openai.com:8443/v1",
"http://api.openai.com:443/v1",
"https://user@api.openai.com/v1",
"https://api.openai.com/v1/models",
"https://api.openai.com/v1?proxy=1",
"https://chatgpt.com/backend-api/codex#fragment",
"not a URL",
]) {
expect(classifyOpenAIBaseUrl(invalid)).toBe("invalid");
}
});
it("recognizes Codex ChatGPT backend routes", () => {
// New canonical form (includes /codex segment; OpenAI removed the
// /backend-api/responses alias server-side on 2026-04).
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/codex")).toBe(true);
expect(isOpenAICodexBaseUrl("http://chatgpt.com/backend-api/codex")).toBe(false);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/codex/")).toBe(true);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/codex/v1")).toBe(true);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/codex/v1/")).toBe(true);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/codex/responses")).toBe(true);
expect(isOpenAICodexBaseUrl("https://chatgpt.com:443/backend-api/codex")).toBe(true);
expect(isOpenAICodexBaseUrl("https://chatgpt.com./backend-api/codex")).toBe(true);
// Legacy form still recognized as a Codex baseURL for backward
// compatibility with existing user configs.
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api")).toBe(true);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/")).toBe(true);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/v1")).toBe(true);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/v1/")).toBe(true);
});
it("rejects non-Codex backend routes", () => {
expect(isOpenAICodexBaseUrl("ftp://chatgpt.com/backend-api/codex")).toBe(false);
expect(isOpenAICodexBaseUrl("https://api.openai.com/v1")).toBe(false);
expect(isOpenAICodexBaseUrl("https://chatgpt.com")).toBe(false);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/v2")).toBe(false);
expect(isOpenAICodexBaseUrl("https://chatgpt.com/backend-api/codex/v2")).toBe(false);
expect(isOpenAICodexBaseUrl(undefined)).toBe(false);
});
it("canonicalizes legacy Codex Responses base URLs", () => {
expect(canonicalizeCodexResponsesBaseUrl("https://chatgpt.com/backend-api")).toBe(
OPENAI_CODEX_RESPONSES_BASE_URL,
);
expect(canonicalizeCodexResponsesBaseUrl("https://chatgpt.com/backend-api/v1")).toBe(
OPENAI_CODEX_RESPONSES_BASE_URL,
);
expect(canonicalizeCodexResponsesBaseUrl("https://chatgpt.com/backend-api/codex/v1")).toBe(
OPENAI_CODEX_RESPONSES_BASE_URL,
);
expect(
canonicalizeCodexResponsesBaseUrl("https://chatgpt.com/backend-api/codex/responses"),
).toBe(OPENAI_CODEX_RESPONSES_BASE_URL);
expect(canonicalizeCodexResponsesBaseUrl("http://chatgpt.com/backend-api/codex")).toBe(
"http://chatgpt.com/backend-api/codex",
);
expect(canonicalizeCodexResponsesBaseUrl("https://proxy.example.com/v1")).toBe(
"https://proxy.example.com/v1",
);
expect(canonicalizeCodexResponsesBaseUrl(undefined)).toBeUndefined();
});
it("resolves default API base URL from OPENAI_BASE_URL", () => {
expect(resolveOpenAIDefaultBaseUrl({})).toBe(OPENAI_API_BASE_URL);
expect(resolveOpenAIDefaultBaseUrl({ OPENAI_BASE_URL: " " })).toBe(OPENAI_API_BASE_URL);
expect(resolveOpenAIDefaultBaseUrl({ OPENAI_BASE_URL: " https://proxy.example/v1 " })).toBe(
"https://proxy.example/v1",
);
});
});