- lib/auth-guard.ts: requireAdmin() toegevoegd — redirect /dashboard bij !userId of !isAdmin - app/(app)/admin/layout.tsx: admin-sidebar met links naar /admin/users, /admin/jobs, /admin/products - app/(app)/admin/page.tsx: redirect-stub naar /admin/users - __tests__/lib/auth-guard.test.ts: 3 tests voor requireAdmin() (geen userId, isAdmin=false, isAdmin=true)
84 lines
3.1 KiB
TypeScript
84 lines
3.1 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
|
|
const getSessionMock = vi.fn()
|
|
const isPairedSessionExpiredMock = vi.fn()
|
|
const redirectMock = vi.fn(() => { throw new Error('REDIRECT_CALLED') })
|
|
|
|
vi.mock('@/lib/auth', () => ({ getSession: getSessionMock }))
|
|
vi.mock('@/lib/auth/pairing', () => ({ isPairedSessionExpired: isPairedSessionExpiredMock }))
|
|
vi.mock('next/navigation', () => ({ redirect: redirectMock }))
|
|
|
|
describe('requireAdmin', () => {
|
|
beforeEach(() => {
|
|
getSessionMock.mockReset()
|
|
isPairedSessionExpiredMock.mockReset()
|
|
redirectMock.mockClear()
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.resetModules()
|
|
})
|
|
|
|
it('redirect /dashboard als userId ontbreekt', async () => {
|
|
getSessionMock.mockResolvedValue({ userId: undefined, isAdmin: false })
|
|
const { requireAdmin } = await import('@/lib/auth-guard')
|
|
await expect(requireAdmin()).rejects.toThrow('REDIRECT_CALLED')
|
|
expect(redirectMock).toHaveBeenCalledWith('/dashboard')
|
|
})
|
|
|
|
it('redirect /dashboard als isAdmin false is', async () => {
|
|
getSessionMock.mockResolvedValue({ userId: 'u1', isAdmin: false })
|
|
const { requireAdmin } = await import('@/lib/auth-guard')
|
|
await expect(requireAdmin()).rejects.toThrow('REDIRECT_CALLED')
|
|
expect(redirectMock).toHaveBeenCalledWith('/dashboard')
|
|
})
|
|
|
|
it('geeft sessie terug als isAdmin true is', async () => {
|
|
const sess = { userId: 'u1', isAdmin: true }
|
|
getSessionMock.mockResolvedValue(sess)
|
|
const { requireAdmin } = await import('@/lib/auth-guard')
|
|
const result = await requireAdmin()
|
|
expect(result).toBe(sess)
|
|
expect(redirectMock).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('requireSession', () => {
|
|
beforeEach(() => {
|
|
getSessionMock.mockReset()
|
|
isPairedSessionExpiredMock.mockReset()
|
|
redirectMock.mockClear()
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.resetModules()
|
|
})
|
|
|
|
it('redirect /login als userId ontbreekt', async () => {
|
|
getSessionMock.mockResolvedValue({ userId: undefined, destroy: vi.fn() })
|
|
isPairedSessionExpiredMock.mockReturnValue(false)
|
|
const { requireSession } = await import('@/lib/auth-guard')
|
|
await expect(requireSession()).rejects.toThrow('REDIRECT_CALLED')
|
|
expect(redirectMock).toHaveBeenCalledWith('/login')
|
|
})
|
|
|
|
it('vernietigt + redirect /login als paired-sessie verlopen is', async () => {
|
|
const destroy = vi.fn().mockResolvedValue(undefined)
|
|
getSessionMock.mockResolvedValue({ userId: 'u1', destroy })
|
|
isPairedSessionExpiredMock.mockReturnValue(true)
|
|
const { requireSession } = await import('@/lib/auth-guard')
|
|
await expect(requireSession()).rejects.toThrow('REDIRECT_CALLED')
|
|
expect(destroy).toHaveBeenCalled()
|
|
expect(redirectMock).toHaveBeenCalledWith('/login')
|
|
})
|
|
|
|
it('geeft sessie terug als alles ok', async () => {
|
|
const sess = { userId: 'u1', destroy: vi.fn() }
|
|
getSessionMock.mockResolvedValue(sess)
|
|
isPairedSessionExpiredMock.mockReturnValue(false)
|
|
const { requireSession } = await import('@/lib/auth-guard')
|
|
const result = await requireSession()
|
|
expect(result).toBe(sess)
|
|
expect(redirectMock).not.toHaveBeenCalled()
|
|
})
|
|
})
|