From a5b595ed7309a26a401157690671c08a60311635 Mon Sep 17 00:00:00 2001 From: Brennan Douglas Date: Fri, 27 Sep 2019 22:24:31 -0700 Subject: [PATCH 1/3] feat(versions): add patch and delete --- src/components/versions/controller.ts | 61 ++++++++++++++++++++++++++- src/components/versions/routes.ts | 7 +++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/components/versions/controller.ts b/src/components/versions/controller.ts index 7f4572b..a98f976 100644 --- a/src/components/versions/controller.ts +++ b/src/components/versions/controller.ts @@ -6,6 +6,8 @@ import { IPostgresController, PostgresController } from "../../dal/postgres"; export interface IVersionController extends IPostgresController { getVersionsByBatch: RequestHandler; + patchVersion: RequestHandler; + deleteVersion: RequestHandler; } /** @@ -22,7 +24,7 @@ export class VersionController extends PostgresController implements IVersionCon } /** - * Returns all versions from the cooresponding batch + * Returns all versions from the coresponding batch * @param {Request} req * @param {Response} res * @param {NextFunction} next @@ -39,4 +41,61 @@ export class VersionController extends PostgresController implements IVersionCon } } + /** + * Patches an existing version. + * @param {Request} req + * @param {Response} res + * @param {NextFunction} next + * @memberof VersionController + */ + public async patchVersion(req: Request, res: Response, next: NextFunction) { + // Find current entity + const results = await this.readById(req.params.id); + + const { keys, values, escapes } = this.splitObjectKeyVals(req.body); + + // if the item does not exist + if (results.rowCount === 0) { + res.status(404).end(); + } else { + try { + // set an update + const { query, idx } = await this.buildUpdateString(keys); + values.push(req.params.id); + + // update the entity + await this.update(query, `id = \$${idx}`, values); + + res.status(204).end(); + } catch (err) { + res.status(400).send(Boom.badRequest(err)); + } + } + } + + /** + * Deletes a version. + * @param {Request} req + * @param {Response} res + * @param {NextFunction} next + * @memberof VersionController + */ + public async deleteVersion(req: Request, res: Response, next: NextFunction) { + try { + // remove the version + const version = await this.deleteById(req.params.id); + + if (version.rowCount > 0) { + res.status(200).json({ + deletedVersions: version.rowCount, + msg: "Success", + }); + } else { + next(); + } + } catch (err) { + res.status(500).send(Boom.badImplementation(err)); + } + } + } diff --git a/src/components/versions/routes.ts b/src/components/versions/routes.ts index 7318b38..36ed64b 100644 --- a/src/components/versions/routes.ts +++ b/src/components/versions/routes.ts @@ -1,6 +1,7 @@ import Boom from "boom"; import { NextFunction, Request, Response, Router } from "express"; import { IVersionController, VersionController } from "./controller"; +import { requireAuthentication } from "../../middleware/auth"; // tslint:disable: no-unsafe-any @@ -19,6 +20,12 @@ export function routes(): Router { // [GET] section router.get("/batch/:batchId", async (req, res, next) => controller.getVersionsByBatch(req, res, next)); + // [PATCH] section + router.patch("/id/:id", requireAuthentication, async (req, res, next) => controller.patchVersion(req, res, next)); + + // [DELETE] section + router.delete("/id/:id", requireAuthentication, async (req, res, next) => controller.deleteVersion(req, res, next)); + router.use( "*", (req: Request, res: Response) => res.status(400).send(Boom.badRequest(`${req.originalUrl} doesn't exist`)), From bad34386a3938960565a6eb0ba3fac42d93b9dae Mon Sep 17 00:00:00 2001 From: Brennan Douglas Date: Fri, 27 Sep 2019 22:52:23 -0700 Subject: [PATCH 2/3] feat(versions): add unit tests for patch and delete --- .../versions/__tests__/controller.test.ts | 50 +++++++++++++++++++ src/components/versions/controller.ts | 4 +- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/components/versions/__tests__/controller.test.ts b/src/components/versions/__tests__/controller.test.ts index 93eff29..d8078f8 100644 --- a/src/components/versions/__tests__/controller.test.ts +++ b/src/components/versions/__tests__/controller.test.ts @@ -10,6 +10,9 @@ describe("VersionController ", () => { let request: any = {}; let response: any = {}; let nextFunction: any = {}; + const keys = "keys"; + const values: any[] = []; + const escapes = "escapes"; beforeAll(() => { tableName = "versions"; @@ -17,12 +20,14 @@ describe("VersionController ", () => { request = { params: { batchId: "1", + id: "1" }, }; response = { status: jest.fn().mockImplementation(() => ({ json: jest.fn(), send: jest.fn(), + end: jest.fn() })), }; nextFunction = jest.fn(); @@ -40,4 +45,49 @@ describe("VersionController ", () => { await controller.getVersionsByBatch(request as Request, response as Response, nextFunction as NextFunction); expect(response.status).toHaveBeenCalledWith(500); }); + + it("patchVersion success", async () => { + const rows = ["TEST"]; + controller.readById = jest.fn().mockResolvedValue({ rowCount: 1 }); + controller.splitObjectKeyVals = jest.fn().mockReturnValue({ keys, values, escapes}); + controller.buildUpdateString = jest.fn().mockResolvedValue({ query: "", idx: 1}); + controller.update = jest.fn().mockResolvedValue({}); + await controller.patchVersion(request as Request, response as Response, nextFunction as NextFunction); + expect(response.status).toHaveBeenCalledWith(204); + }); + + it("patchVersion error", async () => { + const rows = ["TEST"]; + controller.readById = jest.fn().mockResolvedValue({ rowCount: 1 }); + controller.splitObjectKeyVals = jest.fn().mockReturnValue({ keys, values, escapes}); + controller.buildUpdateString = jest.fn().mockResolvedValue({ query: "", idx: 1}); + controller.update = jest.fn().mockRejectedValue({}); + await controller.patchVersion(request as Request, response as Response, nextFunction as NextFunction); + expect(response.status).toHaveBeenCalledWith(500); + }); + + it("patchVersion not found", async () => { + controller.readById = jest.fn().mockResolvedValue({ rowCount: 0 }); + controller.splitObjectKeyVals = jest.fn().mockReturnValue({ keys, values, escapes}); + await controller.patchVersion(request as Request, response as Response, nextFunction as NextFunction); + expect(response.status).toHaveBeenCalledWith(404); + }); + + it("deleteVersion success", async () => { + controller.deleteById = jest.fn().mockResolvedValue({ rowCount: 1 }); + await controller.deleteVersion(request as Request, response as Response, nextFunction as NextFunction); + expect(response.status).toHaveBeenCalledWith(200); + }); + + it("deleteVersion error", async () => { + controller.deleteById = jest.fn().mockRejectedValue({}); + await controller.deleteVersion(request as Request, response as Response, nextFunction as NextFunction); + expect(response.status).toHaveBeenCalledWith(500); + }); + + it("deleteVersion not found", async () => { + controller.deleteById = jest.fn().mockResolvedValue({ rowCount: 0 }); + await controller.deleteVersion(request as Request, response as Response, nextFunction as NextFunction); + expect(nextFunction).toHaveBeenCalled(); + }); }); diff --git a/src/components/versions/controller.ts b/src/components/versions/controller.ts index a98f976..015f7f7 100644 --- a/src/components/versions/controller.ts +++ b/src/components/versions/controller.ts @@ -62,13 +62,13 @@ export class VersionController extends PostgresController implements IVersionCon // set an update const { query, idx } = await this.buildUpdateString(keys); values.push(req.params.id); - + // update the entity await this.update(query, `id = \$${idx}`, values); res.status(204).end(); } catch (err) { - res.status(400).send(Boom.badRequest(err)); + res.status(500).send(Boom.badRequest(err)); } } } From 04e553a0f325ef46a7d157546ad7feb784dad99b Mon Sep 17 00:00:00 2001 From: Brennan Douglas Date: Fri, 27 Sep 2019 23:04:19 -0700 Subject: [PATCH 3/3] fix(versions): change default not found to 404 --- src/components/versions/routes.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/versions/routes.ts b/src/components/versions/routes.ts index 36ed64b..0c2abfd 100644 --- a/src/components/versions/routes.ts +++ b/src/components/versions/routes.ts @@ -28,7 +28,7 @@ export function routes(): Router { router.use( "*", - (req: Request, res: Response) => res.status(400).send(Boom.badRequest(`${req.originalUrl} doesn't exist`)), + (req: Request, res: Response) => res.status(404).send(Boom.badRequest(`${req.originalUrl} doesn't exist`)), ); return router;