Files
pulse-web/src/__tests__/Settings.test.jsx
2026-03-26 19:02:55 +00:00

120 lines
3.4 KiB
JavaScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { MemoryRouter } from 'react-router-dom'
import Settings from '../pages/Settings'
import { ThemeProvider } from '../contexts/ThemeContext'
vi.mock('../api/profile', () => ({
profileApi: {
get: vi.fn(),
update: vi.fn(),
},
}))
vi.mock('../components/Navigation', () => ({
default: () => <nav data-testid="navigation">Nav</nav>,
}))
import { profileApi } from '../api/profile'
const mockProfile = {
username: 'testuser',
telegram_chat_id: 123456,
notifications_enabled: true,
timezone: 'Europe/Moscow',
morning_reminder_time: '09:00',
evening_reminder_time: '21:00',
}
const renderSettings = () => {
const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } })
return render(
<QueryClientProvider client={qc}>
<MemoryRouter>
<ThemeProvider>
<Settings />
</ThemeProvider>
</MemoryRouter>
</QueryClientProvider>
)
}
describe('Settings page', () => {
beforeEach(() => {
vi.clearAllMocks()
profileApi.get.mockResolvedValue(mockProfile)
})
it('shows loading state', () => {
profileApi.get.mockReturnValue(new Promise(() => {}))
renderSettings()
expect(document.querySelector('.animate-spin')).toBeInTheDocument()
})
it('renders settings page', async () => {
renderSettings()
await waitFor(() => {
expect(screen.getByText('Настройки')).toBeInTheDocument()
})
})
it('renders theme section', async () => {
renderSettings()
await waitFor(() => {
expect(screen.getByText('Оформление')).toBeInTheDocument()
})
})
it('renders profile section', async () => {
renderSettings()
await waitFor(() => {
expect(screen.getByText('Профиль')).toBeInTheDocument()
})
})
it('populates username field from profile', async () => {
renderSettings()
await waitFor(() => {
const input = screen.getByDisplayValue('testuser')
expect(input).toBeInTheDocument()
})
})
it('toggles theme', async () => {
renderSettings()
await waitFor(() => {
expect(screen.getByText(/Тёмная тема|Светлая тема/)).toBeInTheDocument()
})
const themeBtn = screen.getByText(/Тёмная тема|Светлая тема/)
fireEvent.click(themeBtn)
expect(screen.getByText(/Тёмная тема|Светлая тема/)).toBeInTheDocument()
})
it('saves settings', async () => {
profileApi.update.mockResolvedValueOnce(mockProfile)
renderSettings()
await waitFor(() => {
expect(screen.getByDisplayValue('testuser')).toBeInTheDocument()
})
fireEvent.change(screen.getByDisplayValue('testuser'), {
target: { value: 'newusername' },
})
await waitFor(() => {
// Button says "Сохранить изменения" in Settings
expect(screen.getByText(/Сохранить/)).toBeInTheDocument()
})
fireEvent.click(screen.getByText(/Сохранить/))
await waitFor(() => {
expect(profileApi.update).toHaveBeenCalled()
})
})
it('renders Telegram section', async () => {
renderSettings()
await waitFor(() => {
expect(screen.getByText('Telegram')).toBeInTheDocument()
})
})
})