Files
DeskClaw/tests/unit/providers.test.ts
2026-03-08 00:00:47 +08:00

120 lines
4.6 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
PROVIDER_TYPES,
PROVIDER_TYPE_INFO,
resolveProviderApiKeyForSave,
resolveProviderModelForSave,
shouldShowProviderModelId,
} from '@/lib/providers';
import {
BUILTIN_PROVIDER_TYPES,
getProviderConfig,
getProviderEnvVar,
getProviderEnvVars,
} from '@electron/utils/provider-registry';
describe('provider metadata', () => {
it('includes ark in the frontend provider registry', () => {
expect(PROVIDER_TYPES).toContain('ark');
expect(PROVIDER_TYPE_INFO).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: 'ark',
name: 'ByteDance Ark',
requiresApiKey: true,
defaultBaseUrl: 'https://ark.cn-beijing.volces.com/api/v3',
showBaseUrl: true,
showModelId: true,
}),
])
);
});
it('includes ark in the backend provider registry', () => {
expect(BUILTIN_PROVIDER_TYPES).toContain('ark');
expect(getProviderEnvVar('ark')).toBe('ARK_API_KEY');
expect(getProviderConfig('ark')).toEqual({
baseUrl: 'https://ark.cn-beijing.volces.com/api/v3',
api: 'openai-completions',
apiKeyEnv: 'ARK_API_KEY',
});
});
it('uses a single canonical env key for moonshot provider', () => {
expect(getProviderEnvVar('moonshot')).toBe('MOONSHOT_API_KEY');
expect(getProviderEnvVars('moonshot')).toEqual(['MOONSHOT_API_KEY']);
expect(getProviderConfig('moonshot')).toEqual(
expect.objectContaining({
baseUrl: 'https://api.moonshot.cn/v1',
apiKeyEnv: 'MOONSHOT_API_KEY',
})
);
});
it('keeps builtin provider sources in sync', () => {
expect(BUILTIN_PROVIDER_TYPES).toEqual(
expect.arrayContaining(['anthropic', 'openai', 'google', 'openrouter', 'ark', 'moonshot', 'siliconflow', 'minimax-portal', 'minimax-portal-cn', 'qwen-portal', 'ollama'])
);
});
it('uses OpenAI-compatible Ollama default base URL', () => {
expect(PROVIDER_TYPE_INFO).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: 'ollama',
defaultBaseUrl: 'http://localhost:11434/v1',
requiresApiKey: false,
showBaseUrl: true,
showModelId: true,
}),
])
);
});
it('only exposes OpenRouter and SiliconFlow model overrides in developer mode', () => {
const openrouter = PROVIDER_TYPE_INFO.find((provider) => provider.id === 'openrouter');
const siliconflow = PROVIDER_TYPE_INFO.find((provider) => provider.id === 'siliconflow');
expect(openrouter).toMatchObject({
showModelId: true,
showModelIdInDevModeOnly: true,
defaultModelId: 'anthropic/claude-opus-4.6',
});
expect(siliconflow).toMatchObject({
showModelId: true,
showModelIdInDevModeOnly: true,
defaultModelId: 'deepseek-ai/DeepSeek-V3',
});
expect(shouldShowProviderModelId(openrouter, false)).toBe(false);
expect(shouldShowProviderModelId(siliconflow, false)).toBe(false);
expect(shouldShowProviderModelId(openrouter, true)).toBe(true);
expect(shouldShowProviderModelId(siliconflow, true)).toBe(true);
});
it('only saves OpenRouter and SiliconFlow model overrides in developer mode', () => {
const openrouter = PROVIDER_TYPE_INFO.find((provider) => provider.id === 'openrouter');
const siliconflow = PROVIDER_TYPE_INFO.find((provider) => provider.id === 'siliconflow');
const ark = PROVIDER_TYPE_INFO.find((provider) => provider.id === 'ark');
expect(resolveProviderModelForSave(openrouter, 'openai/gpt-5', false)).toBeUndefined();
expect(resolveProviderModelForSave(siliconflow, 'Qwen/Qwen3-Coder-480B-A35B-Instruct', false)).toBeUndefined();
expect(resolveProviderModelForSave(openrouter, 'openai/gpt-5', true)).toBe('openai/gpt-5');
expect(resolveProviderModelForSave(siliconflow, 'Qwen/Qwen3-Coder-480B-A35B-Instruct', true)).toBe('Qwen/Qwen3-Coder-480B-A35B-Instruct');
expect(resolveProviderModelForSave(openrouter, ' ', true)).toBe('anthropic/claude-opus-4.6');
expect(resolveProviderModelForSave(siliconflow, ' ', true)).toBe('deepseek-ai/DeepSeek-V3');
expect(resolveProviderModelForSave(ark, ' ep-custom-model ', false)).toBe('ep-custom-model');
});
it('normalizes provider API keys for save flow', () => {
expect(resolveProviderApiKeyForSave('ollama', '')).toBe('ollama-local');
expect(resolveProviderApiKeyForSave('ollama', ' ')).toBe('ollama-local');
expect(resolveProviderApiKeyForSave('ollama', 'real-key')).toBe('real-key');
expect(resolveProviderApiKeyForSave('openai', '')).toBeUndefined();
expect(resolveProviderApiKeyForSave('openai', ' sk-test ')).toBe('sk-test');
});
});