@userfrosting/sprinkle-account
Version:
Account Sprinkle for UserFrosting
235 lines (194 loc) • 7.69 kB
text/typescript
// Unit tests for: useAuthGuard
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'
import { useAuthGuard } from '../../guards/authGuard'
import * as Auth from '../../stores/useAuthStore'
import type { RouteGuard, RoutePermissionGuard } from 'app/assets/interfaces'
// Default mock for the auth store and router
const mockAuthStore = {
isAuthenticated: false,
checkAccess: vi.fn()
}
const mockRouter = {
currentRoute: {
value: {
path: '/foo/bar',
meta: {
auth: undefined as RouteGuard | undefined,
guest: undefined as RouteGuard | undefined,
permission: undefined as RoutePermissionGuard | undefined
},
query: {} as Record<string, string>
}
},
replace: vi.fn()
}
describe('authGuard useAuthGuard() method', () => {
beforeEach(() => {
// Apply the mock to the auth store
vi.spyOn(Auth, 'useAuthStore').mockReturnValue(mockAuthStore as any)
})
afterEach(() => {
// Reset all mocks and "once" implementations
vi.resetAllMocks()
})
test('should not do anything if both path are null (default)', () => {
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).not.toHaveBeenCalled()
})
test('should redirect to login if route requires auth and user is not authenticated', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = { redirect: '/login' }
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = undefined
mockAuthStore.isAuthenticated = false
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalled()
expect(mockRouter.replace).toHaveBeenCalledWith('/login')
})
test('should not redirect if route requires auth and user is authenticated', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = { redirect: '/login' }
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = undefined
mockAuthStore.isAuthenticated = true
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).not.toHaveBeenCalled()
})
test('should not redirect if route requires permission and user does not have it', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = undefined
mockRouter.currentRoute.value.meta.permission = { slug: 'foo.bar', redirect: '/login' }
mockRouter.currentRoute.value.meta.guest = undefined
mockAuthStore.isAuthenticated = true
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalledWith('/login')
})
test('should not redirect if route requires guests and user is not authenticated', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = undefined
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = { redirect: '/' }
mockAuthStore.isAuthenticated = false
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).not.toHaveBeenCalled()
})
test('should redirect to specified redirect if route is for guests and user is authenticated', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = undefined
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = { redirect: '/' }
mockAuthStore.isAuthenticated = true
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalledWith(
expect.objectContaining({
path: '/'
})
)
})
test('should redirect to specified redirect if route is for guests and user is authenticated (with route name)', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = undefined
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = { redirect: { name: 'home' } }
mockAuthStore.isAuthenticated = true
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalledWith(
expect.objectContaining({
name: 'home'
})
)
})
test('should redirect to query redirect if route is for guests and user is authenticated', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = undefined
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = {}
mockAuthStore.isAuthenticated = true
// Set the query parameter
mockRouter.currentRoute.value.query = {
redirect: '/foo/bar'
}
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalledWith(
expect.objectContaining({
path: '/foo/bar'
})
)
})
test('should redirect to error page if route is for guests and user is authenticated', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = undefined
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = {}
mockAuthStore.isAuthenticated = true
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalledWith(
expect.objectContaining({
name: 'Unauthorized'
})
)
})
test('should use default redirect for auth guard if no redirect specified', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = {}
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = undefined
mockAuthStore.isAuthenticated = false
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalledWith(
expect.objectContaining({
name: 'account.login'
})
)
})
test('should use default redirect for permission guard if no redirect specified', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = undefined
mockRouter.currentRoute.value.meta.permission = { slug: 'foo.bar' }
mockRouter.currentRoute.value.meta.guest = undefined
mockAuthStore.isAuthenticated = true
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalledWith(
expect.objectContaining({
name: 'Forbidden'
})
)
})
test('should use default redirect for guest guard if no redirect specified', () => {
// Arrange
mockRouter.currentRoute.value.meta.auth = undefined
mockRouter.currentRoute.value.meta.permission = undefined
mockRouter.currentRoute.value.meta.guest = {}
mockAuthStore.isAuthenticated = true
// Act
useAuthGuard(mockRouter as any)
// Assert
expect(mockRouter.replace).toHaveBeenCalledWith(
expect.objectContaining({
name: 'Unauthorized'
})
)
})
})