205 lines
5.3 KiB
TypeScript
205 lines
5.3 KiB
TypeScript
import { render, screen, waitFor, fireEvent } from '@testing-library/react';
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { BrowserRouter } from 'react-router-dom';
|
|
import { SettingsPage } from './SettingsPage';
|
|
import * as settingsService from '../services/settingsService';
|
|
import { UserSettings } from '../types/settings';
|
|
import { ToastProvider } from '@/components/feedback/ToastProvider';
|
|
|
|
// Mock ResizeObserver for tests
|
|
global.ResizeObserver = vi.fn().mockImplementation(() => ({
|
|
observe: vi.fn(),
|
|
unobserve: vi.fn(),
|
|
disconnect: vi.fn(),
|
|
}));
|
|
|
|
// Mock settingsService
|
|
vi.mock('../services/settingsService', () => ({
|
|
getSettings: vi.fn(),
|
|
updateSettings: vi.fn(),
|
|
}));
|
|
|
|
// Mock useAuthStore
|
|
vi.mock('@/stores/auth', () => ({
|
|
useAuthStore: () => ({
|
|
user: {
|
|
id: 1,
|
|
username: 'testuser',
|
|
email: 'test@example.com',
|
|
},
|
|
}),
|
|
}));
|
|
|
|
// Mock SettingsTabs
|
|
vi.mock('../components/SettingsTabs', () => ({
|
|
SettingsTabs: ({ settings, onChange }: { settings: UserSettings; onChange: (s: UserSettings) => void }) => (
|
|
<div data-testid="settings-tabs">
|
|
<button onClick={() => onChange({ ...settings, preferences: { ...settings.preferences, language: 'fr' } })}>
|
|
Change Language
|
|
</button>
|
|
</div>
|
|
),
|
|
}));
|
|
|
|
const TestWrapper = ({ children }: { children: React.ReactNode }) => (
|
|
<BrowserRouter>
|
|
<ToastProvider>
|
|
{children}
|
|
</ToastProvider>
|
|
</BrowserRouter>
|
|
);
|
|
|
|
describe('SettingsPage', () => {
|
|
const mockSettings: UserSettings = {
|
|
notifications: {
|
|
email_notifications: true,
|
|
push_notifications: true,
|
|
browser_notifications: true,
|
|
email_on_follow: true,
|
|
email_on_like: true,
|
|
email_on_comment: true,
|
|
email_on_message: true,
|
|
email_on_mention: true,
|
|
email_marketing: false,
|
|
},
|
|
privacy: {
|
|
allow_search_indexing: true,
|
|
show_activity: true,
|
|
},
|
|
content: {
|
|
explicit_content: false,
|
|
autoplay: true,
|
|
},
|
|
preferences: {
|
|
language: 'en',
|
|
timezone: 'UTC',
|
|
theme: 'auto',
|
|
},
|
|
};
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it('should load and display settings', async () => {
|
|
vi.mocked(settingsService.getSettings).mockResolvedValue(mockSettings);
|
|
|
|
render(
|
|
<TestWrapper>
|
|
<SettingsPage />
|
|
</TestWrapper>
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Paramètres')).toBeInTheDocument();
|
|
});
|
|
|
|
expect(screen.getByText('Gérez vos paramètres de compte et préférences')).toBeInTheDocument();
|
|
expect(screen.getByTestId('settings-tabs')).toBeInTheDocument();
|
|
expect(screen.getByText('Sauvegarder')).toBeInTheDocument();
|
|
});
|
|
|
|
it('should display loading state', () => {
|
|
vi.mocked(settingsService.getSettings).mockImplementation(
|
|
() => new Promise(() => {}) // Never resolves
|
|
);
|
|
|
|
render(
|
|
<TestWrapper>
|
|
<SettingsPage />
|
|
</TestWrapper>
|
|
);
|
|
|
|
// Should show loading spinner
|
|
expect(screen.queryByText('Paramètres')).not.toBeInTheDocument();
|
|
});
|
|
|
|
it('should save settings on button click', async () => {
|
|
vi.mocked(settingsService.getSettings).mockResolvedValue(mockSettings);
|
|
vi.mocked(settingsService.updateSettings).mockResolvedValue();
|
|
|
|
render(
|
|
<TestWrapper>
|
|
<SettingsPage />
|
|
</TestWrapper>
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Sauvegarder')).toBeInTheDocument();
|
|
});
|
|
|
|
const saveButton = screen.getByText('Sauvegarder');
|
|
fireEvent.click(saveButton);
|
|
|
|
await waitFor(() => {
|
|
expect(settingsService.updateSettings).toHaveBeenCalledWith(1, mockSettings);
|
|
});
|
|
});
|
|
|
|
it('should display validation errors', async () => {
|
|
const invalidSettings: UserSettings = {
|
|
...mockSettings,
|
|
preferences: {
|
|
...mockSettings.preferences,
|
|
language: 'invalid-lang' as any, // Invalid language
|
|
},
|
|
};
|
|
|
|
vi.mocked(settingsService.getSettings).mockResolvedValue(invalidSettings);
|
|
|
|
render(
|
|
<TestWrapper>
|
|
<SettingsPage />
|
|
</TestWrapper>
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Sauvegarder')).toBeInTheDocument();
|
|
});
|
|
|
|
const saveButton = screen.getByText('Sauvegarder');
|
|
fireEvent.click(saveButton);
|
|
|
|
// Validation should prevent save
|
|
await waitFor(() => {
|
|
expect(settingsService.updateSettings).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
it('should handle load error', async () => {
|
|
vi.mocked(settingsService.getSettings).mockRejectedValue(new Error('Failed to load settings'));
|
|
|
|
render(
|
|
<TestWrapper>
|
|
<SettingsPage />
|
|
</TestWrapper>
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Erreur de chargement des paramètres')).toBeInTheDocument();
|
|
});
|
|
});
|
|
|
|
it('should handle save error', async () => {
|
|
vi.mocked(settingsService.getSettings).mockResolvedValue(mockSettings);
|
|
vi.mocked(settingsService.updateSettings).mockRejectedValue(new Error('Failed to save'));
|
|
|
|
render(
|
|
<TestWrapper>
|
|
<SettingsPage />
|
|
</TestWrapper>
|
|
);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('Sauvegarder')).toBeInTheDocument();
|
|
});
|
|
|
|
const saveButton = screen.getByText('Sauvegarder');
|
|
fireEvent.click(saveButton);
|
|
|
|
await waitFor(() => {
|
|
expect(settingsService.updateSettings).toHaveBeenCalled();
|
|
});
|
|
});
|
|
});
|
|
|