mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-13 18:32:12 +03:00
Production (open-sse/utils/socksConnectorWithFamily.ts, 4 sites): every cast was redundant — undici's buildConnector.BuildOptions already has `timeout?: number | null`, socks' SocksClientOptions has `timeout?: number`, and Agent.Options' `connect` / `connectTimeout` narrow to the connector's parameter types on their own. Behaviour unchanged; check:open-sse-typecheck stays at the frozen 5. Tests (51 sites): the socks-timeout mocks now carry the real types — the patched SocksClient.createConnection is typed as the static it replaces, the fake buildConnector returns buildConnector.connector, the proxy is a SocksProxy, the dynamic import is typed as the module it loads; the e2e suite passes a SocksProxy and Agent.Options and no longer casts undici's fetch init (its RequestInit already has `dispatcher`); the isFree suites narrow getCustomModels()' JSON to a declared row shape, feed deliberately-wrong values through `unknown`, and stop casting for zod's safeParse, which takes unknown. The six files' suppression entries are removed: 1238 → 1232 files, 5487 → 5432 suppressed. ESLint without the suppressions file reports 0 problems on all six; with it, no stale entry is left. The five suites pass (4, 2, 5, 4, 4).
173 lines
4.5 KiB
TypeScript
173 lines
4.5 KiB
TypeScript
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import {
|
|
addCustomModel,
|
|
replaceCustomModels,
|
|
updateCustomModel,
|
|
getCustomModels,
|
|
} from "../../src/lib/db/models.ts";
|
|
import { resetDbInstance } from "../../src/lib/db/core.ts";
|
|
import { rmSync, mkdtempSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
|
|
type CustomRow = { id: string; isFree?: boolean };
|
|
|
|
describe("custom isFree tri-state (DB)", () => {
|
|
let dir: string;
|
|
let prevDataDir: string | undefined;
|
|
beforeEach(() => {
|
|
dir = mkdtempSync(join(tmpdir(), "omni-isfree-"));
|
|
prevDataDir = process.env.DATA_DIR;
|
|
process.env.DATA_DIR = dir;
|
|
// force DB to re-create in this DATA_DIR
|
|
resetDbInstance();
|
|
});
|
|
afterEach(() => {
|
|
resetDbInstance();
|
|
if (prevDataDir === undefined) delete process.env.DATA_DIR;
|
|
else process.env.DATA_DIR = prevDataDir;
|
|
try {
|
|
rmSync(dir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
} catch {}
|
|
});
|
|
|
|
it("addCustomModel round-trip isFree:true → kept, isFree absent → not set", async () => {
|
|
await addCustomModel(
|
|
"p",
|
|
"m1",
|
|
"M1",
|
|
"manual",
|
|
"chat-completions",
|
|
["chat"],
|
|
undefined,
|
|
{},
|
|
undefined,
|
|
undefined,
|
|
true
|
|
);
|
|
const rows = (await getCustomModels("p")) as CustomRow[];
|
|
const r = rows.find((x) => x.id === "m1");
|
|
assert.equal(r.isFree, true);
|
|
await addCustomModel(
|
|
"p",
|
|
"m2",
|
|
"M2",
|
|
"manual",
|
|
"chat-completions",
|
|
["chat"],
|
|
undefined,
|
|
{},
|
|
undefined,
|
|
undefined,
|
|
undefined
|
|
);
|
|
const rows2 = (await getCustomModels("p")) as CustomRow[];
|
|
const r2 = rows2.find((x) => x.id === "m2");
|
|
assert.equal(r2.isFree, undefined);
|
|
});
|
|
|
|
it("updateCustomModel isFree:null → delete key (tri-state clear)", async () => {
|
|
await addCustomModel(
|
|
"p",
|
|
"m",
|
|
"M",
|
|
"manual",
|
|
"chat-completions",
|
|
["chat"],
|
|
undefined,
|
|
{},
|
|
undefined,
|
|
undefined,
|
|
true
|
|
);
|
|
await updateCustomModel("p", "m", { isFree: null });
|
|
const rows = (await getCustomModels("p")) as CustomRow[];
|
|
const r = rows.find((x) => x.id === "m");
|
|
assert.equal(r.isFree, undefined);
|
|
});
|
|
|
|
it("updateCustomModel isFree:true → set, then false-effective via tri-state (Boolean) ", async () => {
|
|
await addCustomModel(
|
|
"p",
|
|
"m",
|
|
"M",
|
|
"manual",
|
|
"chat-completions",
|
|
["chat"],
|
|
undefined,
|
|
{},
|
|
undefined,
|
|
undefined,
|
|
undefined
|
|
);
|
|
await updateCustomModel("p", "m", { isFree: true });
|
|
let rows = (await getCustomModels("p")) as CustomRow[];
|
|
assert.equal(rows.find((x) => x.id === "m").isFree, true);
|
|
// tri-state helper treats false as Boolean(false) → stored as false (falsy free), but only true is free per isFree guard
|
|
await updateCustomModel("p", "m", { isFree: false });
|
|
rows = await getCustomModels("p");
|
|
assert.equal(rows.find((x) => x.id === "m").isFree, false);
|
|
});
|
|
|
|
it("replaceCustomModels preserves isFree (new wins else prev)", async () => {
|
|
await addCustomModel(
|
|
"p",
|
|
"keep",
|
|
"K",
|
|
"manual",
|
|
"chat-completions",
|
|
["chat"],
|
|
undefined,
|
|
{},
|
|
undefined,
|
|
undefined,
|
|
true
|
|
);
|
|
await addCustomModel(
|
|
"p",
|
|
"override",
|
|
"O",
|
|
"manual",
|
|
"chat-completions",
|
|
["chat"],
|
|
undefined,
|
|
{},
|
|
undefined,
|
|
undefined,
|
|
undefined
|
|
);
|
|
// replace with new truth for override, omit for keep (prev should win)
|
|
await replaceCustomModels("p", [
|
|
{ id: "keep", name: "keep" },
|
|
{ id: "override", name: "override", isFree: true },
|
|
]);
|
|
const rows = (await getCustomModels("p")) as CustomRow[];
|
|
assert.equal(
|
|
rows.find((x) => x.id === "keep").isFree,
|
|
true,
|
|
"prev isFree preserved when new omits"
|
|
);
|
|
assert.equal(rows.find((x) => x.id === "override").isFree, true, "new isFree wins");
|
|
});
|
|
|
|
it("allowEmpty:false intact (no destructive clear)", async () => {
|
|
await addCustomModel(
|
|
"p",
|
|
"m",
|
|
"M",
|
|
"manual",
|
|
"chat-completions",
|
|
["chat"],
|
|
undefined,
|
|
{},
|
|
undefined,
|
|
undefined,
|
|
true
|
|
);
|
|
const before = (await getCustomModels("p")) as CustomRow[];
|
|
const after = await replaceCustomModels("p", [], { allowEmpty: false });
|
|
assert.equal(after.length, before.length);
|
|
});
|
|
});
|