Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { ProviderExternalAuthProfile } from "../../plugins/types.js";
import {
__testing,
overlayExternalOAuthProfiles,
shouldPersistExternalOAuthProfile,
} from "./external-auth.js";
import type { AuthProfileStore, OAuthCredential } from "./types.js";
const resolveExternalAuthProfilesWithPluginsMock = vi.fn<
(params: unknown) => ProviderExternalAuthProfile[]
>(() => []);
const readCodexCliCredentialsCachedMock = vi.hoisted(() =>
vi.fn<() => OAuthCredential | null>(() => null),
);
vi.mock("../cli-credentials.js", () => ({
readCodexCliCredentialsCached: readCodexCliCredentialsCachedMock,
readMiniMaxCliCredentialsCached: () => null,
}));
function createStore(profiles: AuthProfileStore["profiles"] = {}): AuthProfileStore {
return { version: 1, profiles };
}
function createCredential(overrides: Partial<OAuthCredential> = {}): OAuthCredential {
return {
type: "oauth",
provider: "openai-codex",
access: "access-token",
refresh: "refresh-token",
expires: 123,
...overrides,
};
}
function createUsableOAuthExpiry(): number {
// Keep fixtures comfortably outside the shared near-expiry refresh margin.
return Date.now() + 30 * 60 * 1000;
}
describe("auth external oauth helpers", () => {
beforeEach(() => {
resolveExternalAuthProfilesWithPluginsMock.mockReset();
resolveExternalAuthProfilesWithPluginsMock.mockReturnValue([]);
readCodexCliCredentialsCachedMock.mockReset();
readCodexCliCredentialsCachedMock.mockReturnValue(null);
__testing.setResolveExternalAuthProfilesForTest(resolveExternalAuthProfilesWithPluginsMock);
});
afterEach(() => {
__testing.resetResolveExternalAuthProfilesForTest();
});
it("overlays provider-managed runtime oauth profiles onto the store", () => {
resolveExternalAuthProfilesWithPluginsMock.mockReturnValueOnce([
{
profileId: "openai-codex:default",
credential: createCredential(),
},
]);
const store = overlayExternalOAuthProfiles(createStore());
expect(store.profiles["openai-codex:default"]).toMatchObject({
type: "oauth",
provider: "openai-codex",
access: "access-token",
});
});
it("omits exact runtime-only overlays from persisted store writes", () => {
const credential = createCredential();
resolveExternalAuthProfilesWithPluginsMock.mockReturnValueOnce([
{
profileId: "openai-codex:default",
credential,
},
]);
const shouldPersist = shouldPersistExternalOAuthProfile({
store: createStore({ "openai-codex:default": credential }),
profileId: "openai-codex:default",
credential,
});
expect(shouldPersist).toBe(false);
});
it("keeps persisted copies when the external overlay is marked persisted", () => {
const credential = createCredential();
resolveExternalAuthProfilesWithPluginsMock.mockReturnValueOnce([
{
profileId: "openai-codex:default",
credential,
persistence: "persisted",
},
]);
const shouldPersist = shouldPersistExternalOAuthProfile({
store: createStore({ "openai-codex:default": credential }),
profileId: "openai-codex:default",
credential,
});
expect(shouldPersist).toBe(true);
});
it("keeps stale local copies when runtime overlay no longer matches", () => {
const credential = createCredential();
resolveExternalAuthProfilesWithPluginsMock.mockReturnValueOnce([
{
profileId: "openai-codex:default",
credential: createCredential({ access: "fresh-access-token" }),
},
]);
const shouldPersist = shouldPersistExternalOAuthProfile({
store: createStore({ "openai-codex:default": credential }),
profileId: "openai-codex:default",
credential,
});
expect(shouldPersist).toBe(true);
});
it("does not use Codex CLI OAuth as a runtime overlay source", () => {
readCodexCliCredentialsCachedMock.mockReturnValue(
createCredential({
access: "fresh-cli-access-token",
refresh: "fresh-cli-refresh-token",
expires: createUsableOAuthExpiry(),
accountId: "acct-cli",
}),
);
const overlaid = overlayExternalOAuthProfiles(
createStore({
"openai-codex:default": createCredential({
access: "stale-store-access-token",
refresh: "stale-store-refresh-token",
expires: Date.now() - 60_000,
accountId: "acct-cli",
}),
}),
);
expect(overlaid.profiles["openai-codex:default"]).toMatchObject({
access: "stale-store-access-token",
refresh: "stale-store-refresh-token",
accountId: "acct-cli",
});
});
it("keeps healthy local oauth even when external cli has a fresher token", () => {
readCodexCliCredentialsCachedMock.mockReturnValue(
createCredential({
access: "fresh-cli-access-token",
refresh: "fresh-cli-refresh-token",
expires: Date.now() + 5 * 24 * 60 * 60_000,
}),
);
const overlaid = overlayExternalOAuthProfiles(
createStore({
"openai-codex:default": createCredential({
access: "healthy-local-access-token",
refresh: "healthy-local-refresh-token",
expires: createUsableOAuthExpiry(),
}),
}),
);
expect(overlaid.profiles["openai-codex:default"]).toMatchObject({
access: "healthy-local-access-token",
refresh: "healthy-local-refresh-token",
});
});
it("keeps explicit local non-oauth auth over external cli oauth overlays", () => {
readCodexCliCredentialsCachedMock.mockReturnValue(
createCredential({
access: "fresh-cli-access-token",
refresh: "fresh-cli-refresh-token",
expires: Date.now() + 5 * 24 * 60 * 60_000,
}),
);
const overlaid = overlayExternalOAuthProfiles(
createStore({
"openai-codex:default": {
type: "api_key",
provider: "openai-codex",
key: "sk-local",
},
}),
);
expect(overlaid.profiles["openai-codex:default"]).toMatchObject({
type: "api_key",
provider: "openai-codex",
key: "sk-local",
});
});
it("keeps expired local oauth when external cli belongs to a different account", () => {
readCodexCliCredentialsCachedMock.mockReturnValue(
createCredential({
access: "fresh-cli-access-token",
refresh: "fresh-cli-refresh-token",
expires: createUsableOAuthExpiry(),
accountId: "acct-external",
}),
);
const overlaid = overlayExternalOAuthProfiles(
createStore({
"openai-codex:default": createCredential({
access: "expired-local-access-token",
refresh: "expired-local-refresh-token",
expires: Date.now() - 60_000,
accountId: "acct-local",
}),
}),
);
expect(overlaid.profiles["openai-codex:default"]).toMatchObject({
access: "expired-local-access-token",
refresh: "expired-local-refresh-token",
accountId: "acct-local",
});
});
});
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-04-27)
¤
*© Formatika GbR, Deutschland
|
|