import { describe, expect, it } from 'vitest'; import { screen, waitFor } from '@testing-library/react'; import { apiError, installFetch, installFailingFetch, json, makeUser, renderApp } from './helpers'; describe('защита маршрутов', () => { it('неавторизованного на /app отправляет на /login', async () => { installFetch([ { match: '/api/v1/users/@me', response: () => apiError('auth.unauthorized', 401) }, ]); const { router } = renderApp('/app'); await waitFor(() => { expect(router.state.location.pathname).toBe('/login'); }); expect(await screen.findByLabelText('Почта')).toBeVisible(); }); it('пользователя с onboarding_completed=false отправляет на /onboarding', async () => { const user = makeUser({ onboarding_completed: false }); installFetch([{ match: '/api/v1/users/@me', response: () => json({ user }) }]); const { router } = renderApp('/app'); await waitFor(() => { expect(router.state.location.pathname).toBe('/onboarding'); }); expect(await screen.findByText('Привет, Alice!')).toBeVisible(); }); it('онбординг доступен при незавершённой настройке (без цикла редиректов)', async () => { const user = makeUser({ onboarding_completed: false }); installFetch([ { match: '/api/v1/users/@me', response: () => json({ user }) }, { match: '/api/v1/users/@me/onboarding/complete', method: 'POST', response: () => json({ user }), }, ]); const { router } = renderApp('/onboarding'); expect(await screen.findByLabelText('Как вас показывать?')).toBeVisible(); expect(router.state.location.pathname).toBe('/onboarding'); }); it('/ без сессии ведёт на /login, а /status доступен без авторизации', async () => { installFetch([ { match: '/api/v1/users/@me', response: () => apiError('auth.unauthorized', 401) }, { match: '/api/v1/meta', response: () => apiError('internal.error', 500) }, { match: '/api/v1/readyz', response: () => apiError('internal.error', 500) }, ]); const { router } = renderApp('/'); await waitFor(() => { expect(router.state.location.pathname).toBe('/login'); }); const status = renderApp('/status'); expect(await status.findByTestId('connection-state')).toHaveTextContent('Сервер недоступен'); }); it('сетевую ошибку показывает как сообщение, а не редирект', async () => { installFailingFetch(); const { router } = renderApp('/app'); expect(await screen.findByRole('alert')).toHaveTextContent('Сервер не отвечает'); expect(router.state.location.pathname).toBe('/app'); }); });