feat(ST-1134): (mobile) route group + auth-guard helper + manifest (T-321)
- lib/auth-guard.ts (nieuw): requireSession() — gedeelde auth+paired-expiry guard, hergebruikt door (app)/layout.tsx - (app)/layout.tsx: refactor naar requireSession() (gedraagt zich identiek) - (mobile)/layout.tsx (nieuw): minimal layout met LandscapeGuard + MobileTabBar; geen NavBar/StatusBar/MinWidthBanner/bridges - /m/pair filesystem-move van (app)/ naar (mobile)/ — URL onveranderd - public/manifest.json: orientation landscape - Tests: requireSession-helper (3 paden) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
47d57a0963
commit
7b32fc60e6
7 changed files with 119 additions and 18 deletions
49
__tests__/lib/auth-guard.test.ts
Normal file
49
__tests__/lib/auth-guard.test.ts
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
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('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()
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue