import { describe, it, expect, beforeEach, vi } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import { ProviderForm } from './provider-form';
import { useSettingsStore } from '@/store/use-settings';
// Mock ConnectionStatus component
vi.mock('./connection-status', () => ({
ConnectionStatus: () =>
Connection Status
,
}));
describe('ProviderForm', () => {
beforeEach(() => {
// Reset store state
useSettingsStore.setState({
apiKey: '',
baseUrl: 'https://api.openai.com/v1',
modelName: 'gpt-4-turbo-preview',
isConfigured: false,
});
});
it('renders all required input fields', () => {
render();
expect(screen.getByLabelText(/base url/i)).toBeInTheDocument();
expect(screen.getByLabelText(/model name/i)).toBeInTheDocument();
// Use placeholder for API key since show/hide button has "API key" in aria-label
expect(screen.getByPlaceholderText('sk-...')).toBeInTheDocument();
});
it('shows helper text for API key', () => {
render();
expect(screen.getByText(/stored locally in your browser with basic encoding/i)).toBeInTheDocument();
});
it('has show/hide toggle for API key', () => {
render();
const apiKeyInput = screen.getByPlaceholderText('sk-...') as HTMLInputElement;
const toggleButton = screen.getByRole('button', { name: /show/i });
// Initially password type
expect(apiKeyInput.type).toBe('password');
// Click show button
fireEvent.click(toggleButton);
// Should change to text type
expect(apiKeyInput.type).toBe('text');
});
it('updates base URL when user types', () => {
render();
const baseUrlInput = screen.getByLabelText(/base url/i);
fireEvent.change(baseUrlInput, { target: { value: 'https://api.deepseek.com/v1' } });
const state = useSettingsStore.getState();
expect(state.baseUrl).toBe('https://api.deepseek.com/v1');
});
it('updates model name when user types', () => {
render();
const modelInput = screen.getByLabelText(/model name/i);
fireEvent.change(modelInput, { target: { value: 'deepseek-chat' } });
const state = useSettingsStore.getState();
expect(state.modelName).toBe('deepseek-chat');
});
it('updates API key when user types', () => {
render();
const apiKeyInput = screen.getByPlaceholderText('sk-...');
fireEvent.change(apiKeyInput, { target: { value: 'sk-test-key-12345' } });
const state = useSettingsStore.getState();
expect(state.apiKey).toBe('sk-test-key-12345');
expect(state.isConfigured).toBe(true);
});
it('displays current values from store', () => {
useSettingsStore.setState({
apiKey: 'sk-existing-key',
baseUrl: 'https://api.custom.com/v1',
modelName: 'custom-model',
isConfigured: true,
});
render();
expect(screen.getByPlaceholderText('sk-...')).toHaveValue('sk-existing-key');
expect(screen.getByLabelText(/base url/i)).toHaveValue('https://api.custom.com/v1');
expect(screen.getByLabelText(/model name/i)).toHaveValue('custom-model');
});
it('renders ConnectionStatus component', () => {
render();
expect(screen.getByTestId('connection-status')).toBeInTheDocument();
});
it('has proper accessibility attributes', () => {
render();
// All inputs should have associated labels
expect(screen.getByLabelText(/base url/i)).toBeInTheDocument();
expect(screen.getByLabelText(/model name/i)).toBeInTheDocument();
expect(screen.getByPlaceholderText('sk-...')).toBeInTheDocument();
});
it('displays provider preset buttons', () => {
render();
expect(screen.getByRole('button', { name: 'OpenAI' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'DeepSeek' })).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'OpenRouter' })).toBeInTheDocument();
});
it('applies preset when clicked', () => {
render();
const deepseekButton = screen.getByRole('button', { name: 'DeepSeek' });
fireEvent.click(deepseekButton);
const state = useSettingsStore.getState();
expect(state.baseUrl).toBe('https://api.deepseek.com/v1');
expect(state.modelName).toBe('deepseek-chat');
});
});