153 lines
4.1 KiB
TypeScript
153 lines
4.1 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { createPinia, setActivePinia } from 'pinia'
|
|
import { useAuthStore, type AuthUser } from '../app/stores/auth'
|
|
|
|
type AuthPlugin = typeof import('../app/plugins/auth').default
|
|
|
|
function createRuntimeConfig(authMode: string | undefined = undefined) {
|
|
return {
|
|
public: {
|
|
authMode,
|
|
authLoginUrl: '/login',
|
|
authLogoutUrl: '/logout',
|
|
authUserinfoUrl: '/api/auth/me'
|
|
}
|
|
}
|
|
}
|
|
|
|
async function loadPlugin() {
|
|
vi.resetModules()
|
|
vi.stubGlobal('defineNuxtPlugin', (setup: AuthPlugin) => setup)
|
|
|
|
return (await import('../app/plugins/auth')).default
|
|
}
|
|
|
|
describe('auth plugin', () => {
|
|
beforeEach(() => {
|
|
setActivePinia(createPinia())
|
|
vi.restoreAllMocks()
|
|
vi.unstubAllGlobals()
|
|
})
|
|
|
|
it('initializes a disabled auth client and keeps auth turned off', async () => {
|
|
vi.stubGlobal('useRuntimeConfig', () => createRuntimeConfig())
|
|
|
|
const plugin = await loadPlugin()
|
|
const { provide } = plugin()
|
|
const auth = provide.auth
|
|
|
|
expect(auth.mode).toBe('disabled')
|
|
expect(auth.isEnabled).toBe(false)
|
|
|
|
await auth.ensureInitialized()
|
|
|
|
const store = useAuthStore()
|
|
expect(auth.isReady.value).toBe(true)
|
|
expect(auth.isAuthenticated.value).toBe(false)
|
|
expect(store.isInitialized).toBe(true)
|
|
expect(store.user).toBeNull()
|
|
})
|
|
|
|
it('uses a mock user in mock mode and supports login and logout locally', async () => {
|
|
vi.stubGlobal('useRuntimeConfig', () => createRuntimeConfig('mock'))
|
|
|
|
const plugin = await loadPlugin()
|
|
const { provide } = plugin()
|
|
const auth = provide.auth
|
|
|
|
await auth.ensureInitialized()
|
|
|
|
const store = useAuthStore()
|
|
expect(auth.mode).toBe('mock')
|
|
expect(auth.isEnabled).toBe(true)
|
|
expect(auth.isAuthenticated.value).toBe(true)
|
|
expect(store.user).toMatchObject({
|
|
id: 'mock-user',
|
|
email: 'mock@example.com',
|
|
roles: ['USER']
|
|
})
|
|
|
|
auth.logout()
|
|
expect(store.user).toBeNull()
|
|
|
|
auth.login()
|
|
expect(store.user).toMatchObject({
|
|
id: 'mock-user',
|
|
email: 'mock@example.com'
|
|
})
|
|
})
|
|
|
|
it('loads the current user from the userinfo endpoint in userinfo mode', async () => {
|
|
const fetchMock = vi.fn().mockResolvedValue({
|
|
id: 'user-1',
|
|
email: 'john@example.com',
|
|
roles: ['USER']
|
|
} satisfies AuthUser)
|
|
|
|
vi.stubGlobal('useRuntimeConfig', () => createRuntimeConfig('userinfo'))
|
|
vi.stubGlobal('$fetch', fetchMock)
|
|
|
|
const plugin = await loadPlugin()
|
|
const { provide } = plugin()
|
|
const auth = provide.auth
|
|
|
|
await auth.ensureInitialized()
|
|
|
|
const store = useAuthStore()
|
|
expect(fetchMock).toHaveBeenCalledWith('/api/auth/me', {
|
|
credentials: 'include'
|
|
})
|
|
expect(auth.isAuthenticated.value).toBe(true)
|
|
expect(store.user).toMatchObject({
|
|
id: 'user-1',
|
|
email: 'john@example.com'
|
|
})
|
|
})
|
|
|
|
it('falls back to an anonymous session when userinfo loading fails', async () => {
|
|
const fetchMock = vi.fn().mockRejectedValue(new Error('network error'))
|
|
|
|
vi.stubGlobal('useRuntimeConfig', () => createRuntimeConfig('userinfo'))
|
|
vi.stubGlobal('$fetch', fetchMock)
|
|
|
|
const plugin = await loadPlugin()
|
|
const { provide } = plugin()
|
|
const auth = provide.auth
|
|
|
|
await auth.ensureInitialized()
|
|
|
|
const store = useAuthStore()
|
|
expect(auth.isReady.value).toBe(true)
|
|
expect(auth.isAuthenticated.value).toBe(false)
|
|
expect(store.isInitialized).toBe(true)
|
|
expect(store.user).toBeNull()
|
|
})
|
|
|
|
it('redirects login and logout in userinfo mode', async () => {
|
|
vi.stubGlobal('useRuntimeConfig', () => createRuntimeConfig('userinfo'))
|
|
vi.stubGlobal('$fetch', vi.fn().mockResolvedValue(null))
|
|
vi.stubGlobal('window', {
|
|
location: {
|
|
href: ''
|
|
}
|
|
})
|
|
|
|
const plugin = await loadPlugin()
|
|
const { provide } = plugin()
|
|
const auth = provide.auth
|
|
|
|
auth.login()
|
|
expect(window.location.href).toBe('/login')
|
|
|
|
const store = useAuthStore()
|
|
store.setUser({
|
|
id: 'user-2',
|
|
roles: ['USER']
|
|
})
|
|
|
|
auth.logout()
|
|
expect(window.location.href).toBe('/logout')
|
|
expect(store.user).toBeNull()
|
|
})
|
|
})
|