From 917c6d4f0c24dc2475880f9f0400fdc7cedb2dd4 Mon Sep 17 00:00:00 2001 From: Alejandro Gomez <73868258+agosmou@users.noreply.github.com> Date: Tue, 21 Nov 2023 17:55:55 -0800 Subject: [PATCH] Calculation Endpoints: Adds Validation and Tests (#1521) * adds calculation tests for server * adds admin variables to CI * adds validation for request bodies for calculation endpoints * linting on test file * Fix: resolved undefined return to return id property * adds tests with invalid bodies * fixes test description for invalid bodies * refactors tests * removes stale endpoints --- .github/workflows/tdm-server-tests.yml | 4 +- client/src/services/calculation.service.js | 12 ---- server/{.example.env => .env.example} | 44 ++++++------ server/__tests__/calculation.test.js | 72 +++++++++++++++++++ .../app/controllers/calculation.controller.js | 32 +-------- server/app/routes/calculation.routes.js | 16 ----- server/app/services/calculation.service.js | 46 +----------- 7 files changed, 100 insertions(+), 126 deletions(-) rename server/{.example.env => .env.example} (64%) create mode 100644 server/__tests__/calculation.test.js diff --git a/.github/workflows/tdm-server-tests.yml b/.github/workflows/tdm-server-tests.yml index 221c0e5f..01943a5f 100644 --- a/.github/workflows/tdm-server-tests.yml +++ b/.github/workflows/tdm-server-tests.yml @@ -5,7 +5,7 @@ on: branches: - develop jobs: - build: + server-test: runs-on: ubuntu-latest steps: @@ -39,6 +39,8 @@ jobs: echo "APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://westus-0.in.applicationinsights.azure.com/;LiveEndpoint=https://westus.livediagnostics.monitor.azure.com/" >> .env echo "SECURITY_ADMIN_EMAIL=securityadmin@dispostable.com" >> .env echo "SECURITY_ADMIN_PASSWORD=Dogfood1!" >> .env + echo "ADMIN_EMAIL=ladot@dispostable.com" >> .env + echo "ADMIN_PASSWORD=Dogfood1!" >> .env echo "SQL_SERVER_NAME=localhost" >> .env echo "SQL_SERVER_PORT=1434" >> .env echo "SQL_DATABASE_NAME=tdmtestdb" >> .env diff --git a/client/src/services/calculation.service.js b/client/src/services/calculation.service.js index 9140dadd..bbaf633c 100644 --- a/client/src/services/calculation.service.js +++ b/client/src/services/calculation.service.js @@ -9,15 +9,3 @@ export function get() { export function getById(id) { return axios.get(`${baseUrl}/${id}`); } - -export function post(calculation) { - return axios.post(baseUrl, calculation); -} - -export function put(calculation) { - return axios.put(baseUrl + "/" + calculation.id, calculation); -} - -export function del(id) { - return axios.delete(baseUrl + "/" + id); -} diff --git a/server/.example.env b/server/.env.example similarity index 64% rename from server/.example.env rename to server/.env.example index a63744e7..77cc766b 100644 --- a/server/.example.env +++ b/server/.env.example @@ -67,31 +67,33 @@ APPLICATIONINSIGHTS_CONNECTION_STRING= ############################################################### ## Testing (Comment out ALL the above variables) ## ############################################################### -# TEST_ENV= +# TEST_ENV=true -# PORT= -# NODE_OPTIONS= +# PORT=5002 +# NODE_OPTIONS=--trace-deprecation -# JWT_SECRET_KEY= +# JWT_SECRET_KEY=testingSecretKey -# CLIENT_URL= -# SERVER_URL= +# CLIENT_URL=http://localhost:3001 +# SERVER_URL=http://localhost:5002 -# SENDGRID_API_KEY= -# EMAIL_SENDER= -# EMAIL_PUBLIC_COMMENT_LA_CITY= -# EMAIL_PUBLIC_COMMENT_WEB_TEAM= +# SENDGRID_API_KEY=SG.testAPIkey +# EMAIL_SENDER=tdm+sendgrid@test.org +# EMAIL_PUBLIC_COMMENT_LA_CITY=tdm+devpubliccommentplanning@test.org +# EMAIL_PUBLIC_COMMENT_WEB_TEAM=tdm+devpubliccomment@test.org -# APPLICATIONINSIGHTS_CONNECTION_STRING= +# APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=00000000-0000-0000-0000-000000000000;IngestionEndpoint=https://westus-0.in.applicationinsights.azure.com/;LiveEndpoint=https://westus.livediagnostics.monitor.azure.com/ -## Server Test Accounts -# SECURITY_ADMIN_EMAIL= -# SECURITY_ADMIN_PASSWORD= +# # Server Test Accounts +# SECURITY_ADMIN_EMAIL=securityadmin@dispostable.com +# SECURITY_ADMIN_PASSWORD=Dogfood1! +# ADMIN_EMAIL=ladot@dispostable.com +# ADMIN_PASSWORD=Dogfood1! -## testingcontainer Environment Variables -# SQL_SERVER_NAME= -# SQL_SERVER_PORT= -# SQL_DATABASE_NAME= -# SQL_USER_NAME= -# SQL_PASSWORD= -# SQL_ENCRYPT = +# # testingcontainer Environment Variables +# SQL_SERVER_NAME=localhost +# SQL_SERVER_PORT=1434 +# SQL_DATABASE_NAME=tdmtestdb +# SQL_USER_NAME=sa +# SQL_PASSWORD=TestPassw0rd +# SQL_ENCRYPT = false \ No newline at end of file diff --git a/server/__tests__/calculation.test.js b/server/__tests__/calculation.test.js new file mode 100644 index 00000000..a25c5c0e --- /dev/null +++ b/server/__tests__/calculation.test.js @@ -0,0 +1,72 @@ +const request = require("supertest"); +const { + setupServer, + teardownServer +} = require("../_jest-setup_/utils/server-setup"); + +let server; + +beforeAll(async () => { + server = await setupServer(); +}); + +afterAll(async () => { + await teardownServer(); +}); + +describe("tests that require a calculation id", () => { + ////////////////////////////// + // general // + ////////////////////////////// + let calcId; // id of the calculation + + beforeEach(async () => { + // get a calculation id for the tests + const res = await request(server).get("/api/calculations"); + calcId = res.body[0].id; + }); + + afterEach(async () => { + // cleanup state + calcId = undefined; + }); + + // GET "/" all calculations + it("should get all calculations", async () => { + const res = await request(server).get("/api/calculations"); + expect(Array.isArray(res.body)).toBeTruthy(); + res.body.forEach(calc => { + expect(calc).toHaveProperty("id"); + expect(calc).toHaveProperty("name"); + expect(calc).toHaveProperty("description"); + expect(calc).toHaveProperty("deprecated"); + expect(calc).toHaveProperty("dateCreated"); + expect(calc).toHaveProperty("dateModified"); + }); + }); + + // GET "/:calcId" calculation by id + it("should get calculation by id", async () => { + const res = await request(server).get(`/api/calculations/${calcId}`); + expect(res.statusCode).toEqual(200); + expect(res.body.id).toEqual(calcId); + }); + + // GET "/:calcId" calculation by inexistent id + it("should NOT get calculation by id", async () => { + const res = await request(server).get(`/api/calculations/9999999`); + expect(res.statusCode).toEqual(404); + }); + + // GET "/:calcId/rules" all rules for a calculation + it("should get all rules for a calculation", async () => { + const res = await request(server).get(`/api/calculations/${calcId}/rules`); + expect(res.statusCode).toEqual(200); + expect(Array.isArray(res.body)).toBeTruthy(); + res.body.forEach(calc => { + expect(calc).toHaveProperty("id"); + expect(calc).toHaveProperty("calculationId"); + expect(calc.calculationId).toEqual(calcId); + }); + }); +}); diff --git a/server/app/controllers/calculation.controller.js b/server/app/controllers/calculation.controller.js index 39465b0d..df31cf43 100644 --- a/server/app/controllers/calculation.controller.js +++ b/server/app/controllers/calculation.controller.js @@ -22,37 +22,7 @@ const getById = async (req, res) => { } }; -const post = async (req, res) => { - try { - const outputParms = await calculationService.post(req.body); - res.status(201).json(outputParms); - } catch (err) { - res.status(500).send(err); - } -}; - -const put = async (req, res) => { - try { - await calculationService.put(req.body); - res.sendStatus(200); - } catch (err) { - res.status(500).send(err); - } -}; - -const del = async (req, res) => { - try { - await calculationService.del(req.params.id); - res.sendStatus(200); - } catch (err) { - res.status(500).send(err); - } -}; - module.exports = { getAll, - getById, - post, - put, - del + getById }; diff --git a/server/app/routes/calculation.routes.js b/server/app/routes/calculation.routes.js index 2ec9f6f1..139d7bf5 100644 --- a/server/app/routes/calculation.routes.js +++ b/server/app/routes/calculation.routes.js @@ -2,7 +2,6 @@ const router = require("express").Router(); const calculationController = require("../controllers/calculation.controller"); const ruleController = require("../controllers/rule.controller"); -const jwtSession = require("../../middleware/jwt-session"); module.exports = router; @@ -10,18 +9,3 @@ router.get("/:id", calculationController.getById); // Get all the rules for a calculation router.get("/:id/rules", ruleController.getByCalculationId); router.get("/", calculationController.getAll); -router.post( - "/", - jwtSession.validateRoles(["isAdmin"]), - calculationController.post -); -router.put( - "/:id", - jwtSession.validateRoles(["isAdmin"]), - calculationController.put -); -router.delete( - "/:id", - jwtSession.validateRoles(["isAdmin"]), - calculationController.del -); diff --git a/server/app/services/calculation.service.js b/server/app/services/calculation.service.js index 1c9523ca..340d2836 100644 --- a/server/app/services/calculation.service.js +++ b/server/app/services/calculation.service.js @@ -28,51 +28,7 @@ const getById = async id => { } }; -const post = async item => { - try { - await poolConnect; - const request = pool.request(); - request.input("name", mssql.NVarChar, item.name); // 50 - request.input("description", mssql.NVarChar, item.description); // MAX - request.input("deprecated", mssql.Bit, item.deprecated); - request.output("id", mssql.Int, null); - const response = await request.execute("Calculation_Insert"); - - return response.outputParameters; - } catch (err) { - return Promise.reject(err); - } -}; - -const put = async item => { - try { - await poolConnect; - const request = pool.request(); - request.input("name", mssql.NVarChar, item.name); // 50 - request.input("description", mssql.NVarChar, item.description); // MAX - request.input("deprecated", mssql.Bit, item.deprecated); - request.input("id", mssql.Int, item.id); - await request.execute("Calculation_Update"); - } catch (err) { - return Promise.reject(err); - } -}; - -const del = async id => { - try { - await poolConnect; - const request = pool.request(); - request.input("id", mssql.Int, id); - await request.execute("Calculation_Delete"); - } catch (err) { - return Promise.reject(err); - } -}; - module.exports = { getAll, - getById, - post, - put, - del + getById };