Files
OmniRoute/tests/unit/combo-bracket-names.test.ts
Dizzle b3844550d0 fix(api): refuse creating a routing combo without any model (#11162)
Validated on the combined batch board over tip 92ef3c71: static gates clean (changelog, file-size, complexity 2624<=2774, cognitive 1182<=1223, dead-code 411<=416), typecheck:core clean, focused tests green.

Combo without models is now refused at the schema boundary (API 400), the CLI flags it, and openapi.yaml matches the real contract (phantom props removed). combo-* suites + cli-combo-create-models green on the board. Closes #10954. Thank you @maxmad64bis!
2026-08-22 21:51:19 -03:00

82 lines
2.8 KiB
TypeScript

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-combo-brackets-"));
process.env.DATA_DIR = TEST_DATA_DIR;
const core = await import("../../src/lib/db/core.ts");
const combosDb = await import("../../src/lib/db/combos.ts");
const schemas = await import("../../src/shared/validation/schemas.ts");
const sseModelService = await import("../../src/sse/services/model.ts");
async function resetStorage() {
core.resetDbInstance();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
}
test.beforeEach(async () => {
await resetStorage();
});
test.after(() => {
core.resetDbInstance();
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true });
});
test("combo schemas accept names with spaces and square brackets", () => {
const createResult = schemas.createComboSchema.safeParse({
name: "Claude [1m]",
models: ["anthropic/claude-3-opus"],
});
const updateResult = schemas.updateComboSchema.safeParse({
name: "Claude [1m]",
});
assert.equal(createResult.success, true);
assert.equal(updateResult.success, true);
});
test("combo schemas still reject control characters and whitespace-only names", () => {
assert.equal(schemas.createComboSchema.safeParse({ name: "Claude\n[1m]" }).success, false);
assert.equal(schemas.updateComboSchema.safeParse({ name: "Claude\0[1m]" }).success, false);
assert.equal(schemas.createComboSchema.safeParse({ name: " " }).success, false);
});
test("getComboForModel treats an exact bracketed name as a combo before model suffix parsing", async () => {
const exactCombo = await combosDb.createCombo({
name: "Claude [1m]",
models: [{ provider: "claude", model: "claude-sonnet-4-6" }],
});
await combosDb.createCombo({
name: "Claude",
models: [{ provider: "claude", model: "claude-opus-4-6" }],
});
const resolved = await sseModelService.getComboForModel("Claude [1m]");
const parsedAsModel = sseModelService.parseModel("Claude [1m]");
assert.equal(resolved?.id, exactCombo.id);
assert.equal(resolved?.name, "Claude [1m]");
assert.equal(parsedAsModel.extendedContext, true);
assert.equal(parsedAsModel.model, "Claude");
});
test("getComboForModel falls back to the base combo when no exact context-tagged combo exists", async () => {
await combosDb.createCombo({
name: "Claude",
models: [{ provider: "claude", model: "claude-sonnet-4-6" }],
});
const resolved = await sseModelService.getComboForModel("Claude [1m]");
const parsedAsModel = sseModelService.parseModel("Claude [1m]");
assert.equal(resolved?.name, "Claude");
assert.equal(parsedAsModel.extendedContext, true);
assert.equal(parsedAsModel.model, "Claude");
});