settings-validation.test.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { describe, it, expect } from 'vitest';
  2. import {
  3. isProviderUsable,
  4. validateProvider,
  5. validateModel,
  6. type ProviderCfgLike,
  7. } from '@/lib/store/settings-validation';
  8. describe('isProviderUsable', () => {
  9. it('returns true when provider has client API key', () => {
  10. expect(isProviderUsable({ apiKey: 'sk-xxx' })).toBe(true);
  11. });
  12. it('returns true when provider is server-configured', () => {
  13. expect(isProviderUsable({ isServerConfigured: true })).toBe(true);
  14. });
  15. it('returns true when provider has both client key and server config', () => {
  16. expect(isProviderUsable({ apiKey: 'sk-xxx', isServerConfigured: true })).toBe(true);
  17. });
  18. it('returns false when has neither client key nor server config', () => {
  19. expect(isProviderUsable({ apiKey: '', isServerConfigured: false })).toBe(false);
  20. });
  21. it('returns false when apiKey is empty and not server-configured', () => {
  22. expect(isProviderUsable({ apiKey: '' })).toBe(false);
  23. });
  24. it('returns false for undefined config', () => {
  25. expect(isProviderUsable(undefined)).toBe(false);
  26. });
  27. it('returns false for empty object', () => {
  28. expect(isProviderUsable({})).toBe(false);
  29. });
  30. });
  31. describe('validateProvider', () => {
  32. const cfg = (overrides: Partial<ProviderCfgLike> = {}): ProviderCfgLike => ({
  33. apiKey: '',
  34. isServerConfigured: false,
  35. ...overrides,
  36. });
  37. it('keeps current provider when it is server-configured', () => {
  38. const configMap = {
  39. 'provider-a': cfg({ isServerConfigured: true }),
  40. 'provider-b': cfg(),
  41. };
  42. expect(validateProvider('provider-a', configMap, ['provider-b'])).toBe('provider-a');
  43. });
  44. it('keeps current provider when it has client API key', () => {
  45. const configMap = {
  46. 'provider-a': cfg({ apiKey: 'sk-xxx' }),
  47. 'provider-b': cfg(),
  48. };
  49. expect(validateProvider('provider-a', configMap, ['provider-b'])).toBe('provider-a');
  50. });
  51. it('falls back to first usable provider when current is unusable', () => {
  52. const configMap = {
  53. 'provider-a': cfg(),
  54. 'provider-b': cfg({ isServerConfigured: true }),
  55. };
  56. expect(validateProvider('provider-a', configMap, ['provider-b'])).toBe('provider-b');
  57. });
  58. it('returns empty string when no fallback is usable and no default', () => {
  59. const configMap = {
  60. 'provider-a': cfg(),
  61. 'provider-b': cfg(),
  62. };
  63. expect(validateProvider('provider-a', configMap, ['provider-b'])).toBe('');
  64. });
  65. it('falls back to defaultId when no fallback is usable', () => {
  66. const configMap = {
  67. 'provider-a': cfg(),
  68. 'provider-b': cfg(),
  69. };
  70. expect(validateProvider('provider-a', configMap, ['provider-b'], 'browser-native')).toBe(
  71. 'browser-native',
  72. );
  73. });
  74. it('prefers usable fallback over defaultId', () => {
  75. const configMap = {
  76. 'provider-a': cfg(),
  77. 'provider-b': cfg({ isServerConfigured: true }),
  78. };
  79. expect(validateProvider('provider-a', configMap, ['provider-b'], 'browser-native')).toBe(
  80. 'provider-b',
  81. );
  82. });
  83. it('returns current id unchanged when it is empty', () => {
  84. const configMap = { 'provider-a': cfg({ isServerConfigured: true }) };
  85. expect(validateProvider('', configMap, ['provider-a'])).toBe('');
  86. });
  87. });
  88. describe('validateModel', () => {
  89. it('keeps model when still in available list', () => {
  90. expect(validateModel('gpt-4o', [{ id: 'gpt-4o' }, { id: 'gpt-4o-mini' }])).toBe('gpt-4o');
  91. });
  92. it('falls back to first model when current is not in list', () => {
  93. expect(validateModel('gpt-4-turbo', [{ id: 'gpt-4o' }, { id: 'gpt-4o-mini' }])).toBe('gpt-4o');
  94. });
  95. it('returns empty string when list is empty', () => {
  96. expect(validateModel('gpt-4o', [])).toBe('');
  97. });
  98. it('returns current id unchanged when it is empty', () => {
  99. expect(validateModel('', [{ id: 'gpt-4o' }])).toBe('');
  100. });
  101. });