File size: 5,927 Bytes
5448d8b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | /**
* T-02 auth-hook contract tests.
*
* Covers the `createOmniRouteAuthHook(opts)` factory and its loader behaviour
* against every Auth flavor (`api`, `oauth`, null, empty key). Validates the
* multi-instance fix: provider id flows from plugin options, not a module
* constant.
*/
import test from "node:test";
import assert from "node:assert/strict";
import { createOmniRouteAuthHook } from "../src/index.js";
test("createOmniRouteAuthHook: default providerId is 'omniroute'", () => {
const hook = createOmniRouteAuthHook();
assert.equal(hook.provider, "omniroute");
});
test("createOmniRouteAuthHook: custom providerId binds to hook.provider (multi-instance)", () => {
const hook = createOmniRouteAuthHook({ providerId: "omniroute-preprod" });
assert.equal(hook.provider, "omniroute-preprod");
});
test("createOmniRouteAuthHook: methods[0] is type 'api' with label including displayName", () => {
const hook = createOmniRouteAuthHook();
assert.equal(Array.isArray(hook.methods), true);
assert.equal(hook.methods.length, 1);
const m = hook.methods[0];
assert.equal(m.type, "api");
assert.equal(m.label, "OmniRoute API Key");
const custom = createOmniRouteAuthHook({ providerId: "omniroute-preprod" });
assert.equal(custom.methods[0].label, "OmniRoute (omniroute-preprod) API Key");
});
test("createOmniRouteAuthHook: prompts[0] uses key='apiKey' per @opencode-ai/plugin contract", () => {
// NOTE: spec referenced `name: "apiKey"`; the official
// @opencode-ai/plugin@1.15.6 prompt shape uses `key` + `message` (no
// `name`/`label`/`mask` fields). Asserting against the real type contract.
const hook = createOmniRouteAuthHook();
const m = hook.methods[0];
assert.equal(m.type, "api");
// narrow: api method may carry prompts
const prompts = "prompts" in m ? m.prompts : undefined;
assert.ok(Array.isArray(prompts) && prompts.length === 1, "expected one prompt");
const p = prompts![0];
assert.equal(p.type, "text");
assert.equal((p as { key: string }).key, "apiKey");
assert.ok(
typeof (p as { message: string }).message === "string" &&
(p as { message: string }).message.includes("omniroute"),
"prompt message should mention provider id"
);
});
test("loader: valid api auth β {apiKey} when no baseURL option (T-04: fetch omitted)", async () => {
// T-04 changed the loader return shape: without a resolvable baseURL the
// interceptor cannot gate-keep requests, so the loader falls back to
// apiKey-only and the AI-SDK uses its default fetch. See fetch-interceptor
// tests for the wired-fetch branches.
const hook = createOmniRouteAuthHook();
assert.ok(hook.loader, "loader must be defined");
const result = await hook.loader!(
async () => ({ type: "api", key: "sk-test" }) as never,
{} as never
);
assert.deepEqual(result, { apiKey: "sk-test" });
});
test("loader: valid api auth β {apiKey, baseURL, fetch} when baseURL option set (T-04)", async () => {
const hook = createOmniRouteAuthHook({ baseURL: "https://or.example.com/v1" });
const result = await hook.loader!(
async () => ({ type: "api", key: "sk-x" }) as never,
{} as never
);
assert.equal((result as { apiKey: string }).apiKey, "sk-x");
assert.equal((result as { baseURL: string }).baseURL, "https://or.example.com/v1");
assert.equal(
typeof (result as { fetch?: unknown }).fetch,
"function",
"T-04: loader must wire fetch interceptor when baseURL resolves"
);
});
test("loader: features.fetchInterceptor=false AND geminiSanitization=false β no custom fetch (flags honored)", async () => {
// Regression: both fetch-layer flags were documented + schema-validated but
// silently ignored. Disabling both must fall back to the SDK default fetch.
const hook = createOmniRouteAuthHook({
baseURL: "https://or.example.com/v1",
features: { fetchInterceptor: false, geminiSanitization: false },
});
const result = await hook.loader!(
async () => ({ type: "api", key: "sk-x" }) as never,
{} as never
);
assert.deepEqual(result, { apiKey: "sk-x", baseURL: "https://or.example.com/v1" });
assert.equal(
(result as { fetch?: unknown }).fetch,
undefined,
"both flags off must omit the custom fetch"
);
});
test("loader: features.fetchInterceptor=false but geminiSanitization=true β fetch still wired (sanitizer only)", async () => {
const hook = createOmniRouteAuthHook({
baseURL: "https://or.example.com/v1",
features: { fetchInterceptor: false, geminiSanitization: true },
});
const result = await hook.loader!(
async () => ({ type: "api", key: "sk-x" }) as never,
{} as never
);
assert.equal(
typeof (result as { fetch?: unknown }).fetch,
"function",
"geminiSanitization alone must still provide a fetch wrapper"
);
});
test("loader: null/undefined auth β {} (no creds yet, OC surfaces /connect)", async () => {
const hook = createOmniRouteAuthHook();
const r1 = await hook.loader!(async () => null as never, {} as never);
assert.deepEqual(r1, {});
const r2 = await hook.loader!(async () => undefined as never, {} as never);
assert.deepEqual(r2, {});
});
test("loader: oauth-flavored auth β {} (wrong method type, ignored)", async () => {
const hook = createOmniRouteAuthHook();
const result = await hook.loader!(
async () =>
({
type: "oauth",
refresh: "r",
access: "a",
expires: 0,
}) as never,
{} as never
);
assert.deepEqual(result, {});
});
test("loader: api auth with empty key β {} (empty creds rejected)", async () => {
const hook = createOmniRouteAuthHook();
const result = await hook.loader!(async () => ({ type: "api", key: "" }) as never, {} as never);
assert.deepEqual(result, {});
});
|