Files
Cli-Proxy-API-Management-Ce…/tests/providerWeightTransformers.test.ts
Supra4E8C 8faaa39534 feat: add support for weighted round-robin routing strategy and credential weight management
- Implemented 'weighted-round-robin' as a new routing strategy in DashboardPage.
- Introduced weight input fields in ApiKeyEntriesEditor, BaseProviderForm, and SponsorProviderForm.
- Added validation for credential weights, including integer checks and maximum limits.
- Updated localization files to include new weight-related labels and hints.
- Created utility functions for credential weight validation and parsing.
- Added tests for credential weight handling and visual config routing strategy.
2026-07-30 07:22:24 +08:00

107 lines
3.2 KiB
TypeScript

import { afterEach, describe, expect, test } from 'bun:test';
import { apiClient } from '../src/services/api/client';
import { providersApi } from '../src/services/api/providers';
import {
normalizeGeminiKeyConfig,
normalizeOpenAIProvider,
normalizeProviderKeyConfig,
} from '../src/services/api/transformers';
const originalGet = apiClient.get;
const originalPut = apiClient.put;
afterEach(() => {
apiClient.get = originalGet;
apiClient.put = originalPut;
});
describe('provider credential weight normalization', () => {
test('reads weight for direct API key credentials', () => {
expect(normalizeGeminiKeyConfig({ 'api-key': 'gemini-key', weight: 5 })?.weight).toBe(5);
expect(normalizeProviderKeyConfig({ 'api-key': 'provider-key', weight: 0 })?.weight).toBe(0);
});
test('reads per-key weight for OpenAI-compatible providers', () => {
const provider = normalizeOpenAIProvider({
name: 'example',
'base-url': 'https://example.com/v1',
'api-key-entries': [{ 'api-key': 'key-a', weight: 3 }, { 'api-key': 'key-b' }],
});
expect(provider?.apiKeyEntries[0]?.weight).toBe(3);
expect(provider?.apiKeyEntries[1]?.weight).toBeUndefined();
});
test('removes a cleared Vertex weight while preserving unknown fields', async () => {
let written: unknown;
apiClient.get = (async () => ({
'vertex-api-key': [
{
'api-key': 'vertex-key',
'base-url': 'https://vertex.example',
weight: 9,
'future-field': 'keep',
},
],
})) as typeof apiClient.get;
apiClient.put = (async (_url: string, data?: unknown) => {
written = data;
return undefined;
}) as typeof apiClient.put;
await providersApi.updateVertexConfig('vertex-key', 'https://vertex.example', {
apiKey: 'vertex-key',
baseUrl: 'https://vertex.example',
weight: undefined,
});
expect(written).toEqual([
{
'api-key': 'vertex-key',
'base-url': 'https://vertex.example',
'future-field': 'keep',
},
]);
});
test('writes and clears nested OpenAI-compatible key weights', async () => {
let written: unknown;
apiClient.get = (async () => ({
'openai-compatibility': [
{
name: 'example',
'base-url': 'https://example.com/v1',
'api-key-entries': [
{ 'api-key': 'key-a', weight: 8, custom: 'keep-a' },
{ 'api-key': 'key-b', custom: 'keep-b' },
],
},
],
})) as typeof apiClient.get;
apiClient.put = (async (_url: string, data?: unknown) => {
written = data;
return undefined;
}) as typeof apiClient.put;
await providersApi.updateOpenAIProvider('example', 0, {
name: 'example',
baseUrl: 'https://example.com/v1',
apiKeyEntries: [
{ apiKey: 'key-a', weight: undefined },
{ apiKey: 'key-b', weight: 4 },
],
});
expect(written).toEqual([
{
name: 'example',
'base-url': 'https://example.com/v1',
'api-key-entries': [
{ 'api-key': 'key-a', custom: 'keep-a' },
{ 'api-key': 'key-b', custom: 'keep-b', weight: 4 },
],
},
]);
});
});