This commit is contained in:
156
app/middleware/__tests__/auth.test.ts
Normal file
156
app/middleware/__tests__/auth.test.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { mockNuxtImport } from '@nuxt/test-utils/runtime';
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
/**
|
||||
* Tests for auth middleware
|
||||
* Based on specs from private/specs.md:
|
||||
*
|
||||
* Scenario: Access protected page without auth
|
||||
* Given I am not logged in
|
||||
* When I try to access "/dashboard"
|
||||
* Then I should be redirected to "/login"
|
||||
*/
|
||||
|
||||
// Create mocks at module level to avoid hoisting issues
|
||||
const mockState = {
|
||||
isAuthenticated: false,
|
||||
navigateToSpy: vi.fn(),
|
||||
};
|
||||
|
||||
// Mock useAuth
|
||||
mockNuxtImport('useAuth', () => {
|
||||
return () => ({
|
||||
isAuthenticated: {
|
||||
get value() {
|
||||
return mockState.isAuthenticated;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Mock navigateTo
|
||||
mockNuxtImport('navigateTo', () => {
|
||||
return (path: string) => mockState.navigateToSpy(path);
|
||||
});
|
||||
|
||||
describe('auth middleware', () => {
|
||||
beforeEach(async () => {
|
||||
// Reset state
|
||||
mockState.isAuthenticated = false;
|
||||
mockState.navigateToSpy.mockClear();
|
||||
});
|
||||
|
||||
it('should redirect to /login when user is not authenticated', async () => {
|
||||
mockState.isAuthenticated = false;
|
||||
|
||||
const { default: authMiddleware } = await import('../auth.global');
|
||||
|
||||
const to = {
|
||||
path: '/dashboard',
|
||||
fullPath: '/dashboard',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
const from = {
|
||||
path: '/',
|
||||
fullPath: '/',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
await authMiddleware(to, from);
|
||||
|
||||
expect(mockState.navigateToSpy).toHaveBeenCalledWith({
|
||||
path: '/login',
|
||||
query: {
|
||||
redirect: '/dashboard',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow access when user is authenticated', async () => {
|
||||
mockState.isAuthenticated = true;
|
||||
|
||||
const { default: authMiddleware } = await import('../auth.global');
|
||||
|
||||
const to = {
|
||||
path: '/dashboard',
|
||||
fullPath: '/dashboard',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
const from = {
|
||||
path: '/login',
|
||||
fullPath: '/login',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
const result = await authMiddleware(to, from);
|
||||
|
||||
expect(mockState.navigateToSpy).not.toHaveBeenCalled();
|
||||
expect(result).toBeUndefined(); // No redirect = allow access
|
||||
});
|
||||
|
||||
it('should not redirect if already on login page', async () => {
|
||||
mockState.isAuthenticated = false;
|
||||
|
||||
const { default: authMiddleware } = await import('../auth.global');
|
||||
|
||||
const to = {
|
||||
path: '/login',
|
||||
fullPath: '/login',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
const from = {
|
||||
path: '/dashboard',
|
||||
fullPath: '/dashboard',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
const result = await authMiddleware(to, from);
|
||||
|
||||
expect(mockState.navigateToSpy).not.toHaveBeenCalled();
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should allow access to home page without authentication', async () => {
|
||||
mockState.isAuthenticated = false;
|
||||
|
||||
const { default: authMiddleware } = await import('../auth.global');
|
||||
|
||||
const to = {
|
||||
path: '/',
|
||||
fullPath: '/',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
const from = {
|
||||
path: '/somewhere',
|
||||
fullPath: '/somewhere',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
const result = await authMiddleware(to, from);
|
||||
|
||||
expect(mockState.navigateToSpy).not.toHaveBeenCalled();
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should redirect to /login for any protected route', async () => {
|
||||
mockState.isAuthenticated = false;
|
||||
|
||||
const { default: authMiddleware } = await import('../auth.global');
|
||||
|
||||
const to = {
|
||||
path: '/projects',
|
||||
fullPath: '/projects',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
const from = {
|
||||
path: '/',
|
||||
fullPath: '/',
|
||||
} as RouteLocationNormalized;
|
||||
|
||||
await authMiddleware(to, from);
|
||||
|
||||
expect(mockState.navigateToSpy).toHaveBeenCalledWith({
|
||||
path: '/login',
|
||||
query: {
|
||||
redirect: '/projects',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user