mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-02 05:02:27 +08:00
fix(unit): I believe it should pass now?
This commit is contained in:
parent
a8faf5d699
commit
40cad2e886
@ -4,7 +4,7 @@ import configurationManager from './configuration_manager.js';
|
|||||||
import optionService from '../../options.js';
|
import optionService from '../../options.js';
|
||||||
import type { ProviderType, ModelIdentifier, ModelConfig } from '../interfaces/configuration_interfaces.js';
|
import type { ProviderType, ModelIdentifier, ModelConfig } from '../interfaces/configuration_interfaces.js';
|
||||||
|
|
||||||
// Mock dependencies
|
// Mock dependencies - configuration manager is no longer used
|
||||||
vi.mock('./configuration_manager.js', () => ({
|
vi.mock('./configuration_manager.js', () => ({
|
||||||
default: {
|
default: {
|
||||||
parseModelIdentifier: vi.fn(),
|
parseModelIdentifier: vi.fn(),
|
||||||
@ -17,7 +17,8 @@ vi.mock('./configuration_manager.js', () => ({
|
|||||||
|
|
||||||
vi.mock('../../options.js', () => ({
|
vi.mock('../../options.js', () => ({
|
||||||
default: {
|
default: {
|
||||||
getOption: vi.fn()
|
getOption: vi.fn(),
|
||||||
|
getOptionBool: vi.fn()
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -66,144 +67,173 @@ describe('configuration_helpers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('parseModelIdentifier', () => {
|
describe('parseModelIdentifier', () => {
|
||||||
it('should delegate to configuration manager', () => {
|
it('should parse model identifier directly', () => {
|
||||||
const mockIdentifier: ModelIdentifier = {
|
const result = configHelpers.parseModelIdentifier('openai:gpt-4');
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({
|
||||||
provider: 'openai',
|
provider: 'openai',
|
||||||
modelId: 'gpt-4',
|
modelId: 'gpt-4',
|
||||||
fullIdentifier: 'openai:gpt-4'
|
fullIdentifier: 'openai:gpt-4'
|
||||||
};
|
});
|
||||||
vi.mocked(configurationManager.parseModelIdentifier).mockReturnValueOnce(mockIdentifier);
|
});
|
||||||
|
|
||||||
const result = configHelpers.parseModelIdentifier('openai:gpt-4');
|
it('should handle model without provider', () => {
|
||||||
|
const result = configHelpers.parseModelIdentifier('gpt-4');
|
||||||
|
|
||||||
expect(result).toBe(mockIdentifier);
|
expect(result).toStrictEqual({
|
||||||
expect(configurationManager.parseModelIdentifier).toHaveBeenCalledWith('openai:gpt-4');
|
modelId: 'gpt-4',
|
||||||
|
fullIdentifier: 'gpt-4'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle empty model string', () => {
|
||||||
|
const result = configHelpers.parseModelIdentifier('');
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({
|
||||||
|
modelId: '',
|
||||||
|
fullIdentifier: ''
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('createModelConfig', () => {
|
describe('createModelConfig', () => {
|
||||||
it('should delegate to configuration manager', () => {
|
it('should create model config directly', () => {
|
||||||
const mockConfig: ModelConfig = {
|
|
||||||
provider: 'openai',
|
|
||||||
modelId: 'gpt-4',
|
|
||||||
temperature: 0.7,
|
|
||||||
maxTokens: 1000
|
|
||||||
} as any;
|
|
||||||
vi.mocked(configurationManager.createModelConfig).mockReturnValueOnce(mockConfig);
|
|
||||||
|
|
||||||
const result = configHelpers.createModelConfig('gpt-4', 'openai');
|
const result = configHelpers.createModelConfig('gpt-4', 'openai');
|
||||||
|
|
||||||
expect(result).toBe(mockConfig);
|
expect(result).toStrictEqual({
|
||||||
expect(configurationManager.createModelConfig).toHaveBeenCalledWith('gpt-4', 'openai');
|
provider: 'openai',
|
||||||
|
modelId: 'gpt-4',
|
||||||
|
displayName: 'gpt-4'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle model with provider prefix', () => {
|
||||||
|
const result = configHelpers.createModelConfig('openai:gpt-4');
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({
|
||||||
|
provider: 'openai',
|
||||||
|
modelId: 'gpt-4',
|
||||||
|
displayName: 'openai:gpt-4'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fallback to openai provider when none specified', () => {
|
||||||
|
const result = configHelpers.createModelConfig('gpt-4');
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({
|
||||||
|
provider: 'openai',
|
||||||
|
modelId: 'gpt-4',
|
||||||
|
displayName: 'gpt-4'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getDefaultModelForProvider', () => {
|
describe('getDefaultModelForProvider', () => {
|
||||||
it('should return default model for provider', async () => {
|
it('should return default model for provider', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOption).mockReturnValue('gpt-4');
|
||||||
enabled: true,
|
|
||||||
selectedProvider: 'openai',
|
|
||||||
defaultModels: {
|
|
||||||
openai: 'gpt-4',
|
|
||||||
anthropic: 'claude-3',
|
|
||||||
ollama: 'llama2'
|
|
||||||
},
|
|
||||||
providerSettings: {}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.getDefaultModelForProvider('openai');
|
const result = await configHelpers.getDefaultModelForProvider('openai');
|
||||||
|
|
||||||
expect(result).toBe('gpt-4');
|
expect(result).toBe('gpt-4');
|
||||||
|
expect(optionService.getOption).toHaveBeenCalledWith('openaiDefaultModel');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return undefined if no default model', async () => {
|
it('should return undefined if no default model', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOption).mockReturnValue('');
|
||||||
enabled: true,
|
|
||||||
selectedProvider: 'openai',
|
|
||||||
defaultModels: {},
|
|
||||||
providerSettings: {}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.getDefaultModelForProvider('openai');
|
const result = await configHelpers.getDefaultModelForProvider('anthropic');
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
|
expect(optionService.getOption).toHaveBeenCalledWith('anthropicDefaultModel');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle ollama provider', async () => {
|
||||||
|
vi.mocked(optionService.getOption).mockReturnValue('llama2');
|
||||||
|
|
||||||
|
const result = await configHelpers.getDefaultModelForProvider('ollama');
|
||||||
|
|
||||||
|
expect(result).toBe('llama2');
|
||||||
|
expect(optionService.getOption).toHaveBeenCalledWith('ollamaDefaultModel');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getProviderSettings', () => {
|
describe('getProviderSettings', () => {
|
||||||
it('should return provider settings', async () => {
|
it('should return OpenAI provider settings', async () => {
|
||||||
const mockSettings = {
|
vi.mocked(optionService.getOption)
|
||||||
apiKey: 'test-key',
|
.mockReturnValueOnce('test-key') // openaiApiKey
|
||||||
baseUrl: 'https://api.openai.com'
|
.mockReturnValueOnce('https://api.openai.com') // openaiBaseUrl
|
||||||
};
|
.mockReturnValueOnce('gpt-4'); // openaiDefaultModel
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
|
||||||
enabled: true,
|
|
||||||
selectedProvider: 'openai',
|
|
||||||
defaultModels: {},
|
|
||||||
providerSettings: {
|
|
||||||
openai: mockSettings
|
|
||||||
}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.getProviderSettings('openai');
|
const result = await configHelpers.getProviderSettings('openai');
|
||||||
|
|
||||||
expect(result).toBe(mockSettings);
|
expect(result).toStrictEqual({
|
||||||
|
apiKey: 'test-key',
|
||||||
|
baseUrl: 'https://api.openai.com',
|
||||||
|
defaultModel: 'gpt-4'
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return undefined if no settings', async () => {
|
it('should return Anthropic provider settings', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOption)
|
||||||
enabled: true,
|
.mockReturnValueOnce('anthropic-key') // anthropicApiKey
|
||||||
selectedProvider: 'openai',
|
.mockReturnValueOnce('https://api.anthropic.com') // anthropicBaseUrl
|
||||||
defaultModels: {},
|
.mockReturnValueOnce('claude-3'); // anthropicDefaultModel
|
||||||
providerSettings: {}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.getProviderSettings('openai');
|
const result = await configHelpers.getProviderSettings('anthropic');
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toStrictEqual({
|
||||||
|
apiKey: 'anthropic-key',
|
||||||
|
baseUrl: 'https://api.anthropic.com',
|
||||||
|
defaultModel: 'claude-3'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return Ollama provider settings', async () => {
|
||||||
|
vi.mocked(optionService.getOption)
|
||||||
|
.mockReturnValueOnce('http://localhost:11434') // ollamaBaseUrl
|
||||||
|
.mockReturnValueOnce('llama2'); // ollamaDefaultModel
|
||||||
|
|
||||||
|
const result = await configHelpers.getProviderSettings('ollama');
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({
|
||||||
|
baseUrl: 'http://localhost:11434',
|
||||||
|
defaultModel: 'llama2'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty object for unknown provider', async () => {
|
||||||
|
const result = await configHelpers.getProviderSettings('unknown' as ProviderType);
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isAIEnabled', () => {
|
describe('isAIEnabled', () => {
|
||||||
it('should return true if AI is enabled', async () => {
|
it('should return true if AI is enabled', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOptionBool).mockReturnValue(true);
|
||||||
enabled: true,
|
|
||||||
selectedProvider: 'openai',
|
|
||||||
defaultModels: {},
|
|
||||||
providerSettings: {}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.isAIEnabled();
|
const result = await configHelpers.isAIEnabled();
|
||||||
|
|
||||||
expect(result).toBe(true);
|
expect(result).toBe(true);
|
||||||
|
expect(optionService.getOptionBool).toHaveBeenCalledWith('aiEnabled');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return false if AI is disabled', async () => {
|
it('should return false if AI is disabled', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOptionBool).mockReturnValue(false);
|
||||||
enabled: false,
|
|
||||||
selectedProvider: null,
|
|
||||||
defaultModels: {},
|
|
||||||
providerSettings: {}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.isAIEnabled();
|
const result = await configHelpers.isAIEnabled();
|
||||||
|
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
|
expect(optionService.getOptionBool).toHaveBeenCalledWith('aiEnabled');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('isProviderConfigured', () => {
|
describe('isProviderConfigured', () => {
|
||||||
it('should return true for configured OpenAI', async () => {
|
it('should return true for configured OpenAI', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOption)
|
||||||
enabled: true,
|
.mockReturnValueOnce('test-key') // openaiApiKey
|
||||||
selectedProvider: 'openai',
|
.mockReturnValueOnce('') // openaiBaseUrl
|
||||||
defaultModels: {},
|
.mockReturnValueOnce(''); // openaiDefaultModel
|
||||||
providerSettings: {
|
|
||||||
openai: {
|
|
||||||
apiKey: 'test-key'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.isProviderConfigured('openai');
|
const result = await configHelpers.isProviderConfigured('openai');
|
||||||
|
|
||||||
@ -211,14 +241,10 @@ describe('configuration_helpers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return false for unconfigured OpenAI', async () => {
|
it('should return false for unconfigured OpenAI', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOption)
|
||||||
enabled: true,
|
.mockReturnValueOnce('') // openaiApiKey (empty)
|
||||||
selectedProvider: 'openai',
|
.mockReturnValueOnce('') // openaiBaseUrl
|
||||||
defaultModels: {},
|
.mockReturnValueOnce(''); // openaiDefaultModel
|
||||||
providerSettings: {
|
|
||||||
openai: {}
|
|
||||||
}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.isProviderConfigured('openai');
|
const result = await configHelpers.isProviderConfigured('openai');
|
||||||
|
|
||||||
@ -226,16 +252,10 @@ describe('configuration_helpers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return true for configured Anthropic', async () => {
|
it('should return true for configured Anthropic', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOption)
|
||||||
enabled: true,
|
.mockReturnValueOnce('anthropic-key') // anthropicApiKey
|
||||||
selectedProvider: 'anthropic',
|
.mockReturnValueOnce('') // anthropicBaseUrl
|
||||||
defaultModels: {},
|
.mockReturnValueOnce(''); // anthropicDefaultModel
|
||||||
providerSettings: {
|
|
||||||
anthropic: {
|
|
||||||
apiKey: 'test-key'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.isProviderConfigured('anthropic');
|
const result = await configHelpers.isProviderConfigured('anthropic');
|
||||||
|
|
||||||
@ -243,16 +263,9 @@ describe('configuration_helpers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return true for configured Ollama', async () => {
|
it('should return true for configured Ollama', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
vi.mocked(optionService.getOption)
|
||||||
enabled: true,
|
.mockReturnValueOnce('http://localhost:11434') // ollamaBaseUrl
|
||||||
selectedProvider: 'ollama',
|
.mockReturnValueOnce(''); // ollamaDefaultModel
|
||||||
defaultModels: {},
|
|
||||||
providerSettings: {
|
|
||||||
ollama: {
|
|
||||||
baseUrl: 'http://localhost:11434'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.isProviderConfigured('ollama');
|
const result = await configHelpers.isProviderConfigured('ollama');
|
||||||
|
|
||||||
@ -260,13 +273,6 @@ describe('configuration_helpers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return false for unknown provider', async () => {
|
it('should return false for unknown provider', async () => {
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
|
||||||
enabled: true,
|
|
||||||
selectedProvider: null,
|
|
||||||
defaultModels: {},
|
|
||||||
providerSettings: {}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.isProviderConfigured('unknown' as ProviderType);
|
const result = await configHelpers.isProviderConfigured('unknown' as ProviderType);
|
||||||
|
|
||||||
expect(result).toBe(false);
|
expect(result).toBe(false);
|
||||||
@ -275,17 +281,11 @@ describe('configuration_helpers', () => {
|
|||||||
|
|
||||||
describe('getAvailableSelectedProvider', () => {
|
describe('getAvailableSelectedProvider', () => {
|
||||||
it('should return selected provider if configured', async () => {
|
it('should return selected provider if configured', async () => {
|
||||||
vi.mocked(optionService.getOption).mockReturnValueOnce('openai');
|
vi.mocked(optionService.getOption)
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
.mockReturnValueOnce('openai') // aiSelectedProvider
|
||||||
enabled: true,
|
.mockReturnValueOnce('test-key') // openaiApiKey
|
||||||
selectedProvider: 'openai',
|
.mockReturnValueOnce('') // openaiBaseUrl
|
||||||
defaultModels: {},
|
.mockReturnValueOnce(''); // openaiDefaultModel
|
||||||
providerSettings: {
|
|
||||||
openai: {
|
|
||||||
apiKey: 'test-key'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.getAvailableSelectedProvider();
|
const result = await configHelpers.getAvailableSelectedProvider();
|
||||||
|
|
||||||
@ -301,15 +301,11 @@ describe('configuration_helpers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return null if selected provider not configured', async () => {
|
it('should return null if selected provider not configured', async () => {
|
||||||
vi.mocked(optionService.getOption).mockReturnValueOnce('openai');
|
vi.mocked(optionService.getOption)
|
||||||
vi.mocked(configurationManager.getAIConfig).mockResolvedValueOnce({
|
.mockReturnValueOnce('openai') // aiSelectedProvider
|
||||||
enabled: true,
|
.mockReturnValueOnce('') // openaiApiKey (empty)
|
||||||
selectedProvider: 'openai',
|
.mockReturnValueOnce('') // openaiBaseUrl
|
||||||
defaultModels: {},
|
.mockReturnValueOnce(''); // openaiDefaultModel
|
||||||
providerSettings: {
|
|
||||||
openai: {} // No API key
|
|
||||||
}
|
|
||||||
} as any);
|
|
||||||
|
|
||||||
const result = await configHelpers.getAvailableSelectedProvider();
|
const result = await configHelpers.getAvailableSelectedProvider();
|
||||||
|
|
||||||
@ -318,18 +314,64 @@ describe('configuration_helpers', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('validateConfiguration', () => {
|
describe('validateConfiguration', () => {
|
||||||
it('should delegate to configuration manager', async () => {
|
it('should validate AI configuration directly', async () => {
|
||||||
const mockValidation = {
|
// Mock AI enabled = true, with selected provider and configured settings
|
||||||
isValid: true,
|
vi.mocked(optionService.getOptionBool).mockReturnValue(true);
|
||||||
errors: [],
|
vi.mocked(optionService.getOption)
|
||||||
warnings: []
|
.mockReturnValueOnce('openai') // aiSelectedProvider
|
||||||
};
|
.mockReturnValueOnce('test-key') // openaiApiKey
|
||||||
vi.mocked(configurationManager.validateConfig).mockResolvedValueOnce(mockValidation);
|
.mockReturnValueOnce('') // openaiBaseUrl
|
||||||
|
.mockReturnValueOnce('gpt-4'); // openaiDefaultModel
|
||||||
|
|
||||||
const result = await configHelpers.validateConfiguration();
|
const result = await configHelpers.validateConfiguration();
|
||||||
|
|
||||||
expect(result).toBe(mockValidation);
|
expect(result).toStrictEqual({
|
||||||
expect(configurationManager.validateConfig).toHaveBeenCalled();
|
isValid: true,
|
||||||
|
errors: [],
|
||||||
|
warnings: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return warning when AI is disabled', async () => {
|
||||||
|
vi.mocked(optionService.getOptionBool).mockReturnValue(false);
|
||||||
|
|
||||||
|
const result = await configHelpers.validateConfiguration();
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({
|
||||||
|
isValid: true,
|
||||||
|
errors: [],
|
||||||
|
warnings: ['AI features are disabled']
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return error when no provider selected', async () => {
|
||||||
|
vi.mocked(optionService.getOptionBool).mockReturnValue(true);
|
||||||
|
vi.mocked(optionService.getOption).mockReturnValue(''); // no aiSelectedProvider
|
||||||
|
|
||||||
|
const result = await configHelpers.validateConfiguration();
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({
|
||||||
|
isValid: false,
|
||||||
|
errors: ['No AI provider selected'],
|
||||||
|
warnings: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return warning when provider not configured', async () => {
|
||||||
|
vi.mocked(optionService.getOptionBool).mockReturnValue(true);
|
||||||
|
vi.mocked(optionService.getOption)
|
||||||
|
.mockReturnValueOnce('openai') // aiSelectedProvider
|
||||||
|
.mockReturnValueOnce('') // openaiApiKey (empty)
|
||||||
|
.mockReturnValueOnce('') // openaiBaseUrl
|
||||||
|
.mockReturnValueOnce(''); // openaiDefaultModel
|
||||||
|
|
||||||
|
const result = await configHelpers.validateConfiguration();
|
||||||
|
|
||||||
|
expect(result).toStrictEqual({
|
||||||
|
isValid: true,
|
||||||
|
errors: [],
|
||||||
|
warnings: ['OpenAI API key is not configured']
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user