@kenniy/godeye-data-contracts
Version:
Enterprise-grade base repository architecture for GOD-EYE microservices with zero overhead and maximum code reuse
172 lines (171 loc) • 8.14 kB
JavaScript
;
/**
* Kong Authentication Tests
* Tests the Kong Gateway authentication integration
*/
Object.defineProperty(exports, "__esModule", { value: true });
const common_1 = require("@nestjs/common");
const auth_1 = require("../core/auth");
const auth_constants_1 = require("../constants/auth.constants");
describe('Kong Authentication System', () => {
describe('normalizeHeaders utility', () => {
it('should normalize string headers', () => {
const rawHeaders = {
'x-user-id': '123',
'x-user-email': 'test@example.com'
};
const normalized = (0, auth_1.normalizeHeaders)(rawHeaders);
expect(normalized['x-user-id']).toBe('123');
expect(normalized['x-user-email']).toBe('test@example.com');
});
it('should normalize array headers to comma-separated string', () => {
const rawHeaders = {
'x-user-type': ['admin', 'user']
};
const normalized = (0, auth_1.normalizeHeaders)(rawHeaders);
expect(normalized['x-user-type']).toBe('admin,user');
});
it('should handle mixed header types', () => {
const rawHeaders = {
'x-user-id': '123',
'x-user-type': ['admin', 'user'],
'x-user-email': 'test@example.com'
};
const normalized = (0, auth_1.normalizeHeaders)(rawHeaders);
expect(normalized['x-user-id']).toBe('123');
expect(normalized['x-user-type']).toBe('admin,user');
expect(normalized['x-user-email']).toBe('test@example.com');
});
});
describe('extractKongUserContext utility', () => {
it('should extract complete user context', () => {
const headers = {
[auth_constants_1.KONG_HEADERS.USER_ID]: '123',
[auth_constants_1.KONG_HEADERS.USER_EMAIL]: 'test@example.com',
[auth_constants_1.KONG_HEADERS.USER_TYPE]: 'admin,user',
[auth_constants_1.KONG_HEADERS.PROFILE_ID]: 'profile-456',
[auth_constants_1.KONG_HEADERS.PROFILE_KIND]: 'doctor',
[auth_constants_1.KONG_HEADERS.PHONE]: '+1234567890',
[auth_constants_1.KONG_HEADERS.FIRST_NAME]: 'John',
[auth_constants_1.KONG_HEADERS.LAST_NAME]: 'Doe'
};
const context = (0, auth_1.extractKongUserContext)(headers);
expect(context.id).toBe('123');
expect(context.email).toBe('test@example.com');
expect(context.type).toEqual(['admin', 'user']);
expect(context.profile_id).toBe('profile-456');
expect(context.profile_kind).toBe('doctor');
expect(context.phone).toBe('+1234567890');
expect(context.first_name).toBe('John');
expect(context.last_name).toBe('Doe');
});
it('should extract minimal user context', () => {
const headers = {
[auth_constants_1.KONG_HEADERS.USER_ID]: '123',
[auth_constants_1.KONG_HEADERS.USER_EMAIL]: 'test@example.com'
};
const context = (0, auth_1.extractKongUserContext)(headers);
expect(context.id).toBe('123');
expect(context.email).toBe('test@example.com');
expect(context.type).toEqual([]);
expect(context.profile_id).toBeUndefined();
});
it('should throw error when user ID is missing', () => {
const headers = {
[auth_constants_1.KONG_HEADERS.USER_EMAIL]: 'test@example.com'
};
expect(() => (0, auth_1.extractKongUserContext)(headers)).toThrow(common_1.HttpException);
});
it('should throw error when user email is missing', () => {
const headers = {
[auth_constants_1.KONG_HEADERS.USER_ID]: '123'
};
expect(() => (0, auth_1.extractKongUserContext)(headers)).toThrow(common_1.HttpException);
});
it('should parse comma-separated user types', () => {
const headers = {
[auth_constants_1.KONG_HEADERS.USER_ID]: '123',
[auth_constants_1.KONG_HEADERS.USER_EMAIL]: 'test@example.com',
[auth_constants_1.KONG_HEADERS.USER_TYPE]: 'admin, user, doctor'
};
const context = (0, auth_1.extractKongUserContext)(headers);
expect(context.type).toEqual(['admin', 'user', 'doctor']);
});
});
describe('KongAuthGuard', () => {
let guard;
let mockExecutionContext;
let mockRequest;
beforeEach(() => {
guard = new auth_1.KongAuthGuard();
mockRequest = {
headers: {},
url: '/api/users',
route: { path: '/api/users' }
};
mockExecutionContext = {
switchToHttp: jest.fn(() => ({
getRequest: jest.fn(() => mockRequest),
getResponse: jest.fn()
}))
};
});
it('should allow access with valid Kong headers', () => {
mockRequest.headers = {
[auth_constants_1.KONG_HEADERS.USER_ID]: '123',
[auth_constants_1.KONG_HEADERS.USER_EMAIL]: 'test@example.com',
[auth_constants_1.KONG_HEADERS.USER_TYPE]: 'user'
};
const result = guard.canActivate(mockExecutionContext);
expect(result).toBe(true);
expect(mockRequest.user).toBeDefined();
expect(mockRequest.user.id).toBe('123');
});
it('should reject access with missing headers', () => {
mockRequest.headers = {}; // No Kong headers
expect(() => guard.canActivate(mockExecutionContext)).toThrow(common_1.HttpException);
});
it('should validate required roles', () => {
const guardWithRoles = new auth_1.KongAuthGuard(['admin']);
mockRequest.headers = {
[auth_constants_1.KONG_HEADERS.USER_ID]: '123',
[auth_constants_1.KONG_HEADERS.USER_EMAIL]: 'test@example.com',
[auth_constants_1.KONG_HEADERS.USER_TYPE]: 'user' // Not admin
};
expect(() => guardWithRoles.canActivate(mockExecutionContext)).toThrow(common_1.HttpException);
});
it('should allow access when user has required role', () => {
const guardWithRoles = new auth_1.KongAuthGuard(['admin', 'user']);
mockRequest.headers = {
[auth_constants_1.KONG_HEADERS.USER_ID]: '123',
[auth_constants_1.KONG_HEADERS.USER_EMAIL]: 'test@example.com',
[auth_constants_1.KONG_HEADERS.USER_TYPE]: 'user,admin' // Has admin role
};
const result = guardWithRoles.canActivate(mockExecutionContext);
expect(result).toBe(true);
});
it('should skip authentication for specified routes', () => {
const guardWithSkipRoutes = new auth_1.KongAuthGuard([], ['/api/health']);
mockRequest.url = '/api/health';
mockRequest.route.path = '/api/health';
mockRequest.headers = {}; // No headers needed for skipped routes
const result = guardWithSkipRoutes.canActivate(mockExecutionContext);
expect(result).toBe(true);
});
});
describe('createKongAuthGuard factory', () => {
it('should create guard with specified configuration', () => {
const GuardClass = (0, auth_1.createKongAuthGuard)({
required_roles: ['admin'],
skip_routes: ['/health']
});
const guard = new GuardClass();
expect(guard).toBeInstanceOf(auth_1.KongAuthGuard);
});
it('should create guard without configuration', () => {
const GuardClass = (0, auth_1.createKongAuthGuard)();
const guard = new GuardClass();
expect(guard).toBeInstanceOf(auth_1.KongAuthGuard);
});
});
});