Files
3dp-manager/client/test/auth/PublicRoute.spec.tsx
T
2026-03-30 00:19:52 +03:00

136 lines
4.6 KiB
TypeScript

import { describe, it, expect, vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import { MemoryRouter, Routes, Route } from 'react-router-dom'
import PublicRoute from '@/auth/PublicRoute'
import { AuthProvider } from '@/auth/AuthContext'
// Мокаем localStorage
const localStorageMock = (() => {
let store: Record<string, string> = {}
return {
getItem: vi.fn((key: string) => store[key] || null),
setItem: vi.fn((key: string, value: string) => {
store[key] = value
}),
removeItem: vi.fn((key: string) => {
delete store[key]
}),
clear: vi.fn(() => {
store = {}
}),
}
})()
Object.defineProperty(window, 'localStorage', {
value: localStorageMock,
})
describe('PublicRoute', () => {
beforeEach(() => {
localStorageMock.clear()
vi.clearAllMocks()
})
it('должен рендерить Outlet когда пользователь не авторизован', () => {
localStorageMock.getItem.mockReturnValue(null)
render(
<MemoryRouter initialEntries={['/login']}>
<AuthProvider>
<Routes>
<Route element={<PublicRoute />}>
<Route path="/login" element={<div data-testid="login-page">Login Page</div>} />
</Route>
</Routes>
</AuthProvider>
</MemoryRouter>
)
expect(screen.getByTestId('login-page')).toBeInTheDocument()
expect(screen.getByText('Login Page')).toBeInTheDocument()
})
it('должен перенаправлять на / когда пользователь авторизован', () => {
localStorageMock.getItem.mockReturnValue('valid-token')
render(
<MemoryRouter initialEntries={['/login']}>
<AuthProvider>
<Routes>
<Route element={<PublicRoute />}>
<Route path="/login" element={<div data-testid="login-page">Login Page</div>} />
</Route>
<Route path="/" element={<div data-testid="home-page">Home Page</div>} />
</Routes>
</AuthProvider>
</MemoryRouter>
)
// Должен показать главную страницу вместо login
expect(screen.getByTestId('home-page')).toBeInTheDocument()
expect(screen.getByText('Home Page')).toBeInTheDocument()
})
it('должен работать с несколькими публичными роутами', () => {
localStorageMock.getItem.mockReturnValue(null)
render(
<MemoryRouter initialEntries={['/register']}>
<AuthProvider>
<Routes>
<Route element={<PublicRoute />}>
<Route path="/login" element={<div data-testid="login-page">Login Page</div>} />
<Route path="/register" element={<div data-testid="register-page">Register Page</div>} />
</Route>
</Routes>
</AuthProvider>
</MemoryRouter>
)
expect(screen.getByTestId('register-page')).toBeInTheDocument()
expect(screen.getByText('Register Page')).toBeInTheDocument()
})
it('должен перенаправлять авторизованного пользователя с любого публичного роута', () => {
localStorageMock.getItem.mockReturnValue('valid-token')
render(
<MemoryRouter initialEntries={['/register']}>
<AuthProvider>
<Routes>
<Route element={<PublicRoute />}>
<Route path="/login" element={<div data-testid="login-page">Login Page</div>} />
<Route path="/register" element={<div data-testid="register-page">Register Page</div>} />
</Route>
<Route path="/" element={<div data-testid="home-page">Home Page</div>} />
</Routes>
</AuthProvider>
</MemoryRouter>
)
// Должен показать главную страницу
expect(screen.getByTestId('home-page')).toBeInTheDocument()
expect(screen.queryByTestId('register-page')).not.toBeInTheDocument()
})
it('должен использовать replace при перенаправлении', () => {
localStorageMock.getItem.mockReturnValue('valid-token')
const { container } = render(
<MemoryRouter initialEntries={['/login']}>
<AuthProvider>
<Routes>
<Route element={<PublicRoute />}>
<Route path="/login" element={<div>Login</div>} />
</Route>
<Route path="/" element={<div>Home</div>} />
</Routes>
</AuthProvider>
</MemoryRouter>
)
// Проверяем что рендерится Home
expect(container.textContent).toContain('Home')
})
})