import { describe, it, expect, vi, afterEach } from 'vitest'; import { screen, waitFor, fireEvent } from '@solidjs/testing-library'; import { renderWithProviders } from '../test-utils'; import { DEFAULT_SETTINGS } from '~/types'; import type { UserSettings, ProviderConfig } from '~/types'; // Mock API modules vi.mock('~/api/settings', () => ({ settingsApi: { get: vi.fn(), update: vi.fn(), }, })); vi.mock('~/api/config', () => ({ configApi: { listProviders: vi.fn(), }, })); vi.mock('~/api/apiKeys', () => ({ apiKeysApi: { list: vi.fn(), create: vi.fn(), remove: vi.fn(), test: vi.fn(), exportKeys: vi.fn(), }, })); import { settingsApi } from '~/api/settings'; import { configApi } from '~/api/config'; import { apiKeysApi } from '~/api/apiKeys'; import Settings from '~/pages/Settings'; const mockedGetSettings = vi.mocked(settingsApi.get); const mockedUpdateSettings = vi.mocked(settingsApi.update); const mockedListProviders = vi.mocked(configApi.listProviders); const mockedListKeys = vi.mocked(apiKeysApi.list); const mockSettings: UserSettings = { ...DEFAULT_SETTINGS, theme: 'Intelligence Artificielle', ai_provider: 'gemini', ai_model: 'gemini-2.5-pro', ai_model_writing: 'gemini-2.5-flash', rate_limit_max_requests: null, rate_limit_time_window_seconds: null, }; const mockProviders: ProviderConfig[] = [ { provider_name: 'gemini', display_name: 'Google Gemini', models: [ { model_id: 'gemini-2.5-pro', display_name: 'Gemini 2.5 Pro' }, { model_id: 'gemini-2.5-flash', display_name: 'Gemini 2.5 Flash' }, ], }, { provider_name: 'openai', display_name: 'OpenAI', models: [ { model_id: 'gpt-4o', display_name: 'GPT-4o' }, { model_id: 'gpt-4o-mini', display_name: 'GPT-4o Mini' }, ], }, ]; afterEach(() => { vi.clearAllMocks(); }); describe('Settings Page', () => { it('should render form fields populated from API response', async () => { mockedGetSettings.mockResolvedValue(mockSettings); mockedListProviders.mockResolvedValue(mockProviders); mockedListKeys.mockResolvedValue([]); renderWithProviders(() => ); await waitFor(() => { const themeInput = screen.getByLabelText( 'Theme de la recherche', ) as HTMLInputElement; expect(themeInput.value).toBe('Intelligence Artificielle'); }); }); it('should call PUT /settings when save button is clicked', async () => { mockedGetSettings.mockResolvedValue(mockSettings); mockedListProviders.mockResolvedValue(mockProviders); mockedListKeys.mockResolvedValue([]); mockedUpdateSettings.mockResolvedValue(mockSettings); renderWithProviders(() => ); await waitFor(() => { expect( screen.getByLabelText('Theme de la recherche'), ).toBeInTheDocument(); }); const saveButton = screen.getByText('Enregistrer les parametres'); fireEvent.click(saveButton); await waitFor(() => { expect(mockedUpdateSettings).toHaveBeenCalled(); }); }); it('should populate provider dropdown from config API', async () => { mockedGetSettings.mockResolvedValue(mockSettings); mockedListProviders.mockResolvedValue(mockProviders); mockedListKeys.mockResolvedValue([]); renderWithProviders(() => ); // The provider names appear in the dropdown (