Adds AdminApp as a lazy-loaded route subtree in App.tsx, mounting ProtectedRoute, AdminLogin, AdminLayout, and all five CRUD pages built in Tasks 3-11. Mounted as a sibling of the public Layout route (not nested under it), since the admin panel has its own AdminLayout sidebar rather than the public nav/footer. Manually verified end-to-end against the local Supabase stack: sign-in redirect guard, all five pages rendering real seeded data, creating and cancelling a real booking through the UI (confirming the booked_slots cleanup trigger from the merged Phase 2A follow-up fixes correctly frees the slot), and sign-out. No console errors across the flow. Claude-Session: https://claude.ai/code/session_01NhxA4npAXAxmCDEJt6kxSH
43 lines
1.3 KiB
TypeScript
43 lines
1.3 KiB
TypeScript
import { render, screen } from '@testing-library/react'
|
|
import { MemoryRouter, Routes, Route } from 'react-router-dom'
|
|
import { describe, it, expect, vi } from 'vitest'
|
|
|
|
vi.mock('../../hooks/useAdminAuth', () => ({
|
|
default: () => ({ session: { user: { id: 'admin' } }, loading: false }),
|
|
}))
|
|
vi.mock('../../lib/supabase', () => ({
|
|
supabase: {
|
|
auth: { signOut: vi.fn() },
|
|
from: () => ({
|
|
select: () => ({ order: () => Promise.resolve({ data: [], error: null }) }),
|
|
}),
|
|
},
|
|
}))
|
|
|
|
import AdminApp from './AdminApp'
|
|
|
|
describe('AdminApp routing', () => {
|
|
it('renders the login page at /admin/login', () => {
|
|
render(
|
|
<MemoryRouter initialEntries={['/admin/login']}>
|
|
<Routes>
|
|
<Route path="/admin/*" element={<AdminApp />} />
|
|
</Routes>
|
|
</MemoryRouter>,
|
|
)
|
|
expect(screen.getByRole('heading', { name: /admin login/i })).toBeInTheDocument()
|
|
})
|
|
|
|
it('renders the products page (with layout) at /admin/products when authenticated', async () => {
|
|
render(
|
|
<MemoryRouter initialEntries={['/admin/products']}>
|
|
<Routes>
|
|
<Route path="/admin/*" element={<AdminApp />} />
|
|
</Routes>
|
|
</MemoryRouter>,
|
|
)
|
|
expect(await screen.findByRole('heading', { name: /^products$/i })).toBeInTheDocument()
|
|
expect(screen.getByRole('link', { name: /bookings/i })).toBeInTheDocument()
|
|
})
|
|
})
|