mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-21 06:12:17 +03:00
A write that does not send a proxy `status` (subscription refresh, bulk import, PATCH) no longer turns a disabled or dead proxy back on; the stored status is kept. Real DB-backed tests through `upsertProxy`, the subscription sync against a local feed and `handleProxyUpdate`.
Validated first on the combined board of all 38 PRs of this batch (10 merged as-is, 28 after the maintainer rework) on top of release/v3.8.51 c0f92ec: typecheck:core, check:open-sse-typecheck and check:dashboard-typecheck clean; ESLint clean on every changed file; file-size (rebaselined for the combined growth), complexity, cognitive-complexity, changelog-integrity, docs-counts, docs-sync, migration-numbering and i18n new-key gates green; 735 focused node:test cases with the only batch-caused failure (a flag-count assertion) fixed. Then re-validated alone on the fresh release tip right before this merge: ESLint on the changed files, typecheck:core, check:open-sse-typecheck, the file-size/complexity/changelog gates and this PR's own tests.
Thanks @maxmad64bis!
96 lines
3.5 KiB
TypeScript
96 lines
3.5 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";
|
|
|
|
// zod 4 applies .default() even under .partial(), so a default status on the shared
|
|
// proxy field schema rewrote the stored status on every update or import that simply
|
|
// omitted it. These tests pin "a status is written only when the caller sends one".
|
|
|
|
const TEST_DATA_DIR = fs.mkdtempSync(path.join(os.tmpdir(), "omniroute-proxy-status-schema-"));
|
|
process.env.DATA_DIR = TEST_DATA_DIR;
|
|
process.env.API_KEY_SECRET = "test-secret";
|
|
|
|
const core = await import("../../src/lib/db/core.ts");
|
|
const proxiesDb = await import("../../src/lib/db/proxies.ts");
|
|
const schemas = await import("../../src/shared/validation/schemas/proxy.ts");
|
|
const statuses = await import("../../src/shared/constants/proxyRegistryStatus.ts");
|
|
const { handleProxyUpdate } = await import("../../src/lib/api/proxyRegistryRouteHandlers.ts");
|
|
|
|
function resetStorage() {
|
|
core.resetDbInstance();
|
|
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
fs.mkdirSync(TEST_DATA_DIR, { recursive: true });
|
|
}
|
|
|
|
test.after(() => {
|
|
core.resetDbInstance();
|
|
fs.rmSync(TEST_DATA_DIR, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
});
|
|
|
|
test("update schema does not invent a status the client did not send", () => {
|
|
const parsed = schemas.updateProxyRegistrySchema.parse({ id: "row-1", name: "renamed" });
|
|
assert.equal("status" in parsed, false);
|
|
});
|
|
|
|
test("bulk import schema does not invent a status the client did not send", () => {
|
|
const parsed = schemas.bulkImportProxiesSchema.parse({
|
|
items: [{ name: "n", host: "proxy.example.com", port: 8080 }],
|
|
});
|
|
assert.equal("status" in parsed.items[0], false);
|
|
});
|
|
|
|
test("an explicit status is still validated against the enumeration", () => {
|
|
const bad = schemas.bulkImportProxiesSchema.safeParse({
|
|
items: [{ name: "n", host: "proxy.example.com", port: 8080, status: "bogus" }],
|
|
});
|
|
assert.equal(bad.success, false);
|
|
const good = schemas.updateProxyRegistrySchema.parse({ id: "row-2", status: "inactive" });
|
|
assert.equal(good.status, "inactive");
|
|
});
|
|
|
|
test("isProxyRegistryStatus accepts only the enumerated statuses", () => {
|
|
for (const value of ["active", "inactive", "dead"]) {
|
|
assert.equal(statuses.isProxyRegistryStatus(value), true, value);
|
|
}
|
|
for (const value of ["", "error", "ACTIVE", undefined, null, 1]) {
|
|
assert.equal(statuses.isProxyRegistryStatus(value), false, String(value));
|
|
}
|
|
});
|
|
|
|
test("renaming a dead proxy through the update handler keeps it dead", async () => {
|
|
resetStorage();
|
|
const created = await proxiesDb.createProxy({
|
|
name: "before",
|
|
type: "http",
|
|
host: "10.1.0.1",
|
|
port: 8080,
|
|
});
|
|
await proxiesDb.updateProxy(created.id, { status: "dead" });
|
|
|
|
const response = await handleProxyUpdate(
|
|
new Request("http://localhost/api/v1/management/proxies", {
|
|
method: "PATCH",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ id: created.id, name: "after" }),
|
|
})
|
|
);
|
|
|
|
assert.equal(response.status, 200);
|
|
const row = await proxiesDb.getProxyById(created.id);
|
|
assert.equal(row?.name, "after");
|
|
assert.equal(row?.status, "dead");
|
|
});
|
|
|
|
test("creating a proxy without a status still creates it active", async () => {
|
|
resetStorage();
|
|
const created = await proxiesDb.createProxy({
|
|
name: "fresh",
|
|
type: "http",
|
|
host: "10.1.0.2",
|
|
port: 8080,
|
|
});
|
|
assert.equal((await proxiesDb.getProxyById(created.id))?.status, "active");
|
|
});
|