moex-vibe/apps/frontend/src/pages/login/LoginPage.test.tsx

109 lines
3.9 KiB
TypeScript

import { server } from '@mocks/server'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import {
createMemoryHistory,
createRootRoute,
createRoute,
createRouter,
RouterProvider,
} from '@tanstack/react-router'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { HttpResponse, http } from 'msw'
import { describe, expect, it } from 'vitest'
import { TestSessionProvider } from '@/shared/lib/test/TestSessionProvider'
import { LoginPage } from './ui/LoginPage'
const API = '/api/v1'
function loginTestRouter(initialPath: string) {
const rootRoute = createRootRoute()
const loginRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/login',
component: LoginPage,
})
const homeRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
component: () => <div>Home Page</div>,
})
const routeTree = rootRoute.addChildren([loginRoute, homeRoute])
const history = createMemoryHistory({ initialEntries: [initialPath] })
return createRouter({ routeTree, history })
}
function renderLoginPage(router: ReturnType<typeof loginTestRouter>) {
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } })
return render(
<QueryClientProvider client={queryClient}>
<TestSessionProvider>
<RouterProvider router={router} />
</TestSessionProvider>
</QueryClientProvider>,
)
}
describe('LoginPage', () => {
it('renders login form', async () => {
server.use(http.post(`${API}/auth/refresh`, () => new HttpResponse(null, { status: 401 })))
renderLoginPage(loginTestRouter('/login'))
expect(await screen.findByText('Вход')).toBeInTheDocument()
expect(screen.getByPlaceholderText('email@example.com')).toBeInTheDocument()
expect(screen.getByPlaceholderText('••••••••')).toBeInTheDocument()
})
it('redirects on successful login', async () => {
server.use(http.post(`${API}/auth/refresh`, () => new HttpResponse(null, { status: 401 })))
const user = userEvent.setup()
renderLoginPage(loginTestRouter('/login'))
await screen.findByText('Вход')
await user.type(screen.getByPlaceholderText('email@example.com'), 'test@test.com')
await user.type(screen.getByPlaceholderText('••••••••'), 'password')
await user.click(screen.getByRole('button', { name: 'Войти' }))
await screen.findByText('Home Page')
})
it('shows error on failed login', async () => {
server.use(
http.post(`${API}/auth/refresh`, () => new HttpResponse(null, { status: 401 })),
http.post(
`${API}/auth/login`,
() => new HttpResponse(null, { status: 401, statusText: 'Unauthorized' }),
),
)
const user = userEvent.setup()
renderLoginPage(loginTestRouter('/login'))
await screen.findByText('Вход')
await user.type(screen.getByPlaceholderText('email@example.com'), 'bad@test.com')
await user.type(screen.getByPlaceholderText('••••••••'), 'wrong')
await user.click(screen.getByRole('button', { name: 'Войти' }))
expect(await screen.findByText(/Ошибка API/)).toBeInTheDocument()
})
it('shows loading state while submitting', async () => {
server.use(
http.post(`${API}/auth/refresh`, () => new HttpResponse(null, { status: 401 })),
http.post(`${API}/auth/login`, () => new Promise(() => {})),
)
const user = userEvent.setup()
renderLoginPage(loginTestRouter('/login'))
await screen.findByText('Вход')
await user.type(screen.getByPlaceholderText('email@example.com'), 'test@test.com')
await user.type(screen.getByPlaceholderText('••••••••'), 'password')
await user.click(screen.getByRole('button', { name: 'Войти' }))
await waitFor(() => {
expect(screen.getByRole('button', { name: 'Войти' })).toBeDisabled()
})
})
})