test: expand auth fallback coverage

This commit is contained in:
Peter Steinberger
2026-01-13 04:12:02 +00:00
parent 7ce902b096
commit 32115a8b98
2 changed files with 40 additions and 0 deletions

View File

@@ -144,6 +144,26 @@ describe("runWithModelFallback", () => {
expect(run.mock.calls[1]?.[1]).toBe("claude-haiku-3-5");
});
it("falls back on lowercase credential errors", async () => {
const cfg = makeCfg();
const run = vi
.fn()
.mockRejectedValueOnce(new Error("no api key found for profile openai"))
.mockResolvedValueOnce("ok");
const result = await runWithModelFallback({
cfg,
provider: "openai",
model: "gpt-4.1-mini",
run,
});
expect(result.result).toBe("ok");
expect(run).toHaveBeenCalledTimes(2);
expect(run.mock.calls[1]?.[0]).toBe("anthropic");
expect(run.mock.calls[1]?.[1]).toBe("claude-haiku-3-5");
});
it("appends the configured primary as a last fallback", async () => {
const cfg = makeCfg({
agents: {

View File

@@ -5,6 +5,7 @@ import {
buildBootstrapContextFiles,
classifyFailoverReason,
formatAssistantErrorText,
isAuthErrorMessage,
isBillingErrorMessage,
isCloudCodeAssistFormatError,
isCompactionFailureError,
@@ -122,6 +123,23 @@ describe("isBillingErrorMessage", () => {
});
});
describe("isAuthErrorMessage", () => {
it("matches credential validation errors", () => {
const samples = [
'No credentials found for profile "anthropic:claude-cli".',
"No API key found for profile openai.",
];
for (const sample of samples) {
expect(isAuthErrorMessage(sample)).toBe(true);
}
});
it("ignores unrelated errors", () => {
expect(isAuthErrorMessage("rate limit exceeded")).toBe(false);
expect(isAuthErrorMessage("billing issue detected")).toBe(false);
});
});
describe("isFailoverErrorMessage", () => {
it("matches auth/rate/billing/timeout", () => {
const samples = [
@@ -140,6 +158,8 @@ describe("isFailoverErrorMessage", () => {
describe("classifyFailoverReason", () => {
it("returns a stable reason", () => {
expect(classifyFailoverReason("invalid api key")).toBe("auth");
expect(classifyFailoverReason("no credentials found")).toBe("auth");
expect(classifyFailoverReason("no api key found")).toBe("auth");
expect(classifyFailoverReason("429 too many requests")).toBe("rate_limit");
expect(classifyFailoverReason("resource has been exhausted")).toBe(
"rate_limit",