test: add 5 new test files for DB modules and usage utils

- db-apiKeys-crud.test.ts: 54 tests (API key lifecycle, validation, caching)
- db-core.test.ts: 40 tests (core DB helpers, row conversion, encryption)
- db-domainState-crud.test.ts: 32 tests (domain state, circuit breakers)
- db-registeredKeys-crud.test.ts: 26 tests (key registration, rotation)
- usage-utils.test.ts: 43 tests (parseResetTime, quota snapshots, plan inference)

Total: 195 new test cases, all passing
This commit is contained in:
oyi77
2026-06-01 03:29:50 +07:00
parent 51d66eadee
commit 54ca6ba9b6
5 changed files with 1875 additions and 0 deletions

View File

@@ -0,0 +1,542 @@
/**
* Tests for src/lib/db/apiKeys.ts — API key lifecycle, validation, caching, wildcard matching.
*
* Coverage targets:
* - createApiKey, getApiKeys, getApiKeyById
* - validateApiKey (env key, DB-backed, cache, banned/revoked/expired/inactive)
* - getApiKeyMetadata (env key, DB-backed, cache)
* - isModelAllowedForKey (no restrictions, exact, prefix, wildcard, group deny)
* - updateApiKeyPermissions (all field types, scopes with transaction)
* - deleteApiKey, revokeApiKey, setApiKeyExpiry, regenerateApiKey
* - clearApiKeyCaches, resetApiKeyState
* - matchesWildcardPattern (unit-level)
*/
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-db-apikeys-"));
process.env.DATA_DIR = TEST_DATA_DIR;
process.env.API_KEY_SECRET = "test-api-key-secret-for-crc-operations-do-not-use-in-prod";
const core = await import("../../src/lib/db/core.ts");
const apiKeys = await import("../../src/lib/db/apiKeys.ts");
async function resetStorage() {
apiKeys.resetApiKeyState();
core.resetDbInstance();
for (let attempt = 0; attempt < 10; attempt++) {
try {
if (fs.existsSync(TEST_DATA_DIR)) {
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
}
break;
} catch {
await new Promise((r) => setTimeout(r, 50 * (attempt + 1)));
}
}
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
core.getDbInstance();
}
await resetStorage();
// ──────────────── createApiKey ────────────────
test("createApiKey creates a key and returns it with id, key, name, machineId", async () => {
await resetStorage();
const key = await apiKeys.createApiKey("Test Key", "machine-001");
assert.ok(key.id);
assert.ok(key.key);
assert.ok(key.key.startsWith("omni_") || key.key.length > 0);
assert.equal(key.name, "Test Key");
assert.equal(key.machineId, "machine-001");
});
test("createApiKey with scopes stores them", async () => {
await resetStorage();
const key = await apiKeys.createApiKey("Scoped Key", "machine-002", ["read", "write"]);
assert.ok(key.id);
assert.deepEqual(key.scopes, ["read", "write"]);
});
test("createApiKey rejects empty machineId", async () => {
await resetStorage();
await assert.rejects(
() => apiKeys.createApiKey("Bad Key", ""),
{ message: /machineId is required/i }
);
});
// ──────────────── getApiKeys ────────────────
test("getApiKeys returns empty array when no keys exist", async () => {
await resetStorage();
const keys = await apiKeys.getApiKeys();
assert.deepEqual(keys, []);
});
test("getApiKeys returns all created keys", async () => {
await resetStorage();
await apiKeys.createApiKey("Key A", "ma-001");
await apiKeys.createApiKey("Key B", "ma-002");
const all = await apiKeys.getApiKeys();
assert.equal(all.length, 2);
const names = all.map((k) => k.name).sort();
assert.deepEqual(names, ["Key A", "Key B"]);
});
// ──────────────── getApiKeyById ────────────────
test("getApiKeyById returns key by id", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Find Me", "ma-003");
const loaded = await apiKeys.getApiKeyById(created.id);
assert.ok(loaded !== null);
assert.equal(loaded!.name, "Find Me");
assert.equal(loaded!.id, created.id);
assert.equal(loaded!.machineId, "ma-003");
});
test("getApiKeyById returns null for missing id", async () => {
await resetStorage();
const loaded = await apiKeys.getApiKeyById("no-such-id");
assert.equal(loaded, null);
});
// ──────────────── validateApiKey ────────────────
test("validateApiKey returns false for null / undefined / empty", async () => {
await resetStorage();
assert.equal(await apiKeys.validateApiKey(null), false);
assert.equal(await apiKeys.validateApiKey(undefined), false);
assert.equal(await apiKeys.validateApiKey(""), false);
});
test("validateApiKey returns true for env key", async () => {
await resetStorage();
const prev = process.env.OMNIROUTE_API_KEY;
process.env.OMNIROUTE_API_KEY = "env-key-test-abc123";
try {
assert.equal(await apiKeys.validateApiKey("env-key-test-abc123"), true);
} finally {
process.env.OMNIROUTE_API_KEY = prev;
}
});
test("validateApiKey returns true for valid key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Valid Key", "ma-004");
assert.equal(await apiKeys.validateApiKey(created.key), true);
});
test("validateApiKey returns false for non-existent key", async () => {
await resetStorage();
assert.equal(await apiKeys.validateApiKey("omni_nonexistent_key_abc123"), false);
});
test("validateApiKey returns false for banned key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Banned Soon", "ma-005");
await apiKeys.updateApiKeyPermissions(created.id, { isBanned: true });
// Caches may still hold the old valid state — validateApiKey should check DB
// after cache miss; call resetApiKeyState() to clear caches for a fresh read.
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.validateApiKey(created.key), false);
});
test("validateApiKey returns false for revoked key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Revoked Soon", "ma-006");
await apiKeys.revokeApiKey(created.id);
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.validateApiKey(created.key), false);
});
test("validateApiKey returns false for expired key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Expiring Soon", "ma-007");
await apiKeys.setApiKeyExpiry(created.id, "2020-01-01T00:00:00Z");
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.validateApiKey(created.key), false);
});
test("validateApiKey returns false for inactive key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Inactive Soon", "ma-008");
await apiKeys.updateApiKeyPermissions(created.id, { isActive: false });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.validateApiKey(created.key), false);
});
// ──────────────── getApiKeyMetadata ────────────────
test("getApiKeyMetadata returns null for null / undefined / empty", async () => {
await resetStorage();
assert.equal(await apiKeys.getApiKeyMetadata(null), null);
assert.equal(await apiKeys.getApiKeyMetadata(undefined), null);
assert.equal(await apiKeys.getApiKeyMetadata(""), null);
});
test("getApiKeyMetadata returns env-key record for env key", async () => {
await resetStorage();
const prev = process.env.OMNIROUTE_API_KEY;
process.env.OMNIROUTE_API_KEY = "env-key-meta-001";
try {
const meta = await apiKeys.getApiKeyMetadata("env-key-meta-001");
assert.ok(meta !== null);
assert.equal(meta!.id, "env-key");
assert.equal(meta!.name, "Environment Key");
assert.ok(meta!.scopes.includes("manage"));
assert.equal(meta!.isActive, true);
} finally {
process.env.OMNIROUTE_API_KEY = prev;
}
});
test("getApiKeyMetadata returns metadata for valid key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Meta Key", "ma-009");
const meta = await apiKeys.getApiKeyMetadata(created.key);
assert.ok(meta !== null);
assert.equal(meta!.id, created.id);
assert.equal(meta!.name, "Meta Key");
assert.equal(meta!.machineId, "ma-009");
assert.deepEqual(meta!.allowedModels, []);
assert.equal(meta!.noLog, false);
assert.equal(meta!.isActive, true);
});
test("getApiKeyMetadata returns null for non-existent key", async () => {
await resetStorage();
assert.equal(await apiKeys.getApiKeyMetadata("omni_meta_nonexistent"), null);
});
// ──────────────── isModelAllowedForKey ────────────────
test("isModelAllowedForKey returns true when no key provided", async () => {
await resetStorage();
assert.equal(await apiKeys.isModelAllowedForKey(null, "gpt-4"), true);
assert.equal(await apiKeys.isModelAllowedForKey(undefined, "gpt-4"), true);
});
test("isModelAllowedForKey returns false when no modelId provided", async () => {
await resetStorage();
assert.equal(await apiKeys.isModelAllowedForKey("some-key", null), false);
assert.equal(await apiKeys.isModelAllowedForKey("some-key", undefined), false);
});
test("isModelAllowedForKey returns false for non-existent key", async () => {
await resetStorage();
assert.equal(await apiKeys.isModelAllowedForKey("omni_bogus_key", "gpt-4"), false);
});
test("isModelAllowedForKey returns true when allowedModels is unrestricted (empty)", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Unrestricted", "ma-010");
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "gpt-4"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "claude-opus-4"), true);
});
test("isModelAllowedForKey exact match", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Exact", "ma-011");
await apiKeys.updateApiKeyPermissions(created.id, { allowedModels: ["gpt-4", "claude-3"] });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "gpt-4"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "claude-3"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "gpt-5"), false);
});
test("isModelAllowedForKey prefix match (/*)", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Prefix", "ma-012");
await apiKeys.updateApiKeyPermissions(created.id, { allowedModels: ["openai/*"] });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/gpt-4"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/gpt-5"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "anthropic/claude-3"), false);
});
test("isModelAllowedForKey wildcard match", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Wildcard", "ma-013");
// Pattern "gpt-*-turbo" should match "gpt-4-turbo" but not "gpt-4"
await apiKeys.updateApiKeyPermissions(created.id, { allowedModels: ["gpt-*-turbo"] });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "gpt-4-turbo"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "gpt-4"), false);
});
// ──────────────── updateApiKeyPermissions ────────────────
test("updateApiKeyPermissions updates name", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Old Name", "ma-020");
const result = await apiKeys.updateApiKeyPermissions(created.id, { name: "New Name" });
assert.equal(result, true);
const loaded = await apiKeys.getApiKeyById(created.id);
assert.equal(loaded!.name, "New Name");
});
test("updateApiKeyPermissions toggles isActive", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Toggle Key", "ma-021");
assert.equal((await apiKeys.getApiKeyById(created.id))!.isActive, true);
await apiKeys.updateApiKeyPermissions(created.id, { isActive: false });
assert.equal((await apiKeys.getApiKeyById(created.id))!.isActive, false);
await apiKeys.updateApiKeyPermissions(created.id, { isActive: true });
assert.equal((await apiKeys.getApiKeyById(created.id))!.isActive, true);
});
test("updateApiKeyPermissions toggles noLog", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("NoLog Key", "ma-022");
await apiKeys.updateApiKeyPermissions(created.id, { noLog: true });
assert.equal((await apiKeys.getApiKeyById(created.id))!.noLog, true);
});
test("updateApiKeyPermissions sets isBanned", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Ban Key", "ma-023");
await apiKeys.updateApiKeyPermissions(created.id, { isBanned: true });
assert.equal((await apiKeys.getApiKeyById(created.id))!.isBanned, true);
await apiKeys.updateApiKeyPermissions(created.id, { isBanned: false });
assert.equal((await apiKeys.getApiKeyById(created.id))!.isBanned, false);
});
test("updateApiKeyPermissions sets accessSchedule", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Scheduled", "ma-024");
const schedule = {
enabled: true,
from: "09:00",
until: "17:00",
days: [1, 2, 3, 4, 5],
tz: "America/New_York",
};
await apiKeys.updateApiKeyPermissions(created.id, { accessSchedule: schedule });
const loaded = await apiKeys.getApiKeyById(created.id);
assert.deepEqual(loaded!.accessSchedule, schedule);
});
test("updateApiKeyPermissions clears accessSchedule with null", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Clear Schedule", "ma-025");
await apiKeys.updateApiKeyPermissions(created.id, {
accessSchedule: { enabled: true, from: "00:00", until: "23:59", days: [0], tz: "UTC" },
});
assert.ok((await apiKeys.getApiKeyById(created.id))!.accessSchedule !== null);
await apiKeys.updateApiKeyPermissions(created.id, { accessSchedule: null });
assert.equal((await apiKeys.getApiKeyById(created.id))!.accessSchedule, null);
});
test("updateApiKeyPermissions sets rateLimits", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Rate Limited", "ma-026");
const limits = [{ limit: 100, window: 60 }, { limit: 1000, window: 3600 }];
await apiKeys.updateApiKeyPermissions(created.id, { rateLimits: limits });
const loaded = await apiKeys.getApiKeyById(created.id);
assert.deepEqual(loaded!.rateLimits, limits);
});
test("updateApiKeyPermissions sets maxSessions", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Session Limit", "ma-027");
await apiKeys.updateApiKeyPermissions(created.id, { maxSessions: 5 });
// maxSessions is not exposed in the getApiKeyById return type directly,
// but is part of metadata — verify via getApiKeyMetadata
const meta = await apiKeys.getApiKeyMetadata(created.key);
assert.ok(meta);
assert.equal(meta!.maxSessions, 5);
});
test("updateApiKeyPermissions with legacy array format sets allowedModels", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Legacy Format", "ma-028");
const result = await apiKeys.updateApiKeyPermissions(created.id, ["model-a", "model-b"]);
assert.equal(result, true);
const loaded = await apiKeys.getApiKeyById(created.id);
assert.deepEqual(loaded!.allowedModels, ["model-a", "model-b"]);
});
test("updateApiKeyPermissions updates scopes", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Scopes Update", "ma-029");
const result = await apiKeys.updateApiKeyPermissions(created.id, { scopes: ["read", "manage"] });
assert.equal(result, true);
const loaded = await apiKeys.getApiKeyById(created.id);
assert.deepEqual(loaded!.scopes, ["read", "manage"]);
});
test("updateApiKeyPermissions empty update returns false", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("No Changes", "ma-030");
const result = await apiKeys.updateApiKeyPermissions(created.id, {});
assert.equal(result, false);
});
test("updateApiKeyPermissions non-existent id returns false", async () => {
await resetStorage();
const result = await apiKeys.updateApiKeyPermissions("no-such-key", {
name: "Wont Work",
});
assert.equal(result, false);
});
// ──────────────── deleteApiKey ────────────────
test("deleteApiKey deletes existing key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Delete Me", "ma-040");
const result = await apiKeys.deleteApiKey(created.id);
assert.equal(result, true);
const loaded = await apiKeys.getApiKeyById(created.id);
assert.equal(loaded, null);
});
test("deleteApiKey non-existent id returns false", async () => {
await resetStorage();
const result = await apiKeys.deleteApiKey("no-such-id");
assert.equal(result, false);
});
// ──────────────── revokeApiKey ────────────────
test("revokeApiKey revokes existing key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Revoke Me", "ma-050");
const result = await apiKeys.revokeApiKey(created.id);
assert.equal(result, true);
const loaded = await apiKeys.getApiKeyById(created.id);
assert.ok(loaded !== null);
assert.equal(loaded!.isActive, false);
assert.ok(loaded!.revokedAt);
});
test("revokeApiKey non-existent id returns false", async () => {
await resetStorage();
assert.equal(await apiKeys.revokeApiKey("no-such-id"), false);
});
test("revokeApiKey double revoke is idempotent", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Double Revoke", "ma-051");
assert.equal(await apiKeys.revokeApiKey(created.id), true);
assert.equal(await apiKeys.revokeApiKey(created.id), true);
});
// ──────────────── setApiKeyExpiry ────────────────
test("setApiKeyExpiry sets expiry on existing key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Expiry Test", "ma-060");
const result = await apiKeys.setApiKeyExpiry(created.id, "2030-12-31T23:59:59Z");
assert.equal(result, true);
const meta = await apiKeys.getApiKeyMetadata(created.key);
assert.ok(meta);
assert.equal(meta!.expiresAt, "2030-12-31T23:59:59Z");
});
test("setApiKeyExpiry clears expiry with null", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Clear Expiry", "ma-061");
await apiKeys.setApiKeyExpiry(created.id, "2030-01-01T00:00:00Z");
await apiKeys.setApiKeyExpiry(created.id, null);
const meta = await apiKeys.getApiKeyMetadata(created.key);
assert.ok(meta);
assert.equal(meta!.expiresAt, null);
});
test("setApiKeyExpiry non-existent id returns false", async () => {
await resetStorage();
assert.equal(await apiKeys.setApiKeyExpiry("no-such-id", "2030-01-01T00:00:00Z"), false);
});
// ──────────────── regenerateApiKey ────────────────
test("regenerateApiKey regenerates key", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Regen Key", "ma-070");
const oldKey = created.key;
const result = await apiKeys.regenerateApiKey(created.id);
assert.ok(result !== null);
assert.equal(result!.id, created.id);
assert.ok(result!.key);
assert.notEqual(result!.key, oldKey);
});
test("regenerateApiKey non-existent id returns null", async () => {
await resetStorage();
assert.equal(await apiKeys.regenerateApiKey("no-such-id"), null);
});
// ──────────────── clearApiKeyCaches / resetApiKeyState ────────────────
test("clearApiKeyCaches and resetApiKeyState do not throw", async () => {
await resetStorage();
// Fill caches with some activity
const created = await apiKeys.createApiKey("Cache Test", "ma-080");
await apiKeys.validateApiKey(created.key);
await apiKeys.getApiKeyMetadata(created.key);
// Should not throw
apiKeys.clearApiKeyCaches();
apiKeys.resetApiKeyState();
assert.ok(true);
});
// ──────────────── matchesWildcardPattern (unit-level) ────────────────
test("matchesWildcardPattern exact match", async () => {
// Directly test the underlying function logic via isModelAllowedForKey
await resetStorage();
const created = await apiKeys.createApiKey("Wild Exact", "ma-090");
await apiKeys.updateApiKeyPermissions(created.id, { allowedModels: ["openai/gpt-4"] });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/gpt-4"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/claude"), false);
});
test("isModelAllowedForKey segment count mismatch via matchesWildcardPattern", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Wild Segments", "ma-091");
await apiKeys.updateApiKeyPermissions(created.id, { allowedModels: ["openai/gpt-*"] });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/gpt-4"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/gpt-4/sub"), false);
});
test("matchesWildcardPattern wildcard within segment", async () => {
// Pattern "gpt-*-turbo" should match "gpt-4-turbo" but not "gpt-4"
await resetStorage();
const created = await apiKeys.createApiKey("Wild Within", "ma-092");
await apiKeys.updateApiKeyPermissions(created.id, { allowedModels: ["gpt-*-turbo"] });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "gpt-4-turbo"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "gpt-5-turbo"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "gpt-4"), false);
});
test("matchesWildcardPattern pattern with only *", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Wild Star", "ma-093");
await apiKeys.updateApiKeyPermissions(created.id, { allowedModels: ["openai/*"] });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/anything"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/"), true);
});
test("matchesWildcardPattern multiple segments with wildcards", async () => {
await resetStorage();
const created = await apiKeys.createApiKey("Wild Multi", "ma-094");
await apiKeys.updateApiKeyPermissions(created.id, { allowedModels: ["openai/*/turbo"] });
apiKeys.resetApiKeyState();
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/gpt-4/turbo"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/gpt-5/turbo"), true);
assert.equal(await apiKeys.isModelAllowedForKey(created.key, "openai/gpt-4"), false);
});

361
tests/unit/db-core.test.ts Normal file
View File

@@ -0,0 +1,361 @@
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
const serial = { concurrency: false };
function makeTempDir(prefix: string): string {
return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
}
function removePath(targetPath: string) {
fs.rmSync(targetPath, { recursive: true, force: true });
}
const originalEnv = {
DATA_DIR: process.env.DATA_DIR,
NEXT_PHASE: process.env.NEXT_PHASE,
};
function restoreEnv() {
for (const [key, value] of Object.entries(originalEnv)) {
if (value === undefined) {
delete process.env[key];
} else {
process.env[key] = value;
}
}
}
function cleanupGlobalDb() {
try {
if ((globalThis as any).__omnirouteDb?.open) {
(globalThis as any).__omnirouteDb.close();
}
} catch {}
delete (globalThis as any).__omnirouteDb;
}
async function importFresh(modulePath: string) {
const url = pathToFileURL(path.resolve(modulePath)).href;
return import(`${url}?test=${Date.now()}-${Math.random().toString(16).slice(2)}`);
}
async function withEnv(overrides: Record<string, string | undefined>, fn: () => Promise<void>) {
const snapshot: Record<string, string | undefined> = {};
for (const key of Object.keys(overrides)) {
snapshot[key] = process.env[key];
const value = overrides[key];
if (value === undefined) {
delete process.env[key];
} else {
process.env[key] = value;
}
}
try {
return await fn();
} finally {
for (const [key, value] of Object.entries(snapshot)) {
if (value === undefined) {
delete process.env[key];
} else {
process.env[key] = value;
}
}
}
}
// ──────────────── Pure Utility Functions ────────────────
test("toSnakeCase converts camelCase to snake_case", () => {
// Import once at module level for pure functions
// We use a lazy import pattern
});
// We'll use a single import for the module
let core: any;
test.before(async () => {
const dataDir = makeTempDir("omniroute-db-core-utils-");
try {
await withEnv({ DATA_DIR: dataDir }, async () => {
core = await importFresh("src/lib/db/core.ts");
// Initialize DB so DB functions work too
core.getDbInstance();
});
} catch {
removePath(dataDir);
}
});
test.after(() => {
try {
core?.resetDbInstance();
} catch {}
cleanupGlobalDb();
restoreEnv();
});
// ─── toSnakeCase ───────────────────────────────────────
test("toSnakeCase: basic camelCase conversion", () => {
assert.equal(core.toSnakeCase("apiKey"), "api_key");
assert.equal(core.toSnakeCase("isActive"), "is_active");
assert.equal(core.toSnakeCase("providerName"), "provider_name");
});
test("toSnakeCase: empty string and single word", () => {
assert.equal(core.toSnakeCase(""), "");
assert.equal(core.toSnakeCase("name"), "name");
assert.equal(core.toSnakeCase("id"), "id");
});
test("toSnakeCase: consecutive uppercase (acronyms)", () => {
// The implementation inserts _ before each uppercase including the first
// character, then lowercases. So "APIKey" → "_a_p_i_key".
assert.equal(core.toSnakeCase("APIKey"), "_a_p_i_key");
assert.equal(core.toSnakeCase("DBConnection"), "_d_b_connection");
});
test("toSnakeCase: already snake_case stays same", () => {
assert.equal(core.toSnakeCase("already_snake"), "already_snake");
assert.equal(core.toSnakeCase("already_snake_case"), "already_snake_case");
});
test("toSnakeCase: mixed snake and camel", () => {
assert.equal(core.toSnakeCase("provider_name"), "provider_name");
assert.equal(core.toSnakeCase("provider_Name"), "provider__name");
});
// ─── toCamelCase ───────────────────────────────────────
test("toCamelCase: basic snake_case conversion", () => {
assert.equal(core.toCamelCase("api_key"), "apiKey");
assert.equal(core.toCamelCase("is_active"), "isActive");
assert.equal(core.toCamelCase("provider_name"), "providerName");
});
test("toCamelCase: empty string and single word", () => {
assert.equal(core.toCamelCase(""), "");
assert.equal(core.toCamelCase("name"), "name");
assert.equal(core.toCamelCase("id"), "id");
});
test("toCamelCase: multiple underscores", () => {
assert.equal(core.toCamelCase("foo_bar_baz"), "fooBarBaz");
assert.equal(core.toCamelCase("a_b_c"), "aBC");
});
test("toCamelCase: leading underscore", () => {
assert.equal(core.toCamelCase("_private"), "Private");
});
test("toCamelCase: trailing underscore is preserved", () => {
// Regex _([a-z]) doesn't match trailing underscore (no char after it)
assert.equal(core.toCamelCase("trailing_"), "trailing_");
});
// ─── objToSnake ────────────────────────────────────────
test("objToSnake: converts object keys to snake_case", () => {
const input = { apiKey: "sk-test", isActive: true, providerName: "openai" };
const result = core.objToSnake(input);
assert.deepEqual(result, { api_key: "sk-test", is_active: true, provider_name: "openai" });
});
test("objToSnake: null/undefined/non-object input", () => {
assert.equal(core.objToSnake(null), null);
assert.equal(core.objToSnake(undefined), undefined);
assert.equal(core.objToSnake("string"), "string");
assert.equal(core.objToSnake(42), 42);
});
test("objToSnake: empty object", () => {
assert.deepEqual(core.objToSnake({}), {});
});
test("objToSnake: nested values preserved as-is (shallow)", () => {
const input = { nestedObj: { innerKey: "val" }, items: [1, 2, 3] };
const result = core.objToSnake(input);
assert.deepEqual(result, { nested_obj: { innerKey: "val" }, items: [1, 2, 3] });
});
// ─── rowToCamel ────────────────────────────────────────
test("rowToCamel: converts snake_case row to camelCase", () => {
const row = { api_key: "sk-test", is_active: 1, provider_name: "openai" };
const result = core.rowToCamel(row);
assert.deepEqual(result, { apiKey: "sk-test", isActive: true, providerName: "openai" });
});
test("rowToCamel: null/undefined row returns null", () => {
assert.equal(core.rowToCamel(null), null);
assert.equal(core.rowToCamel(undefined), null);
});
test("rowToCamel: isActive boolean conversion (1/0)", () => {
assert.deepEqual(core.rowToCamel({ is_active: 1 }), { isActive: true });
assert.deepEqual(core.rowToCamel({ is_active: 0 }), { isActive: false });
assert.deepEqual(core.rowToCamel({ is_active: true }), { isActive: true });
assert.deepEqual(core.rowToCamel({ is_active: false }), { isActive: false });
});
test("rowToCamel: rateLimitProtection boolean conversion", () => {
assert.deepEqual(core.rowToCamel({ rate_limit_protection: 1 }), { rateLimitProtection: true });
assert.deepEqual(core.rowToCamel({ rate_limit_protection: 0 }), { rateLimitProtection: false });
});
test("rowToCamel: providerSpecificData JSON string parsing", () => {
const data = JSON.stringify({ org: "my-org" });
const result = core.rowToCamel({ provider_specific_data: data });
assert.deepEqual(result, { providerSpecificData: { org: "my-org" } });
});
test("rowToCamel: providerSpecificData invalid JSON", () => {
const result = core.rowToCamel({ provider_specific_data: "not-json" });
assert.equal(result?.providerSpecificData, "not-json");
});
test("rowToCamel: providerSpecificData non-string passes through", () => {
const result = core.rowToCamel({ provider_specific_data: 42 });
assert.equal(result?.providerSpecificData, 42);
});
test("rowToCamel: _json suffix columns parsed into base key", () => {
const result = core.rowToCamel({ quota_window_thresholds_json: JSON.stringify([1, 2, 3]) });
assert.deepEqual(result, { quotaWindowThresholds: [1, 2, 3] });
});
test("rowToCamel: _json suffix with invalid JSON sets null", () => {
const result = core.rowToCamel({ quota_window_thresholds_json: "broken" });
assert.deepEqual(result, { quotaWindowThresholds: null });
});
test("rowToCamel: ordinary fields pass through unchanged", () => {
const result = core.rowToCamel({ name: "test", created_at: "2025-01-01" });
assert.deepEqual(result, { name: "test", createdAt: "2025-01-01" });
});
test("rowToCamel: empty row returns empty object", () => {
assert.deepEqual(core.rowToCamel({}), {});
});
// ─── cleanNulls ────────────────────────────────────────
test("cleanNulls: removes null and undefined values", () => {
const result = core.cleanNulls({ a: 1, b: null, c: "keep", d: undefined, e: 0, f: "" });
assert.deepEqual(result, { a: 1, c: "keep", e: 0, f: "" });
});
test("cleanNulls: all values kept", () => {
const result = core.cleanNulls({ a: 1, b: "x", c: false });
assert.deepEqual(result, { a: 1, b: "x", c: false });
});
test("cleanNulls: empty object returns empty object", () => {
assert.deepEqual(core.cleanNulls({}), {});
});
test("cleanNulls: all null/undefined returns empty object", () => {
assert.deepEqual(core.cleanNulls({ a: null, b: undefined }), {});
});
// ─── getDriverInfo ─────────────────────────────────────
test("getDriverInfo returns null (setDriverInfo never called)", () => {
// setDriverInfo() exists but is never called in core.ts, so getDriverInfo
// always returns null until/unless a caller invokes setDriverInfo().
assert.equal(core.getDriverInfo(), null);
});
// ─── DB Functions (autoVacuum, pageSize, cacheSize) ───
test("setAutoVacuum and getAutoVacuumMode round-trip", serial, () => {
// Get current
const originalMode = core.getAutoVacuumMode();
// Set to NONE first
core.setAutoVacuum("NONE");
assert.equal(core.getAutoVacuumMode(), "NONE");
// Set to FULL
core.setAutoVacuum("FULL");
assert.equal(core.getAutoVacuumMode(), "FULL");
// Set to INCREMENTAL
core.setAutoVacuum("INCREMENTAL");
assert.equal(core.getAutoVacuumMode(), "INCREMENTAL");
// Restore original
core.setAutoVacuum(originalMode);
assert.equal(core.getAutoVacuumMode(), originalMode);
});
test("setAutoVacuum same mode is idempotent", serial, () => {
const mode = core.getAutoVacuumMode();
// Calling again with same mode should not throw
core.setAutoVacuum(mode);
assert.equal(core.getAutoVacuumMode(), mode);
});
test("runManualVacuum succeeds", serial, () => {
const result = core.runManualVacuum();
assert.equal(result.success, true);
assert.equal(typeof result.duration, "number");
assert.ok(result.duration >= 0);
assert.equal(result.error, undefined);
});
test("setPageSize round-trip", serial, () => {
// Capture current page_size so we can restore it
// We'll set to a known value, verify, then set back
// Note: page_size can only be set if the DB is empty or after VACUUM
// The implementation calls VACUUM after setting, which is safe
const testPageSize = 4096;
core.setPageSize(testPageSize);
// We can't read it back directly via exported function, but it shouldn't throw
// Verify by running it again (idempotent)
core.setPageSize(testPageSize);
});
test("setCacheSize round-trip", serial, () => {
core.setCacheSize(16384);
// Verify idempotent
core.setCacheSize(16384);
});
// ─── Edge Cases ────────────────────────────────────────
test("toSnakeCase and toCamelCase are inverses for simple cases", () => {
const pairs = [
["apiKey", "api_key"],
["isActive", "is_active"],
["providerName", "provider_name"],
["createdAt", "created_at"],
["updatedAt", "updated_at"],
];
for (const [camel, snake] of pairs) {
assert.equal(core.toSnakeCase(camel), snake);
assert.equal(core.toCamelCase(snake), camel);
}
});
test("cleanNulls with falsy values preserves 0, false, empty string", () => {
const result = core.cleanNulls({ zero: 0, falseVal: false, emptyStr: "", nil: null });
assert.deepEqual(result, { zero: 0, falseVal: false, emptyStr: "" });
});
test("objToSnake returns same object reference for primitives", () => {
const num = 42;
assert.equal(core.objToSnake(num), 42);
});
test("rowToCamel with isActive=1/non-1 edge cases", () => {
assert.deepEqual(core.rowToCamel({ is_active: 1 }), { isActive: true });
assert.deepEqual(core.rowToCamel({ is_active: 0 }), { isActive: false });
assert.deepEqual(core.rowToCamel({ is_active: 2 }), { isActive: false });
assert.deepEqual(core.rowToCamel({ is_active: "yes" }), { isActive: false });
});

View File

@@ -0,0 +1,362 @@
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-db-domainstate-"));
process.env.DATA_DIR = TEST_DATA_DIR;
const core = await import("../../src/lib/db/core.ts");
const ds = await import("../../src/lib/db/domainState.ts");
async function resetStorage() {
core.resetDbInstance();
for (let attempt = 0; attempt < 10; attempt++) {
try {
if (fs.existsSync(TEST_DATA_DIR)) {
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
}
break;
} catch {
await new Promise((r) => setTimeout(r, 50 * (attempt + 1)));
}
}
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
core.getDbInstance();
}
await resetStorage();
// ──────────────── Fallback Chains ────────────────
test("saveFallbackChain and loadFallbackChain round-trip", async () => {
await resetStorage();
const model = "gpt-4";
const chain = [
{ provider: "openai", priority: 1, enabled: true },
{ provider: "anthropic", priority: 2, enabled: false },
];
ds.saveFallbackChain(model, chain);
const loaded = ds.loadFallbackChain(model);
assert.deepEqual(loaded, chain);
});
test("loadFallbackChain returns null for missing model", async () => {
await resetStorage();
const result = ds.loadFallbackChain("nonexistent");
assert.equal(result, null);
});
test("loadAllFallbackChains returns all chains", async () => {
await resetStorage();
ds.saveFallbackChain("model-a", [{ provider: "p1", priority: 1, enabled: true }]);
ds.saveFallbackChain("model-b", [{ provider: "p2", priority: 2, enabled: false }]);
const all = ds.loadAllFallbackChains();
assert.ok("model-a" in all);
assert.ok("model-b" in all);
assert.equal((all["model-a"] as any[]).length, 1);
});
test("deleteFallbackChain removes a chain", async () => {
await resetStorage();
ds.saveFallbackChain("to-delete", [{ provider: "p", priority: 1, enabled: true }]);
assert.equal(ds.deleteFallbackChain("to-delete"), true);
assert.equal(ds.loadFallbackChain("to-delete"), null);
});
test("deleteFallbackChain returns false when chain does not exist", async () => {
await resetStorage();
assert.equal(ds.deleteFallbackChain("never-existed"), false);
});
test("deleteAllFallbackChains clears everything", async () => {
await resetStorage();
ds.saveFallbackChain("a", [{ provider: "p", priority: 1, enabled: true }]);
ds.saveFallbackChain("b", [{ provider: "p", priority: 1, enabled: true }]);
ds.deleteAllFallbackChains();
assert.deepEqual(ds.loadAllFallbackChains(), {});
});
// ──────────────── Budgets ────────────────
test("saveBudget and loadBudget round-trip", async () => {
await resetStorage();
ds.saveBudget("key-1", {
dailyLimitUsd: 10,
weeklyLimitUsd: 50,
monthlyLimitUsd: 200,
warningThreshold: 0.8,
resetInterval: "daily",
resetTime: "08:00",
budgetResetAt: 1000,
lastBudgetResetAt: 500,
warningEmittedAt: 900,
warningPeriodStart: 800,
});
const loaded = ds.loadBudget("key-1");
assert.ok(loaded !== null);
assert.equal(loaded.dailyLimitUsd, 10);
assert.equal(loaded.weeklyLimitUsd, 50);
assert.equal(loaded.monthlyLimitUsd, 200);
assert.equal(loaded.warningThreshold, 0.8);
assert.equal(loaded.resetInterval, "daily");
assert.equal(loaded.resetTime, "08:00");
assert.equal(loaded.budgetResetAt, 1000);
assert.equal(loaded.lastBudgetResetAt, 500);
assert.equal(loaded.warningEmittedAt, 900);
assert.equal(loaded.warningPeriodStart, 800);
});
test("loadBudget returns null for missing key", () => {
assert.equal(ds.loadBudget("no-such-key"), null);
});
test("saveBudget with minimal fields uses defaults", async () => {
await resetStorage();
ds.saveBudget("key-minimal", {});
const loaded = ds.loadBudget("key-minimal");
assert.ok(loaded !== null);
assert.equal(loaded.dailyLimitUsd, 0);
assert.equal(loaded.warningThreshold, 0.8);
assert.equal(loaded.resetInterval, "daily");
assert.equal(loaded.resetTime, "00:00");
assert.equal(loaded.budgetResetAt, null);
assert.equal(loaded.lastBudgetResetAt, null);
});
test("loadAllBudgets returns all budget configs", async () => {
await resetStorage();
ds.saveBudget("key-a", { dailyLimitUsd: 5 });
ds.saveBudget("key-b", { dailyLimitUsd: 10 });
const all = ds.loadAllBudgets();
assert.equal(Object.keys(all).length, 2);
assert.equal(all["key-a"].dailyLimitUsd, 5);
assert.equal(all["key-b"].dailyLimitUsd, 10);
});
test("saveBudgetResetLog and loadBudgetResetLogs", async () => {
await resetStorage();
ds.saveBudget("budget-key", { dailyLimitUsd: 10 });
const now = Date.now();
ds.saveBudgetResetLog({
apiKeyId: "budget-key",
resetInterval: "daily",
previousSpend: 8,
resetAt: now,
nextResetAt: now + 86400000,
periodStart: now - 86400000,
periodEnd: now,
});
const logs = ds.loadBudgetResetLogs("budget-key");
assert.equal(logs.length, 1);
assert.equal(logs[0].previousSpend, 8);
assert.equal(logs[0].resetInterval, "daily");
const noLogs = ds.loadBudgetResetLogs("no-such-key");
assert.deepEqual(noLogs, []);
});
test("deleteBudget removes budget and reset logs", async () => {
await resetStorage();
ds.saveBudget("del-key", { dailyLimitUsd: 10 });
ds.saveBudgetResetLog({ apiKeyId: "del-key", resetInterval: "daily", previousSpend: 3, resetAt: 1, nextResetAt: 2, periodStart: 0, periodEnd: 1 });
ds.deleteBudget("del-key");
assert.equal(ds.loadBudget("del-key"), null);
assert.deepEqual(ds.loadBudgetResetLogs("del-key"), []);
});
// ──────────────── Cost History ────────────────
test("saveCostEntry and loadCostTotal", async () => {
await resetStorage();
ds.saveCostEntry("cost-key", 1.5, 1000);
ds.saveCostEntry("cost-key", 2.5, 2000);
ds.saveCostEntry("cost-key", 3.0, 3000);
const total = ds.loadCostTotal("cost-key", 1500);
assert.equal(total, 5.5); // 2.5 + 3.0
const all = ds.loadCostTotal("cost-key", 0);
assert.equal(all, 7.0);
});
test("loadCostTotal returns 0 for no entries", () => {
assert.equal(ds.loadCostTotal("no-key", 0), 0);
});
test("batchSaveCostEntries inserts multiple entries", async () => {
await resetStorage();
ds.batchSaveCostEntries([
{ apiKeyId: "batch-key", cost: 1, timestamp: 100 },
{ apiKeyId: "batch-key", cost: 2, timestamp: 200 },
]);
assert.equal(ds.loadCostTotal("batch-key", 0), 3);
});
test("batchSaveCostEntries skips empty array", () => {
assert.doesNotThrow(() => ds.batchSaveCostEntries([]));
});
test("loadCostEntries returns entries in order", async () => {
await resetStorage();
ds.saveCostEntry("ce-key", 1, 100);
ds.saveCostEntry("ce-key", 2, 200);
ds.saveCostEntry("ce-key", 3, 300);
const entries = ds.loadCostEntries("ce-key", 150);
assert.equal(entries.length, 2);
assert.equal((entries[0] as any).cost, 2);
assert.equal((entries[1] as any).cost, 3);
});
test("loadCostEntriesInRange returns bounded entries", async () => {
await resetStorage();
ds.saveCostEntry("range-key", 1, 100);
ds.saveCostEntry("range-key", 2, 200);
ds.saveCostEntry("range-key", 3, 300);
const entries = ds.loadCostEntriesInRange("range-key", 150, 250);
assert.equal(entries.length, 1);
assert.equal((entries[0] as any).cost, 2);
});
test("cleanOldCostEntries deletes old entries", async () => {
await resetStorage();
ds.saveCostEntry("clean-key", 1, 100);
ds.saveCostEntry("clean-key", 2, 200);
ds.saveCostEntry("clean-key", 3, 300);
const deleted = ds.cleanOldCostEntries(250);
assert.equal(deleted, 2); // entries at 100 and 200
assert.equal(ds.loadCostTotal("clean-key", 0), 3);
});
test("deleteCostEntries removes all for key", async () => {
await resetStorage();
ds.saveCostEntry("del-cost", 5, 100);
ds.saveCostEntry("del-cost", 10, 200);
ds.deleteCostEntries("del-cost");
assert.equal(ds.loadCostTotal("del-cost", 0), 0);
});
test("deleteAllCostData wipes budgets and cost data", async () => {
await resetStorage();
ds.saveBudget("wipe-key", { dailyLimitUsd: 10 });
ds.saveCostEntry("wipe-key", 5, 100);
ds.deleteAllCostData();
assert.equal(ds.loadBudget("wipe-key"), null);
assert.equal(ds.loadCostTotal("wipe-key", 0), 0);
});
// ──────────────── Lockout State ────────────────
test("saveLockoutState and loadLockoutState round-trip", async () => {
await resetStorage();
ds.saveLockoutState("user-1", { attempts: [100, 200, 300], lockedUntil: 9999999999999 });
const loaded = ds.loadLockoutState("user-1");
assert.ok(loaded !== null);
assert.deepEqual(loaded.attempts, [100, 200, 300]);
assert.equal(loaded.lockedUntil, 9999999999999);
});
test("loadLockoutState returns null for missing identifier", () => {
assert.equal(ds.loadLockoutState("no-such"), null);
});
test("saveLockoutState with null lockedUntil", async () => {
await resetStorage();
ds.saveLockoutState("not-locked", { attempts: [], lockedUntil: null });
const loaded = ds.loadLockoutState("not-locked");
assert.ok(loaded !== null);
assert.deepEqual(loaded.attempts, []);
assert.equal(loaded.lockedUntil, null);
});
test("deleteLockoutState removes state", async () => {
await resetStorage();
ds.saveLockoutState("del-lock", { attempts: [1], lockedUntil: null });
ds.deleteLockoutState("del-lock");
assert.equal(ds.loadLockoutState("del-lock"), null);
});
test("loadAllLockedIdentifiers returns only currently locked", async () => {
await resetStorage();
ds.saveLockoutState("locked-now", { attempts: [1], lockedUntil: Date.now() + 3600000 });
ds.saveLockoutState("expired", { attempts: [1], lockedUntil: Date.now() - 3600000 });
ds.saveLockoutState("no-lock", { attempts: [], lockedUntil: null });
const locked = ds.loadAllLockedIdentifiers();
assert.equal(locked.length, 1);
assert.equal(locked[0].identifier, "locked-now");
});
// ──────────────── Circuit Breakers ────────────────
test("saveCircuitBreakerState and loadCircuitBreakerState round-trip", async () => {
await resetStorage();
ds.saveCircuitBreakerState("cb-1", {
state: "OPEN",
failureCount: 5,
lastFailureTime: 1000,
options: { timeout: 30000 },
});
const loaded = ds.loadCircuitBreakerState("cb-1");
assert.ok(loaded !== null);
assert.equal(loaded.state, "OPEN");
assert.equal(loaded.failureCount, 5);
assert.equal(loaded.lastFailureTime, 1000);
assert.deepEqual(loaded.options, { timeout: 30000 });
});
test("loadCircuitBreakerState returns null for missing name", () => {
assert.equal(ds.loadCircuitBreakerState("no-such"), null);
});
test("saveCircuitBreakerState without options", async () => {
await resetStorage();
ds.saveCircuitBreakerState("cb-simple", {
state: "CLOSED",
failureCount: 0,
lastFailureTime: null,
});
const loaded = ds.loadCircuitBreakerState("cb-simple");
assert.ok(loaded !== null);
assert.equal(loaded.state, "CLOSED");
assert.equal(loaded.failureCount, 0);
assert.equal(loaded.lastFailureTime, null);
assert.equal(loaded.options, null);
});
test("loadAllCircuitBreakerStates returns all", async () => {
await resetStorage();
ds.saveCircuitBreakerState("cb-a", { state: "HALF_OPEN", failureCount: 2, lastFailureTime: 500 });
ds.saveCircuitBreakerState("cb-b", { state: "CLOSED", failureCount: 0, lastFailureTime: null });
const all = ds.loadAllCircuitBreakerStates();
assert.equal(all.length, 2);
const names = all.map((r: any) => r.name).sort();
assert.deepEqual(names, ["cb-a", "cb-b"]);
});
test("deleteCircuitBreakerState removes state", async () => {
await resetStorage();
ds.saveCircuitBreakerState("del-cb", { state: "OPEN", failureCount: 1, lastFailureTime: 100 });
ds.deleteCircuitBreakerState("del-cb");
assert.equal(ds.loadCircuitBreakerState("del-cb"), null);
});
test("deleteAllCircuitBreakerStates clears everything", async () => {
await resetStorage();
ds.saveCircuitBreakerState("a", { state: "OPEN", failureCount: 1, lastFailureTime: 100 });
ds.saveCircuitBreakerState("b", { state: "CLOSED", failureCount: 0, lastFailureTime: null });
ds.deleteAllCircuitBreakerStates();
assert.deepEqual(ds.loadAllCircuitBreakerStates(), []);
});

View File

@@ -0,0 +1,311 @@
import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-db-regkeys-"));
process.env.DATA_DIR = TEST_DATA_DIR;
const core = await import("../../src/lib/db/core.ts");
const rk = await import("../../src/lib/db/registeredKeys.ts");
async function resetStorage() {
core.resetDbInstance();
for (let attempt = 0; attempt < 10; attempt++) {
try {
if (fs.existsSync(TEST_DATA_DIR)) {
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
}
break;
} catch {
await new Promise((r) => setTimeout(r, 50 * (attempt + 1)));
}
}
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
core.getDbInstance();
}
await resetStorage();
// ──────────────── issueRegisteredKey ────────────────
test("issueRegisteredKey creates a key and returns it with rawKey", async () => {
await resetStorage();
const result = rk.issueRegisteredKey({
name: "Test Key",
provider: "openai",
accountId: "acc-1",
});
assert.ok("rawKey" in result && !("idempotencyConflict" in result));
assert.ok(result.rawKey.startsWith("ork_"));
assert.equal(result.name, "Test Key");
assert.equal(result.provider, "openai");
assert.equal(result.accountId, "acc-1");
assert.equal(result.isActive, true);
assert.ok(result.id);
assert.ok(result.keyPrefix);
});
test("issueRegisteredKey with idempotency key", async () => {
await resetStorage();
const first = rk.issueRegisteredKey({
name: "Idempotent",
idempotencyKey: "idem-1",
});
const second = rk.issueRegisteredKey({
name: "Should Conflict",
idempotencyKey: "idem-1",
});
assert.ok("idempotencyConflict" in second);
assert.equal(second.idempotencyConflict, true);
assert.equal(second.existing.id, (first as any).id);
});
test("issueRegisteredKey with expiresAt and budgets", async () => {
await resetStorage();
const result = rk.issueRegisteredKey({
name: "Budgeted Key",
provider: "anthropic",
expiresAt: "2027-01-01T00:00:00Z",
dailyBudget: 100,
hourlyBudget: 10,
});
assert.ok("rawKey" in result);
assert.equal(result.expiresAt, "2027-01-01T00:00:00Z");
assert.equal(result.dailyBudget, 100);
assert.equal(result.hourlyBudget, 10);
});
test("issueRegisteredKey without provider skips provider quotas", async () => {
await resetStorage();
const result = rk.issueRegisteredKey({ name: "No Provider Key" });
assert.ok("rawKey" in result);
});
// ──────────────── getRegisteredKey ────────────────
test("getRegisteredKey returns key by id", async () => {
await resetStorage();
const created = rk.issueRegisteredKey({ name: "Get Me" }) as any;
const loaded = rk.getRegisteredKey(created.id);
assert.ok(loaded !== null);
assert.equal(loaded.name, "Get Me");
assert.equal(loaded.id, created.id);
});
test("getRegisteredKey returns null for missing id", () => {
assert.equal(rk.getRegisteredKey("no-such-id"), null);
});
// ──────────────── listRegisteredKeys ────────────────
test("listRegisteredKeys returns all keys", async () => {
await resetStorage();
rk.issueRegisteredKey({ name: "Key A", provider: "openai" });
rk.issueRegisteredKey({ name: "Key B", provider: "anthropic" });
const all = rk.listRegisteredKeys();
assert.equal(all.length, 2);
});
test("listRegisteredKeys filters by provider", async () => {
await resetStorage();
rk.issueRegisteredKey({ name: "OA", provider: "openai" });
rk.issueRegisteredKey({ name: "AN", provider: "anthropic" });
const filtered = rk.listRegisteredKeys({ provider: "openai" });
assert.equal(filtered.length, 1);
assert.equal(filtered[0].name, "OA");
});
test("listRegisteredKeys filters by accountId", async () => {
await resetStorage();
rk.issueRegisteredKey({ name: "Acc1 Key", accountId: "acc-1" });
rk.issueRegisteredKey({ name: "Acc2 Key", accountId: "acc-2" });
const filtered = rk.listRegisteredKeys({ accountId: "acc-1" });
assert.equal(filtered.length, 1);
assert.equal(filtered[0].name, "Acc1 Key");
});
// ──────────────── revokeRegisteredKey ────────────────
test("revokeRegisteredKey deactivates a key", async () => {
await resetStorage();
const created = rk.issueRegisteredKey({ name: "Revoke Me" }) as any;
assert.equal(created.isActive, true);
const revoked = rk.revokeRegisteredKey(created.id);
assert.equal(revoked, true);
const loaded = rk.getRegisteredKey(created.id);
assert.equal(loaded!.isActive, false);
assert.ok(loaded!.revokedAt);
});
test("revokeRegisteredKey returns false for already revoked or missing key", async () => {
await resetStorage();
assert.equal(rk.revokeRegisteredKey("no-such-id"), false);
const created = rk.issueRegisteredKey({ name: "To Revoke" }) as any;
rk.revokeRegisteredKey(created.id);
assert.equal(rk.revokeRegisteredKey(created.id), false);
});
// ──────────────── validateRegisteredKey ────────────────
test("validateRegisteredKey validates raw key by hash", async () => {
await resetStorage();
const created = rk.issueRegisteredKey({ name: "Validate Me" }) as any;
const validated = rk.validateRegisteredKey(created.rawKey);
assert.ok(validated !== null);
assert.equal(validated.name, "Validate Me");
});
test("validateRegisteredKey returns null for invalid key", () => {
assert.equal(rk.validateRegisteredKey("ork_invalid"), null);
});
test("validateRegisteredKey returns null for revoked key", async () => {
await resetStorage();
const created = rk.issueRegisteredKey({ name: "Soon Revoked" }) as any;
rk.revokeRegisteredKey(created.id);
assert.equal(rk.validateRegisteredKey(created.rawKey), null);
});
// ──────────────── incrementRegisteredKeyUsage ────────────────
test("incrementRegisteredKeyUsage bumps counters", async () => {
await resetStorage();
const created = rk.issueRegisteredKey({
name: "Usage Test",
dailyBudget: 100,
hourlyBudget: 50,
}) as any;
assert.equal(created.dailyUsed, 0);
assert.equal(created.hourlyUsed, 0);
rk.incrementRegisteredKeyUsage(created.id);
const loaded = rk.getRegisteredKey(created.id);
assert.equal(loaded!.dailyUsed, 1);
assert.equal(loaded!.hourlyUsed, 1);
});
test("validateRegisteredKey respects budget limits", async () => {
await resetStorage();
const created = rk.issueRegisteredKey({
name: "Budget Limit",
dailyBudget: 3,
}) as any;
assert.ok(rk.validateRegisteredKey(created.rawKey) !== null);
rk.incrementRegisteredKeyUsage(created.id);
rk.incrementRegisteredKeyUsage(created.id);
rk.incrementRegisteredKeyUsage(created.id);
// After 3 increments, daily_used == daily_budget == 3
assert.equal(rk.validateRegisteredKey(created.rawKey), null);
});
// ──────────────── checkQuota ────────────────
test("checkQuota returns allowed true when no limits set", async () => {
await resetStorage();
const result = rk.checkQuota("openai", "acc-1");
assert.equal(result.allowed, true);
});
test("checkQuota returns allowed true with no provider or account", () => {
const result = rk.checkQuota("", "");
assert.equal(result.allowed, true);
});
test("checkQuota rejects when hourly limit exceeded", async () => {
await resetStorage();
rk.setProviderKeyLimit("limited-provider", { hourlyIssueLimit: 2 });
rk.issueRegisteredKey({ name: "K1", provider: "limited-provider" });
rk.issueRegisteredKey({ name: "K2", provider: "limited-provider" });
const result = rk.checkQuota("limited-provider");
assert.equal(result.allowed, false);
assert.equal(result.errorCode, "PROVIDER_QUOTA_EXCEEDED");
});
test("checkQuota rejects when max active keys exceeded", async () => {
await resetStorage();
rk.setProviderKeyLimit("maxed-provider", { maxActiveKeys: 1 });
rk.issueRegisteredKey({ name: "Only One", provider: "maxed-provider" });
const result = rk.checkQuota("maxed-provider");
assert.equal(result.allowed, false);
assert.equal(result.errorCode, "MAX_ACTIVE_KEYS_EXCEEDED");
});
test("checkQuota account-level rejection", async () => {
await resetStorage();
rk.setAccountKeyLimit("limited-account", { dailyIssueLimit: 1 });
rk.issueRegisteredKey({ name: "Only", accountId: "limited-account" });
const result = rk.checkQuota("", "limited-account");
assert.equal(result.allowed, false);
assert.equal(result.errorCode, "ACCOUNT_QUOTA_EXCEEDED");
});
// ──────────────── setProviderKeyLimit / getProviderKeyLimit ────────────────
test("setProviderKeyLimit and getProviderKeyLimit round-trip", async () => {
await resetStorage();
rk.setProviderKeyLimit("test-provider", {
maxActiveKeys: 5,
dailyIssueLimit: 100,
hourlyIssueLimit: 20,
});
const limit = rk.getProviderKeyLimit("test-provider");
assert.ok(limit !== null);
assert.equal(limit.provider, "test-provider");
assert.equal(limit.maxActiveKeys, 5);
assert.equal(limit.dailyIssueLimit, 100);
assert.equal(limit.hourlyIssueLimit, 20);
});
test("getProviderKeyLimit returns null for unknown provider", () => {
assert.equal(rk.getProviderKeyLimit("no-such-provider"), null);
});
test("setProviderKeyLimit with partial limits", async () => {
await resetStorage();
rk.setProviderKeyLimit("partial-provider", { maxActiveKeys: 3 });
const limit = rk.getProviderKeyLimit("partial-provider");
assert.equal(limit!.maxActiveKeys, 3);
assert.equal(limit!.dailyIssueLimit, null);
assert.equal(limit!.hourlyIssueLimit, null);
});
// ──────────────── setAccountKeyLimit / getAccountKeyLimit ────────────────
test("setAccountKeyLimit and getAccountKeyLimit round-trip", async () => {
await resetStorage();
rk.setAccountKeyLimit("test-account", {
maxActiveKeys: 10,
dailyIssueLimit: 200,
hourlyIssueLimit: 50,
});
const limit = rk.getAccountKeyLimit("test-account");
assert.ok(limit !== null);
assert.equal(limit.accountId, "test-account");
assert.equal(limit.maxActiveKeys, 10);
assert.equal(limit.dailyIssueLimit, 200);
assert.equal(limit.hourlyIssueLimit, 50);
});
test("getAccountKeyLimit returns null for unknown account", () => {
assert.equal(rk.getAccountKeyLimit("no-such-account"), null);
});

View File

@@ -0,0 +1,299 @@
/**
* Tests for pure utility functions exported via usage.__testing
*
* Covers: parseResetTime, formatGitHubQuotaSnapshot, inferGitHubPlanName,
* getMiniMaxPlanLabel, inferMiniMaxPlanLabelFromTotals,
* extractCodeAssistSubscriptionTier, extractCodeAssistOnboardTierId.
*
* These are pure functions (no fetch, no DB) — run without DATA_DIR override.
*/
import { describe, it } from "node:test";
import assert from "node:assert/strict";
process.env.NODE_ENV = "test";
const usage = await import("../../open-sse/services/usage.ts");
const { __testing } = usage;
/* ------------------------------------------------------------------ */
/* parseResetTime */
/* ------------------------------------------------------------------ */
describe("parseResetTime", () => {
it("returns null for null / undefined", () => {
assert.equal(__testing.parseResetTime(null), null);
assert.equal(__testing.parseResetTime(undefined), null);
});
it("returns null for epoch-zero", () => {
assert.equal(__testing.parseResetTime(0), null);
assert.equal(__testing.parseResetTime("1970-01-01T00:00:00.000Z"), null);
});
it("parses a number as ms timestamp (value > 1e12)", () => {
const ms = 1_700_000_000_000;
const out = __testing.parseResetTime(ms);
assert.equal(out, new Date(ms).toISOString());
});
it("parses a number as seconds (value < 1e12)", () => {
const sec = 1_700_000_000; // < 1e12
const out = __testing.parseResetTime(sec);
assert.equal(out, new Date(sec * 1000).toISOString());
});
it("parses an ISO date string", () => {
const iso = "2026-06-15T12:00:00.000Z";
assert.equal(__testing.parseResetTime(iso), new Date(iso).toISOString());
});
it("parses a Date object", () => {
const d = new Date("2026-07-01T00:00:00Z");
assert.equal(__testing.parseResetTime(d), d.toISOString());
});
it("returns null for non-date values (objects, booleans)", () => {
assert.equal(__testing.parseResetTime({}), null);
assert.equal(__testing.parseResetTime(true), null);
});
it("returns null for invalid date strings", () => {
assert.equal(__testing.parseResetTime("not-a-date"), null);
});
});
/* ------------------------------------------------------------------ */
/* formatGitHubQuotaSnapshot */
/* ------------------------------------------------------------------ */
describe("formatGitHubQuotaSnapshot", () => {
it("returns null for empty object", () => {
assert.equal(__testing.formatGitHubQuotaSnapshot({}), null);
});
it("builds quota from snapshot with all fields", () => {
const snap = {
entitlement: 1000,
used: 300,
remaining: 700,
percent_remaining: 70,
};
const q = __testing.formatGitHubQuotaSnapshot(snap, "2026-07-01T00:00:00.000Z");
assert.equal(q.total, 1000);
assert.equal(q.used, 300);
assert.equal(q.remaining, 700);
assert.equal(q.remainingPercentage, 70);
assert.equal(q.resetAt, "2026-07-01T00:00:00.000Z");
assert.equal(q.unlimited, false);
});
it("uses entitlement when total is missing", () => {
const snap = { entitlement: 500, remaining: 0.5, percent_remaining: 50 };
const q = __testing.formatGitHubQuotaSnapshot(snap);
assert.equal(q.total, 500);
assert.ok(q.remaining !== undefined);
});
it("detects unlimited plan", () => {
const snap = { entitlement: 0, total: 0, unlimited: true };
const q = __testing.formatGitHubQuotaSnapshot(snap);
assert.equal(q.unlimited, true);
assert.equal(q.total, 0); // total is 0 when percent_remaining is missing
});
it("clamps negative values to 0", () => {
const snap = { used: -10, entitlement: 100, remaining: -5, percent_remaining: -1 };
const q = __testing.formatGitHubQuotaSnapshot(snap);
assert.equal(q.used, 0);
assert.equal(q.remaining, 0);
assert.equal(q.remainingPercentage, 0);
});
it("computes missing used from total - remaining", () => {
const snap = { entitlement: 200, remaining: 50 };
const q = __testing.formatGitHubQuotaSnapshot(snap);
assert.equal(q.used, 150); // 200 - 50
});
it("computes missing remaining from total - used", () => {
const snap = { used: 30, entitlement: 100 };
const q = __testing.formatGitHubQuotaSnapshot(snap);
assert.equal(q.remaining, 70);
});
});
/* ------------------------------------------------------------------ */
/* inferGitHubPlanName */
/* ------------------------------------------------------------------ */
describe("inferGitHubPlanName", () => {
it("detects Copilot Pro+ from combined string", () => {
const data = { copilot_plan: "PRO_PLUS" };
assert.equal(__testing.inferGitHubPlanName(data, null), "Copilot Pro+");
});
it("detects Copilot Enterprise", () => {
const data = { copilot_plan: "ENTERPRISE" };
assert.equal(__testing.inferGitHubPlanName(data, null), "Copilot Enterprise");
});
it("detects Copilot Business", () => {
const data = { copilot_plan: "BUSINESS" };
assert.equal(__testing.inferGitHubPlanName(data, null), "Copilot Business");
});
it("detects Copilot Student", () => {
const data = { copilot_plan: "STUDENT" };
assert.equal(__testing.inferGitHubPlanName(data, null), "Copilot Student");
});
it("detects Copilot Free", () => {
const data = { copilot_plan: "FREE" };
assert.equal(__testing.inferGitHubPlanName(data, null), "Copilot Free");
});
it("detects Copilot Pro", () => {
const data = { copilot_plan: "PRO" };
assert.equal(__testing.inferGitHubPlanName(data, null), "Copilot Pro");
});
it("infers Pro+ from premiumTotal >= 1400", () => {
const data = { copilot_plan: "INDIVIDUAL" };
const premium = { used: 0, total: 1500, remaining: 1500, remainingPercentage: 100, unlimited: false };
assert.equal(__testing.inferGitHubPlanName(data, premium), "Copilot Pro+");
});
it("infers Enterprise from premiumTotal >= 900", () => {
const data = { copilot_plan: "INDIVIDUAL" };
const premium = { used: 0, total: 900, remaining: 900, remainingPercentage: 100, unlimited: false };
assert.equal(__testing.inferGitHubPlanName(data, premium), "Copilot Enterprise");
});
it("infers Pro when premiumTotal >= 250 and combined has INDIVIDUAL", () => {
const data = { copilot_plan: "INDIVIDUAL" };
const premium = { used: 0, total: 300, remaining: 300, remainingPercentage: 100, unlimited: false };
assert.equal(__testing.inferGitHubPlanName(data, premium), "Copilot Pro");
});
it("returns 'GitHub Copilot' fallback when nothing matches", () => {
const data = {};
assert.equal(__testing.inferGitHubPlanName(data, null), "GitHub Copilot");
});
it("falls back to sku label when planText is empty", () => {
const data = { access_type_sku: "BUSINESS_SPO" };
// "BUSINESS_SPO" upper-cased matches "BUSINESS" check first
assert.equal(__testing.inferGitHubPlanName(data, null), "Copilot Business");
});
});
/* ------------------------------------------------------------------ */
/* getMiniMaxPlanLabel */
/* ------------------------------------------------------------------ */
describe("getMiniMaxPlanLabel", () => {
it("returns cleaned title from payload", () => {
const payload = { current_subscribe_title: "MiniMax Coding Plan Pro" };
assert.equal(__testing.getMiniMaxPlanLabel(payload), "Pro");
});
it("removes 'minimax ' prefix and 'coding plan' text", () => {
const payload = { plan: "MiniMax Coding Plan Ultra" };
assert.equal(__testing.getMiniMaxPlanLabel(payload), "Ultra");
});
it("calls inferMiniMaxPlanLabelFromTotals when no title present", () => {
const models = [{ current_interval_total_count: 500, current_weekly_total_count: 200 }];
const label = __testing.getMiniMaxPlanLabel({}, models);
assert.ok(typeof label === "string");
assert.ok(label.length > 0);
});
it("returns 'Coding Plan' fallback when nothing matches", () => {
assert.equal(__testing.getMiniMaxPlanLabel({}), "Coding Plan");
});
it("picks first non-empty string from multiple candidate fields", () => {
const payload = { combo_title: "", plan_name: "MiniMax Turbo", plan: "" };
const label = __testing.getMiniMaxPlanLabel(payload);
assert.equal(label, "Turbo");
});
});
/* ------------------------------------------------------------------ */
/* inferMiniMaxPlanLabelFromTotals */
/* ------------------------------------------------------------------ */
describe("inferMiniMaxPlanLabelFromTotals", () => {
it("returns 'Max' for totals >= 15K", () => {
const models = [{ current_interval_total_count: 20_000 }];
assert.equal(__testing.inferMiniMaxPlanLabelFromTotals(models), "Max");
});
it("returns 'Plus' for totals >= 4.5K but < 15K", () => {
const models = [{ current_interval_total_count: 5_000 }];
assert.equal(__testing.inferMiniMaxPlanLabelFromTotals(models), "Plus");
});
it("returns 'Starter' for totals >= 1.5K but < 4.5K", () => {
const models = [{ current_interval_total_count: 2_000 }];
assert.equal(__testing.inferMiniMaxPlanLabelFromTotals(models), "Starter");
});
it("returns null when models array is empty", () => {
assert.equal(__testing.inferMiniMaxPlanLabelFromTotals([]), null);
});
});
/* ------------------------------------------------------------------ */
/* getGeminiCliPlanLabel */
/* ------------------------------------------------------------------ */
describe("getGeminiCliPlanLabel", () => {
it("returns a string label", () => {
const label = __testing.getGeminiCliPlanLabel();
assert.ok(typeof label === "string");
assert.ok(label.length > 0);
});
});
/* ------------------------------------------------------------------ */
/* getAntigravityPlanLabel */
/* ------------------------------------------------------------------ */
describe("getAntigravityPlanLabel", () => {
it("returns a string label", () => {
const label = __testing.getAntigravityPlanLabel();
assert.ok(typeof label === "string");
assert.ok(label.length > 0);
});
});
/* ------------------------------------------------------------------ */
/* extractCodeAssist helpers */
/* ------------------------------------------------------------------ */
describe("extractCodeAssistOnboardTierId", () => {
it("extracts tier id from paidTier", () => {
const sub = { paidTier: { id: "pro-tier" } };
assert.equal(__testing.extractCodeAssistOnboardTierId(sub), "pro-tier");
});
it("extracts tier id from currentTier when paidTier is absent", () => {
const sub = { currentTier: { id: "starter-tier" } };
assert.equal(__testing.extractCodeAssistOnboardTierId(sub), "starter-tier");
});
it("returns 'legacy-tier' when no tier data is present", () => {
assert.equal(__testing.extractCodeAssistOnboardTierId({}), "legacy-tier");
});
});
describe("extractCodeAssistSubscriptionTier", () => {
it("reads tier name from paidTier.name", () => {
const info = { paidTier: { name: "ULTRA" } };
assert.equal(__testing.extractCodeAssistSubscriptionTier(info), "ULTRA");
});
it("reads tier from currentTier.name", () => {
const info = { currentTier: { name: "Pro" } };
assert.equal(__testing.extractCodeAssistSubscriptionTier(info), "Pro");
});
it("returns null when nothing matches", () => {
assert.equal(__testing.extractCodeAssistSubscriptionTier({}), null);
});
});