openreader/tests/unit/tts-settings-admin-view-model.spec.ts
Richard R 913c6d5d76 refactor(tts,config,admin): update provider resolution logic and ordering for consistency
Remove fallbackProviderRef usage from settings and config context to streamline
provider resolution. Adjust normalizeLegacyProviderRef to retain 'default-openai'
unless a non-default fallback is explicitly provided. Update provider listing to
enforce deterministic ordering by updatedAt, createdAt, and slug. Expand unit tests
to verify provider ordering, legacy ref normalization, and selection logic.
2026-05-13 12:08:39 -06:00

149 lines
4.7 KiB
TypeScript

import { expect, test } from '@playwright/test';
import { resolveTtsSettingsViewModel } from '../../src/lib/client/settings/tts-settings';
import type { SharedProviderEntry } from '../../src/hooks/useSharedProviders';
const SHARED: SharedProviderEntry[] = [
{
slug: 'shared-openai',
displayName: 'OpenAI Shared',
providerType: 'openai',
defaultModel: 'gpt-4o-mini-tts',
defaultInstructions: 'Default shared instructions',
},
{
slug: 'shared-replicate',
displayName: 'Replicate Shared',
providerType: 'replicate',
defaultModel: 'owner/model:ver',
defaultInstructions: null,
},
];
test.describe('resolveTtsSettingsViewModel (admin/shared modes)', () => {
test('keeps default-openai selection when that shared provider exists', () => {
const vm = resolveTtsSettingsViewModel({
providerRef: 'default-openai',
providerType: 'unknown',
modelValue: 'kokoro',
customModelInput: '',
showAllDeepInfra: false,
showAllProviderModels: true,
sharedProviders: [
{
slug: 'default-openai',
displayName: 'Default OpenAI',
providerType: 'openai',
defaultModel: 'gpt-4o-mini-tts',
defaultInstructions: null,
},
...SHARED,
],
allowBuiltInProviders: false,
});
expect(vm.selectedProviderRef).toBe('default-openai');
expect(vm.selectedSharedProvider?.slug).toBe('default-openai');
expect(vm.selectedModelId).toBe('gpt-4o-mini-tts');
});
test('restrict mode exposes only shared providers', () => {
const vm = resolveTtsSettingsViewModel({
providerRef: 'shared-openai',
providerType: 'unknown',
modelValue: 'gpt-4o-mini-tts',
customModelInput: '',
showAllDeepInfra: false,
showAllProviderModels: true,
sharedProviders: SHARED,
allowBuiltInProviders: false,
});
expect(vm.providers.map((p) => p.id)).toEqual(['shared-openai', 'shared-replicate']);
expect(vm.providers.every((p) => p.shared)).toBe(true);
});
test('invalid provider falls back to first available option', () => {
const vm = resolveTtsSettingsViewModel({
providerRef: 'missing-provider',
providerType: 'unknown',
modelValue: 'kokoro',
customModelInput: '',
showAllDeepInfra: false,
showAllProviderModels: true,
sharedProviders: SHARED,
allowBuiltInProviders: false,
});
expect(vm.selectedSharedProvider?.slug).toBe('shared-openai');
expect(vm.selectedModelId).toBe('gpt-4o-mini-tts');
});
test('custom-model capable providers use custom mode for unknown model ids', () => {
const vm = resolveTtsSettingsViewModel({
providerRef: 'shared-replicate',
providerType: 'unknown',
modelValue: 'my-custom-model',
customModelInput: '',
showAllDeepInfra: false,
showAllProviderModels: true,
sharedProviders: SHARED,
allowBuiltInProviders: false,
});
expect(vm.supportsCustomModel).toBe(true);
expect(vm.selectedModelId).toBe('custom');
expect(vm.canSubmit).toBe(false);
});
test('non-custom providers fall back to preset model selection', () => {
const vm = resolveTtsSettingsViewModel({
providerRef: 'shared-openai',
providerType: 'unknown',
modelValue: 'not-in-presets',
customModelInput: '',
showAllDeepInfra: false,
showAllProviderModels: true,
sharedProviders: SHARED,
allowBuiltInProviders: false,
});
expect(vm.supportsCustomModel).toBe(false);
expect(vm.selectedModelId).not.toBe('custom');
expect(vm.models.length).toBeGreaterThan(0);
});
test('legacy default-openai provider ref normalizes to first shared provider', () => {
const vm = resolveTtsSettingsViewModel({
providerRef: 'default-openai',
providerType: 'unknown',
modelValue: 'kokoro',
customModelInput: '',
showAllDeepInfra: false,
showAllProviderModels: true,
sharedProviders: SHARED,
allowBuiltInProviders: false,
});
expect(vm.selectedProviderRef).toBe('shared-openai');
expect(vm.selectedModelId).toBe('gpt-4o-mini-tts');
});
test('showAllProviderModels=false locks model picker to provider default', () => {
const vm = resolveTtsSettingsViewModel({
providerRef: 'shared-replicate',
providerType: 'unknown',
modelValue: 'my-custom-model',
customModelInput: 'my-custom-model',
showAllDeepInfra: false,
showAllProviderModels: false,
sharedProviders: SHARED,
allowBuiltInProviders: false,
});
expect(vm.models).toEqual([{ id: 'owner/model:ver', name: 'owner/model:ver' }]);
expect(vm.supportsCustomModel).toBe(false);
expect(vm.selectedModelId).toBe('owner/model:ver');
expect(vm.canSubmit).toBe(true);
});
});