2 years ago
#75149

Ahmed J.
In a NestJs app, how to unitTest rolesGuard and test it with stub user and admin roles?
So I have this nestjs app that uses jwtAuthGuard and RolesGuard on some api calls. I want to write unit tests to test that a method call (say Delete) requires an admin Role and user role cant perform this operation. I want to unit test this with the RolesGuard.
Update: Below are the code samples, hope it clarify things. I provided some code about RolesGuard, authController and authController spec. I would like to, for example, test the rolesGuard for getUserById and check that the user has the correct role to access it or provide a forbidden message error.
RolesGuard
@Injectable()
export class RolesGuard implements CanActivate {
private readonly logger = new Logger(RolesGuard.name)
constructor(private reflector: Reflector, private authService: AuthService) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>('roles', [context.getHandler(), context.getClass()])
if (!requiredRoles) {
return true
}
const { user } = context.switchToHttp().getRequest()
if (!user) {
this.logger.error('User was not found in request')
return false
}
const currentUser = await this.authService.getCurrentUserById(user.userId)
if (!currentUser) {
this.logger.error(`User with id ${user.userId} not found`)
return false
}
const hasRole = () => requiredRoles.some((requiredRole) => currentUser.role.includes(requiredRole))
return user && user.role && hasRole()
}
}
AuthController
...
@Get('users/:userId')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(Role.USER, Role.ADMIN)
...other dependencies
async getUserById(@Req() request: Request, @Param('userId') userId: string): Promise<UserResponseDto> {
this.logger.log('Get user by id')
return await this.authService.getUserById(request, userId)
}
AuthController.spec
...
describe('Auth Controller:', () => {
let controller: AuthController
let service: AuthService
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [],
controllers: [AuthController],
providers: [
AuthService,
{
provide: JwtAuthGuard,
useValue: jest.fn().mockImplementation(() => {
return {
canActivate: jest.fn().mockResolvedValue(() => {
return true
}),
}
}),
},
{
provide: LocalAuthGuard,
useValue: jest.fn().mockImplementation(() => {
return { canActivate: jest.fn().mockResolvedValue(true) }
}),
},
{
provide: RefreshAuthGuard,
useValue: jest.fn().mockImplementation(() => {
return { canActivate: jest.fn().mockResolvedValue(true) }
}),
},
{
provide: RolesGuard,
useValue: jest.fn().mockImplementation((req, res, next) => {
return {
canActivate: jest.fn().mockResolvedValue(() => {
return {
roles: [Role.USER],
}
}),
}
}),
},
],
}).compile()
controller = module.get<AuthController>(AuthController)
service = module.get<AuthService>(AuthService)
jest.clearAllMocks()
})
...
Any help is appreciated.
authentication
jestjs
nestjs
user-roles
0 Answers
Your Answer