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: () =>
Home Page
, }) const routeTree = rootRoute.addChildren([loginRoute, homeRoute]) const history = createMemoryHistory({ initialEntries: [initialPath] }) return createRouter({ routeTree, history }) } function renderLoginPage(router: ReturnType) { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } }) return render( , ) } 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() }) }) })