refactor(test): simplify auth-profile-cooldowns tests with helpers

- Add makeStore() helper to eliminate repeated store object literals
- Add withTempDir() helper to eliminate try/finally boilerplate
- Merge cooldownKey edge cases into main describe block
- Remove redundant markAuthProfileCooldown test (covered by markAuthProfileFailure)
- Net reduction: 245 lines removed (57% smaller), 19→17 tests
This commit is contained in:
Bruno Guidolim 2026-01-29 01:04:26 +01:00
parent e3caf006bb
commit e954d29291

View File

@ -20,7 +20,6 @@ import {
clearAuthProfileCooldown,
cooldownKey,
isProfileInCooldown,
markAuthProfileCooldown,
markAuthProfileFailure,
markAuthProfileUsed,
saveAuthProfileStore,
@ -28,6 +27,24 @@ import {
import type { AuthProfileStore } from "./auth-profiles.js";
import { AUTH_STORE_VERSION } from "./auth-profiles/constants.js";
// Test helpers
const makeStore = (usageStats?: AuthProfileStore["usageStats"]): AuthProfileStore => ({
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
...(usageStats && { usageStats }),
});
async function withTempDir<T>(fn: (tempDir: string) => Promise<T>): Promise<T> {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
try {
return await fn(tempDir);
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
}
describe("auth profile cooldowns", () => {
it("applies exponential backoff with a 1h cap", () => {
expect(calculateAuthProfileCooldownMs(1)).toBe(60_000);
@ -39,9 +56,11 @@ describe("auth profile cooldowns", () => {
});
describe("cooldownKey", () => {
it("returns profileId when model is not provided", () => {
it("returns profileId when model is not provided or empty", () => {
expect(cooldownKey("openai:default")).toBe("openai:default");
expect(cooldownKey("openai:default", undefined)).toBe("openai:default");
expect(cooldownKey("openai:default", "")).toBe("openai:default");
expect(cooldownKey("openai:default", " ")).toBe("openai:default");
});
it("returns composite key when model is provided", () => {
@ -52,44 +71,20 @@ describe("cooldownKey", () => {
describe("isProfileInCooldown with per-model support", () => {
it("returns false when no cooldown exists", () => {
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
};
const store = makeStore();
expect(isProfileInCooldown(store, "openai:default")).toBe(false);
expect(isProfileInCooldown(store, "openai:default", "gpt-4")).toBe(false);
});
it("checks profile-level cooldown when model not provided", () => {
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
"openai:default": { cooldownUntil: Date.now() + 60_000 },
},
};
const store = makeStore({ "openai:default": { cooldownUntil: Date.now() + 60_000 } });
expect(isProfileInCooldown(store, "openai:default")).toBe(true);
});
it("checks per-model cooldown when model is provided", () => {
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
"openai:default:gpt-4": { cooldownUntil: Date.now() + 60_000 },
},
};
// model-specific cooldown exists
const store = makeStore({ "openai:default:gpt-4": { cooldownUntil: Date.now() + 60_000 } });
expect(isProfileInCooldown(store, "openai:default", "gpt-4")).toBe(true);
// different model is not in cooldown
expect(isProfileInCooldown(store, "openai:default", "gpt-3.5")).toBe(false);
// profile-level is not in cooldown
expect(isProfileInCooldown(store, "openai:default")).toBe(false);
});
@ -97,55 +92,31 @@ describe("isProfileInCooldown with per-model support", () => {
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"github-copilot:default": {
type: "api_key",
provider: "github-copilot",
key: "test",
},
},
usageStats: {
// gpt-5.2 is in cooldown (rate limited)
"github-copilot:default:gpt-5.2": { cooldownUntil: Date.now() + 60_000 },
// gpt-5-mini has no cooldown (unlimited quota)
"github-copilot:default": { type: "api_key", provider: "github-copilot", key: "test" },
},
usageStats: { "github-copilot:default:gpt-5.2": { cooldownUntil: Date.now() + 60_000 } },
};
expect(isProfileInCooldown(store, "github-copilot:default", "gpt-5.2")).toBe(true);
expect(isProfileInCooldown(store, "github-copilot:default", "gpt-5-mini")).toBe(false);
});
it("returns false when cooldown has expired", () => {
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
"openai:default:gpt-4": { cooldownUntil: Date.now() - 1000 }, // expired
},
};
const store = makeStore({ "openai:default:gpt-4": { cooldownUntil: Date.now() - 1000 } });
expect(isProfileInCooldown(store, "openai:default", "gpt-4")).toBe(false);
});
});
describe("markAuthProfileUsed with per-model support", () => {
it("clears per-model cooldown when model is provided", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
const cooldownTime = Date.now() + 60_000;
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
await withTempDir(async (tempDir) => {
const cooldownTime = Date.now() + 60_000;
const store = makeStore({
"openai:default": { cooldownUntil: cooldownTime },
"openai:default:gpt-4": { cooldownUntil: cooldownTime, errorCount: 3 },
"openai:default:gpt-3.5": { cooldownUntil: cooldownTime },
},
};
saveAuthProfileStore(store, tempDir);
});
saveAuthProfileStore(store, tempDir);
try {
// Mark gpt-4 as used (successful)
await markAuthProfileUsed({
store,
profileId: "openai:default",
@ -153,84 +124,41 @@ describe("markAuthProfileUsed with per-model support", () => {
agentDir: tempDir,
});
// Profile-level cooldown should be cleared
expect(store.usageStats?.["openai:default"]?.cooldownUntil).toBeUndefined();
// Per-model cooldown for gpt-4 should be cleared
expect(store.usageStats?.["openai:default:gpt-4"]?.cooldownUntil).toBeUndefined();
expect(store.usageStats?.["openai:default:gpt-4"]?.errorCount).toBe(0);
// Per-model cooldown for gpt-3.5 should remain (different model)
expect(store.usageStats?.["openai:default:gpt-3.5"]?.cooldownUntil).toBe(cooldownTime);
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});
it("only clears profile-level cooldown when model is not provided", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
const cooldownTime = Date.now() + 60_000;
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
await withTempDir(async (tempDir) => {
const cooldownTime = Date.now() + 60_000;
const store = makeStore({
"openai:default": { cooldownUntil: cooldownTime },
"openai:default:gpt-4": { cooldownUntil: cooldownTime },
},
};
saveAuthProfileStore(store, tempDir);
});
saveAuthProfileStore(store, tempDir);
try {
// Mark profile as used without specifying model
await markAuthProfileUsed({ store, profileId: "openai:default", agentDir: tempDir });
// Profile-level cooldown should be cleared
expect(store.usageStats?.["openai:default"]?.cooldownUntil).toBeUndefined();
// Per-model cooldown should remain (no model specified)
expect(store.usageStats?.["openai:default:gpt-4"]?.cooldownUntil).toBe(cooldownTime);
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});
describe("cooldownKey edge cases", () => {
it("treats empty string model the same as undefined", () => {
// Empty string should be treated as "no model" to avoid trailing colon
expect(cooldownKey("openai:default", "")).toBe("openai:default");
expect(cooldownKey("openai:default", " ")).toBe("openai:default");
});
});
});
describe("isProfileInCooldown backward compatibility", () => {
it("returns true for any model when profile-level cooldown exists", () => {
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
"openai:default": { cooldownUntil: Date.now() + 60_000 }, // profile-level only
},
};
// Any model should be blocked when profile-level cooldown exists
const store = makeStore({ "openai:default": { cooldownUntil: Date.now() + 60_000 } });
expect(isProfileInCooldown(store, "openai:default", "gpt-4")).toBe(true);
expect(isProfileInCooldown(store, "openai:default", "gpt-3.5")).toBe(true);
expect(isProfileInCooldown(store, "openai:default", "o1-preview")).toBe(true);
// Profile-level check also works
expect(isProfileInCooldown(store, "openai:default")).toBe(true);
});
it("checks disabledUntil for per-model cooldowns (billing failures)", () => {
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
"openai:default:gpt-4": { disabledUntil: Date.now() + 60_000 }, // billing failure
},
};
const store = makeStore({ "openai:default:gpt-4": { disabledUntil: Date.now() + 60_000 } });
expect(isProfileInCooldown(store, "openai:default", "gpt-4")).toBe(true);
expect(isProfileInCooldown(store, "openai:default", "gpt-3.5")).toBe(false);
});
@ -238,16 +166,10 @@ describe("isProfileInCooldown backward compatibility", () => {
describe("markAuthProfileFailure with per-model support", () => {
it("tracks failure per model when model is provided", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
};
saveAuthProfileStore(store, tempDir);
await withTempDir(async (tempDir) => {
const store = makeStore();
saveAuthProfileStore(store, tempDir);
try {
await markAuthProfileFailure({
store,
profileId: "openai:default",
@ -256,29 +178,18 @@ describe("markAuthProfileFailure with per-model support", () => {
agentDir: tempDir,
});
// Per-model key should have cooldown
expect(store.usageStats?.["openai:default:gpt-4"]?.cooldownUntil).toBeGreaterThan(Date.now());
expect(store.usageStats?.["openai:default:gpt-4"]?.errorCount).toBe(1);
// Profile-level should NOT have cooldown (only model-specific)
expect(store.usageStats?.["openai:default"]?.cooldownUntil).toBeUndefined();
// Other models should not be affected
expect(store.usageStats?.["openai:default:gpt-3.5"]).toBeUndefined();
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});
it("tracks failure at profile level when model is not provided", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
};
saveAuthProfileStore(store, tempDir);
await withTempDir(async (tempDir) => {
const store = makeStore();
saveAuthProfileStore(store, tempDir);
try {
await markAuthProfileFailure({
store,
profileId: "openai:default",
@ -286,25 +197,16 @@ describe("markAuthProfileFailure with per-model support", () => {
agentDir: tempDir,
});
// Profile-level key should have cooldown
expect(store.usageStats?.["openai:default"]?.cooldownUntil).toBeGreaterThan(Date.now());
expect(store.usageStats?.["openai:default"]?.errorCount).toBe(1);
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});
it("tracks billing failures with disabledUntil per model", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
};
saveAuthProfileStore(store, tempDir);
await withTempDir(async (tempDir) => {
const store = makeStore();
saveAuthProfileStore(store, tempDir);
try {
await markAuthProfileFailure({
store,
profileId: "openai:default",
@ -313,62 +215,23 @@ describe("markAuthProfileFailure with per-model support", () => {
agentDir: tempDir,
});
// Billing failures use disabledUntil instead of cooldownUntil
expect(store.usageStats?.["openai:default:gpt-4"]?.disabledUntil).toBeGreaterThan(Date.now());
expect(store.usageStats?.["openai:default:gpt-4"]?.disabledReason).toBe("billing");
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});
describe("markAuthProfileCooldown with per-model support", () => {
it("marks cooldown per model when model is provided", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
};
saveAuthProfileStore(store, tempDir);
try {
await markAuthProfileCooldown({
store,
profileId: "openai:default",
model: "gpt-4",
agentDir: tempDir,
});
// Per-model key should have cooldown
expect(store.usageStats?.["openai:default:gpt-4"]?.cooldownUntil).toBeGreaterThan(Date.now());
// Profile-level should NOT have cooldown
expect(store.usageStats?.["openai:default"]?.cooldownUntil).toBeUndefined();
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});
});
describe("clearAuthProfileCooldown with per-model support", () => {
it("clears per-model cooldown when model is provided", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
const cooldownTime = Date.now() + 60_000;
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
await withTempDir(async (tempDir) => {
const cooldownTime = Date.now() + 60_000;
const store = makeStore({
"openai:default": { cooldownUntil: cooldownTime },
"openai:default:gpt-4": { cooldownUntil: cooldownTime, errorCount: 3 },
"openai:default:gpt-3.5": { cooldownUntil: cooldownTime },
},
};
saveAuthProfileStore(store, tempDir);
});
saveAuthProfileStore(store, tempDir);
try {
await clearAuthProfileCooldown({
store,
profileId: "openai:default",
@ -376,47 +239,27 @@ describe("clearAuthProfileCooldown with per-model support", () => {
agentDir: tempDir,
});
// Per-model cooldown for gpt-4 should be cleared
expect(store.usageStats?.["openai:default:gpt-4"]?.cooldownUntil).toBeUndefined();
expect(store.usageStats?.["openai:default:gpt-4"]?.errorCount).toBe(0);
// Profile-level cooldown should remain (different key)
expect(store.usageStats?.["openai:default"]?.cooldownUntil).toBe(cooldownTime);
// Other model cooldown should remain
expect(store.usageStats?.["openai:default:gpt-3.5"]?.cooldownUntil).toBe(cooldownTime);
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});
it("clears profile-level cooldown when model is not provided", async () => {
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "moltbot-auth-"));
const cooldownTime = Date.now() + 60_000;
const store: AuthProfileStore = {
version: AUTH_STORE_VERSION,
profiles: {
"openai:default": { type: "api_key", provider: "openai", key: "test" },
},
usageStats: {
await withTempDir(async (tempDir) => {
const cooldownTime = Date.now() + 60_000;
const store = makeStore({
"openai:default": { cooldownUntil: cooldownTime, errorCount: 2 },
"openai:default:gpt-4": { cooldownUntil: cooldownTime },
},
};
saveAuthProfileStore(store, tempDir);
try {
await clearAuthProfileCooldown({
store,
profileId: "openai:default",
agentDir: tempDir,
});
saveAuthProfileStore(store, tempDir);
await clearAuthProfileCooldown({ store, profileId: "openai:default", agentDir: tempDir });
// Profile-level cooldown should be cleared
expect(store.usageStats?.["openai:default"]?.cooldownUntil).toBeUndefined();
expect(store.usageStats?.["openai:default"]?.errorCount).toBe(0);
// Per-model cooldown should remain (different key)
expect(store.usageStats?.["openai:default:gpt-4"]?.cooldownUntil).toBe(cooldownTime);
} finally {
await fs.rm(tempDir, { recursive: true, force: true });
}
});
});
});