test(auth): add unit tests for various guards and services with mocked dependencies
This commit is contained in:
84
backend/src/auth/guards/optional-auth.guard.spec.ts
Normal file
84
backend/src/auth/guards/optional-auth.guard.spec.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { ExecutionContext } from "@nestjs/common";
|
||||
import { ConfigService } from "@nestjs/config";
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { getIronSession } from "iron-session";
|
||||
import { JwtService } from "../../crypto/services/jwt.service";
|
||||
import { OptionalAuthGuard } from "./optional-auth.guard";
|
||||
|
||||
jest.mock("jose", () => ({}));
|
||||
jest.mock("iron-session", () => ({
|
||||
getIronSession: jest.fn(),
|
||||
}));
|
||||
|
||||
describe("OptionalAuthGuard", () => {
|
||||
let guard: OptionalAuthGuard;
|
||||
let _jwtService: JwtService;
|
||||
|
||||
const mockJwtService = {
|
||||
verifyJwt: jest.fn(),
|
||||
};
|
||||
|
||||
const mockConfigService = {
|
||||
get: jest.fn().mockReturnValue("session-password"),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
OptionalAuthGuard,
|
||||
{ provide: JwtService, useValue: mockJwtService },
|
||||
{ provide: ConfigService, useValue: mockConfigService },
|
||||
],
|
||||
}).compile();
|
||||
|
||||
guard = module.get<OptionalAuthGuard>(OptionalAuthGuard);
|
||||
_jwtService = module.get<JwtService>(JwtService);
|
||||
});
|
||||
|
||||
it("should return true and set user for valid token", async () => {
|
||||
const request = { user: null };
|
||||
const context = {
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => request,
|
||||
getResponse: () => ({}),
|
||||
}),
|
||||
} as unknown as ExecutionContext;
|
||||
|
||||
(getIronSession as jest.Mock).mockResolvedValue({ accessToken: "valid" });
|
||||
mockJwtService.verifyJwt.mockResolvedValue({ sub: "u1" });
|
||||
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
expect(request.user).toEqual({ sub: "u1" });
|
||||
});
|
||||
|
||||
it("should return true if no token", async () => {
|
||||
const context = {
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({}),
|
||||
getResponse: () => ({}),
|
||||
}),
|
||||
} as ExecutionContext;
|
||||
|
||||
(getIronSession as jest.Mock).mockResolvedValue({});
|
||||
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return true even if token invalid", async () => {
|
||||
const context = {
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({ user: null }),
|
||||
getResponse: () => ({}),
|
||||
}),
|
||||
} as ExecutionContext;
|
||||
|
||||
(getIronSession as jest.Mock).mockResolvedValue({ accessToken: "invalid" });
|
||||
mockJwtService.verifyJwt.mockRejectedValue(new Error("invalid"));
|
||||
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
expect(context.switchToHttp().getRequest().user).toBeNull();
|
||||
});
|
||||
});
|
||||
90
backend/src/auth/guards/roles.guard.spec.ts
Normal file
90
backend/src/auth/guards/roles.guard.spec.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { ExecutionContext } from "@nestjs/common";
|
||||
import { Reflector } from "@nestjs/core";
|
||||
import { Test, TestingModule } from "@nestjs/testing";
|
||||
import { RbacService } from "../rbac.service";
|
||||
import { RolesGuard } from "./roles.guard";
|
||||
|
||||
describe("RolesGuard", () => {
|
||||
let guard: RolesGuard;
|
||||
let _reflector: Reflector;
|
||||
let _rbacService: RbacService;
|
||||
|
||||
const mockReflector = {
|
||||
getAllAndOverride: jest.fn(),
|
||||
};
|
||||
|
||||
const mockRbacService = {
|
||||
getUserRoles: jest.fn(),
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
RolesGuard,
|
||||
{ provide: Reflector, useValue: mockReflector },
|
||||
{ provide: RbacService, useValue: mockRbacService },
|
||||
],
|
||||
}).compile();
|
||||
|
||||
guard = module.get<RolesGuard>(RolesGuard);
|
||||
_reflector = module.get<Reflector>(Reflector);
|
||||
_rbacService = module.get<RbacService>(RbacService);
|
||||
});
|
||||
|
||||
it("should return true if no roles required", async () => {
|
||||
mockReflector.getAllAndOverride.mockReturnValue(null);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
} as ExecutionContext;
|
||||
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false if no user in request", async () => {
|
||||
mockReflector.getAllAndOverride.mockReturnValue(["admin"]);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({ user: null }),
|
||||
}),
|
||||
} as ExecutionContext;
|
||||
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it("should return true if user has required role", async () => {
|
||||
mockReflector.getAllAndOverride.mockReturnValue(["admin"]);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({ user: { sub: "u1" } }),
|
||||
}),
|
||||
} as ExecutionContext;
|
||||
|
||||
mockRbacService.getUserRoles.mockResolvedValue(["admin", "user"]);
|
||||
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false if user doesn't have required role", async () => {
|
||||
mockReflector.getAllAndOverride.mockReturnValue(["admin"]);
|
||||
const context = {
|
||||
getHandler: () => ({}),
|
||||
getClass: () => ({}),
|
||||
switchToHttp: () => ({
|
||||
getRequest: () => ({ user: { sub: "u1" } }),
|
||||
}),
|
||||
} as ExecutionContext;
|
||||
|
||||
mockRbacService.getUserRoles.mockResolvedValue(["user"]);
|
||||
|
||||
const result = await guard.canActivate(context);
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user