import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { PreferenceSettings } from './PreferenceSettings'; import { PreferenceSettings as PreferenceSettingsType } from '../../types/settings'; // Mock ResizeObserver for tests global.ResizeObserver = vi.fn().mockImplementation(() => ({ observe: vi.fn(), unobserve: vi.fn(), disconnect: vi.fn(), })); // Mock Select component vi.mock('@/components/ui/select', () => ({ Select: ({ value, onChange, options, placeholder }: any) => (
), })); // Mock RadioGroup vi.mock('@/components/ui/radio-group', () => ({ RadioGroup: ({ children, value, onValueChange }: any) => (
{children}
), RadioGroupItem: ({ value, id }: any) => ( ), })); // Mock Label vi.mock('@/components/ui/label', () => ({ Label: ({ children, htmlFor }: any) => ( ), })); // Mock useTranslation hook vi.mock('@/hooks/useTranslation', () => ({ useTranslation: () => ({ t: (key: string) => { const translations: Record = { 'settings.language.language': 'Language', 'settings.language.title': 'Language and Region', 'settings.preferences.timezone': 'Time Zone', 'settings.language.description': 'Choose your preferred language', 'settings.appearance.theme': 'Theme', 'settings.appearance.light': 'Light', 'settings.appearance.dark': 'Dark', 'settings.appearance.system': 'System', 'common.search': 'Search', }; return translations[key] ?? key; }, changeLanguage: vi.fn(), language: 'en', isReady: true, }), })); describe('PreferenceSettings Component', () => { const mockPreferences: PreferenceSettingsType = { language: 'en', timezone: 'UTC', theme: 'auto', }; const mockOnChange = vi.fn(); beforeEach(() => { vi.clearAllMocks(); }); it('should render all preference fields', () => { render( , ); expect(screen.getByText('Language')).toBeInTheDocument(); // Bug #18: label was "Language and Region", now correctly "Time Zone" expect(screen.getByText('Time Zone')).toBeInTheDocument(); expect(screen.getByText('Theme')).toBeInTheDocument(); expect(screen.getByTestId('radio-group')).toBeInTheDocument(); }); it('should display current language value', () => { render( , ); const selects = screen.getAllByTestId('select'); const languageSelect = selects[0].querySelector('select'); expect(languageSelect).toHaveValue('en'); }); it('should call onChange when language changes', () => { render( , ); const selects = screen.getAllByTestId('select'); const languageSelect = selects[0].querySelector('select'); if (languageSelect) { fireEvent.change(languageSelect, { target: { value: 'fr' } }); expect(mockOnChange).toHaveBeenCalledWith({ ...mockPreferences, language: 'fr', }); } }); it('should display current timezone value', () => { render( , ); const selects = screen.getAllByTestId('select'); const timezoneSelect = selects[1].querySelector('select'); expect(timezoneSelect).toHaveValue('UTC'); }); it('should call onChange when timezone changes', () => { render( , ); const selects = screen.getAllByTestId('select'); const timezoneSelect = selects[1].querySelector('select'); if (timezoneSelect) { fireEvent.change(timezoneSelect, { target: { value: 'Europe/Paris' } }); expect(mockOnChange).toHaveBeenCalledWith({ ...mockPreferences, timezone: 'Europe/Paris', }); } }); it('should display current theme value', () => { render( , ); const radioGroup = screen.getByTestId('radio-group'); expect(radioGroup).toHaveAttribute('data-value', 'auto'); }); it('should call onChange when theme changes to light', () => { render( , ); const lightButton = screen.getByText('Select Light'); fireEvent.click(lightButton); expect(mockOnChange).toHaveBeenCalledWith({ ...mockPreferences, theme: 'light', }); }); it('should call onChange when theme changes to dark', () => { render( , ); const darkButton = screen.getByText('Select Dark'); fireEvent.click(darkButton); expect(mockOnChange).toHaveBeenCalledWith({ ...mockPreferences, theme: 'dark', }); }); it('should call onChange when theme changes to auto', () => { render( , ); const autoButton = screen.getByText('Select Auto'); fireEvent.click(autoButton); expect(mockOnChange).toHaveBeenCalledWith({ ...mockPreferences, theme: 'auto', }); }); it('should render all theme options', () => { render( , ); expect(screen.getByTestId('radio-light')).toBeInTheDocument(); expect(screen.getByTestId('radio-dark')).toBeInTheDocument(); expect(screen.getByTestId('radio-auto')).toBeInTheDocument(); }); });