From be4ecae119cb361e43a9e13828537b94a05f0182 Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Sun, 7 Jul 2024 14:57:38 +0530 Subject: [PATCH] =?UTF-8?q?Issues=20apis=20and=20test=20=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + jest.config.js | 3 +++ src/__tests__/issuesController.test.ts | 24 +++++++++++------------- src/controllers/issuesController.ts | 22 +++++++++------------- src/middlewares/catchAsyncError.ts | 7 ++++++- src/repositories/issueRepository.ts | 4 ++-- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index b6d813a..5721857 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules # Keep environment variables out of version control .env dist +coverage diff --git a/jest.config.js b/jest.config.js index 7b238aa..e625ceb 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,4 +2,7 @@ module.exports = { preset: "ts-jest", testEnvironment: "node", testMatch: ["**/__tests__/**/*.ts", "**/?(*.)+(spec|test).ts"], + collectCoverage: true, + coverageDirectory: "coverage", + coverageReporters: ["text", "lcov"], }; diff --git a/src/__tests__/issuesController.test.ts b/src/__tests__/issuesController.test.ts index 3404856..2ecb840 100644 --- a/src/__tests__/issuesController.test.ts +++ b/src/__tests__/issuesController.test.ts @@ -2,6 +2,7 @@ import { Request, Response, NextFunction } from "express"; import { createIssue, deleteIssue, getAllIssues, updateIssue } from "../controllers/issuesController"; import issueService from "../services/issueService"; import issueRepository from "../repositories/issueRepository"; +import ErrorHandlerClass from "../utils/errorClass"; jest.mock('../services/issueService'); jest.mock('../repositories/issueRepository'); @@ -146,7 +147,7 @@ describe('Issue Controller', () => { }); }); describe('deleteIssue', () => { - it.only('should delete an issue and return 200 status', async () => { + it('should delete an issue and return 200 status', async () => { const req = { params: { issue_id: '1' }, } as unknown as Request; @@ -169,7 +170,8 @@ describe('Issue Controller', () => { message: 'Issue deleted successfully', }); }); - it('should return 404 if the issue does not exist', async () => { + + it('should call next with an error if issue deletion fails', async () => { const req = { params: { issue_id: '1' }, } as unknown as Request; @@ -181,18 +183,15 @@ describe('Issue Controller', () => { const next = jest.fn() as NextFunction; - (issueRepository.isIssuePresent as jest.Mock).mockResolvedValue(false); + (issueRepository.isIssuePresent as jest.Mock).mockResolvedValue(true); + (issueService.deleteIssue as jest.Mock).mockRejectedValue(new Error('Unable to delete issue')); await deleteIssue(req, res, next); - expect(res.status).toHaveBeenCalledWith(404); - expect(res.json).toHaveBeenCalledWith({ - success: false, - message: 'Issue not found', - }); + expect(next).toHaveBeenCalledWith(expect.any(Error)); }); - it('should call next with an error if issue deletion fails', async () => { + it('should log a message if the issue does not exist', async () => { const req = { params: { issue_id: '1' }, } as unknown as Request; @@ -205,11 +204,10 @@ describe('Issue Controller', () => { const next = jest.fn() as NextFunction; (issueRepository.isIssuePresent as jest.Mock).mockResolvedValue(false); - (issueService.deleteIssue as jest.Mock).mockRejectedValue(new Error('Unable to delete issue')); - await deleteIssue(req, res, next); + await deleteIssue(req as Request, res as Response, next as NextFunction); - expect(next).toHaveBeenCalledWith(expect.any(Error)); + expect(next).toHaveBeenCalledWith(new ErrorHandlerClass('Requested issue not found', 404)); }); }); -}) +}); \ No newline at end of file diff --git a/src/controllers/issuesController.ts b/src/controllers/issuesController.ts index aa1d2f9..3f12fe6 100644 --- a/src/controllers/issuesController.ts +++ b/src/controllers/issuesController.ts @@ -1,11 +1,9 @@ import { Request, Response, NextFunction } from "express"; -import { catchAsyncError } from "../middlewares/catchAsyncError"; import ErrorHandlerClass from "../utils/errorClass"; import issueService from "../services/issueService"; -import prisma from "../config/primsa-client"; import issueRepository from "../repositories/issueRepository"; -export const createIssue = catchAsyncError(async (req: Request, res: Response, next: NextFunction): Promise => { +export const createIssue = async (req: Request, res: Response, next: NextFunction): Promise => { try { const newIssue = await issueService.createIssue(req.body); @@ -19,9 +17,9 @@ export const createIssue = catchAsyncError(async (req: Request, res: Response, n } catch (error) { next(new ErrorHandlerClass("Unable to create issue", 500)); } -}); +}; -export const getAllIssues = catchAsyncError(async (req: Request, res: Response, next: NextFunction): Promise => { +export const getAllIssues = async (req: Request, res: Response, next: NextFunction): Promise => { try { const allIssues = await issueService.getAllIssues(); @@ -33,9 +31,9 @@ export const getAllIssues = catchAsyncError(async (req: Request, res: Response, } catch (error) { next(new ErrorHandlerClass("Failed to fetch issues", 500)) } -}); +}; -export const updateIssue = catchAsyncError(async (req: Request, res: Response, next: NextFunction): Promise => { +export const updateIssue = async (req: Request, res: Response, next: NextFunction): Promise => { try { const { issue_id } = req.params; @@ -51,17 +49,15 @@ export const updateIssue = catchAsyncError(async (req: Request, res: Response, n next(new ErrorHandlerClass("unable to update the issue", 500)) } -}); +}; - -export const deleteIssue = catchAsyncError(async (req: Request, res: Response, next: NextFunction): Promise => { +export const deleteIssue = async (req: Request, res: Response, next: NextFunction): Promise => { try { const { issue_id } = req.params; const isExists = await issueRepository.isIssuePresent(Number(issue_id)); - if (!isExists) { - throw new ErrorHandlerClass("Issue not found", 404) + next(new ErrorHandlerClass("Requested issue not found", 404)); } await issueService.deleteIssue(Number(issue_id)); @@ -74,4 +70,4 @@ export const deleteIssue = catchAsyncError(async (req: Request, res: Response, n } catch (error) { next(new ErrorHandlerClass("Unable to delete the issue", 500)); } -}); \ No newline at end of file +}; diff --git a/src/middlewares/catchAsyncError.ts b/src/middlewares/catchAsyncError.ts index 7df1670..71fb55b 100644 --- a/src/middlewares/catchAsyncError.ts +++ b/src/middlewares/catchAsyncError.ts @@ -2,6 +2,11 @@ import { Request, Response, NextFunction } from 'express'; export const catchAsyncError = (passedFunction: (req: Request, res: Response, next: NextFunction) => Promise) => { return (req: Request, res: Response, next: NextFunction) => { - Promise.resolve(passedFunction(req, res, next)).catch(next); + Promise.resolve(passedFunction(req, res, next)).catch((error) => { + res.status(500).json({ + success: false, + message: 'An unexpected error occurred', + }); + }); }; }; \ No newline at end of file diff --git a/src/repositories/issueRepository.ts b/src/repositories/issueRepository.ts index 56a50af..6c84ea6 100644 --- a/src/repositories/issueRepository.ts +++ b/src/repositories/issueRepository.ts @@ -1,6 +1,6 @@ import { Customer, Issue, Organization, Organization_People, Prisma } from "@prisma/client"; import prisma from "../config/primsa-client"; -import { IssueBodyData, IssueCreateData } from "../interfaces/issueInterface"; +import { IssueCreateData } from "../interfaces/issueInterface"; class IssueRepository { async findOrganization(): Promise { @@ -55,7 +55,7 @@ class IssueRepository { } async deleteIssue(issue_id: number): Promise { - return prisma.issue.delete({ + return await prisma.issue.delete({ where: { issue_id } }); }