Skip to content

Commit

Permalink
Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
w3bdesign committed Nov 20, 2024
1 parent d695cb0 commit 38bad59
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
node-version: '22'

- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 8
run_install: false
Expand Down
166 changes: 166 additions & 0 deletions backend/src/main.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { Test } from '@nestjs/testing';
import { ValidationPipe, INestApplication } from '@nestjs/common';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { NestFactory } from '@nestjs/core';

// Mock AppModule
jest.mock('./app.module', () => ({
AppModule: class MockAppModule {},
}));

// Mock NestFactory
const mockApp = {
enableCors: jest.fn(),
useGlobalPipes: jest.fn(),
listen: jest.fn().mockResolvedValue(undefined),
init: jest.fn().mockResolvedValue(undefined),
close: jest.fn().mockResolvedValue(undefined),
get: jest.fn(),
select: jest.fn(),
useGlobalFilters: jest.fn(),
useGlobalInterceptors: jest.fn(),
useGlobalGuards: jest.fn(),
use: jest.fn(),
} as unknown as INestApplication;

jest.mock('@nestjs/core', () => ({
NestFactory: {
create: jest.fn().mockResolvedValue(mockApp),
},
}));

// Mock SwaggerModule
jest.mock('@nestjs/swagger', () => ({
SwaggerModule: {
createDocument: jest.fn().mockReturnValue({
openapi: '3.0.0',
info: {
title: 'Hair Salon Booking API',
description: 'API documentation for the Hair Salon Booking System',
version: '1.0',
},
paths: {},
}),
setup: jest.fn(),
},
DocumentBuilder: jest.fn().mockReturnValue({
setTitle: jest.fn().mockReturnThis(),
setDescription: jest.fn().mockReturnThis(),
setVersion: jest.fn().mockReturnThis(),
addBearerAuth: jest.fn().mockReturnThis(),
build: jest.fn().mockReturnThis(),
}),
}));

// Mock console.log to reduce noise in tests
console.log = jest.fn();

describe('Bootstrap', () => {
beforeEach(() => {
jest.clearAllMocks();
});

afterEach(() => {
jest.resetModules();
});

it('should create NestJS application', async () => {
// Run the bootstrap function in isolation
await jest.isolateModules(async () => {
await require('./main');
expect(NestFactory.create).toHaveBeenCalledWith(AppModule);
});
});

it('should enable CORS with correct configuration', async () => {
await jest.isolateModules(async () => {
await require('./main');
expect(mockApp.enableCors).toHaveBeenCalledWith({
origin: true,
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS',
credentials: true,
});
});
});

it('should set up global validation pipe with correct configuration', async () => {
await jest.isolateModules(async () => {
await require('./main');
expect(mockApp.useGlobalPipes).toHaveBeenCalledWith(
expect.any(ValidationPipe)
);

const validationPipe = (mockApp.useGlobalPipes as jest.Mock).mock.calls[0][0];
expect(validationPipe.options).toEqual({
whitelist: true,
transform: true,
forbidNonWhitelisted: true,
transformOptions: {
enableImplicitConversion: true,
},
disableErrorMessages: false,
validationError: {
target: false,
value: false,
},
});
});
});

it('should set up Swagger documentation', async () => {
await jest.isolateModules(async () => {
await require('./main');

const documentBuilder = new DocumentBuilder();
expect(documentBuilder.setTitle).toHaveBeenCalledWith('Hair Salon Booking API');
expect(documentBuilder.setDescription).toHaveBeenCalledWith('API documentation for the Hair Salon Booking System');
expect(documentBuilder.setVersion).toHaveBeenCalledWith('1.0');
expect(documentBuilder.addBearerAuth).toHaveBeenCalledWith(
{
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
name: 'JWT',
description: 'Enter JWT token',
in: 'header',
},
'JWT-auth'
);
expect(documentBuilder.build).toHaveBeenCalled();
expect(SwaggerModule.createDocument).toHaveBeenCalled();
expect(SwaggerModule.setup).toHaveBeenCalledWith('api', mockApp, expect.any(Object), {
swaggerOptions: {
persistAuthorization: true,
docExpansion: 'none',
filter: true,
showRequestDuration: true,
},
});
});
});

it('should listen on the configured port', async () => {
const originalEnv = process.env.PORT;
process.env.PORT = '4000';

await jest.isolateModules(async () => {
await require('./main');
expect(mockApp.listen).toHaveBeenCalledWith('4000');
});

process.env.PORT = originalEnv;
});

it('should use default port 3000 when PORT env is not set', async () => {
const originalEnv = process.env.PORT;
delete process.env.PORT;

await jest.isolateModules(async () => {
await require('./main');
expect(mockApp.listen).toHaveBeenCalledWith(3000);
});

process.env.PORT = originalEnv;
});
});

0 comments on commit 38bad59

Please sign in to comment.