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

187 lines
5.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect, vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import { MemoryRouter, Routes, Route } from 'react-router-dom'
import RequireAuth from '@/auth/RequireAuth'
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('RequireAuth', () => {
beforeEach(() => {
localStorageMock.clear()
vi.clearAllMocks()
})
it('должен рендерить children когда пользователь авторизован', () => {
localStorageMock.getItem.mockReturnValue('valid-token')
render(
<MemoryRouter initialEntries={['/protected']}>
<AuthProvider>
<Routes>
<Route
path="/protected"
element={
<RequireAuth>
<div data-testid="protected-content">Protected Content</div>
</RequireAuth>
}
/>
</Routes>
</AuthProvider>
</MemoryRouter>
)
expect(screen.getByTestId('protected-content')).toBeInTheDocument()
expect(screen.getByText('Protected Content')).toBeInTheDocument()
})
it('должен перенаправлять на /login когда пользователь не авторизован', () => {
localStorageMock.getItem.mockReturnValue(null)
render(
<MemoryRouter initialEntries={['/protected']}>
<AuthProvider>
<Routes>
<Route
path="/protected"
element={
<RequireAuth>
<div data-testid="protected-content">Protected Content</div>
</RequireAuth>
}
/>
<Route path="/login" element={<div data-testid="login-page">Login Page</div>} />
</Routes>
</AuthProvider>
</MemoryRouter>
)
expect(screen.getByTestId('login-page')).toBeInTheDocument()
expect(screen.getByText('Login Page')).toBeInTheDocument()
})
it('должен сохранять state.from с текущим location при перенаправлении на login', () => {
localStorageMock.getItem.mockReturnValue(null)
render(
<MemoryRouter initialEntries={['/settings']}>
<AuthProvider>
<Routes>
<Route
path="/settings"
element={
<RequireAuth>
<div data-testid="settings-content">Settings</div>
</RequireAuth>
}
/>
<Route path="/login" element={<div data-testid="login-page">Login Page</div>} />
</Routes>
</AuthProvider>
</MemoryRouter>
)
// Должен показать login страницу
expect(screen.getByTestId('login-page')).toBeInTheDocument()
})
it('должен использовать replace: true при перенаправлении', () => {
// Этот тест проверяет поведение Navigate компонента
// В реальном сценарии replace предотвращает добавление записи в историю
localStorageMock.getItem.mockReturnValue(null)
const { container } = render(
<MemoryRouter initialEntries={['/protected']}>
<AuthProvider>
<Routes>
<Route
path="/protected"
element={
<RequireAuth>
<div>Protected</div>
</RequireAuth>
}
/>
<Route path="/login" element={<div>Login</div>} />
</Routes>
</AuthProvider>
</MemoryRouter>
)
// Проверяем что рендерится login
expect(container.textContent).toContain('Login')
})
it('должен работать с вложенными роутами', () => {
localStorageMock.getItem.mockReturnValue('valid-token')
render(
<MemoryRouter initialEntries={['/dashboard/profile']}>
<AuthProvider>
<Routes>
<Route
path="/dashboard/*"
element={
<RequireAuth>
<Routes>
<Route path="profile" element={<div data-testid="profile">Profile</div>} />
</Routes>
</RequireAuth>
}
/>
</Routes>
</AuthProvider>
</MemoryRouter>
)
expect(screen.getByTestId('profile')).toBeInTheDocument()
})
it('должен блокировать доступ к защищённому маршруту без авторизации', () => {
localStorageMock.getItem.mockReturnValue(null)
render(
<MemoryRouter initialEntries={['/admin']}>
<AuthProvider>
<Routes>
<Route
path="/admin"
element={
<RequireAuth>
<div data-testid="admin-content">Admin Panel</div>
</RequireAuth>
}
/>
<Route path="/login" element={<div data-testid="login-page">Login Page</div>} />
</Routes>
</AuthProvider>
</MemoryRouter>
)
// Контент админки не должен быть доступен
expect(screen.queryByTestId('admin-content')).not.toBeInTheDocument()
// Должна показываться страница логина
expect(screen.getByTestId('login-page')).toBeInTheDocument()
})
})