diff --git a/src/common/constants.ts b/src/common/constants.ts index 0f809fcb77aaee85feb998253a2ad399a53eaaa0..5eb7eddb441b27dab25ae42df4dca6267f1b7139 100644 --- a/src/common/constants.ts +++ b/src/common/constants.ts @@ -4,4 +4,5 @@ export const StatusCodes = { NO_CONTENT: 204, BAD_REQUEST: 400, NOT_FOUND: 404, + CONFLICT: 409, } \ No newline at end of file diff --git a/src/modules/ttl/ttl.controller.spec.ts b/src/modules/ttl/ttl.controller.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..15488422db58165f3dc182385ce09b856c72c957 --- /dev/null +++ b/src/modules/ttl/ttl.controller.spec.ts @@ -0,0 +1,155 @@ +import 'reflect-metadata'; +import { Container } from 'typedi'; +import { TtlController } from './ttl.controller'; +import { TtlService } from './ttl.service'; +import { TtlValidationService } from './validation'; +import { StatusCodes } from '../../common/constants'; + +const mockResponse = { + json: jest.fn(), + status: jest.fn().mockImplementation(() => mockResponse), + send: jest.fn(), +}; + +describe('TtlController', () => { + let ttlController: TtlController; + let validateService: TtlValidationService; + let ttlService: TtlService; + + beforeEach(() => { + ttlController = Container.get(TtlController); + validateService = Container.get(TtlValidationService); + ttlService = Container.get(TtlService); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('add item to store', () => { + it('When body does not pass validation -> should return 400', async () => { + const body = {}; + const mockRequest: any = { + body, + }; + const errors: any[] = [new Error('Wrong data')]; + jest.spyOn(validateService, 'validateBody').mockResolvedValue(errors); + jest.spyOn(ttlService, 'get').mockImplementation(() => ({}) as any); + jest.spyOn(ttlService, 'add').mockImplementation(() => ({}) as any); + + await ttlController.add(mockRequest, mockResponse); + + expect(mockResponse.status).toBeCalledWith(StatusCodes.BAD_REQUEST); + expect(mockResponse.send).toBeCalledWith({ errors }); + expect(mockResponse.json).not.toBeCalled(); + expect(ttlService.get).not.toBeCalled(); + expect(ttlService.add).not.toBeCalled(); + }); + + describe('When body passes validation', () => { + it('When key already exists -> should return 409', async () => { + const body = {}; + const mockRequest: any = { + body, + }; + const errors: any[] = []; + jest.spyOn(validateService, 'validateBody').mockResolvedValue(errors); + jest.spyOn(ttlService, 'get').mockImplementation(() => ({}) as any); + jest.spyOn(ttlService, 'add').mockImplementation(() => ({}) as any); + + await ttlController.add(mockRequest, mockResponse); + + expect(mockResponse.status).toBeCalledWith(StatusCodes.CONFLICT); + expect(mockResponse.send).not.toBeCalled(); + expect(mockResponse.json).toBeCalled(); + expect(ttlService.get).toBeCalled(); + expect(ttlService.add).not.toBeCalled(); + }); + + it('When key does not exist -> should return 201', async () => { + const body = {}; + const mockRequest: any = { + body, + }; + const errors: any[] = []; + const result: any = {} + jest.spyOn(validateService, 'validateBody').mockResolvedValue(errors); + jest.spyOn(ttlService, 'get').mockImplementation(() => null as any); + jest.spyOn(ttlService, 'add').mockImplementation(() => result); + + await ttlController.add(mockRequest, mockResponse); + + expect(mockResponse.status).toBeCalledWith(StatusCodes.CREATED); + expect(mockResponse.send).not.toBeCalled(); + expect(mockResponse.json).toBeCalledWith(result); + expect(ttlService.get).toBeCalled(); + expect(ttlService.add).toBeCalledWith(body); + }); + }); + }); + + describe('get item', () => { + it('When key does not exist -> should return 404', () => { + const params = { + key: '', + }; + const mockRequest: any = { + params, + }; + jest.spyOn(ttlService, 'get').mockImplementation(() => null as any); + + ttlController.get(mockRequest, mockResponse); + + expect(mockResponse.status).toBeCalledWith(StatusCodes.NOT_FOUND); + }); + + it('When key exists -> should return 200', () => { + const params = { + key: '', + }; + const mockRequest: any = { + params, + }; + const response: any = {}; + jest.spyOn(ttlService, 'get').mockImplementation(() => response); + + ttlController.get(mockRequest, mockResponse); + + expect(mockResponse.status).toBeCalledWith(StatusCodes.OK_RESPONSE); + expect(mockResponse.json).toBeCalledWith(response); + }); + }); + + describe('remove item', () => { + it('When key does not exist -> should return 404', function () { + const params = { + key: '', + }; + const mockRequest: any = { + params, + }; + const response: any = null; + jest.spyOn(ttlService, 'remove').mockImplementation(() => response); + + ttlController.remove(mockRequest, mockResponse); + + expect(mockResponse.status).toBeCalledWith(StatusCodes.NOT_FOUND); + }); + + it('When key exists -> should return 204', function () { + const params = { + key: '', + }; + const mockRequest: any = { + params, + }; + const response: any = {}; + jest.spyOn(ttlService, 'remove').mockImplementation(() => response); + + ttlController.remove(mockRequest, mockResponse); + + expect(mockResponse.status).toBeCalledWith(StatusCodes.NO_CONTENT); + expect(mockResponse.send).toBeCalled(); + }); + }); +}); diff --git a/src/modules/ttl/ttl.controller.ts b/src/modules/ttl/ttl.controller.ts index 92e8092db18d3c1e12a23ba69036e9639bf900d6..43a3423211cada5a06588ea08a2470c7e2a1da28 100644 --- a/src/modules/ttl/ttl.controller.ts +++ b/src/modules/ttl/ttl.controller.ts @@ -3,6 +3,7 @@ import { Service } from 'typedi'; import { TtlService } from './ttl.service'; import { TtlResponse } from './ttl.dto'; import { TtlValidationService } from './validation'; +import { StatusCodes } from '../../common/constants'; @Service() export class TtlController { @@ -14,33 +15,33 @@ export class TtlController { async add(req: Request, res: Response): Promise> { const errors = await this.validationService.validateBody(req.body); if (errors.length > 0) { - return res.status(400).send({ errors }); + return res.status(StatusCodes.BAD_REQUEST).send({ errors }); } const data = this.ttlService.get(req.body.key); if (data) { - return res.status(409).json({ message: 'Key already exist' }); + return res.status(StatusCodes.CONFLICT).json({ message: 'Key already exist' }); } const result = this.ttlService.add(req.body); - return res.status(201).json(result); + return res.status(StatusCodes.CREATED).json(result); } get(req: Request, res: Response): Response { const result = this.ttlService.get(req.params.key); if (!result) { - return res.status(404).json({ message: 'Not found key' }) + return res.status(StatusCodes.NOT_FOUND).json({ message: 'Not found key' }) } - return res.status(200).json(result); + return res.status(StatusCodes.OK_RESPONSE).json(result); } remove(req: Request, res: Response): Response { const result = this.ttlService.remove(req.params.key); if (!result) { - return res.status(404).json({ message: 'Not found key' }) + return res.status(StatusCodes.NOT_FOUND).json({ message: 'Not found key' }) } - return res.status(204).send(); + return res.status(StatusCodes.NO_CONTENT).send(); } }