test: add comprehensive tests for pages, components, contexts (194 tests, 27 files)
Some checks failed
CI / lint-test (push) Failing after 1s
Some checks failed
CI / lint-test (push) Failing after 1s
This commit is contained in:
116
src/__tests__/ResetPassword.test.jsx
Normal file
116
src/__tests__/ResetPassword.test.jsx
Normal file
@@ -0,0 +1,116 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom'
|
||||
import ResetPassword from '../pages/ResetPassword'
|
||||
|
||||
vi.mock('../api/client', () => ({
|
||||
default: {
|
||||
post: vi.fn(),
|
||||
get: vi.fn(),
|
||||
interceptors: {
|
||||
request: { use: vi.fn() },
|
||||
response: { use: vi.fn() },
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
import api from '../api/client'
|
||||
|
||||
const mockNavigate = vi.fn()
|
||||
vi.mock('react-router-dom', async (importOriginal) => {
|
||||
const actual = await importOriginal()
|
||||
return {
|
||||
...actual,
|
||||
useNavigate: () => mockNavigate,
|
||||
}
|
||||
})
|
||||
|
||||
describe('ResetPassword page', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
const renderPage = (search = '') =>
|
||||
render(
|
||||
<MemoryRouter initialEntries={[`/reset-password${search}`]}>
|
||||
<Routes>
|
||||
<Route path="/reset-password" element={<ResetPassword />} />
|
||||
</Routes>
|
||||
</MemoryRouter>
|
||||
)
|
||||
|
||||
it('renders form', () => {
|
||||
renderPage('?token=abc')
|
||||
// Use getAllByText since "Новый пароль" appears as h1 and label
|
||||
expect(screen.getAllByText('Новый пароль').length).toBeGreaterThan(0)
|
||||
expect(screen.getByPlaceholderText('Минимум 8 символов')).toBeInTheDocument()
|
||||
expect(screen.getByText('Сохранить пароль')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('shows error when no token on submit', async () => {
|
||||
renderPage()
|
||||
fireEvent.change(screen.getByPlaceholderText('Минимум 8 символов'), {
|
||||
target: { value: 'newpassword123' },
|
||||
})
|
||||
fireEvent.click(screen.getByText('Сохранить пароль'))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Токен не найден')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it('shows success state on successful reset', async () => {
|
||||
api.post.mockResolvedValueOnce({})
|
||||
renderPage('?token=valid-token')
|
||||
|
||||
fireEvent.change(screen.getByPlaceholderText('Минимум 8 символов'), {
|
||||
target: { value: 'newpassword123' },
|
||||
})
|
||||
fireEvent.click(screen.getByText('Сохранить пароль'))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Пароль изменён! 🎉')).toBeInTheDocument()
|
||||
}, { timeout: 3000 })
|
||||
})
|
||||
|
||||
it('shows error on failure', async () => {
|
||||
api.post.mockRejectedValueOnce({ response: { data: { error: 'Token invalid' } } })
|
||||
renderPage('?token=bad-token')
|
||||
|
||||
fireEvent.change(screen.getByPlaceholderText('Минимум 8 символов'), {
|
||||
target: { value: 'newpassword123' },
|
||||
})
|
||||
fireEvent.click(screen.getByText('Сохранить пароль'))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Token invalid')).toBeInTheDocument()
|
||||
}, { timeout: 3000 })
|
||||
})
|
||||
|
||||
it('toggles password visibility', () => {
|
||||
renderPage('?token=abc')
|
||||
const passwordInput = screen.getByPlaceholderText('Минимум 8 символов')
|
||||
expect(passwordInput.type).toBe('password')
|
||||
|
||||
const toggleBtn = passwordInput.parentElement.querySelector('button[type="button"]')
|
||||
fireEvent.click(toggleBtn)
|
||||
expect(passwordInput.type).toBe('text')
|
||||
})
|
||||
|
||||
it('calls correct API endpoint', async () => {
|
||||
api.post.mockResolvedValueOnce({})
|
||||
renderPage('?token=mytoken')
|
||||
|
||||
fireEvent.change(screen.getByPlaceholderText('Минимум 8 символов'), {
|
||||
target: { value: 'mynewpassword' },
|
||||
})
|
||||
fireEvent.click(screen.getByText('Сохранить пароль'))
|
||||
|
||||
await waitFor(() => {
|
||||
expect(api.post).toHaveBeenCalledWith('/auth/reset-password', {
|
||||
token: 'mytoken',
|
||||
new_password: 'mynewpassword',
|
||||
})
|
||||
}, { timeout: 3000 })
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user