Skip to content

Commit d5483aa

Browse files
committed
fix(auth): fix AuthGuard unit tests after Public decorator implementation
- Inject and mock Reflector in AuthGuard unit tests - Fix NestJS context mocks in tests to include getHandler and getClass - Add test cases for Public decorator behavior in AuthGuard Signed-off-by: betterclever <[email protected]>
1 parent 87cdf01 commit d5483aa

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

backend/src/auth/__tests__/auth.guard.spec.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { afterEach, beforeEach, describe, expect, it, vi } from 'bun:test';
22
import type { ExecutionContext } from '@nestjs/common';
33
import { UnauthorizedException } from '@nestjs/common';
4+
import { Reflector } from '@nestjs/core';
45
import type { Request } from 'express';
56

67
import { AuthGuard, type RequestWithAuthContext } from '../auth.guard';
@@ -18,6 +19,9 @@ describe('AuthGuard', () => {
1819
let mockApiKeysService: {
1920
validateKey: ReturnType<typeof vi.fn>;
2021
};
22+
let mockReflector: {
23+
getAllAndOverride: ReturnType<typeof vi.fn>;
24+
};
2125
let mockExecutionContext: ExecutionContext;
2226
let mockRequest: RequestWithAuthContext;
2327

@@ -30,11 +34,15 @@ describe('AuthGuard', () => {
3034
mockApiKeysService = {
3135
validateKey: vi.fn(),
3236
};
37+
mockReflector = {
38+
getAllAndOverride: vi.fn(),
39+
};
3340

3441
// Create guard with mocked dependencies
3542
guard = new AuthGuard(
3643
mockAuthService as unknown as AuthService,
3744
mockApiKeysService as unknown as ApiKeysService,
45+
mockReflector as unknown as Reflector,
3846
);
3947

4048
// Setup mock request
@@ -50,6 +58,8 @@ describe('AuthGuard', () => {
5058
switchToHttp: vi.fn(() => ({
5159
getRequest: vi.fn(() => mockRequest),
5260
})),
61+
getHandler: vi.fn(),
62+
getClass: vi.fn(),
5363
} as unknown as ExecutionContext;
5464
});
5565

@@ -59,6 +69,8 @@ describe('AuthGuard', () => {
5969
switchToHttp: vi.fn(() => ({
6070
getRequest: vi.fn(() => null),
6171
})),
72+
getHandler: vi.fn(),
73+
getClass: vi.fn(),
6274
} as unknown as ExecutionContext;
6375

6476
const result = await guard.canActivate(contextWithoutRequest);
@@ -565,5 +577,35 @@ describe('AuthGuard', () => {
565577
expect(mockRequest.auth?.provider).toBe('api-key');
566578
});
567579
});
580+
581+
describe('Public decorator', () => {
582+
it('should allow access to endpoints marked as public', async () => {
583+
mockReflector.getAllAndOverride.mockReturnValue(true);
584+
585+
const result = await guard.canActivate(mockExecutionContext);
586+
587+
expect(result).toBe(true);
588+
expect(mockAuthService.authenticate).not.toHaveBeenCalled();
589+
expect(mockApiKeysService.validateKey).not.toHaveBeenCalled();
590+
expect(mockRequest.auth).toBeUndefined();
591+
});
592+
593+
it('should continue authentication for endpoints not marked as public', async () => {
594+
mockReflector.getAllAndOverride.mockReturnValue(false);
595+
mockAuthService.authenticate.mockResolvedValue({
596+
userId: 'user-1',
597+
organizationId: 'org-1',
598+
roles: ['MEMBER'],
599+
isAuthenticated: true,
600+
provider: 'clerk',
601+
});
602+
603+
const result = await guard.canActivate(mockExecutionContext);
604+
605+
expect(result).toBe(true);
606+
expect(mockAuthService.authenticate).toHaveBeenCalled();
607+
expect(mockRequest.auth?.userId).toBe('user-1');
608+
});
609+
});
568610
});
569611

0 commit comments

Comments
 (0)