Files
diegosouzapw--omniroute/tests/unit/noauth-proxy-resolution.test.ts
2026-07-13 13:39:12 +08:00

94 lines
3.7 KiB
TypeScript

import { test } from "node:test";
import assert from "node:assert/strict";
import {
resolveAccountProxies,
type ProxyByIdLookup,
} from "../../src/sse/services/noAuthProxyResolution.ts";
// #5217 (Gap 1): per-account Proxy Pool reference resolution.
// The OpenCode Free per-account proxy modal now stores a proxy REFERENCE (proxyId)
// instead of forcing manual host/port re-entry. The server resolves that id to the
// live pool record so the executor still receives an inline {type,host,port,...}.
const POOL: Record<string, { type: string; host: string; port: number; username?: string; password?: string }> = {
"pool-1": { type: "http", host: "1.2.3.4", port: 8080, username: "u", password: "p" },
"pool-2": { type: "socks5", host: "9.9.9.9", port: 1080 },
};
const lookup: ProxyByIdLookup = async (id) => POOL[id] ?? null;
test("by-id reference resolves to the pool record (type/host/port/credentials)", async () => {
const out = await resolveAccountProxies([{ fingerprint: "acc-a", proxyId: "pool-1" }], lookup);
assert.equal(out.length, 1);
assert.equal(out[0].fingerprint, "acc-a");
assert.deepEqual(out[0].proxy, {
type: "http",
host: "1.2.3.4",
port: 8080,
username: "u",
password: "p",
});
});
test("by-id reference without credentials omits username/password", async () => {
const out = await resolveAccountProxies([{ fingerprint: "acc-b", proxyId: "pool-2" }], lookup);
assert.deepEqual(out[0].proxy, { type: "socks5", host: "9.9.9.9", port: 1080 });
});
test("inline custom proxy passes through unchanged (escape hatch / legacy)", async () => {
const inline = { type: "https", host: "5.6.7.8", port: 3128, username: "x", password: "y" };
const out = await resolveAccountProxies([{ fingerprint: "acc-c", proxy: inline }], lookup);
assert.deepEqual(out[0].proxy, inline);
});
test("unknown / deleted proxyId degrades safely to direct (null), no crash", async () => {
const out = await resolveAccountProxies([{ fingerprint: "acc-d", proxyId: "gone" }], lookup);
assert.equal(out.length, 1);
assert.equal(out[0].proxy, null);
});
test("a throwing lookup degrades to direct (null) rather than rejecting", async () => {
const throwing: ProxyByIdLookup = async () => {
throw new Error("db down");
};
const out = await resolveAccountProxies([{ fingerprint: "acc-e", proxyId: "pool-1" }], throwing);
assert.equal(out[0].proxy, null);
});
test("proxyId takes precedence over an inline proxy on the same entry", async () => {
const out = await resolveAccountProxies(
[{ fingerprint: "acc-f", proxyId: "pool-2", proxy: { type: "http", host: "0.0.0.0", port: 1 } }],
lookup
);
assert.equal(out[0].proxy?.host, "9.9.9.9");
});
test("entry with neither proxyId nor proxy.host yields direct (null)", async () => {
const out = await resolveAccountProxies(
[{ fingerprint: "acc-g" }, { fingerprint: "acc-h", proxy: null }],
lookup
);
assert.equal(out[0].proxy, null);
assert.equal(out[1].proxy, null);
});
test("non-array / malformed input is ignored without throwing", async () => {
assert.deepEqual(await resolveAccountProxies(undefined, lookup), []);
assert.deepEqual(await resolveAccountProxies(null, lookup), []);
const out = await resolveAccountProxies(
[null, 42, "x", { proxyId: "pool-1" }, { fingerprint: "ok", proxyId: "pool-2" }],
lookup
);
// Only the well-formed entry (with a string fingerprint) survives.
assert.equal(out.length, 1);
assert.equal(out[0].fingerprint, "ok");
});
test("inline proxy missing host is treated as direct (null)", async () => {
const out = await resolveAccountProxies(
[{ fingerprint: "acc-i", proxy: { type: "http", port: 8080 } as never }],
lookup
);
assert.equal(out[0].proxy, null);
});