import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { ProvidersSettings } from '@/components/settings/ProvidersSettings'; const baseProviderState = { statuses: [ { id: 'moonshot-existing', name: 'Moonshot Existing', type: 'moonshot', model: 'kimi-k2.6', enabled: true, createdAt: '2026-06-19T00:00:00.000Z', updatedAt: '2026-06-19T00:00:00.000Z', hasKey: true, keyMasked: 'sk-***', }, ], accounts: [ { id: 'moonshot-existing', vendorId: 'moonshot', label: 'Moonshot Existing', authMode: 'api_key', model: 'kimi-k2.6', enabled: true, isDefault: true, createdAt: '2026-06-19T00:00:00.000Z', updatedAt: '2026-06-19T00:00:00.000Z', }, ], vendors: [], defaultAccountId: 'moonshot-existing', loading: false, refreshProviderSnapshot: vi.fn().mockResolvedValue(undefined), createAccount: vi.fn().mockResolvedValue(undefined), removeAccount: vi.fn().mockResolvedValue(undefined), updateAccount: vi.fn().mockResolvedValue(undefined), setDefaultAccount: vi.fn().mockResolvedValue(undefined), importUserModelConfig: vi.fn().mockResolvedValue({ account: { id: 'niancode-user-models', vendorId: 'custom', label: 'Makelore Models', authMode: 'api_key', enabled: true, isDefault: true, createdAt: '2026-06-19T00:00:00.000Z', updatedAt: '2026-06-19T00:00:00.000Z', }, importedModels: ['gpt-4.1-mini'], }), validateAccountApiKey: vi.fn().mockResolvedValue({ valid: true }), }; let providerState: typeof baseProviderState; const authState = { accessToken: null as string | null, }; vi.mock('@/stores/settings', () => ({ useSettingsStore: (selector: (state: { devModeUnlocked: boolean }) => unknown) => selector({ devModeUnlocked: true }), })); vi.mock('@/stores/auth', () => ({ useAuthStore: (selector: (state: { accessToken: string | null }) => unknown) => selector(authState), })); vi.mock('@/stores/providers', () => ({ useProviderStore: () => providerState, })); vi.mock('react-i18next', () => ({ useTranslation: () => ({ i18n: { language: 'en' }, t: (key: string, fallback?: string) => fallback ?? key, }), })); describe('ProvidersSettings', () => { beforeEach(() => { providerState = { ...baseProviderState, statuses: [...baseProviderState.statuses], accounts: [...baseProviderState.accounts], importUserModelConfig: vi.fn().mockResolvedValue({ account: { id: 'niancode-user-models', vendorId: 'custom', label: 'Makelore Models', authMode: 'api_key', enabled: true, isDefault: true, createdAt: '2026-06-19T00:00:00.000Z', updatedAt: '2026-06-19T00:00:00.000Z', }, importedModels: ['gpt-4.1-mini'], }), }; authState.accessToken = null; vi.clearAllMocks(); }); it('keeps add, edit, and delete controls available after one provider is configured', () => { render(); const editButton = screen.getByTestId('provider-edit-moonshot-existing'); const deleteButton = screen.getByTestId('provider-delete-moonshot-existing'); expect(editButton).toBeVisible(); expect(deleteButton).toBeVisible(); expect(editButton.parentElement).not.toHaveClass('opacity-0'); fireEvent.click(screen.getByTestId('providers-add-button')); expect(screen.getByTestId('add-provider-type-moonshot')).toBeVisible(); }); it('syncs current user model config even when the NianCode model account already exists', async () => { authState.accessToken = 'access-token'; providerState.accounts = [ { id: 'niancode-user-models', vendorId: 'custom', label: 'Old Makelore Models', authMode: 'api_key', model: 'old-model', fallbackModels: ['old-fallback'], enabled: true, isDefault: true, createdAt: '2026-06-19T00:00:00.000Z', updatedAt: '2026-06-19T00:00:00.000Z', }, ]; render(); await waitFor(() => { expect(providerState.importUserModelConfig).toHaveBeenCalledWith('access-token'); }); }); });