Files
nuxt4/tests/auth.middleware.spec.ts
T
2026-05-03 07:26:12 +00:00

115 lines
3.3 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest'
import { computed } from 'vue'
import { createPinia, setActivePinia } from 'pinia'
import { useAuthStore } from '../app/stores/auth'
async function loadMiddleware() {
vi.resetModules()
vi.stubGlobal('defineNuxtRouteMiddleware', (setup: unknown) => setup)
return (await import('../app/middleware/auth.global')).default
}
function createAuthClient(overrides: Partial<ReturnType<typeof buildAuthClient>> = {}) {
return {
...buildAuthClient(),
...overrides
}
}
function buildAuthClient() {
return {
isEnabled: true,
isAuthenticated: computed(() => false),
ensureInitialized: vi.fn().mockResolvedValue(undefined),
login: vi.fn().mockResolvedValue(undefined)
}
}
describe('auth middleware', () => {
beforeEach(() => {
setActivePinia(createPinia())
vi.restoreAllMocks()
vi.unstubAllGlobals()
vi.stubGlobal('useAuthStore', useAuthStore)
})
it('skips public routes and disabled auth', async () => {
const publicAuth = createAuthClient()
vi.stubGlobal('useAuth', () => publicAuth)
const middleware = await loadMiddleware()
await expect(middleware({ meta: { public: true } })).resolves.toBeUndefined()
expect(publicAuth.ensureInitialized).not.toHaveBeenCalled()
const disabledAuth = createAuthClient({ isEnabled: false })
vi.stubGlobal('useAuth', () => disabledAuth)
await expect(middleware({ meta: { requiresAuth: true } })).resolves.toBeUndefined()
expect(disabledAuth.ensureInitialized).not.toHaveBeenCalled()
})
it('requests login for unauthenticated protected routes', async () => {
const auth = createAuthClient({
isAuthenticated: computed(() => false)
})
vi.stubGlobal('useAuth', () => auth)
const middleware = await loadMiddleware()
await expect(middleware({ meta: { requiresAuth: true } })).resolves.toBeUndefined()
expect(auth.ensureInitialized).toHaveBeenCalledOnce()
expect(auth.login).toHaveBeenCalledOnce()
})
it('allows authenticated users with a matching role', async () => {
const authStore = useAuthStore()
authStore.setUser({
id: 'user-1',
roles: ['ADMIN']
})
const auth = createAuthClient({
isAuthenticated: computed(() => true)
})
vi.stubGlobal('useAuth', () => auth)
const middleware = await loadMiddleware()
await expect(middleware({ meta: { roles: ['ADMIN'] } })).resolves.toBeUndefined()
expect(auth.ensureInitialized).toHaveBeenCalledOnce()
expect(auth.login).not.toHaveBeenCalled()
})
it('throws a 403 error for authenticated users without a required role', async () => {
const authStore = useAuthStore()
authStore.setUser({
id: 'user-2',
roles: ['USER']
})
const createErrorMock = vi.fn((error: { statusCode: number; statusMessage: string }) => error)
vi.stubGlobal('createError', createErrorMock)
const auth = createAuthClient({
isAuthenticated: computed(() => true)
})
vi.stubGlobal('useAuth', () => auth)
const middleware = await loadMiddleware()
await expect(middleware({ meta: { roles: ['ADMIN'] } })).rejects.toMatchObject({
statusCode: 403,
statusMessage: 'Forbidden'
})
expect(createErrorMock).toHaveBeenCalledWith({
statusCode: 403,
statusMessage: 'Forbidden'
})
})
})