Skip to content

Commit

Permalink
Merge pull request #2 from RazinSyakib43/Ch8BE-unit-testing
Browse files Browse the repository at this point in the history
[C8 BE*] Auth and App Unit Testing
  • Loading branch information
RazinSyakib43 authored Aug 28, 2024
2 parents 47cf434 + abfa03a commit 365ad59
Show file tree
Hide file tree
Showing 7 changed files with 2,440 additions and 270 deletions.
20 changes: 20 additions & 0 deletions __tests__/app.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import request from 'supertest';
import app from "../index";

describe('GET /', () => {
it('should render the index page with a title and name', async () => {
const response = await request(app).get('/').query({ name: 'John' });

expect(response.status).toBe(200);
expect(response.text).toContain('BCR Car Management Dashboard - Hello World!');
expect(response.text).toContain('John');
});

it('should render the index page with default name', async () => {
const response = await request(app).get('/');

expect(response.status).toBe(200);
expect(response.text).toContain('BCR Car Management Dashboard - Hello World!');
expect(response.text).toContain('Guest');
});
});
113 changes: 113 additions & 0 deletions __tests__/auth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import request from 'supertest';
import express from 'express';
import multer from 'multer';
import bodyParser from 'body-parser';
import { registerAdmin, registerMember, loginSuperadmin, loginAdmin, loginMember } from '../controllers/authController';
import { AuthService } from '../services/authService';
import { UserService } from '../services/userService';

jest.mock('../services/authService');
jest.mock('../services/userService');

const authService = new AuthService();
const userService = new UserService();

const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const upload = multer();
app.post('/api/v1/dashboard/auth/register/admin', upload.single('avatar'), registerAdmin);
app.post('/api/v1/dashboard/auth/register/member', upload.single('avatar'), registerMember);
app.post('/api/v1/dashboard/auth/login/superadmin', loginSuperadmin);
app.post('/api/v1/dashboard/auth/login/admin', loginAdmin);
app.post('/api/v1/dashboard/auth/login/member', loginMember);

interface User {
id: number;
name: string;
email: string;
password: string;
avatar: string | null;
role: string | null;
createdAt: Date | null;
createdBy: string | null;
updatedAt: Date | null;
updatedBy: string | null;
status: string | null;
deletedAt: Date | null;
deletedBy: string | null;
}

interface ApiResponse {
code: number;
status: string;
message: string;
data: {
token: string;
};
}

const mockUserService = userService as jest.Mocked<UserService>;
const mockAuthService = authService as jest.Mocked<AuthService>;

describe('AuthController', () => {
beforeEach(() => {
jest.resetAllMocks();
});

describe('POST /register/member', () => {
it('should create a new member user', async () => {
mockUserService.getActiveUserByEmail.mockResolvedValue(null);
mockAuthService.registerMember.mockResolvedValue({ name: 'Himmel', email: '[email protected]', password: "iamhimmel" } as User);

const response = await request(app)
.post('/api/v1/dashboard/auth/register/member')
.field('name', 'Himmel')
.field('email', '[email protected]')
.field('password', 'himmel')
.attach('avatar', Buffer.from('test'), 'test.jpg');

expect(response.status).toBe(201);
expect(response.body.status).toBe('success');
});

it('should return 400 if email is already taken', async () => {
mockUserService.getActiveUserByEmail.mockResolvedValue({ name: 'Frieren', email: '[email protected]', password: "iamfrieren" } as User);

const response = await request(app)
.post('/api/v1/dashboard/auth/register/member')
.field('name', 'Frieren')
.field('email', '[email protected]')
.field('password', 'iamfrieren')
.attach('avatar', Buffer.from('test'), 'test.jpg');

expect(response.status).toBe(400);
expect(response.body.message).toBe('This email is already taken');
});
});

describe('POST /login/superadmin', () => {
it('should login a superadmin user', async () => {
mockAuthService.loginSuperadmin.mockResolvedValue({ data: { token: 'superadmin-token' } } as ApiResponse);

const response = await request(app)
.post('/api/v1/dashboard/auth/login/superadmin')
.send({ email: '[email protected]', password: 'iamayano' });

expect(response.status).toBe(200);
expect(response.body.data.token).toBe('superadmin-token');
});

it('should return 500 on login failure', async () => {
mockAuthService.loginSuperadmin.mockRejectedValue(new Error('Login failed'));

const response = await request(app)
.post('/api/v1/dashboard/auth/login/superadmin')
.send({ email: '[email protected]', password: 'password' });

expect(response.status).toBe(500);
expect(response.body.message).toBe('Login failed');
});
});
});
Binary file added __tests__/test.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,6 @@ app.get('/api-docs', swaggerUi.setup(swaggerDocument));
// Server Listening
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT} | http://localhost:${PORT}`);
});
});

export default app;
7 changes: 7 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: ['/node_modules/', '/dist/'],
collectCoverage: true,
coverageDirectory: 'coverage',
};
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"test": "jest",
"start": "node index.js",
"dev": "ts-node-dev index.ts",
"build": "tsc"
Expand Down Expand Up @@ -41,6 +41,11 @@
"devDependencies": {
"@types/bcryptjs": "^2.4.6",
"@types/cors": "^2.8.17",
"@types/pg": "^8.11.6"
"@types/jest": "^29.5.12",
"@types/pg": "^8.11.6",
"@types/supertest": "^6.0.2",
"jest": "^29.7.0",
"supertest": "^7.0.0",
"ts-jest": "^29.2.5"
}
}
Loading

0 comments on commit 365ad59

Please sign in to comment.