mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-31 04:12:10 +03:00
Remove the Petals executor from registration and exports. Improve type safety by replacing broad any usage in MCP tool registration with inferred types and documenting dynamic handler type limitations. Add request validation for the agent bridge cert route and expand tests to ensure switch buttons explicitly declare type="button", preventing implicit form submissions.
98 lines
3.4 KiB
TypeScript
98 lines
3.4 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
const { validateProviderApiKey } = await import("../../src/lib/providers/validation.ts");
|
|
|
|
const originalFetch = globalThis.fetch;
|
|
|
|
test.afterEach(() => {
|
|
globalThis.fetch = originalFetch;
|
|
});
|
|
|
|
const imageOnlyProviders = {
|
|
"fal-ai": {
|
|
url: "https://api.fal.ai/v1/models?limit=1",
|
|
header: "Authorization",
|
|
value: "Key fal-ai-key",
|
|
},
|
|
"stability-ai": {
|
|
url: "https://api.stability.ai/v1/user/account",
|
|
header: "Authorization",
|
|
value: "Bearer stability-ai-key",
|
|
},
|
|
"black-forest-labs": {
|
|
url: "https://api.bfl.ai/v1/credits",
|
|
header: "x-key",
|
|
value: "black-forest-labs-key",
|
|
},
|
|
recraft: {
|
|
url: "https://external.api.recraft.ai/v1/users/me",
|
|
header: "Authorization",
|
|
value: "Bearer recraft-key",
|
|
},
|
|
topaz: {
|
|
url: "https://api.topazlabs.com/account/v1/credits/balance",
|
|
header: "X-API-Key",
|
|
value: "topaz-key",
|
|
},
|
|
};
|
|
|
|
const expectedValidationError = (status: number) =>
|
|
status === 429 ? "Validation rate limited (429)" : `Validation failed: ${status}`;
|
|
|
|
for (const [provider, config] of Object.entries(imageOnlyProviders)) {
|
|
test(`${provider} API key validator returns valid on 200`, async () => {
|
|
let fetchCalled = false;
|
|
globalThis.fetch = async (url, init = {}) => {
|
|
fetchCalled = true;
|
|
assert.equal(String(url), config.url);
|
|
assert.equal((init.headers as Record<string, string>)[config.header], config.value);
|
|
return new Response(JSON.stringify({ ok: true }), { status: 200 });
|
|
};
|
|
|
|
const result = await validateProviderApiKey({ provider, apiKey: `${provider}-key` });
|
|
|
|
assert.equal(result.valid, true, `${provider} should validate a 200 response`);
|
|
assert.equal(result.error, null, `${provider} should not return an error for 200`);
|
|
assert.equal(fetchCalled, true, `${provider} should call its validation endpoint`);
|
|
});
|
|
}
|
|
|
|
for (const provider of Object.keys(imageOnlyProviders)) {
|
|
for (const status of [401, 403]) {
|
|
test(`${provider} API key validator returns invalid on ${status}`, async () => {
|
|
let fetchCalled = false;
|
|
globalThis.fetch = async () => {
|
|
fetchCalled = true;
|
|
return new Response(JSON.stringify({ error: "unauthorized" }), { status });
|
|
};
|
|
|
|
const result = await validateProviderApiKey({ provider, apiKey: `${provider}-key` });
|
|
|
|
assert.equal(result.valid, false, `${provider} should reject ${status}`);
|
|
assert.equal(result.error, "Invalid API key", `${provider} should surface auth failure`);
|
|
assert.equal(fetchCalled, true, `${provider} should call its validation endpoint`);
|
|
});
|
|
}
|
|
|
|
for (const status of [400, 404, 429]) {
|
|
test(`${provider} API key validator returns validation failed on ${status}`, async () => {
|
|
let fetchCalled = false;
|
|
globalThis.fetch = async () => {
|
|
fetchCalled = true;
|
|
return new Response(JSON.stringify({ error: "validation failed" }), { status });
|
|
};
|
|
|
|
const result = await validateProviderApiKey({ provider, apiKey: `${provider}-key` });
|
|
|
|
assert.equal(result.valid, false, `${provider} should reject ${status}`);
|
|
assert.equal(
|
|
result.error,
|
|
expectedValidationError(status),
|
|
`${provider} should surface validation failure`
|
|
);
|
|
assert.equal(fetchCalled, true, `${provider} should call its validation endpoint`);
|
|
});
|
|
}
|
|
}
|