@10abdullahbutt/auth-module
Version:
A NestJS-style authentication module with JWT and role-based access control.
96 lines (84 loc) • 3.47 kB
text/typescript
import { Test, TestingModule } from '@nestjs/testing';
import { AuthModule } from '../src/auth.module';
import { JwtAuthGuard } from '../src/guards/jwt-auth.guard';
import { RolesGuard } from '../src/guards/roles.guard';
import { Reflector } from '@nestjs/core';
import { Roles } from '../src/decorators/roles.decorator';
import { JwtStrategy } from '../src/strategies/jwt.strategy';
import { ConfigService } from '@nestjs/config';
// Mock ConfigService for JwtStrategy
class MockConfigService {
get(key: string, defaultValue?: any) {
if (key === 'JWT_SECRET') return 'test_secret';
if (key === 'JWT_EXPIRES_IN') return '1h';
return defaultValue;
}
}
describe('AuthModule', () => {
let module: TestingModule;
beforeAll(async () => {
module = await Test.createTestingModule({
imports: [AuthModule],
}).compile();
});
it('should be defined', () => {
expect(module).toBeDefined();
});
it('should provide JwtAuthGuard', () => {
const guard = module.get<JwtAuthGuard>(JwtAuthGuard);
expect(guard).toBeInstanceOf(JwtAuthGuard);
});
it('should provide RolesGuard', () => {
const guard = module.get<RolesGuard>(RolesGuard);
expect(guard).toBeInstanceOf(RolesGuard);
});
it('RolesGuard should throw if user has no roles', () => {
const reflector = new Reflector();
const guard = new RolesGuard(reflector);
const context: any = {
switchToHttp: () => ({ getRequest: () => ({ user: {} }) }),
getHandler: () => undefined,
getClass: () => undefined,
};
expect(() => guard.canActivate(context)).toThrow();
});
it('RolesGuard should allow access if user has required role', () => {
const reflector = { getAllAndOverride: () => ['admin'] } as any;
const guard = new RolesGuard(reflector);
const context: any = {
switchToHttp: () => ({ getRequest: () => ({ user: { roles: ['admin'] } }) }),
getHandler: () => undefined,
getClass: () => undefined,
};
expect(guard.canActivate(context)).toBe(true);
});
it('RolesGuard should deny access if user lacks required role', () => {
const reflector = { getAllAndOverride: () => ['admin'] } as any;
const guard = new RolesGuard(reflector);
const context: any = {
switchToHttp: () => ({ getRequest: () => ({ user: { roles: ['user'] } }) }),
getHandler: () => undefined,
getClass: () => undefined,
};
expect(() => guard.canActivate(context)).toThrow();
});
it('Roles decorator should set metadata', () => {
const roles = ['admin', 'user'];
const metadata = Reflect.getMetadata('roles', Roles(...roles));
expect(metadata).toBeUndefined(); // Decorator sets metadata on target, not return value
});
it('JwtStrategy should use ConfigService for secret', async () => {
const strategy = new JwtStrategy(new MockConfigService() as any);
const payload = { sub: '1', username: 'test', roles: ['admin'] };
const user = await strategy.validate(payload);
expect(user).toEqual({ userId: '1', username: 'test', roles: ['admin'] });
});
it('JwtStrategy should return user with correct fields', async () => {
const strategy = new JwtStrategy(new MockConfigService() as any);
const payload = { sub: '2', username: 'foo', roles: ['user'] };
const user = await strategy.validate(payload);
expect(user.userId).toBe('2');
expect(user.username).toBe('foo');
expect(user.roles).toEqual(['user']);
});
});