Files
EasyCLIProxyAPI/tests/pluginOAuthProviders.test.ts
T
lzt404 3b11361f1b feat: refine management UI and enhance credential and plugin OAuth support
- Adopt a compact seven-column credential layout with visible quotas, request stats, and actions
- Display cooldown scope, countdowns, and model details with accessible reset controls
- Fix cooldown misassignment when merging same-named credentials from different accounts
- Add client visibility management with search, auto-detection, and persisted preferences
- Integrate plugin OAuth providers with deduplication and change synchronization
- Refine dashboard typography and spacing, and streamline usage history controls
- Add translations, unit tests, and responsive interaction coverage
2026-10-04 17:31:52 +08:00

113 lines
4.3 KiB
TypeScript

import { describe, expect, it } from 'bun:test';
import { collectPluginOAuthProviders } from '../src/services/pluginOAuthProviders';
import { getPluginTitle } from '../src/services/pluginResources';
import { normalizePluginList, type PluginListEntry } from '../src/services/plugins';
function rawPlugin(id: string, provider: string, overrides: Record<string, unknown> = {}) {
return {
id,
path: `plugins/windows/amd64/${id}.dll`,
configured: true,
registered: true,
enabled: true,
effective_enabled: true,
supports_oauth: true,
oauth_provider: provider,
supports_quota: false,
quota_provider: '',
logo: '',
config_fields: [],
menus: [],
metadata: null,
...overrides,
};
}
function normalize(plugins: unknown[]): PluginListEntry[] {
return normalizePluginList({
plugins_enabled: true,
plugins_dir: 'plugins',
plugins,
}).plugins;
}
describe('plugin OAuth provider discovery', () => {
it('shows ZCode and CodeBuddy from the backend capabilities without menus or quota support', () => {
const plugins = normalize([
rawPlugin('zcode', 'zcode', { metadata: { name: 'ZCode', version: '1.0.0' } }),
rawPlugin('codebuddy', 'codebuddy', { metadata: { name: 'CodeBuddy', version: '1.0.0' } }),
]);
const providers = collectPluginOAuthProviders(plugins);
expect(providers.map(plugin => plugin.oauthProvider)).toEqual(['zcode', 'codebuddy']);
expect(providers.map(getPluginTitle)).toEqual(['ZCode', 'CodeBuddy']);
expect(providers.every(plugin => plugin.menus.length === 0 && !plugin.supportsQuota)).toBe(true);
expect(providers[0]).toBe(plugins[0]);
expect(providers[1]).toBe(plugins[1]);
});
it('only includes effective plugins that declare OAuth and a valid provider key', () => {
const plugins = normalize([
rawPlugin('active', 'zcode'),
rawPlugin('disabled', 'disabled', { enabled: false, effective_enabled: false }),
rawPlugin('not-loaded', 'not-loaded', { registered: false, effective_enabled: false }),
rawPlugin('no-oauth', 'no-oauth', { supports_oauth: false }),
rawPlugin('missing-provider', ''),
rawPlugin('invalid-provider', '../config'),
]);
expect(collectPluginOAuthProviders(plugins).map(plugin => plugin.id)).toEqual(['active']);
});
it('rejects invalid provider keys even if an entry reaches the helper without normalization', () => {
const [plugin] = normalize([rawPlugin('active', 'zcode')]);
const invalidProviders = [undefined, '', ' ', '../config', 'a/b', 'a?b', 'https://provider.test'];
expect(collectPluginOAuthProviders(invalidProviders.map(oauthProvider => ({
...plugin, oauthProvider,
})))).toEqual([]);
});
it('deduplicates by OAuth provider and excludes built-ins rather than using plugin registration IDs', () => {
const plugins = normalize([
rawPlugin('disabled-copy', 'zcode', { effective_enabled: false }),
rawPlugin('zcode-auth-extension', 'zcode'),
rawPlugin('another-zcode-extension', 'zcode'),
rawPlugin('codex-auth-extension', 'codex'),
rawPlugin('claude-auth-extension', 'claude'),
rawPlugin('codebuddy-auth-extension', 'codebuddy'),
]);
expect(collectPluginOAuthProviders(plugins, ['codex', 'claude']).map(plugin => ({
id: plugin.id, provider: plugin.oauthProvider,
}))).toEqual([
{ id: 'zcode-auth-extension', provider: 'zcode' },
{ id: 'codebuddy-auth-extension', provider: 'codebuddy' },
]);
});
it('accepts future backend-declared providers without a provider name allowlist', () => {
const plugins = normalize([
rawPlugin('custom-auth-extension', ' Future-Provider-42 ', {
metadata: { name: 'Future Provider' },
}),
]);
const providers = collectPluginOAuthProviders(plugins, ['codex', 'claude']);
expect(providers).toHaveLength(1);
expect(providers[0].oauthProvider).toBe('future-provider-42');
expect(getPluginTitle(providers[0])).toBe('Future Provider');
});
it('keeps a usable plugin title when metadata is absent or its name is blank', () => {
const providers = collectPluginOAuthProviders(normalize([
rawPlugin('zcode', 'zcode'),
rawPlugin('codebuddy', 'codebuddy', { metadata: { name: ' ' } }),
]));
expect(providers.map(getPluginTitle)).toEqual(['zcode', 'codebuddy']);
});
});