From bbe8821b532e755ac1a1019c486ec5c07720e8f5 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Tue, 21 May 2024 14:02:58 -0500 Subject: [PATCH 01/58] Re-org for new test files. Working 'exists' and 'end to end' route tests for routes under consideration. Some will be skipped. --- __tests__/exist.test.js | 13 ---- bin/testApp.js | 120 ----------------------------- package.json | 5 +- routes/__later__/api.later.js | 16 ---- routes/__tests__/create.test.js | 34 ++++++++ routes/__tests__/delete.test.js | 34 ++++++++ routes/__tests__/index.test.js | 16 ++++ routes/__tests__/overwrite.test.js | 39 ++++++++++ routes/__tests__/query.test.js | 35 +++++++++ routes/__tests__/update.test.js | 39 ++++++++++ 10 files changed, 200 insertions(+), 151 deletions(-) delete mode 100644 __tests__/exist.test.js delete mode 100644 bin/testApp.js delete mode 100644 routes/__later__/api.later.js create mode 100644 routes/__tests__/create.test.js create mode 100644 routes/__tests__/delete.test.js create mode 100644 routes/__tests__/index.test.js create mode 100644 routes/__tests__/overwrite.test.js create mode 100644 routes/__tests__/query.test.js create mode 100644 routes/__tests__/update.test.js diff --git a/__tests__/exist.test.js b/__tests__/exist.test.js deleted file mode 100644 index 76048ca..0000000 --- a/__tests__/exist.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import request from "supertest" -//Fun fact, if you don't require app, you don't get coverage even though the tests run just fine. -import app from "../app.js" - -it('/ -- Make sure index exists', function(done) { - request(app) - .get("/index.html") - .expect(200) - .then(response => { - done() - }) - .catch(err => done(err)) -}) diff --git a/bin/testApp.js b/bin/testApp.js deleted file mode 100644 index 9d9ce3a..0000000 --- a/bin/testApp.js +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env node - -/** - * @author thehabes - * */ - -/** - * Module dependencies. - */ -import dotenv from "dotenv" -import dotenvExpand from "dotenv-expand" -const storedEnv = dotenv.config() -dotenvExpand.expand(storedEnv) - -import jest from "jest" -import runCLI from "jest-cli" -import app from "../app.js" -import http from "http" - - -/** - * Get port from environment and store in Express. - */ - -const port = normalizePort('3333') -app.set('port', port) - -/** - * Create HTTP server. - */ - -const server = http.createServer(app) - -/** - * Listen on provided port, on all network interfaces. - */ - -server.listen(port) -server.on('error', onError) -server.on('listening', onListening) - -/** - * Control the keep alive header - */ -// Ensure all inactive connections are terminated by the ALB, by setting this a few seconds higher than the ALB idle timeout -server.keepAliveTimeout = 8 * 1000 //8 seconds -// Ensure the headersTimeout is set higher than the keepAliveTimeout due to this nodejs regression bug: https://github.com/nodejs/node/issues/27363 -server.headersTimeout = 8.5 * 1000 //8 seconds - -/** - * Normalize a port into a number, string, or false. - */ - -function normalizePort(val) { - const portCheck = parseInt(val, 10) - - if (isNaN(portCheck)) { - // named pipe - return val - } - - if (portCheck >= 0) { - // port number - return portCheck - } - - return false -} - -/** - * Event listener for HTTP server "error" event. - */ - -function onError(error) { - if (error.syscall !== 'listen') { - throw error - } - - const bind = typeof port === 'string' - ? 'Pipe ' + port - : 'Port ' + port - - // handle specific listen errors with friendly messages - switch (error.code) { - case 'EACCES': - console.error(bind + ' requires elevated privileges') - process.exit(1) - break - case 'EADDRINUSE': - console.error(bind + ' is already in use') - process.exit(1) - break - default: - throw error - } -} - -/** - * Event listener for HTTP server "listening" event. - */ - -async function onListening() { - console.log("LISTENING ON "+port) - jest.runCLI( - { - "colors" : "true" - }, - ["jest.config.js"]) - .then(({ results }) => { - if (results.success) { - console.log('Tests completed') - process.exit(0) - } - else { - console.error('Tests failed') - process.exit(1) - } - }) -} - diff --git a/package.json b/package.json index caa531c..968a740 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,9 @@ }, "scripts": { "start": "node ./bin/tinyNode.js", - "test": "jest", - "runtest": "node --experimental-vm-modules ./bin/testApp.js" + "allTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js", + "E2Etests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t e2e ", + "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t exists_unit " }, "dependencies": { "cors": "^2.8.5", diff --git a/routes/__later__/api.later.js b/routes/__later__/api.later.js deleted file mode 100644 index 6a3542a..0000000 --- a/routes/__later__/api.later.js +++ /dev/null @@ -1,16 +0,0 @@ -import request from "supertest" -import app from "../../app.js" - -describe("Test /create", () => { - // TODO: This needs to be not creating new objects all the time. - test("New Object saved", async () => { - const response = await request(app) - .post("/create") - .send({test:"item"}) - - expect(response.header).toHaveProperty('location') - expect(response.header).toHaveProperty('etag') - expect(response.header).toHaveProperty('keep-alive') - expect(response.statusCode).toBe(201) - }) -}) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js new file mode 100644 index 0000000..0e3fd27 --- /dev/null +++ b/routes/__tests__/create.test.js @@ -0,0 +1,34 @@ +import express from "express" +import request from "supertest" +import createRoute from "../create.js" +import app from "../../app.js" + +const routeTester = new express() +routeTester.use("/create", createRoute) + +describe("Combined unit tests for the '/create' route.", () => { + it("/create is a registered route in the app. #exists", () => { + let exists = false + const stack = app._router.stack + for(const middleware of stack){ + if(middleware.regexp && middleware.regexp.toString().includes("/create")) { + exists = true + break + } + } + expect(exists).toBe(true) + }) + + // TODO: Can we avoid creating an object + it("/create route can save an object to RERUM. #e2e", () => { + request(routeTester) + .post("/create") + .send({"test":"item"}) + .then(response => { + expect(response.header).toHaveProperty('location') + expect(response.statusCode).toBe(201) + expect(response.body.test.toBe("item")) + }) + .catch(err => err) + }) +}) diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js new file mode 100644 index 0000000..d8e5997 --- /dev/null +++ b/routes/__tests__/delete.test.js @@ -0,0 +1,34 @@ +import express from "express" +import request from "supertest" +import deleteRoute from "../delete.js" +import app from "../../app.js" + +const routeTester = new express() +routeTester.use("/delete", deleteRoute) + +describe("Combined unit tests for the '/delete' route.", () => { + it("/delete is a registered route in the app. #exists", () => { + let exists = false + const stack = app._router.stack + for(const middleware of stack){ + if(middleware.regexp && middleware.regexp.toString().includes("/delete")) { + exists = true + break + } + } + expect(exists).toBe(true) + }) + + // TODO: Test delete capabilities. + it.skip("/delete route can delete an object in RERUM. #e2e", () => { + expect(true).toBe(true) + // request(routeTester) + // .delete("/delete/00000") + // .then(response => { + // expect(response.statusCode).toBe(204) + // done() + // }) + // .catch(err => done(err)) + // expect(response.statusCode).toBe(204) + }) +}) diff --git a/routes/__tests__/index.test.js b/routes/__tests__/index.test.js new file mode 100644 index 0000000..9e3b84e --- /dev/null +++ b/routes/__tests__/index.test.js @@ -0,0 +1,16 @@ +import express from "express" +import request from "supertest" +import indexRoute from "../index.js" + +const routeTester = new express() +routeTester.use("/", indexRoute) + +it("responds to / with a 200 status and and the index.html page.", () => { + request(routeTester).get("/") + .then(response => { + expect(res.statusCode).toBe(200) + expect(res.type).toMatch(/html/) + }) + .catch(err => err) +}) + diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js new file mode 100644 index 0000000..92ed787 --- /dev/null +++ b/routes/__tests__/overwrite.test.js @@ -0,0 +1,39 @@ +import express from "express" +import request from "supertest" +import overwriteRoute from "../overwrite.js" +import app from "../../app.js" + +const routeTester = new express() +routeTester.use("/overwrite ", overwriteRoute) + +describe("Combined unit tests for the '/overwrite ' route.", () => { + it("/overwrite is a registered route in the app. #exists", () => { + let exists = false + const stack = app._router.stack + for(const middleware of stack){ + if(middleware.regexp && middleware.regexp.toString().includes("/overwrite")) { + exists = true + break + } + } + expect(exists).toBe(true) + }) + + // TODO: Test overwrite capabilities + it.skip("Can overwrite the RERUM test obj using the app's /overwrite endpoint. #e2e", () => { + expect(true).toBe(true) + // request(routeTester) + // .put("/overwrite ") + // .send({ + // "@id":`${process.env.RERUM_ID_PATTERN}11111`, + // "test":"item" + // }) + // .then(response => { + // expect(response.header).toHaveProperty('location') + // expect(response.statusCode).toBe(200) + // done() + // }) + // .catch(err => done(err)) + + }) +}) \ No newline at end of file diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js new file mode 100644 index 0000000..762fa53 --- /dev/null +++ b/routes/__tests__/query.test.js @@ -0,0 +1,35 @@ +import express from "express" +import request from "supertest" +import queryRoute from "../query.js" +import app from "../../app.js" + +const routeTester = new express() +routeTester.use("/query", queryRoute) + +describe("Combined unit tests for the '/query' route.", () => { + it("/query is a registered route in the app. #exists", () => { + let exists = false + const stack = app._router.stack + for(const middleware of stack){ + if(middleware.regexp && middleware.regexp.toString().includes("/query")) { + exists = true + break + } + } + expect(exists).toBe(true) + }) + + it("Can query for objects in RERUM using the app's /query endpoint. #e2e", () => { + request(routeTester) + .post("/query") + .send({ + "test":"item" + }) + .then(response => { + expect(response.statusCode).toBe(200) + expect(Array.isArray(response.body)).toBe(true) + expect(response.body.length).toBeTruthy() + }) + .catch(err => err) + }) +}) \ No newline at end of file diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js new file mode 100644 index 0000000..6b22c68 --- /dev/null +++ b/routes/__tests__/update.test.js @@ -0,0 +1,39 @@ +import dotenv from "dotenv" +dotenv.config() +import express from "express" +import request from "supertest" +import updateRoute from "../update.js" +import app from "../../app.js" + +const routeTester = new express() +routeTester.use("/update", updateRoute) + +describe("Combined unit tests for the '/update' route.", () => { + it("/update is a registered route in the app. #exists", () => { + let exists = false + const stack = app._router.stack + for(const middleware of stack){ + if(middleware.regexp && middleware.regexp.toString().includes("/update")) { + exists = true + break + } + } + expect(exists).toBe(true) + }) + + // TODO: Can we avoid updating the RERUM test obj? + it("Can update the RERUM test obj using the app's /update endpoint. #e2e", () => { + request(routeTester) + .put("/update") + .send({ + "@id":`${process.env.RERUM_ID_PATTERN}11111`, + "test":"item" + }) + .then(response => { + expect(response.header).toHaveProperty('location') + expect(response.statusCode).toBe(200) + expect(response.body.test.toBe("item")) + }) + .catch(err => err) + }) +}) From 9a27735914c76f7eb746e3857b18a342130096d2 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Tue, 21 May 2024 14:07:37 -0500 Subject: [PATCH 02/58] Don't need dotenv because we have app.js here --- routes/__tests__/update.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 6b22c68..66389f4 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -1,5 +1,3 @@ -import dotenv from "dotenv" -dotenv.config() import express from "express" import request from "supertest" import updateRoute from "../update.js" From e68e4aae2617223212aafc24cfb5ba76ae887b69 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Tue, 21 May 2024 14:45:24 -0500 Subject: [PATCH 03/58] Check expected RESTful responses on common incorrect usages of the routes. --- routes/__tests__/create.test.js | 39 ++++++++++++++++++++++++++++++ routes/__tests__/delete.test.js | 38 +++++++++++++++++++++++++++++ routes/__tests__/overwrite.test.js | 39 ++++++++++++++++++++++++++++++ routes/__tests__/query.test.js | 39 ++++++++++++++++++++++++++++++ routes/__tests__/update.test.js | 39 ++++++++++++++++++++++++++++++ 5 files changed, 194 insertions(+) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 0e3fd27..cf7281b 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -19,6 +19,45 @@ describe("Combined unit tests for the '/create' route.", () => { expect(exists).toBe(true) }) + // TODO: Can we avoid creating an object + it("Incorrect /create route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/create") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/create") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/create") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .delete("/create") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/create") + .send("not json") + .then(response => { + expect(response.statusCode).toBe(400) + }) + .catch(err => err) + }) + // TODO: Can we avoid creating an object it("/create route can save an object to RERUM. #e2e", () => { request(routeTester) diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js index d8e5997..9fdba7a 100644 --- a/routes/__tests__/delete.test.js +++ b/routes/__tests__/delete.test.js @@ -19,6 +19,44 @@ describe("Combined unit tests for the '/delete' route.", () => { expect(exists).toBe(true) }) + // TODO: Can we avoid creating an object + it("Incorrect /delete route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/delete") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/delete") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/delete") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/delete") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + // request(routeTester) + // .delete("/delete") + // .then(response => { + // expect(response.statusCode).toBe(400) + // }) + // .catch(err => err) + }) + // TODO: Test delete capabilities. it.skip("/delete route can delete an object in RERUM. #e2e", () => { expect(true).toBe(true) diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index 92ed787..bdf8afc 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -19,6 +19,45 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { expect(exists).toBe(true) }) + // TODO: Can we avoid creating an object + it("Incorrect /overwrite route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/overwrite") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/overwrite") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/overwrite") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .delete("/overwrite") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/overwrite") + .send("not json") + .then(response => { + expect(response.statusCode).toBe(400) + }) + .catch(err => err) + }) + // TODO: Test overwrite capabilities it.skip("Can overwrite the RERUM test obj using the app's /overwrite endpoint. #e2e", () => { expect(true).toBe(true) diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js index 762fa53..e674a2b 100644 --- a/routes/__tests__/query.test.js +++ b/routes/__tests__/query.test.js @@ -19,6 +19,45 @@ describe("Combined unit tests for the '/query' route.", () => { expect(exists).toBe(true) }) + // TODO: Can we avoid creating an object + it("Incorrect /query route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/query") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/query") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/query") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .delete("/query") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/query") + .send("not json") + .then(response => { + expect(response.statusCode).toBe(400) + }) + .catch(err => err) + }) + it("Can query for objects in RERUM using the app's /query endpoint. #e2e", () => { request(routeTester) .post("/query") diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 66389f4..0e78290 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -19,6 +19,45 @@ describe("Combined unit tests for the '/update' route.", () => { expect(exists).toBe(true) }) + // TODO: Can we avoid creating an object + it("Incorrect /update route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/update") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/update") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/update") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .delete("/update") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/update") + .send("not json") + .then(response => { + expect(response.statusCode).toBe(400) + }) + .catch(err => err) + }) + // TODO: Can we avoid updating the RERUM test obj? it("Can update the RERUM test obj using the app's /update endpoint. #e2e", () => { request(routeTester) From f869317e4518d677595de5f617cc9bd1769b90bd Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Tue, 21 May 2024 15:20:55 -0500 Subject: [PATCH 04/58] introduce CI/CD file improvements --- .github/workflows/cd_dev.yaml | 39 ++++++++------------------ .github/workflows/cd_prod.yaml | 39 ++++++++------------------ .github/workflows/ci_dev.yaml | 22 +++++++++++++++ .github/workflows/ci_prod.yaml | 22 +++++++++++++++ .github/workflows/test_pushes.yaml | 44 ++++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+), 56 deletions(-) create mode 100644 .github/workflows/ci_dev.yaml create mode 100644 .github/workflows/ci_prod.yaml create mode 100644 .github/workflows/test_pushes.yaml diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index a46d4e8..6ea290d 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -17,38 +17,21 @@ jobs: message: Merge main into this branch to deploy to dev for testing. test: needs: merge-branch - runs-on: ubuntu-latest + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} steps: - uses: actions/checkout@master - - name: Create .env from secrets - uses: SpicyPizza/create-envfile@v2 - with: - envkey_ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} - envkey_REFRESH_TOKEN: ${{ secrets.REFRESH_TOKEN }} - envkey_RERUM_REGISTRATION_URL: ${{ secrets.RERUM_REGISTRATION_URL }} - envkey_RERUM_API_ADDR: ${{ secrets.RERUM_API_ADDR }} - envkey_RERUM_ID_PATTERN: ${{ secrets.RERUM_ID_PATTERN }} - envkey_RERUM_ACCESS_TOKEN_URL: ${{ secrets.RERUM_ACCESS_TOKEN_URL }} - - name: Setup Node.js - uses: actions/setup-node@master - with: - node-version: "21" - - name: Cache node modules - uses: actions/cache@master - env: - cache-name: cache-node-modules - with: - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ - hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - name: Install dependencies and run the test + - name: Test the app on the server run: | + cd /srv/node/tiny-node/ + git stash + git checkout main + git pull npm install - npm run runtest + npm run allTests deploy: if: github.event.pull_request.draft == false needs: diff --git a/.github/workflows/cd_prod.yaml b/.github/workflows/cd_prod.yaml index 3c73cc6..417ab46 100644 --- a/.github/workflows/cd_prod.yaml +++ b/.github/workflows/cd_prod.yaml @@ -4,38 +4,21 @@ on: branches: main jobs: test: - runs-on: ubuntu-latest + strategy: + matrix: + machines: + - vlcdhprdp02 + runs-on: ${{ matrix.machines }} steps: - uses: actions/checkout@master - - name: Create .env from secrets - uses: SpicyPizza/create-envfile@v2 - with: - envkey_ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} - envkey_REFRESH_TOKEN: ${{ secrets.REFRESH_TOKEN }} - envkey_RERUM_REGISTRATION_URL: ${{ secrets.RERUM_REGISTRATION_URL }} - envkey_RERUM_API_ADDR: ${{ secrets.RERUM_API_ADDR }} - envkey_RERUM_ID_PATTERN: ${{ secrets.RERUM_ID_PATTERN }} - envkey_RERUM_ACCESS_TOKEN_URL: ${{ secrets.RERUM_ACCESS_TOKEN_URL }} - - name: Setup Node.js - uses: actions/setup-node@master - with: - node-version: "21" - - name: Cache node modules - uses: actions/cache@master - env: - cache-name: cache-node-modules - with: - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ - hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - name: Install dependencies and run the test + - name: Test the app on the server run: | + cd /srv/node/tiny-node/ + git stash + git checkout main + git pull npm install - npm run runtest + npm run allTests deploy: needs: - test diff --git a/.github/workflows/ci_dev.yaml b/.github/workflows/ci_dev.yaml new file mode 100644 index 0000000..fcacf66 --- /dev/null +++ b/.github/workflows/ci_dev.yaml @@ -0,0 +1,22 @@ +name: TinyNode end to end tests on PR to development +on: + pull_request: + branches: release +jobs: + test: + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} + steps: + - uses: actions/checkout@master + - name: Test the app on the server + run: | + cd /srv/node/tiny-node/ + git stash + git checkout main + git pull + npm install + npm run allTests + \ No newline at end of file diff --git a/.github/workflows/ci_prod.yaml b/.github/workflows/ci_prod.yaml new file mode 100644 index 0000000..e59a416 --- /dev/null +++ b/.github/workflows/ci_prod.yaml @@ -0,0 +1,22 @@ +name: TinyNode end to end tests on PR to main +on: + pull_request: + branches: main +jobs: + test: + strategy: + matrix: + machines: + - vlcdhprdp02 + runs-on: ${{ matrix.machines }} + steps: + - uses: actions/checkout@master + - name: Test the app on the server + run: | + cd /srv/node/tiny-node/ + git stash + git checkout main + git pull + npm install + npm run allTests + \ No newline at end of file diff --git a/.github/workflows/test_pushes.yaml b/.github/workflows/test_pushes.yaml new file mode 100644 index 0000000..bd74e96 --- /dev/null +++ b/.github/workflows/test_pushes.yaml @@ -0,0 +1,44 @@ +name: TinyNode tests on any push +on: + push: + branches: + - '*' + - '!main' + - '!release' +jobs: + check_for_open_pr: + runs-on: ubuntu-latest + steps: + - name: Set the branch name as a processable string by making it an env variable. + run: echo BranchName=${GITHUB_REF##*/} >> $GITHUB_ENV + - name: Find Pull Request + uses: juliangruber/find-pull-request-action@v1 + id: find-pull-request + with: + branch: ${{ env.BranchName }} + - name: Make the PR number a processable string. Output that string for the next job. + run: | + echo Name $BranchName + echo PRnumber=${{steps.find-pull-request.outputs.number}} >> $GITHUB_ENV + outputs: + number: ${{ env.PRnumber }} + test: + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} + needs: + - check_for_open_pr + if: needs.check_for_open_pr.outputs.number == '' + steps: + - uses: actions/checkout@master + - name: Test the app on the server + run: | + cd /srv/node/tiny-node/ + git stash + git checkout main + git pull + npm install + npm run allTests + \ No newline at end of file From 887ef4e54ed46787a3a290d8815f3407a1a81347 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Tue, 21 May 2024 15:41:30 -0500 Subject: [PATCH 05/58] introduce CI/CD file improvements --- .github/workflows/cd_dev.yaml | 11 ++++++----- .github/workflows/cd_prod.yaml | 1 + .github/workflows/ci_dev.yaml | 6 +++--- .github/workflows/ci_prod.yaml | 2 +- .github/workflows/test_pushes.yaml | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 6ea290d..51ca2fb 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -1,7 +1,7 @@ -name: TinyNode Dev Deploy on PR to main +name: TinyNode Dev Deploy on push to release on: - pull_request: - branches: main + push: + branches: release jobs: merge-branch: runs-on: ubuntu-latest @@ -12,7 +12,7 @@ jobs: with: type: now from_branch: main - target_branch: ${{ github.head_ref }} + target_branch: release github_token: ${{ secrets.BRY_PAT }} message: Merge main into this branch to deploy to dev for testing. test: @@ -28,7 +28,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash - git checkout main + git checkout release git pull npm install npm run allTests @@ -53,6 +53,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash + git checkout release git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/cd_prod.yaml b/.github/workflows/cd_prod.yaml index 417ab46..09ce21d 100644 --- a/.github/workflows/cd_prod.yaml +++ b/.github/workflows/cd_prod.yaml @@ -38,6 +38,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash + git checkout main git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/ci_dev.yaml b/.github/workflows/ci_dev.yaml index fcacf66..dfcc97a 100644 --- a/.github/workflows/ci_dev.yaml +++ b/.github/workflows/ci_dev.yaml @@ -1,4 +1,4 @@ -name: TinyNode end to end tests on PR to development +name: TinyNode end to end tests on PR to release on: pull_request: branches: release @@ -15,8 +15,8 @@ jobs: run: | cd /srv/node/tiny-node/ git stash - git checkout main + git checkout $GITHUB_HEAD_REF git pull npm install - npm run allTests + npm run E2Etests \ No newline at end of file diff --git a/.github/workflows/ci_prod.yaml b/.github/workflows/ci_prod.yaml index e59a416..057a3a7 100644 --- a/.github/workflows/ci_prod.yaml +++ b/.github/workflows/ci_prod.yaml @@ -15,7 +15,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash - git checkout main + git checkout $GITHUB_HEAD_REF git pull npm install npm run allTests diff --git a/.github/workflows/test_pushes.yaml b/.github/workflows/test_pushes.yaml index bd74e96..2d73bb5 100644 --- a/.github/workflows/test_pushes.yaml +++ b/.github/workflows/test_pushes.yaml @@ -37,7 +37,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash - git checkout main + git checkout $GITHUB_REF git pull npm install npm run allTests From 480e6101d573deac837c980e41e1fa9b6f68db0d Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 22 May 2024 11:56:23 -0500 Subject: [PATCH 06/58] Include testing around the '/app' version of routes as well --- routes/__tests__/create.test.js | 74 ++++++++++++++++++++++++--- routes/__tests__/delete.test.js | 74 ++++++++++++++++++++++++--- routes/__tests__/index.test.js | 4 ++ routes/__tests__/overwrite.test.js | 80 ++++++++++++++++++++++++++---- routes/__tests__/query.test.js | 74 ++++++++++++++++++++++++--- routes/__tests__/update.test.js | 78 ++++++++++++++++++++++++++--- 6 files changed, 345 insertions(+), 39 deletions(-) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index cf7281b..3ab8114 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -7,20 +7,79 @@ const routeTester = new express() routeTester.use("/create", createRoute) describe("Combined unit tests for the '/create' route.", () => { - it("/create is a registered route in the app. #exists", () => { + it("'/app/create' and '/create' are registered routes in the app. #exists", () => { let exists = false + let count = 0 const stack = app._router.stack for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/create")) { - exists = true - break - } + if(middleware.regexp && middleware.regexp.toString().includes("/app/create")) { + count++ + } + else if(middleware.regexp && middleware.regexp.toString().includes("/create")) { + count++ + } + if(count === 2){ + exists = true + break + } } expect(exists).toBe(true) }) + // TODO: Can we avoid creating an object + it("Incorrect '/app/create' route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/app/create") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/app/create") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/app/create") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .delete("/app/create") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/app/create") + .send("not json") + .then(response => { + expect(response.statusCode).toBe(400) + }) + .catch(err => err) + }) + + // TODO: Can we avoid creating an object + it("'/app/create' route can save an object to RERUM. #e2e", () => { + request(routeTester) + .post("/app/create") + .send({"test":"item"}) + .then(response => { + expect(response.header).toHaveProperty('location') + expect(response.statusCode).toBe(201) + expect(response.body.test.toBe("item")) + }) + .catch(err => err) + }) + // TODO: Can we avoid creating an object - it("Incorrect /create route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/create' route usage has expected RESTful responses. #rest", () => { request(routeTester) .get("/create") .then(response => { @@ -59,7 +118,7 @@ describe("Combined unit tests for the '/create' route.", () => { }) // TODO: Can we avoid creating an object - it("/create route can save an object to RERUM. #e2e", () => { + it("'/create' route can save an object to RERUM. #e2e", () => { request(routeTester) .post("/create") .send({"test":"item"}) @@ -70,4 +129,5 @@ describe("Combined unit tests for the '/create' route.", () => { }) .catch(err => err) }) + }) diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js index 9fdba7a..21ac234 100644 --- a/routes/__tests__/delete.test.js +++ b/routes/__tests__/delete.test.js @@ -7,20 +7,78 @@ const routeTester = new express() routeTester.use("/delete", deleteRoute) describe("Combined unit tests for the '/delete' route.", () => { - it("/delete is a registered route in the app. #exists", () => { + it("'/app/delete' and '/delete' are registered routes in the app. #exists", () => { let exists = false + let count = 0 const stack = app._router.stack for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/delete")) { - exists = true - break - } + if(middleware.regexp && middleware.regexp.toString().includes("/app/delete")) { + count++ + } + else if(middleware.regexp && middleware.regexp.toString().includes("/delete")) { + count++ + } + if(count === 2){ + exists = true + break + } } expect(exists).toBe(true) }) - // TODO: Can we avoid creating an object - it("Incorrect /delete route usage has expected RESTful responses. #rest", () => { + // TODO: Can we avoid creating an object + it("Incorrect '/app/delete' route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/app/delete") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/app/delete") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/app/delete") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/app/delete") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + // request(routeTester) + // .delete("/app/delete") + // .then(response => { + // expect(response.statusCode).toBe(400) + // }) + // .catch(err => err) + }) + + // TODO: Test delete capabilities. + it.skip("'/app/delete' route can delete an object in RERUM. #e2e", () => { + expect(true).toBe(true) + // request(routeTester) + // .delete("/app/delete/00000") + // .then(response => { + // expect(response.statusCode).toBe(204) + // done() + // }) + // .catch(err => done(err)) + // expect(response.statusCode).toBe(204) + }) + + // TODO: Can we avoid creating an object + it("Incorrect '/delete' route usage has expected RESTful responses. #rest", () => { request(routeTester) .get("/delete") .then(response => { @@ -58,7 +116,7 @@ describe("Combined unit tests for the '/delete' route.", () => { }) // TODO: Test delete capabilities. - it.skip("/delete route can delete an object in RERUM. #e2e", () => { + it.skip("'/delete' route can delete an object in RERUM. #e2e", () => { expect(true).toBe(true) // request(routeTester) // .delete("/delete/00000") diff --git a/routes/__tests__/index.test.js b/routes/__tests__/index.test.js index 9e3b84e..df4ea4f 100644 --- a/routes/__tests__/index.test.js +++ b/routes/__tests__/index.test.js @@ -1,3 +1,7 @@ +/** + * Test the app index and make sure it what we expect. + */ + import express from "express" import request from "supertest" import indexRoute from "../index.js" diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index bdf8afc..9482183 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -7,20 +7,83 @@ const routeTester = new express() routeTester.use("/overwrite ", overwriteRoute) describe("Combined unit tests for the '/overwrite ' route.", () => { - it("/overwrite is a registered route in the app. #exists", () => { + it("'/app/overwrite' and '/overwrite' are registered routes in the app. #exists", () => { let exists = false + let count = 0 const stack = app._router.stack for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/overwrite")) { - exists = true - break - } + if(middleware.regexp && middleware.regexp.toString().includes("/app/overwrite")) { + count++ + } + else if(middleware.regexp && middleware.regexp.toString().includes("/overwrite")) { + count++ + } + if(count === 2){ + exists = true + break + } } expect(exists).toBe(true) }) - // TODO: Can we avoid creating an object - it("Incorrect /overwrite route usage has expected RESTful responses. #rest", () => { + // TODO: Can we avoid creating an object + it("Incorrect '/app/overwrite' route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/app/overwrite") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/app/overwrite") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/app/overwrite") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .delete("/app/overwrite") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/app/overwrite") + .send("not json") + .then(response => { + expect(response.statusCode).toBe(400) + }) + .catch(err => err) + }) + + // TODO: Test overwrite capabilities + it.skip("Can overwrite the RERUM test obj using the app's '/app/overwrite' route. #e2e", () => { + expect(true).toBe(true) + // request(routeTester) + // .put("/app/overwrite ") + // .send({ + // "@id":`${process.env.RERUM_ID_PATTERN}11111`, + // "test":"item" + // }) + // .then(response => { + // expect(response.header).toHaveProperty('location') + // expect(response.statusCode).toBe(200) + // done() + // }) + // .catch(err => done(err)) + }) + + // TODO: Can we avoid creating an object + it("Incorrect '/overwrite' route usage has expected RESTful responses. #rest", () => { request(routeTester) .get("/overwrite") .then(response => { @@ -59,7 +122,7 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { }) // TODO: Test overwrite capabilities - it.skip("Can overwrite the RERUM test obj using the app's /overwrite endpoint. #e2e", () => { + it.skip("Can overwrite the RERUM test obj using the app's '/overwrite' route. #e2e", () => { expect(true).toBe(true) // request(routeTester) // .put("/overwrite ") @@ -73,6 +136,5 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { // done() // }) // .catch(err => done(err)) - }) }) \ No newline at end of file diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js index e674a2b..1bbc747 100644 --- a/routes/__tests__/query.test.js +++ b/routes/__tests__/query.test.js @@ -7,20 +7,80 @@ const routeTester = new express() routeTester.use("/query", queryRoute) describe("Combined unit tests for the '/query' route.", () => { - it("/query is a registered route in the app. #exists", () => { + it("'/app/query' and '/query' are registered routes in the app. #exists", () => { let exists = false + let count = 0 const stack = app._router.stack for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/query")) { - exists = true - break - } + if(middleware.regexp && middleware.regexp.toString().includes("/app/query")) { + count++ + } + else if(middleware.regexp && middleware.regexp.toString().includes("/query")) { + count++ + } + if(count === 2){ + exists = true + break + } } expect(exists).toBe(true) }) // TODO: Can we avoid creating an object - it("Incorrect /query route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/app/query' route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/app/query") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/app/query") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/app/query") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .delete("/app/query") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/app/query") + .send("not json") + .then(response => { + expect(response.statusCode).toBe(400) + }) + .catch(err => err) + }) + + it("Can query for objects in RERUM using the app's '/app/query' route. #e2e", () => { + request(routeTester) + .post("/app/query") + .send({ + "test":"item" + }) + .then(response => { + expect(response.statusCode).toBe(200) + expect(Array.isArray(response.body)).toBe(true) + expect(response.body.length).toBeTruthy() + }) + .catch(err => err) + }) + + // TODO: Can we avoid creating an object + it("Incorrect '/query' route usage has expected RESTful responses. #rest", () => { request(routeTester) .get("/query") .then(response => { @@ -58,7 +118,7 @@ describe("Combined unit tests for the '/query' route.", () => { .catch(err => err) }) - it("Can query for objects in RERUM using the app's /query endpoint. #e2e", () => { + it("Can query for objects in RERUM using the app's '/query' route. #e2e", () => { request(routeTester) .post("/query") .send({ diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 0e78290..d5d7224 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -7,20 +7,82 @@ const routeTester = new express() routeTester.use("/update", updateRoute) describe("Combined unit tests for the '/update' route.", () => { - it("/update is a registered route in the app. #exists", () => { + it("'/app/update' and '/update' are registered routes in the app. #exists", () => { let exists = false + let count = 0 const stack = app._router.stack for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/update")) { - exists = true - break - } + if(middleware.regexp && middleware.regexp.toString().includes("/app/update")) { + count++ + } + else if(middleware.regexp && middleware.regexp.toString().includes("/update")) { + count++ + } + if(count === 2){ + exists = true + break + } } expect(exists).toBe(true) }) - // TODO: Can we avoid creating an object - it("Incorrect /update route usage has expected RESTful responses. #rest", () => { + // TODO: Can we avoid creating an object + it("Incorrect '/app/update' route usage has expected RESTful responses. #rest", () => { + request(routeTester) + .get("/app/update") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .post("/app/update") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .patch("/app/update") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .delete("/app/update") + .then(response => { + expect(response.statusCode).toBe(405) + }) + .catch(err => err) + + request(routeTester) + .put("/app/update") + .send("not json") + .then(response => { + expect(response.statusCode).toBe(400) + }) + .catch(err => err) + }) + + // TODO: Can we avoid updating the RERUM test obj? + it("Can update the RERUM test obj using the app's '/app/update' route. #e2e", () => { + request(routeTester) + .put("/app/update") + .send({ + "@id":`${process.env.RERUM_ID_PATTERN}11111`, + "test":"item" + }) + .then(response => { + expect(response.header).toHaveProperty('location') + expect(response.statusCode).toBe(200) + expect(response.body.test.toBe("item")) + }) + .catch(err => err) + }) + + // TODO: Can we avoid creating an object + it("Incorrect '/update' route usage has expected RESTful responses. #rest", () => { request(routeTester) .get("/update") .then(response => { @@ -59,7 +121,7 @@ describe("Combined unit tests for the '/update' route.", () => { }) // TODO: Can we avoid updating the RERUM test obj? - it("Can update the RERUM test obj using the app's /update endpoint. #e2e", () => { + it("Can update the RERUM test obj using the app's '/update' route. #e2e", () => { request(routeTester) .put("/update") .send({ From 68d8771f82a789cb0c1168be479fc9041d0e048c Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 22 May 2024 12:13:22 -0500 Subject: [PATCH 07/58] proper rebase --- .github/workflows/cd_dev.yaml | 10 +++++----- .github/workflows/cd_prod.yaml | 8 ++++---- .github/workflows/ci_dev.yaml | 4 ++-- .github/workflows/ci_prod.yaml | 6 +++--- package.json | 3 ++- routes/__tests__/create.test.js | 4 ++-- routes/__tests__/delete.test.js | 4 ++-- routes/__tests__/overwrite.test.js | 4 ++-- routes/__tests__/query.test.js | 4 ++-- routes/__tests__/update.test.js | 4 ++-- 10 files changed, 26 insertions(+), 25 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 51ca2fb..ffe964f 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -1,7 +1,7 @@ -name: TinyNode Dev Deploy on push to release +name: TinyNode Dev Deploy on push to deepfakemain on: push: - branches: release + branches: deepfakemain jobs: merge-branch: runs-on: ubuntu-latest @@ -12,7 +12,7 @@ jobs: with: type: now from_branch: main - target_branch: release + target_branch: deepfakemain github_token: ${{ secrets.BRY_PAT }} message: Merge main into this branch to deploy to dev for testing. test: @@ -28,7 +28,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash - git checkout release + git checkout deepfakemain git pull npm install npm run allTests @@ -53,7 +53,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash - git checkout release + git checkout deepfakemain git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/cd_prod.yaml b/.github/workflows/cd_prod.yaml index 09ce21d..13b5481 100644 --- a/.github/workflows/cd_prod.yaml +++ b/.github/workflows/cd_prod.yaml @@ -1,7 +1,7 @@ -name: TinyNode production deploy on push to main. +name: TinyNode production deploy on push to release. on: push: - branches: main + branches: release jobs: test: strategy: @@ -15,7 +15,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash - git checkout main + git checkout release git pull npm install npm run allTests @@ -38,7 +38,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash - git checkout main + git checkout release git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/ci_dev.yaml b/.github/workflows/ci_dev.yaml index dfcc97a..e82990d 100644 --- a/.github/workflows/ci_dev.yaml +++ b/.github/workflows/ci_dev.yaml @@ -1,7 +1,7 @@ -name: TinyNode end to end tests on PR to release +name: TinyNode end to end tests on PR to deepfakemain on: pull_request: - branches: release + branches: deepfakemain jobs: test: strategy: diff --git a/.github/workflows/ci_prod.yaml b/.github/workflows/ci_prod.yaml index 057a3a7..2898c6d 100644 --- a/.github/workflows/ci_prod.yaml +++ b/.github/workflows/ci_prod.yaml @@ -1,7 +1,7 @@ -name: TinyNode end to end tests on PR to main +name: TinyNode end to end tests on PR to release on: pull_request: - branches: main + branches: release jobs: test: strategy: @@ -18,5 +18,5 @@ jobs: git checkout $GITHUB_HEAD_REF git pull npm install - npm run allTests + npm run E2Etests \ No newline at end of file diff --git a/package.json b/package.json index 968a740..865d47b 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "start": "node ./bin/tinyNode.js", "allTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js", "E2Etests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t e2e ", - "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t exists_unit " + "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t exists ", + "functionalTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t exists " }, "dependencies": { "cors": "^2.8.5", diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 3ab8114..233e0f4 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/create' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/create' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/app/create' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/app/create") .then(response => { @@ -79,7 +79,7 @@ describe("Combined unit tests for the '/create' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/create' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/create' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/create") .then(response => { diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js index 21ac234..a7362e0 100644 --- a/routes/__tests__/delete.test.js +++ b/routes/__tests__/delete.test.js @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/delete' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/delete' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/app/delete' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/app/delete") .then(response => { @@ -78,7 +78,7 @@ describe("Combined unit tests for the '/delete' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/delete' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/delete' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/delete") .then(response => { diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index 9482183..91c210a 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/overwrite' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/app/overwrite' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/app/overwrite") .then(response => { @@ -83,7 +83,7 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/overwrite' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/overwrite' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/overwrite") .then(response => { diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js index 1bbc747..293f94d 100644 --- a/routes/__tests__/query.test.js +++ b/routes/__tests__/query.test.js @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/query' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/query' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/app/query' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/app/query") .then(response => { @@ -80,7 +80,7 @@ describe("Combined unit tests for the '/query' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/query' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/query' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/query") .then(response => { diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index d5d7224..613480f 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/update' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/update' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/app/update' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/app/update") .then(response => { @@ -82,7 +82,7 @@ describe("Combined unit tests for the '/update' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/update' route usage has expected RESTful responses. #rest", () => { + it("Incorrect '/update' route usage has expected RESTful responses. #rest_functions", () => { request(routeTester) .get("/update") .then(response => { From e880f0862d1fb9a126deb1c9bcaaf3d7d429f56d Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 22 May 2024 12:14:49 -0500 Subject: [PATCH 08/58] ah another main to deep fake --- .github/workflows/test_pushes.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_pushes.yaml b/.github/workflows/test_pushes.yaml index 2d73bb5..cef9f14 100644 --- a/.github/workflows/test_pushes.yaml +++ b/.github/workflows/test_pushes.yaml @@ -3,7 +3,7 @@ on: push: branches: - '*' - - '!main' + - '!deepfakemain' - '!release' jobs: check_for_open_pr: From b04c7c6419318ecf4973c3255040660da0014f85 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 22 May 2024 12:27:37 -0500 Subject: [PATCH 09/58] more rebase --- .github/workflows/cd_dev.yaml | 4 ++-- .github/workflows/ci_dev.yaml | 1 + .github/workflows/ci_prod.yaml | 1 + .github/workflows/test_pushes.yaml | 1 + 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index ffe964f..11a599b 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -7,11 +7,11 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - - name: Merge with main + - name: Merge with release uses: devmasx/merge-branch@master with: type: now - from_branch: main + from_branch: release target_branch: deepfakemain github_token: ${{ secrets.BRY_PAT }} message: Merge main into this branch to deploy to dev for testing. diff --git a/.github/workflows/ci_dev.yaml b/.github/workflows/ci_dev.yaml index e82990d..5937341 100644 --- a/.github/workflows/ci_dev.yaml +++ b/.github/workflows/ci_dev.yaml @@ -15,6 +15,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash + git pull git checkout $GITHUB_HEAD_REF git pull npm install diff --git a/.github/workflows/ci_prod.yaml b/.github/workflows/ci_prod.yaml index 2898c6d..9bac65d 100644 --- a/.github/workflows/ci_prod.yaml +++ b/.github/workflows/ci_prod.yaml @@ -15,6 +15,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash + git pull git checkout $GITHUB_HEAD_REF git pull npm install diff --git a/.github/workflows/test_pushes.yaml b/.github/workflows/test_pushes.yaml index cef9f14..21920b2 100644 --- a/.github/workflows/test_pushes.yaml +++ b/.github/workflows/test_pushes.yaml @@ -37,6 +37,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash + git pull git checkout $GITHUB_REF git pull npm install From 0772216b522d02f1d238f146bf22100b99a90b27 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 22 May 2024 12:46:57 -0500 Subject: [PATCH 10/58] trigger again and watch logs --- .github/workflows/cd_dev.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 11a599b..7591f87 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -14,7 +14,7 @@ jobs: from_branch: release target_branch: deepfakemain github_token: ${{ secrets.BRY_PAT }} - message: Merge main into this branch to deploy to dev for testing. + message: Merge deepfakemain into this branch to deploy to dev for testing. test: needs: merge-branch strategy: From 228439e56d7f609dbfaa70f190e1125c5eda40bd Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 22 May 2024 13:01:27 -0500 Subject: [PATCH 11/58] Rewording for which tests run during which situations --- .github/workflows/test_pushes.yaml | 4 ++-- package.json | 6 +++--- routes/__tests__/create.test.js | 10 +++++----- routes/__tests__/delete.test.js | 10 +++++----- routes/__tests__/overwrite.test.js | 10 +++++----- routes/__tests__/query.test.js | 10 +++++----- routes/__tests__/update.test.js | 10 +++++----- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/test_pushes.yaml b/.github/workflows/test_pushes.yaml index 21920b2..d487b9c 100644 --- a/.github/workflows/test_pushes.yaml +++ b/.github/workflows/test_pushes.yaml @@ -1,4 +1,4 @@ -name: TinyNode tests on any push +name: TinyNode tests on any push to a branch without an open PR on: push: branches: @@ -41,5 +41,5 @@ jobs: git checkout $GITHUB_REF git pull npm install - npm run allTests + npm run functionalTests \ No newline at end of file diff --git a/package.json b/package.json index 865d47b..d945e7d 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,9 @@ "scripts": { "start": "node ./bin/tinyNode.js", "allTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js", - "E2Etests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t e2e ", - "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t exists ", - "functionalTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t exists " + "E2Etests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __e2e ", + "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __exists ", + "coreTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __core " }, "dependencies": { "cors": "^2.8.5", diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 233e0f4..ef6e244 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -7,7 +7,7 @@ const routeTester = new express() routeTester.use("/create", createRoute) describe("Combined unit tests for the '/create' route.", () => { - it("'/app/create' and '/create' are registered routes in the app. #exists", () => { + it("'/app/create' and '/create' are registered routes in the app. __exists __core", () => { let exists = false let count = 0 const stack = app._router.stack @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/create' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/create' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/app/create' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/app/create") .then(response => { @@ -66,7 +66,7 @@ describe("Combined unit tests for the '/create' route.", () => { }) // TODO: Can we avoid creating an object - it("'/app/create' route can save an object to RERUM. #e2e", () => { + it("'/app/create' route can save an object to RERUM. __e2e", () => { request(routeTester) .post("/app/create") .send({"test":"item"}) @@ -79,7 +79,7 @@ describe("Combined unit tests for the '/create' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/create' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/create' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/create") .then(response => { @@ -118,7 +118,7 @@ describe("Combined unit tests for the '/create' route.", () => { }) // TODO: Can we avoid creating an object - it("'/create' route can save an object to RERUM. #e2e", () => { + it("'/create' route can save an object to RERUM. __e2e", () => { request(routeTester) .post("/create") .send({"test":"item"}) diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js index a7362e0..c266bdb 100644 --- a/routes/__tests__/delete.test.js +++ b/routes/__tests__/delete.test.js @@ -7,7 +7,7 @@ const routeTester = new express() routeTester.use("/delete", deleteRoute) describe("Combined unit tests for the '/delete' route.", () => { - it("'/app/delete' and '/delete' are registered routes in the app. #exists", () => { + it("'/app/delete' and '/delete' are registered routes in the app. __exists __core", () => { let exists = false let count = 0 const stack = app._router.stack @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/delete' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/delete' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/app/delete' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/app/delete") .then(response => { @@ -65,7 +65,7 @@ describe("Combined unit tests for the '/delete' route.", () => { }) // TODO: Test delete capabilities. - it.skip("'/app/delete' route can delete an object in RERUM. #e2e", () => { + it.skip("'/app/delete' route can delete an object in RERUM. __e2e", () => { expect(true).toBe(true) // request(routeTester) // .delete("/app/delete/00000") @@ -78,7 +78,7 @@ describe("Combined unit tests for the '/delete' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/delete' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/delete' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/delete") .then(response => { @@ -116,7 +116,7 @@ describe("Combined unit tests for the '/delete' route.", () => { }) // TODO: Test delete capabilities. - it.skip("'/delete' route can delete an object in RERUM. #e2e", () => { + it.skip("'/delete' route can delete an object in RERUM. __e2e", () => { expect(true).toBe(true) // request(routeTester) // .delete("/delete/00000") diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index 91c210a..dd219a4 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -7,7 +7,7 @@ const routeTester = new express() routeTester.use("/overwrite ", overwriteRoute) describe("Combined unit tests for the '/overwrite ' route.", () => { - it("'/app/overwrite' and '/overwrite' are registered routes in the app. #exists", () => { + it("'/app/overwrite' and '/overwrite' are registered routes in the app. __exists __core", () => { let exists = false let count = 0 const stack = app._router.stack @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/overwrite' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/app/overwrite' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/app/overwrite") .then(response => { @@ -66,7 +66,7 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { }) // TODO: Test overwrite capabilities - it.skip("Can overwrite the RERUM test obj using the app's '/app/overwrite' route. #e2e", () => { + it.skip("Can overwrite the RERUM test obj using the app's '/app/overwrite' route. __e2e", () => { expect(true).toBe(true) // request(routeTester) // .put("/app/overwrite ") @@ -83,7 +83,7 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/overwrite' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/overwrite' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/overwrite") .then(response => { @@ -122,7 +122,7 @@ describe("Combined unit tests for the '/overwrite ' route.", () => { }) // TODO: Test overwrite capabilities - it.skip("Can overwrite the RERUM test obj using the app's '/overwrite' route. #e2e", () => { + it.skip("Can overwrite the RERUM test obj using the app's '/overwrite' route. __e2e", () => { expect(true).toBe(true) // request(routeTester) // .put("/overwrite ") diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js index 293f94d..871203b 100644 --- a/routes/__tests__/query.test.js +++ b/routes/__tests__/query.test.js @@ -7,7 +7,7 @@ const routeTester = new express() routeTester.use("/query", queryRoute) describe("Combined unit tests for the '/query' route.", () => { - it("'/app/query' and '/query' are registered routes in the app. #exists", () => { + it("'/app/query' and '/query' are registered routes in the app. __exists __core ", () => { let exists = false let count = 0 const stack = app._router.stack @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/query' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/query' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/app/query' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/app/query") .then(response => { @@ -65,7 +65,7 @@ describe("Combined unit tests for the '/query' route.", () => { .catch(err => err) }) - it("Can query for objects in RERUM using the app's '/app/query' route. #e2e", () => { + it("Can query for objects in RERUM using the app's '/app/query' route. __e2e", () => { request(routeTester) .post("/app/query") .send({ @@ -80,7 +80,7 @@ describe("Combined unit tests for the '/query' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/query' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/query' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/query") .then(response => { @@ -118,7 +118,7 @@ describe("Combined unit tests for the '/query' route.", () => { .catch(err => err) }) - it("Can query for objects in RERUM using the app's '/query' route. #e2e", () => { + it("Can query for objects in RERUM using the app's '/query' route. __e2e", () => { request(routeTester) .post("/query") .send({ diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 613480f..7e4ffd2 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -7,7 +7,7 @@ const routeTester = new express() routeTester.use("/update", updateRoute) describe("Combined unit tests for the '/update' route.", () => { - it("'/app/update' and '/update' are registered routes in the app. #exists", () => { + it("'/app/update' and '/update' are registered routes in the app. __exists __core", () => { let exists = false let count = 0 const stack = app._router.stack @@ -27,7 +27,7 @@ describe("Combined unit tests for the '/update' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/app/update' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/app/update' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/app/update") .then(response => { @@ -66,7 +66,7 @@ describe("Combined unit tests for the '/update' route.", () => { }) // TODO: Can we avoid updating the RERUM test obj? - it("Can update the RERUM test obj using the app's '/app/update' route. #e2e", () => { + it("Can update the RERUM test obj using the app's '/app/update' route. __e2e", () => { request(routeTester) .put("/app/update") .send({ @@ -82,7 +82,7 @@ describe("Combined unit tests for the '/update' route.", () => { }) // TODO: Can we avoid creating an object - it("Incorrect '/update' route usage has expected RESTful responses. #rest_functions", () => { + it("Incorrect '/update' route usage has expected RESTful responses. __rest __core", () => { request(routeTester) .get("/update") .then(response => { @@ -121,7 +121,7 @@ describe("Combined unit tests for the '/update' route.", () => { }) // TODO: Can we avoid updating the RERUM test obj? - it("Can update the RERUM test obj using the app's '/update' route. #e2e", () => { + it("Can update the RERUM test obj using the app's '/update' route. __e2e", () => { request(routeTester) .put("/update") .send({ From ffa6dcba0892fe6523bd0b6e2f26202a2e6dd3af Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 22 May 2024 13:19:25 -0500 Subject: [PATCH 12/58] Rewording for which tests run during which situations --- .github/workflows/cd_prod.yaml | 1 + .github/workflows/test_pushes.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cd_prod.yaml b/.github/workflows/cd_prod.yaml index 13b5481..35b42f9 100644 --- a/.github/workflows/cd_prod.yaml +++ b/.github/workflows/cd_prod.yaml @@ -1,3 +1,4 @@ +#https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release name: TinyNode production deploy on push to release. on: push: diff --git a/.github/workflows/test_pushes.yaml b/.github/workflows/test_pushes.yaml index d487b9c..17308b3 100644 --- a/.github/workflows/test_pushes.yaml +++ b/.github/workflows/test_pushes.yaml @@ -41,5 +41,5 @@ jobs: git checkout $GITHUB_REF git pull npm install - npm run functionalTests + npm run coreTests \ No newline at end of file From 06707aafa315d0158e2847499b52e3a0f34cee3f Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Thu, 23 May 2024 16:29:08 -0500 Subject: [PATCH 13/58] Notes and demo --- jest.config.js | 2 +- package-lock.json | 231 ++++++++++++++++++++++++++++++-- package.json | 18 +-- routes/__tests__/create.test.js | 45 ++++++- routes/create.js | 27 +++- 5 files changed, 298 insertions(+), 25 deletions(-) diff --git a/jest.config.js b/jest.config.js index 3286333..3b05500 100644 --- a/jest.config.js +++ b/jest.config.js @@ -47,7 +47,7 @@ const config = { verbose: true, //Don't show console.log and console.debug from the app code - silent: true, + silent: false, // The root directory that Jest should scan for tests and modules within rootDir: "./", diff --git a/package-lock.json b/package-lock.json index 0a8f0fc..6c6660b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "tinynode", "version": "0.1.1", + "license": "CC-BY", "dependencies": { "cors": "^2.8.5", "debug": "~2.6.9", @@ -15,7 +16,8 @@ "envfile": "^7.1.0", "express": "^4.18.2", "http-errors": "~1.6.3", - "morgan": "~1.9.1" + "morgan": "~1.9.1", + "node-mocks-http": "^1.14.1" }, "devDependencies": { "jest": "^29.7.0", @@ -1122,6 +1124,45 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz", + "integrity": "sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -1131,6 +1172,11 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -1155,11 +1201,47 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, "node_modules/@types/node": { - "version": "17.0.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz", - "integrity": "sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==", - "dev": true + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } }, "node_modules/@types/stack-utils": { "version": "2.0.3", @@ -3611,6 +3693,28 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, + "node_modules/node-mocks-http": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.14.1.tgz", + "integrity": "sha512-mfXuCGonz0A7uG1FEjnypjm34xegeN5+HI6xeGhYKecfgaZhjsmYoLE9LEFmT+53G1n8IuagPZmVnEL/xNsFaA==", + "dependencies": { + "@types/express": "^4.17.21", + "@types/node": "^20.10.6", + "accepts": "^1.3.7", + "content-disposition": "^0.5.3", + "depd": "^1.1.0", + "fresh": "^0.5.2", + "merge-descriptors": "^1.0.1", + "methods": "^1.1.2", + "mime": "^1.3.4", + "parseurl": "^1.3.3", + "range-parser": "^1.2.0", + "type-is": "^1.6.18" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -4542,6 +4646,11 @@ "node": ">= 0.6" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -5582,6 +5691,45 @@ "@babel/types": "^7.20.7" } }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.19.1", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz", + "integrity": "sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==", + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -5591,6 +5739,11 @@ "@types/node": "*" } }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + }, "@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -5615,11 +5768,47 @@ "@types/istanbul-lib-report": "*" } }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + }, "@types/node": { - "version": "17.0.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz", - "integrity": "sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==", - "dev": true + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "requires": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } }, "@types/stack-utils": { "version": "2.0.3", @@ -7447,6 +7636,25 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, + "node-mocks-http": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.14.1.tgz", + "integrity": "sha512-mfXuCGonz0A7uG1FEjnypjm34xegeN5+HI6xeGhYKecfgaZhjsmYoLE9LEFmT+53G1n8IuagPZmVnEL/xNsFaA==", + "requires": { + "@types/express": "^4.17.21", + "@types/node": "^20.10.6", + "accepts": "^1.3.7", + "content-disposition": "^0.5.3", + "depd": "^1.1.0", + "fresh": "^0.5.2", + "merge-descriptors": "^1.0.1", + "methods": "^1.1.2", + "mime": "^1.3.4", + "parseurl": "^1.3.3", + "range-parser": "^1.2.0", + "type-is": "^1.6.18" + } + }, "node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -8127,6 +8335,11 @@ "mime-types": "~2.1.24" } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/package.json b/package.json index d945e7d..4b9d085 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,12 @@ "version": "0.1.1", "private": true, "keywords": [ - "rerum", - "nodejs", - "mongodb", - "TinyThings", - "TinyNode" - ], + "rerum", + "nodejs", + "mongodb", + "TinyThings", + "TinyNode" + ], "homepage": "https://tiny.rerum.io", "license": "CC-BY", "author": "Research Computing Group (https://slu.edu)", @@ -22,7 +22,8 @@ "allTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js", "E2Etests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __e2e ", "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __exists ", - "coreTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __core " + "coreTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __core ", + "mocks": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __mockit " }, "dependencies": { "cors": "^2.8.5", @@ -32,7 +33,8 @@ "envfile": "^7.1.0", "express": "^4.18.2", "http-errors": "~1.6.3", - "morgan": "~1.9.1" + "morgan": "~1.9.1", + "node-mocks-http": "^1.14.1" }, "devDependencies": { "jest": "^29.7.0", diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index ef6e244..82245e5 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -2,10 +2,49 @@ import express from "express" import request from "supertest" import createRoute from "../create.js" import app from "../../app.js" - +import {createRequest, createResponse} from 'node-mocks-http' const routeTester = new express() routeTester.use("/create", createRoute) +//wrap these separately as their own suite, not necessarily another file + +/** + * To run just the mocks, do npm run mocks + * Mock lib: https://github.com/eugef/node-mocks-http + * + * Remember to actually test create.js. + * This test should fail if create.js fails its basic request processings and response building. + * + * This test runs the logic of the route file 'create.js' but does not actually communicate with RERUM. + * + * Then what is tested exacly in create.js by this test? + * - Is the express req/resp sent into the route + * - Can the route read the JSON body + * - Does the route add @id and __rerum + * - Does the route respond 201 + * - Does the route respond with the object that was in the request body + * - Does the route respond with a 'Location' header + */ + +describe("Playing with a successful mock create. __mockit", () => { + it("'/create' route request and response behavior is functioning.", () => { + /** Request Mock */ + let mock_request = createRequest({ + method: "POST", + url: "/", + body: {"test":"item"} + }) + let mock_response = createResponse() + createRoute(mock_request, mock_response) + const data = mock_response._getJSONData() + console.log(mock_response._getHeaders()) + expect(mock_response._getHeaders()).toHaveProperty('location') + expect(mock_response.statusCode).toBe(201) + expect(data["test"]).toBe("item") + }) +}) + + describe("Combined unit tests for the '/create' route.", () => { it("'/app/create' and '/create' are registered routes in the app. __exists __core", () => { let exists = false @@ -117,6 +156,8 @@ describe("Combined unit tests for the '/create' route.", () => { .catch(err => err) }) + // This is a full integration test that we need that should fail when RERUM is down + // TODO: Can we avoid creating an object it("'/create' route can save an object to RERUM. __e2e", () => { request(routeTester) @@ -125,7 +166,7 @@ describe("Combined unit tests for the '/create' route.", () => { .then(response => { expect(response.header).toHaveProperty('location') expect(response.statusCode).toBe(201) - expect(response.body.test.toBe("item")) + expect(response.body.test).toBe("item") }) .catch(err => err) }) diff --git a/routes/create.js b/routes/create.js index 6c73aa7..8d98675 100644 --- a/routes/create.js +++ b/routes/create.js @@ -3,10 +3,12 @@ const router = express.Router() /* POST a create to the thing. */ router.post('/', async (req, res, next) => { - try { - // check body for JSON const body = JSON.stringify(req.body) + // Make a valid looking result to use for testing. + let result = JSON.parse(JSON.stringify(req.body)) + result["@id"] = "https://store.rerum.io/v1/id/_not_" + result["__rerum"] = {"stuff":"here"} const createOptions = { method: 'POST', body, @@ -17,13 +19,28 @@ router.post('/', async (req, res, next) => { } } const createURL = `${process.env.RERUM_API_ADDR}create` - const result = await fetch(createURL, createOptions).then(res=>res.json()) - .catch(err=>next(err)) + // accomodate a JEST test attempting to test the req/resp behavior without involving RERUM + // https://stackoverflow.com/questions/50940640/how-to-determine-if-jest-is-running-the-code-or-not/52231746#52231746 + // console.log(process.env.JEST_WORKER_ID) + // if(process.env.JEST_WORKER_ID === undefined || process.env.NODE_ENV !== 'test'){ + // // POST to RERUM to generate a result object + // result = await fetch(createURL, createOptions) + // .then(res => res.json()) + // .catch(err=> next(err)) + // } + + // Mock libraries hard fail on this line of code and return a headerless empty 200 response. + // If we want to test this file, we need to circumvent this fetch when a test is using this route. + result = await fetch(createURL, createOptions) + .then(res => res.json()) + .catch(err=> next(err)) res.setHeader("Location", result["@id"]) res.status(201) - res.send(result) + console.log("CREATE ROUTE create.js sending a response") + res.json(result) } catch (err) { + console.log("CAN'T DO IT II") console.log(err) res.status(500).send("Caught Error:" + err) } From 391ca555582144f4fcea74268835a9cb980b93f3 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 14:57:26 -0500 Subject: [PATCH 14/58] Get rid of noise. Full test suite for the create route. --- package.json | 2 +- routes/__tests__/create.test.js | 282 +++++++++++++++-------------- routes/__tests__/delete.test.js | 130 ------------- routes/__tests__/index.test.js | 20 -- routes/__tests__/overwrite.test.js | 140 -------------- routes/__tests__/query.test.js | 134 -------------- routes/__tests__/update.test.js | 138 -------------- routes/create.js | 27 +-- routes/overwrite.js | 6 +- routes/update.js | 6 +- 10 files changed, 161 insertions(+), 724 deletions(-) delete mode 100644 routes/__tests__/delete.test.js delete mode 100644 routes/__tests__/index.test.js delete mode 100644 routes/__tests__/overwrite.test.js delete mode 100644 routes/__tests__/query.test.js delete mode 100644 routes/__tests__/update.test.js diff --git a/package.json b/package.json index 4b9d085..437a73e 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "E2Etests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __e2e ", "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __exists ", "coreTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __core ", - "mocks": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __mockit " + "functionalTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __mock_functions " }, "dependencies": { "cors": "^2.8.5", diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 82245e5..276cb9b 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -1,21 +1,17 @@ import express from "express" import request from "supertest" +import { jest } from '@jest/globals' import createRoute from "../create.js" import app from "../../app.js" -import {createRequest, createResponse} from 'node-mocks-http' const routeTester = new express() +routeTester.use(express.json()) +routeTester.use(express.urlencoded({ extended: false })) routeTester.use("/create", createRoute) +routeTester.use("/app/create", createRoute) -//wrap these separately as their own suite, not necessarily another file /** - * To run just the mocks, do npm run mocks - * Mock lib: https://github.com/eugef/node-mocks-http - * - * Remember to actually test create.js. - * This test should fail if create.js fails its basic request processings and response building. - * - * This test runs the logic of the route file 'create.js' but does not actually communicate with RERUM. + * This test suite runs the logic of the route file 'create.js' but does not actually communicate with RERUM. * * Then what is tested exacly in create.js by this test? * - Is the express req/resp sent into the route @@ -24,151 +20,171 @@ routeTester.use("/create", createRoute) * - Does the route respond 201 * - Does the route respond with the object that was in the request body * - Does the route respond with a 'Location' header - */ - -describe("Playing with a successful mock create. __mockit", () => { - it("'/create' route request and response behavior is functioning.", () => { - /** Request Mock */ - let mock_request = createRequest({ - method: "POST", - url: "/", - body: {"test":"item"} - }) - let mock_response = createResponse() - createRoute(mock_request, mock_response) - const data = mock_response._getJSONData() - console.log(mock_response._getHeaders()) - expect(mock_response._getHeaders()).toHaveProperty('location') - expect(mock_response.statusCode).toBe(201) - expect(data["test"]).toBe("item") + */ +describe("Check that the request/response behavior of the TinyNode create route functions. Mock the connection to RERUM. __mock_functions", () => { + it("'/create' route request and response behavior is functioning.", async () => { + + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/create) call in create.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve({ "@id": "https://devstore.rerum.io/v1/id/_not_", "test": "item", "__rerum": { "stuff": "here" } }) + }) + ) + + const response = await request(routeTester) + .post("/create") + .send({ "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.header).toHaveProperty('location') + expect(response.statusCode).toBe(201) + expect(response.body.test).toBe("item") }) }) -describe("Combined unit tests for the '/create' route.", () => { +/** + * This test suite uses the built app.js app and checks that the expected create endpoints are registered. + * - /create + * - /app/create + */ +describe("Check that the expected TinyNode create route patterns are registered.", () => { it("'/app/create' and '/create' are registered routes in the app. __exists __core", () => { let exists = false let count = 0 const stack = app._router.stack - for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/app/create")) { + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/create")) { count++ - } - else if(middleware.regexp && middleware.regexp.toString().includes("/create")) { + } else if (middleware.regexp && middleware.regexp.toString().includes("/create")) { count++ - } - if(count === 2){ + } + if (count === 2) { exists = true break } } expect(exists).toBe(true) }) +}) - // TODO: Can we avoid creating an object - it("Incorrect '/app/create' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/app/create") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/app/create") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/app/create") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .delete("/app/create") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/app/create") - .send("not json") - .then(response => { - expect(response.statusCode).toBe(400) - }) - .catch(err => err) +describe("Check that incorrect TinyNode create route usage results in expected RESTful responses from RERUM.", () => { + it("Incorrect '/app/create' route usage has expected RESTful responses. __rest __core", async () => { + let response = null + // Wrong Method + response = await request(routeTester) + .get("/app/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .put("/app/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/app/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .delete("/app/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .get("/app/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + // Bad request body + response = await request(routeTester) + .post("/app/create") + .set("Content-Type", "application/json") + .send("not json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) }) - // TODO: Can we avoid creating an object - it("'/app/create' route can save an object to RERUM. __e2e", () => { - request(routeTester) - .post("/app/create") - .send({"test":"item"}) - .then(response => { - expect(response.header).toHaveProperty('location') - expect(response.statusCode).toBe(201) - expect(response.body.test.toBe("item")) - }) - .catch(err => err) - }) + it("Incorrect '/create' route usage has expected RESTful responses. __rest __core", async () => { + let response = null + + response = await request(routeTester) + .get("/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .put("/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .delete("/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .get("/create") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .post("/create") + .set("Content-Type", "application/json") + .send("not json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) - // TODO: Can we avoid creating an object - it("Incorrect '/create' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/create") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/create") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/create") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .delete("/create") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/create") - .send("not json") - .then(response => { - expect(response.statusCode).toBe(400) - }) - .catch(err => err) }) +}) - // This is a full integration test that we need that should fail when RERUM is down - - // TODO: Can we avoid creating an object - it("'/create' route can save an object to RERUM. __e2e", () => { - request(routeTester) - .post("/create") - .send({"test":"item"}) - .then(response => { - expect(response.header).toHaveProperty('location') - expect(response.statusCode).toBe(201) - expect(response.body.test).toBe("item") - }) - .catch(err => err) +/** + * Full integration test. Checks the TinyNode app functionality and RERUM connection. + */ +describe("Check that the properly used create endpoints function and interact with RERUM.", () => { + it("'/app/create' route can save an object to RERUM. __e2e", async () => { + const response = await request(routeTester) + .post("/app/create") + .send({ "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.header).toHaveProperty('location') + expect(response.statusCode).toBe(201) + expect(response.body.test).toBe("item") }) -}) + it("'/create' route can save an object to RERUM. __e2e", async () => { + const response = await request(routeTester) + .post("/create") + .send({ "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.header).toHaveProperty('location') + expect(response.statusCode).toBe(201) + expect(response.body.test).toBe("item") + }) +}) \ No newline at end of file diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js deleted file mode 100644 index c266bdb..0000000 --- a/routes/__tests__/delete.test.js +++ /dev/null @@ -1,130 +0,0 @@ -import express from "express" -import request from "supertest" -import deleteRoute from "../delete.js" -import app from "../../app.js" - -const routeTester = new express() -routeTester.use("/delete", deleteRoute) - -describe("Combined unit tests for the '/delete' route.", () => { - it("'/app/delete' and '/delete' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/app/delete")) { - count++ - } - else if(middleware.regexp && middleware.regexp.toString().includes("/delete")) { - count++ - } - if(count === 2){ - exists = true - break - } - } - expect(exists).toBe(true) - }) - - // TODO: Can we avoid creating an object - it("Incorrect '/app/delete' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/app/delete") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/app/delete") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/app/delete") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/app/delete") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - // request(routeTester) - // .delete("/app/delete") - // .then(response => { - // expect(response.statusCode).toBe(400) - // }) - // .catch(err => err) - }) - - // TODO: Test delete capabilities. - it.skip("'/app/delete' route can delete an object in RERUM. __e2e", () => { - expect(true).toBe(true) - // request(routeTester) - // .delete("/app/delete/00000") - // .then(response => { - // expect(response.statusCode).toBe(204) - // done() - // }) - // .catch(err => done(err)) - // expect(response.statusCode).toBe(204) - }) - - // TODO: Can we avoid creating an object - it("Incorrect '/delete' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/delete") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/delete") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/delete") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/delete") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - // request(routeTester) - // .delete("/delete") - // .then(response => { - // expect(response.statusCode).toBe(400) - // }) - // .catch(err => err) - }) - - // TODO: Test delete capabilities. - it.skip("'/delete' route can delete an object in RERUM. __e2e", () => { - expect(true).toBe(true) - // request(routeTester) - // .delete("/delete/00000") - // .then(response => { - // expect(response.statusCode).toBe(204) - // done() - // }) - // .catch(err => done(err)) - // expect(response.statusCode).toBe(204) - }) -}) diff --git a/routes/__tests__/index.test.js b/routes/__tests__/index.test.js deleted file mode 100644 index df4ea4f..0000000 --- a/routes/__tests__/index.test.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Test the app index and make sure it what we expect. - */ - -import express from "express" -import request from "supertest" -import indexRoute from "../index.js" - -const routeTester = new express() -routeTester.use("/", indexRoute) - -it("responds to / with a 200 status and and the index.html page.", () => { - request(routeTester).get("/") - .then(response => { - expect(res.statusCode).toBe(200) - expect(res.type).toMatch(/html/) - }) - .catch(err => err) -}) - diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js deleted file mode 100644 index dd219a4..0000000 --- a/routes/__tests__/overwrite.test.js +++ /dev/null @@ -1,140 +0,0 @@ -import express from "express" -import request from "supertest" -import overwriteRoute from "../overwrite.js" -import app from "../../app.js" - -const routeTester = new express() -routeTester.use("/overwrite ", overwriteRoute) - -describe("Combined unit tests for the '/overwrite ' route.", () => { - it("'/app/overwrite' and '/overwrite' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/app/overwrite")) { - count++ - } - else if(middleware.regexp && middleware.regexp.toString().includes("/overwrite")) { - count++ - } - if(count === 2){ - exists = true - break - } - } - expect(exists).toBe(true) - }) - - // TODO: Can we avoid creating an object - it("Incorrect '/app/overwrite' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/app/overwrite") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/app/overwrite") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/app/overwrite") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .delete("/app/overwrite") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/app/overwrite") - .send("not json") - .then(response => { - expect(response.statusCode).toBe(400) - }) - .catch(err => err) - }) - - // TODO: Test overwrite capabilities - it.skip("Can overwrite the RERUM test obj using the app's '/app/overwrite' route. __e2e", () => { - expect(true).toBe(true) - // request(routeTester) - // .put("/app/overwrite ") - // .send({ - // "@id":`${process.env.RERUM_ID_PATTERN}11111`, - // "test":"item" - // }) - // .then(response => { - // expect(response.header).toHaveProperty('location') - // expect(response.statusCode).toBe(200) - // done() - // }) - // .catch(err => done(err)) - }) - - // TODO: Can we avoid creating an object - it("Incorrect '/overwrite' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/overwrite") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/overwrite") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/overwrite") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .delete("/overwrite") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/overwrite") - .send("not json") - .then(response => { - expect(response.statusCode).toBe(400) - }) - .catch(err => err) - }) - - // TODO: Test overwrite capabilities - it.skip("Can overwrite the RERUM test obj using the app's '/overwrite' route. __e2e", () => { - expect(true).toBe(true) - // request(routeTester) - // .put("/overwrite ") - // .send({ - // "@id":`${process.env.RERUM_ID_PATTERN}11111`, - // "test":"item" - // }) - // .then(response => { - // expect(response.header).toHaveProperty('location') - // expect(response.statusCode).toBe(200) - // done() - // }) - // .catch(err => done(err)) - }) -}) \ No newline at end of file diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js deleted file mode 100644 index 871203b..0000000 --- a/routes/__tests__/query.test.js +++ /dev/null @@ -1,134 +0,0 @@ -import express from "express" -import request from "supertest" -import queryRoute from "../query.js" -import app from "../../app.js" - -const routeTester = new express() -routeTester.use("/query", queryRoute) - -describe("Combined unit tests for the '/query' route.", () => { - it("'/app/query' and '/query' are registered routes in the app. __exists __core ", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/app/query")) { - count++ - } - else if(middleware.regexp && middleware.regexp.toString().includes("/query")) { - count++ - } - if(count === 2){ - exists = true - break - } - } - expect(exists).toBe(true) - }) - - // TODO: Can we avoid creating an object - it("Incorrect '/app/query' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/app/query") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/app/query") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/app/query") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .delete("/app/query") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/app/query") - .send("not json") - .then(response => { - expect(response.statusCode).toBe(400) - }) - .catch(err => err) - }) - - it("Can query for objects in RERUM using the app's '/app/query' route. __e2e", () => { - request(routeTester) - .post("/app/query") - .send({ - "test":"item" - }) - .then(response => { - expect(response.statusCode).toBe(200) - expect(Array.isArray(response.body)).toBe(true) - expect(response.body.length).toBeTruthy() - }) - .catch(err => err) - }) - - // TODO: Can we avoid creating an object - it("Incorrect '/query' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/query") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/query") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/query") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .delete("/query") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/query") - .send("not json") - .then(response => { - expect(response.statusCode).toBe(400) - }) - .catch(err => err) - }) - - it("Can query for objects in RERUM using the app's '/query' route. __e2e", () => { - request(routeTester) - .post("/query") - .send({ - "test":"item" - }) - .then(response => { - expect(response.statusCode).toBe(200) - expect(Array.isArray(response.body)).toBe(true) - expect(response.body.length).toBeTruthy() - }) - .catch(err => err) - }) -}) \ No newline at end of file diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js deleted file mode 100644 index 7e4ffd2..0000000 --- a/routes/__tests__/update.test.js +++ /dev/null @@ -1,138 +0,0 @@ -import express from "express" -import request from "supertest" -import updateRoute from "../update.js" -import app from "../../app.js" - -const routeTester = new express() -routeTester.use("/update", updateRoute) - -describe("Combined unit tests for the '/update' route.", () => { - it("'/app/update' and '/update' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for(const middleware of stack){ - if(middleware.regexp && middleware.regexp.toString().includes("/app/update")) { - count++ - } - else if(middleware.regexp && middleware.regexp.toString().includes("/update")) { - count++ - } - if(count === 2){ - exists = true - break - } - } - expect(exists).toBe(true) - }) - - // TODO: Can we avoid creating an object - it("Incorrect '/app/update' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/app/update") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/app/update") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/app/update") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .delete("/app/update") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/app/update") - .send("not json") - .then(response => { - expect(response.statusCode).toBe(400) - }) - .catch(err => err) - }) - - // TODO: Can we avoid updating the RERUM test obj? - it("Can update the RERUM test obj using the app's '/app/update' route. __e2e", () => { - request(routeTester) - .put("/app/update") - .send({ - "@id":`${process.env.RERUM_ID_PATTERN}11111`, - "test":"item" - }) - .then(response => { - expect(response.header).toHaveProperty('location') - expect(response.statusCode).toBe(200) - expect(response.body.test.toBe("item")) - }) - .catch(err => err) - }) - - // TODO: Can we avoid creating an object - it("Incorrect '/update' route usage has expected RESTful responses. __rest __core", () => { - request(routeTester) - .get("/update") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .post("/update") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .patch("/update") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .delete("/update") - .then(response => { - expect(response.statusCode).toBe(405) - }) - .catch(err => err) - - request(routeTester) - .put("/update") - .send("not json") - .then(response => { - expect(response.statusCode).toBe(400) - }) - .catch(err => err) - }) - - // TODO: Can we avoid updating the RERUM test obj? - it("Can update the RERUM test obj using the app's '/update' route. __e2e", () => { - request(routeTester) - .put("/update") - .send({ - "@id":`${process.env.RERUM_ID_PATTERN}11111`, - "test":"item" - }) - .then(response => { - expect(response.header).toHaveProperty('location') - expect(response.statusCode).toBe(200) - expect(response.body.test.toBe("item")) - }) - .catch(err => err) - }) -}) diff --git a/routes/create.js b/routes/create.js index 8d98675..a1dabae 100644 --- a/routes/create.js +++ b/routes/create.js @@ -3,12 +3,10 @@ const router = express.Router() /* POST a create to the thing. */ router.post('/', async (req, res, next) => { + try { + // check body for JSON const body = JSON.stringify(req.body) - // Make a valid looking result to use for testing. - let result = JSON.parse(JSON.stringify(req.body)) - result["@id"] = "https://store.rerum.io/v1/id/_not_" - result["__rerum"] = {"stuff":"here"} const createOptions = { method: 'POST', body, @@ -19,28 +17,13 @@ router.post('/', async (req, res, next) => { } } const createURL = `${process.env.RERUM_API_ADDR}create` - // accomodate a JEST test attempting to test the req/resp behavior without involving RERUM - // https://stackoverflow.com/questions/50940640/how-to-determine-if-jest-is-running-the-code-or-not/52231746#52231746 - // console.log(process.env.JEST_WORKER_ID) - // if(process.env.JEST_WORKER_ID === undefined || process.env.NODE_ENV !== 'test'){ - // // POST to RERUM to generate a result object - // result = await fetch(createURL, createOptions) - // .then(res => res.json()) - // .catch(err=> next(err)) - // } - - // Mock libraries hard fail on this line of code and return a headerless empty 200 response. - // If we want to test this file, we need to circumvent this fetch when a test is using this route. - result = await fetch(createURL, createOptions) - .then(res => res.json()) - .catch(err=> next(err)) + const result = await fetch(createURL, createOptions).then(res=>res.json()) + .catch(err=>next(err)) res.setHeader("Location", result["@id"]) res.status(201) - console.log("CREATE ROUTE create.js sending a response") res.json(result) } catch (err) { - console.log("CAN'T DO IT II") console.log(err) res.status(500).send("Caught Error:" + err) } @@ -50,4 +33,4 @@ router.all('/', (req, res, next) => { res.status(405).send("Method Not Allowed") }) -export default router +export default router \ No newline at end of file diff --git a/routes/overwrite.js b/routes/overwrite.js index 6c2fb14..61f822e 100644 --- a/routes/overwrite.js +++ b/routes/overwrite.js @@ -8,9 +8,9 @@ router.put('/', async (req, res, next) => { // check body for JSON const body = JSON.stringify(req.body) - // check for @id; any value is valid - if (!(req.body['@id'] ?? req.body.id)) { - throw Error("No record id to overwrite! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#overwrite)") + // check for at-id -- any value is valid + if (!req?.body || !(req.body['@id'] ?? req.body.id)) { + res.status(400).send("No record id to update! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#update)") } const overwriteOptions = { diff --git a/routes/update.js b/routes/update.js index 0bbd702..93c5adb 100644 --- a/routes/update.js +++ b/routes/update.js @@ -8,9 +8,9 @@ router.put('/', async (req, res, next) => { // check body for JSON const body = JSON.stringify(req.body) - // check for @id; any value is valid - if (!(req.body['@id'] ?? req.body.id)) { - throw Error("No record id to update! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#update)") + // check for at-id -- any value is valid + if (!req?.body || !(req.body['@id'] ?? req.body.id)) { + res.status(400).send("No record id to update! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#update)") } const updateOptions = { From dafece1ee337b6efea90d3361e7dbbda7279e3b6 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 14:58:43 -0500 Subject: [PATCH 15/58] Get rid of noise. Full test suite for the create route. --- routes/overwrite.js | 2 +- routes/update.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/overwrite.js b/routes/overwrite.js index 61f822e..cbb3d34 100644 --- a/routes/overwrite.js +++ b/routes/overwrite.js @@ -8,7 +8,7 @@ router.put('/', async (req, res, next) => { // check body for JSON const body = JSON.stringify(req.body) - // check for at-id -- any value is valid + // check for @id in body. Any value is valid. Lack of value is a bad request. if (!req?.body || !(req.body['@id'] ?? req.body.id)) { res.status(400).send("No record id to update! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#update)") } diff --git a/routes/update.js b/routes/update.js index 93c5adb..32ed90b 100644 --- a/routes/update.js +++ b/routes/update.js @@ -8,7 +8,7 @@ router.put('/', async (req, res, next) => { // check body for JSON const body = JSON.stringify(req.body) - // check for at-id -- any value is valid + // check for @id in body. Any value is valid. Lack of value is a bad request. if (!req?.body || !(req.body['@id'] ?? req.body.id)) { res.status(400).send("No record id to update! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#update)") } From d394771fe365dcc263c14811df42583c2b61084d Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 15:00:05 -0500 Subject: [PATCH 16/58] undiff --- routes/__tests__/create.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 276cb9b..9c85d6b 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -187,4 +187,4 @@ describe("Check that the properly used create endpoints function and interact wi expect(response.statusCode).toBe(201) expect(response.body.test).toBe("item") }) -}) \ No newline at end of file +}) From bf808a7c92525f7331c4a5fe18abdd76a04d258a Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 15:01:24 -0500 Subject: [PATCH 17/58] undiff --- package-lock.json | 208 ++-------------------------------------------- package.json | 3 +- 2 files changed, 8 insertions(+), 203 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c6660b..edd5aac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,8 +16,7 @@ "envfile": "^7.1.0", "express": "^4.18.2", "http-errors": "~1.6.3", - "morgan": "~1.9.1", - "node-mocks-http": "^1.14.1" + "morgan": "~1.9.1" }, "devDependencies": { "jest": "^29.7.0", @@ -1124,45 +1123,6 @@ "@babel/types": "^7.20.7" } }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz", - "integrity": "sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -1172,11 +1132,6 @@ "@types/node": "*" } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -1201,48 +1156,15 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, "node_modules/@types/node": { "version": "20.12.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, - "node_modules/@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -3693,28 +3615,6 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node_modules/node-mocks-http": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.14.1.tgz", - "integrity": "sha512-mfXuCGonz0A7uG1FEjnypjm34xegeN5+HI6xeGhYKecfgaZhjsmYoLE9LEFmT+53G1n8IuagPZmVnEL/xNsFaA==", - "dependencies": { - "@types/express": "^4.17.21", - "@types/node": "^20.10.6", - "accepts": "^1.3.7", - "content-disposition": "^0.5.3", - "depd": "^1.1.0", - "fresh": "^0.5.2", - "merge-descriptors": "^1.0.1", - "methods": "^1.1.2", - "mime": "^1.3.4", - "parseurl": "^1.3.3", - "range-parser": "^1.2.0", - "type-is": "^1.6.18" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -4649,7 +4549,8 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "node_modules/unpipe": { "version": "1.0.0", @@ -5691,45 +5592,6 @@ "@babel/types": "^7.20.7" } }, - "@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "requires": { - "@types/node": "*" - } - }, - "@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz", - "integrity": "sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -5739,11 +5601,6 @@ "@types/node": "*" } }, - "@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" - }, "@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -5768,48 +5625,15 @@ "@types/istanbul-lib-report": "*" } }, - "@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, "@types/node": { "version": "20.12.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", + "dev": true, "requires": { "undici-types": "~5.26.4" } }, - "@types/qs": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" - }, - "@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" - }, - "@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "requires": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, "@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -7636,25 +7460,6 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node-mocks-http": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/node-mocks-http/-/node-mocks-http-1.14.1.tgz", - "integrity": "sha512-mfXuCGonz0A7uG1FEjnypjm34xegeN5+HI6xeGhYKecfgaZhjsmYoLE9LEFmT+53G1n8IuagPZmVnEL/xNsFaA==", - "requires": { - "@types/express": "^4.17.21", - "@types/node": "^20.10.6", - "accepts": "^1.3.7", - "content-disposition": "^0.5.3", - "depd": "^1.1.0", - "fresh": "^0.5.2", - "merge-descriptors": "^1.0.1", - "methods": "^1.1.2", - "mime": "^1.3.4", - "parseurl": "^1.3.3", - "range-parser": "^1.2.0", - "type-is": "^1.6.18" - } - }, "node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -8338,7 +8143,8 @@ "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true }, "unpipe": { "version": "1.0.0", diff --git a/package.json b/package.json index 437a73e..1275299 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,7 @@ "envfile": "^7.1.0", "express": "^4.18.2", "http-errors": "~1.6.3", - "morgan": "~1.9.1", - "node-mocks-http": "^1.14.1" + "morgan": "~1.9.1" }, "devDependencies": { "jest": "^29.7.0", From 4b37bf42eef06da0603aec4c03c6d88500213972 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 15:03:10 -0500 Subject: [PATCH 18/58] undiff --- package-lock.json | 37 +++++++++---------------------------- 1 file changed, 9 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index edd5aac..e5c39b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,7 +7,6 @@ "": { "name": "tinynode", "version": "0.1.1", - "license": "CC-BY", "dependencies": { "cors": "^2.8.5", "debug": "~2.6.9", @@ -1157,13 +1156,10 @@ } }, "node_modules/@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } + "version": "17.0.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz", + "integrity": "sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==", + "dev": true }, "node_modules/@types/stack-utils": { "version": "2.0.3", @@ -4546,12 +4542,6 @@ "node": ">= 0.6" } }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -5626,13 +5616,10 @@ } }, "@types/node": { - "version": "20.12.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", - "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", - "dev": true, - "requires": { - "undici-types": "~5.26.4" - } + "version": "17.0.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.19.tgz", + "integrity": "sha512-PfeQhvcMR4cPFVuYfBN4ifG7p9c+Dlh3yUZR6k+5yQK7wX3gDgVxBly4/WkBRs9x4dmcy1TVl08SY67wwtEvmA==", + "dev": true }, "@types/stack-utils": { "version": "2.0.3", @@ -8140,12 +8127,6 @@ "mime-types": "~2.1.24" } }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -8267,4 +8248,4 @@ "dev": true } } -} +} \ No newline at end of file From 8cd8b5947e30a44570179d0c8d375836d77b2e52 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 15:03:38 -0500 Subject: [PATCH 19/58] undiff --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index e5c39b7..0a8f0fc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8248,4 +8248,4 @@ "dev": true } } -} \ No newline at end of file +} From 1ba34ecd6695bcbce42b41cb9b35e2de490e0b30 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 15:14:54 -0500 Subject: [PATCH 20/58] documentation --- routes/__tests__/create.test.js | 77 +++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 9c85d6b..051a7e2 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -9,6 +9,31 @@ routeTester.use(express.urlencoded({ extended: false })) routeTester.use("/create", createRoute) routeTester.use("/app/create", createRoute) +/** + * This test suite uses the built app.js app and checks that the expected create endpoints are registered. + * - /create + * - /app/create + */ +describe("Check that the expected TinyNode create route patterns are registered.", () => { + it("'/app/create' and '/create' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/create")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/create")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + /** * This test suite runs the logic of the route file 'create.js' but does not actually communicate with RERUM. @@ -44,34 +69,37 @@ describe("Check that the request/response behavior of the TinyNode create route expect(response.statusCode).toBe(201) expect(response.body.test).toBe("item") }) -}) + it("'/app/create' route request and response behavior is functioning.", async () => { -/** - * This test suite uses the built app.js app and checks that the expected create endpoints are registered. - * - /create - * - /app/create - */ -describe("Check that the expected TinyNode create route patterns are registered.", () => { - it("'/app/create' and '/create' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for (const middleware of stack) { - if (middleware.regexp && middleware.regexp.toString().includes("/app/create")) { - count++ - } else if (middleware.regexp && middleware.regexp.toString().includes("/create")) { - count++ - } - if (count === 2) { - exists = true - break - } - } - expect(exists).toBe(true) + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/create) call in create.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve({ "@id": "https://devstore.rerum.io/v1/id/_not_", "test": "item", "__rerum": { "stuff": "here" } }) + }) + ) + + const response = await request(routeTester) + .post("/app/create") + .send({ "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.header).toHaveProperty('location') + expect(response.statusCode).toBe(201) + expect(response.body.test).toBe("item") }) }) +/** + * This test suite checks the RESTful responses when using the TinyNode create endpoint incorrectly. + * + * - Incorrect HTTP method + * - Invalid JSON body + */ describe("Check that incorrect TinyNode create route usage results in expected RESTful responses from RERUM.", () => { it("Incorrect '/app/create' route usage has expected RESTful responses. __rest __core", async () => { let response = null @@ -161,7 +189,8 @@ describe("Check that incorrect TinyNode create route usage results in expected R }) /** - * Full integration test. Checks the TinyNode app functionality and RERUM connection. + * Full integration test. Checks the TinyNode app create endpoint functionality and RERUM connection. + * */ describe("Check that the properly used create endpoints function and interact with RERUM.", () => { it("'/app/create' route can save an object to RERUM. __e2e", async () => { From 6af1c91c1823bd941edb7e1cf529a80e3e4b961c Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 15:22:39 -0500 Subject: [PATCH 21/58] Move test differentiation tags to describe --- routes/__tests__/create.test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 051a7e2..dde3bfc 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -100,8 +100,8 @@ describe("Check that the request/response behavior of the TinyNode create route * - Incorrect HTTP method * - Invalid JSON body */ -describe("Check that incorrect TinyNode create route usage results in expected RESTful responses from RERUM.", () => { - it("Incorrect '/app/create' route usage has expected RESTful responses. __rest __core", async () => { +describe("Check that incorrect TinyNode create route usage results in expected RESTful responses from RERUM. __rest __core", () => { + it("Incorrect '/app/create' route usage has expected RESTful responses.", async () => { let response = null // Wrong Method response = await request(routeTester) @@ -144,7 +144,7 @@ describe("Check that incorrect TinyNode create route usage results in expected R expect(response.statusCode).toBe(400) }) - it("Incorrect '/create' route usage has expected RESTful responses. __rest __core", async () => { + it("Incorrect '/create' route usage has expected RESTful responses.", async () => { let response = null response = await request(routeTester) @@ -192,8 +192,8 @@ describe("Check that incorrect TinyNode create route usage results in expected R * Full integration test. Checks the TinyNode app create endpoint functionality and RERUM connection. * */ -describe("Check that the properly used create endpoints function and interact with RERUM.", () => { - it("'/app/create' route can save an object to RERUM. __e2e", async () => { +describe("Check that the properly used create endpoints function and interact with RERUM. __e2e", () => { + it("'/app/create' route can save an object to RERUM.", async () => { const response = await request(routeTester) .post("/app/create") .send({ "test": "item" }) @@ -205,7 +205,7 @@ describe("Check that the properly used create endpoints function and interact wi expect(response.body.test).toBe("item") }) - it("'/create' route can save an object to RERUM. __e2e", async () => { + it("'/create' route can save an object to RERUM.", async () => { const response = await request(routeTester) .post("/create") .send({ "test": "item" }) From 2e7cc05e08127fa9e3774f44f28bbc2b172c113c Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 24 May 2024 15:25:17 -0500 Subject: [PATCH 22/58] ah words --- routes/overwrite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/overwrite.js b/routes/overwrite.js index cbb3d34..421ff4c 100644 --- a/routes/overwrite.js +++ b/routes/overwrite.js @@ -10,7 +10,7 @@ router.put('/', async (req, res, next) => { // check for @id in body. Any value is valid. Lack of value is a bad request. if (!req?.body || !(req.body['@id'] ?? req.body.id)) { - res.status(400).send("No record id to update! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#update)") + res.status(400).send("No record id to overwrite! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#overwrite)") } const overwriteOptions = { From 61acd2a486b3cbb728931dc275fee4c8b088a3f5 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Tue, 28 May 2024 14:24:14 -0500 Subject: [PATCH 23/58] create, update, and overwrite tests --- routes/__tests__/create.test.js | 85 ++++------- routes/__tests__/overwrite.test.js | 227 ++++++++++++++++++++++++++++ routes/__tests__/update.test.js | 229 +++++++++++++++++++++++++++++ routes/create.js | 3 +- routes/overwrite.js | 3 +- routes/update.js | 3 +- 6 files changed, 491 insertions(+), 59 deletions(-) create mode 100644 routes/__tests__/overwrite.test.js create mode 100644 routes/__tests__/update.test.js diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index dde3bfc..16fd3a6 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -1,6 +1,8 @@ import express from "express" import request from "supertest" -import { jest } from '@jest/globals' +import { jest } from "@jest/globals" +import dotenv from "dotenv" +dotenv.config() import createRoute from "../create.js" import app from "../../app.js" const routeTester = new express() @@ -9,6 +11,28 @@ routeTester.use(express.urlencoded({ extended: false })) routeTester.use("/create", createRoute) routeTester.use("/app/create", createRoute) +const rerum_uri = `${process.env.RERUM_ID_PATTERN}_not_` +console.log(rerum_uri) + +beforeEach(() => { + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/create) call in create.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve({ "@id": rerum_uri, "test": "item", "__rerum": { "stuff": "here" } }) + }) + ) +}) + +afterEach(() => { + /** + * Food for thought: delete data generated by tests? + * Make a test.store available that uses the same annotationStoreTesting as RERUM tests? + */ +}) + /** * This test suite uses the built app.js app and checks that the expected create endpoints are registered. * - /create @@ -37,58 +61,37 @@ describe("Check that the expected TinyNode create route patterns are registered. /** * This test suite runs the logic of the route file 'create.js' but does not actually communicate with RERUM. - * - * Then what is tested exacly in create.js by this test? + * It will confirm the following: * - Is the express req/resp sent into the route * - Can the route read the JSON body * - Does the route add @id and __rerum * - Does the route respond 201 * - Does the route respond with the object that was in the request body - * - Does the route respond with a 'Location' header + * - Does the route respond with the proper 'Location' header */ describe("Check that the request/response behavior of the TinyNode create route functions. Mock the connection to RERUM. __mock_functions", () => { it("'/create' route request and response behavior is functioning.", async () => { - /** - * Request/Response Mock Using manual fetch replacement - * This is overruling the fetch(store.rerum.io/v1/api/create) call in create.js - */ - global.fetch = jest.fn(() => - Promise.resolve({ - json: () => Promise.resolve({ "@id": "https://devstore.rerum.io/v1/id/_not_", "test": "item", "__rerum": { "stuff": "here" } }) - }) - ) - const response = await request(routeTester) .post("/create") .send({ "test": "item" }) .set("Content-Type", "application/json") .then(resp => resp) .catch(err => err) - expect(response.header).toHaveProperty('location') + expect(response.header.location).toBe(rerum_uri) expect(response.statusCode).toBe(201) expect(response.body.test).toBe("item") }) it("'/app/create' route request and response behavior is functioning.", async () => { - /** - * Request/Response Mock Using manual fetch replacement - * This is overruling the fetch(store.rerum.io/v1/api/create) call in create.js - */ - global.fetch = jest.fn(() => - Promise.resolve({ - json: () => Promise.resolve({ "@id": "https://devstore.rerum.io/v1/id/_not_", "test": "item", "__rerum": { "stuff": "here" } }) - }) - ) - const response = await request(routeTester) .post("/app/create") .send({ "test": "item" }) .set("Content-Type", "application/json") .then(resp => resp) .catch(err => err) - expect(response.header).toHaveProperty('location') + expect(response.header.location).toBe(rerum_uri) expect(response.statusCode).toBe(201) expect(response.body.test).toBe("item") }) @@ -99,7 +102,7 @@ describe("Check that the request/response behavior of the TinyNode create route * * - Incorrect HTTP method * - Invalid JSON body - */ + */ describe("Check that incorrect TinyNode create route usage results in expected RESTful responses from RERUM. __rest __core", () => { it("Incorrect '/app/create' route usage has expected RESTful responses.", async () => { let response = null @@ -128,12 +131,6 @@ describe("Check that incorrect TinyNode create route usage results in expected R .catch(err => err) expect(response.statusCode).toBe(405) - response = await request(routeTester) - .get("/app/create") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - // Bad request body response = await request(routeTester) .post("/app/create") @@ -171,12 +168,6 @@ describe("Check that incorrect TinyNode create route usage results in expected R .catch(err => err) expect(response.statusCode).toBe(405) - response = await request(routeTester) - .get("/create") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - response = await request(routeTester) .post("/create") .set("Content-Type", "application/json") @@ -190,21 +181,9 @@ describe("Check that incorrect TinyNode create route usage results in expected R /** * Full integration test. Checks the TinyNode app create endpoint functionality and RERUM connection. - * + * Note this endpoint also has the '/app/create' alias. */ describe("Check that the properly used create endpoints function and interact with RERUM. __e2e", () => { - it("'/app/create' route can save an object to RERUM.", async () => { - const response = await request(routeTester) - .post("/app/create") - .send({ "test": "item" }) - .set("Content-Type", "application/json") - .then(resp => resp) - .catch(err => err) - expect(response.header).toHaveProperty('location') - expect(response.statusCode).toBe(201) - expect(response.body.test).toBe("item") - }) - it("'/create' route can save an object to RERUM.", async () => { const response = await request(routeTester) .post("/create") @@ -216,4 +195,4 @@ describe("Check that the properly used create endpoints function and interact wi expect(response.statusCode).toBe(201) expect(response.body.test).toBe("item") }) -}) +}) \ No newline at end of file diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js new file mode 100644 index 0000000..a6c5823 --- /dev/null +++ b/routes/__tests__/overwrite.test.js @@ -0,0 +1,227 @@ +import express from "express" +import request from "supertest" +import { jest } from "@jest/globals" +import dotenv from "dotenv" +dotenv.config() +import overwriteRoute from "../overwrite.js" +import app from "../../app.js" +const routeTester = new express() +routeTester.use(express.json()) +routeTester.use(express.urlencoded({ extended: false })) +routeTester.use("/overwrite", overwriteRoute) +routeTester.use("/app/overwrite", overwriteRoute) + +const rerum_tiny_test_obj_id = `${process.env.RERUM_ID_PATTERN}tiny_tester` + +beforeEach(() => { + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/create) call in create.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve({ "@id": rerum_tiny_test_obj_id, "testing": "item", "__rerum": { "stuff": "here" } }) + }) + ) +}) + +afterEach(() => { + /** + * Food for thought: delete data generated by tests? + * Make a test.store available that uses the same annotationStoreTesting as RERUM tests? + */ +}) + +/** + * This test suite uses the built app.js app and checks that the expected overwrite endpoints are registered. + * - /overwrite + * - /app/overwrite + */ +describe("Check that the expected TinyNode overwrite route patterns are registered.", () => { + it("'/app/overwrite' and '/overwrite' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/overwrite")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/overwrite")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + +/** + * This test suite runs the logic of the route file 'overwrite.js' but does not actually communicate with RERUM. + * It will confirm the following: + * - Is the express req/resp sent into the route + * - Can the route read the JSON body + * - Does the route add @id and __rerum + * - Does the route respond 200 + * - Does the route respond with the object that was in the request body + * - Does the route respond with the proper 'Location' header + */ +describe("Check that the request/response behavior of the TinyNode overwrite route functions. Mock the connection to RERUM. __mock_functions", () => { + it("'/overwrite' route request and response behavior is functioning.", async () => { + const response = await request(routeTester) + .put("/overwrite") + .send({ "@id": rerum_tiny_test_obj_id, "testing": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 + //expect(response.header.location).toBe(rerum_tiny_test_obj_id) + expect(response.statusCode).toBe(200) + expect(response.body.testing).toBe("item") + }) + + it("'/app/overwrite' route request and response behavior is functioning.", async () => { + + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/overwrite) call in overwrite.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve({ "@id": rerum_tiny_test_obj_id, "testing": "item", "__rerum": { "stuff": "here" } }) + }) + ) + + const response = await request(routeTester) + .put("/app/overwrite") + .send({ "@id": rerum_tiny_test_obj_id, "testing": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 + //expect(response.header.location).toBe(rerum_tiny_test_obj_id) + expect(response.statusCode).toBe(200) + expect(response.body.testing).toBe("item") + }) +}) + +/** + * This test suite checks the RESTful responses when using the TinyNode overwrite endpoint incorrectly. + * + * - Incorrect HTTP method + * - Invalid JSON body + */ +describe("Check that incorrect TinyNode overwrite route usage results in expected RESTful responses from RERUM. __rest __core", () => { + it("Incorrect '/app/overwrite' route usage has expected RESTful responses.", async () => { + let response = null + // Wrong Method + + response = await request(routeTester) + .get("/app/overwrite") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .post("/app/overwrite") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/app/overwrite") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .delete("/app/overwrite") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + // Bad request body + response = await request(routeTester) + .put("/app/overwrite") + .set("Content-Type", "application/json") + .send("not json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + + response = await request(routeTester) + .put("/app/overwrite") + .set("Content-Type", "application/json") + .send({ "no": "@id" }) + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + }) + + it("Incorrect '/overwrite' route usage has expected RESTful responses.", async () => { + let response = null + + response = await request(routeTester) + .get("/overwrite") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .post("/overwrite") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/overwrite") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .delete("/overwrite") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + //Bad request body + response = await request(routeTester) + .put("/overwrite") + .set("Content-Type", "application/json") + .send("not json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + + response = await request(routeTester) + .put("/overwrite") + .set("Content-Type", "application/json") + .send({ "no": "@id" }) + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + + }) +}) + +/** + * Full integration test. Checks the TinyNode app overwrite endpoint functionality and RERUM connection. + * Note this endpoint also has the '/app/overwrite' alias. + */ +describe("Check that the properly used overwrite endpoints function and interact with RERUM. __e2e", () => { + it("'/overwrite' route can overwrite an object in RERUM.", async () => { + const response = await request(routeTester) + .put("/overwrite") + .send({ "@id": rerum_tiny_test_obj_id, "testing": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 + //expect(response.header).toHaveProperty("location") + //expect(response.header.location).toBe(rerum_tiny_test_obj_id) + expect(response.statusCode).toBe(200) + expect(response.body.testing).toBe("item") + }) +}) diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js new file mode 100644 index 0000000..69ad98f --- /dev/null +++ b/routes/__tests__/update.test.js @@ -0,0 +1,229 @@ +import express from "express" +import request from "supertest" +import { jest } from "@jest/globals" +import dotenv from "dotenv" +dotenv.config() +import updateRoute from "../update.js" +import app from "../../app.js" +const routeTester = new express() +routeTester.use(express.json()) +routeTester.use(express.urlencoded({ extended: false })) +routeTester.use("/update", updateRoute) +routeTester.use("/app/update", updateRoute) + +const rerum_uri_orig = `${process.env.RERUM_ID_PATTERN}_not_` +const rerum_uri_updated = `${process.env.RERUM_ID_PATTERN}_updated_` +const rerum_tiny_test_obj_id = `${process.env.RERUM_ID_PATTERN}tiny_tester` + +beforeEach(() => { + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/create) call in create.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve({ "@id": rerum_uri_updated, "testing": "item", "__rerum": { "stuff": "here" } }) + }) + ) +}) + +afterEach(() => { + /** + * Food for thought: delete data generated by tests? + * Make a test.store available that uses the same annotationStoreTesting as RERUM tests? + */ +}) + +/** + * This test suite uses the built app.js app and checks that the expected update endpoints are registered. + * - /update + * - /app/update + */ +describe("Check that the expected TinyNode update route patterns are registered.", () => { + it("'/app/update' and '/update' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/update")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/update")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + +/** + * This test suite runs the logic of the route file 'update.js' but does not actually communicate with RERUM. + * It will confirm the following: + * - Is the express req/resp sent into the route + * - Can the route read the JSON body + * - Does the route add @id and __rerum + * - Does the route respond 200 + * - Does the route respond with the object that was in the request body + * - Does the route respond with the proper 'Location' header + */ +describe("Check that the request/response behavior of the TinyNode update route functions. Mock the connection to RERUM. __mock_functions", () => { + it("'/update' route request and response behavior is functioning.", async () => { + const response = await request(routeTester) + .put("/update") + .send({ "@id": rerum_uri_orig, "testing": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 + //expect(response.header.location).toBe(rerum_uri_updated) + expect(response.statusCode).toBe(200) + expect(response.body.testing).toBe("item") + }) + + it("'/app/update' route request and response behavior is functioning.", async () => { + + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/update) call in update.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve({ "@id": rerum_uri_updated, "testing": "item", "__rerum": { "stuff": "here" } }) + }) + ) + + const response = await request(routeTester) + .put("/app/update") + .send({ "@id": rerum_uri_orig, "testing": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 + //expect(response.header.location).toBe(rerum_uri_updated) + expect(response.statusCode).toBe(200) + expect(response.body.testing).toBe("item") + }) +}) + +/** + * This test suite checks the RESTful responses when using the TinyNode update endpoint incorrectly. + * + * - Incorrect HTTP method + * - Invalid JSON body + */ +describe("Check that incorrect TinyNode update route usage results in expected RESTful responses from RERUM. __rest __core", () => { + it("Incorrect '/app/update' route usage has expected RESTful responses.", async () => { + let response = null + // Wrong Method + + response = await request(routeTester) + .get("/app/update") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .post("/app/update") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/app/update") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .delete("/app/update") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + // Bad request body + response = await request(routeTester) + .put("/app/update") + .set("Content-Type", "application/json") + .send("not json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + + response = await request(routeTester) + .put("/app/update") + .set("Content-Type", "application/json") + .send({ "no": "@id" }) + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + }) + + it("Incorrect '/update' route usage has expected RESTful responses.", async () => { + let response = null + + response = await request(routeTester) + .get("/update") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .post("/update") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/update") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .delete("/update") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + //Bad request body + response = await request(routeTester) + .put("/update") + .set("Content-Type", "application/json") + .send("not json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + + response = await request(routeTester) + .put("/update") + .set("Content-Type", "application/json") + .send({ "no": "@id" }) + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + + }) +}) + +/** + * Full integration test. Checks the TinyNode app update endpoint functionality and RERUM connection. + * Note this endpoint also has the '/app/update' alias. + */ +describe("Check that the properly used update endpoints function and interact with RERUM. __e2e", () => { + it("'/update' route can update an object in RERUM.", async () => { + const response = await request(routeTester) + .put("/update") + .send({ "@id": rerum_tiny_test_obj_id, "testing": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 + //expect(response.header).toHaveProperty("location") + //expect(response.header.location).not().toBe(rerum_tiny_test_obj_id) + expect(response.statusCode).toBe(200) + expect(response.body.testing).toBe("item") + }) +}) diff --git a/routes/create.js b/routes/create.js index a1dabae..a570402 100644 --- a/routes/create.js +++ b/routes/create.js @@ -24,8 +24,7 @@ router.post('/', async (req, res, next) => { res.json(result) } catch (err) { - console.log(err) - res.status(500).send("Caught Error:" + err) + next(err) } }) diff --git a/routes/overwrite.js b/routes/overwrite.js index 421ff4c..a3dac18 100644 --- a/routes/overwrite.js +++ b/routes/overwrite.js @@ -29,8 +29,7 @@ router.put('/', async (req, res, next) => { res.send(result) } catch (err) { - console.log(err) - res.status(500).send("Caught Error:" + err) + next(err) } }) diff --git a/routes/update.js b/routes/update.js index 32ed90b..6181ab4 100644 --- a/routes/update.js +++ b/routes/update.js @@ -29,8 +29,7 @@ router.put('/', async (req, res, next) => { res.send(result) } catch (err) { - console.log(err) - res.status(500).send("Caught Error:" + err) + next(err) } }) From dda04a315c7888fe7e0d9fda065465a6efa98f32 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Tue, 28 May 2024 15:32:26 -0500 Subject: [PATCH 24/58] All API tests pretty and passing. Prepare for review. --- routes/__tests__/delete.test.js | 184 ++++++++++++++++++++++++++++ routes/__tests__/index.test.js | 15 +++ routes/__tests__/overwrite.test.js | 2 +- routes/__tests__/query.test.js | 187 +++++++++++++++++++++++++++++ routes/__tests__/update.test.js | 2 +- routes/delete.js | 6 +- routes/query.js | 3 +- 7 files changed, 391 insertions(+), 8 deletions(-) create mode 100644 routes/__tests__/delete.test.js create mode 100644 routes/__tests__/index.test.js create mode 100644 routes/__tests__/query.test.js diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js new file mode 100644 index 0000000..8312dbb --- /dev/null +++ b/routes/__tests__/delete.test.js @@ -0,0 +1,184 @@ +import express from "express" +import request from "supertest" +import { jest } from "@jest/globals" +import dotenv from "dotenv" +dotenv.config() +import deleteRoute from "../delete.js" +import app from "../../app.js" +const routeTester = new express() +routeTester.use(express.json()) +routeTester.use(express.urlencoded({ extended: false })) +routeTester.use("/delete", deleteRoute) +routeTester.use("/app/delete", deleteRoute) + +const rerum_uri = `${process.env.RERUM_ID_PATTERN}_not_` + +beforeEach(() => { + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/delete) call in delete.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + text: () => Promise.resolve("") + }) + ) +}) + +describe("Combined unit tests for the '/delete' route.", () => { + it("'/app/delete' and '/delete' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/delete")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/delete")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + +/** + * This test suite runs the logic of the route file 'delete.js' but does not actually communicate with RERUM. + * It will confirm the following: + * - Is the express req/resp sent into the route + * - Can the route read the JSON body + * - Does the route respond 204 + */ +describe("Check that the request/response behavior of the TinyNode delete route functions. Mock the connection to RERUM. __mock_functions", () => { + it("'/delete' route request and response behavior is functioning.", async () => { + + let response = await request(routeTester) + .delete("/delete") + .send({ "@id": rerum_uri, "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(204) + + response = await request(routeTester) + .delete("/delete/00000") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(204) + }) + + it("'/app/delete' route request and response behavior is functioning.", async () => { + + let response = await request(routeTester) + .delete("/app/delete") + .send({ "@id": rerum_uri, "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(204) + + response = await request(routeTester) + .delete("/app/delete/00000") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(204) + }) +}) + +describe("Check that incorrect TinyNode delete route usage results in expected RESTful responses from RERUM. __rest __core", () => { + it("Incorrect '/app/delete' route usage has expected RESTful responses.", async () => { + let response = null + + // Wrong Method + response = await request(routeTester) + .get("/app/delete") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .put("/app/delete") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/app/delete") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .post("/app/delete") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + //Bad request body + //FIXME to uncomment: https://github.com/CenterForDigitalHumanities/TinyNode/issues/89 + // response = await request(routeTester) + // .delete("/app/delete") + // .set("Content-Type", "application/json") + // .then(resp => resp) + // .catch(err => err) + // expect(response.statusCode).toBe(400) + }) + + it("Incorrect '/delete' route usage has expected RESTful responses.", async () => { + let response = null + + response = await request(routeTester) + .get("/delete") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .put("/delete") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/delete") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .post("/delete") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + //Bad request body + //FIXME to uncomment: https://github.com/CenterForDigitalHumanities/TinyNode/issues/89 + // response = await request(routeTester) + // .delete("/delete") + // .set("Content-Type", "application/json") + // .then(resp => resp) + // .catch(err => err) + // expect(response.statusCode).toBe(400) + + }) +}) + +/** + * TODO - skipped for now. + * Full integration test. Checks the TinyNode app delete endpoint functionality and RERUM connection. + * Note this endpoint also has the '/app/delete' alias. + */ +describe.skip("Check that the properly used delete endpoints function and interact with RERUM. __e2e", () => { + it("'/delete' route can delete an object in RERUM. __e2e", async () => { + const response = await request(routeTester) + .delete("/app/delete/00000") + .then(response => { + expect(response.statusCode).toBe(204) + }) + .catch(err => err) + expect(response.statusCode).toBe(204) + }) +}) \ No newline at end of file diff --git a/routes/__tests__/index.test.js b/routes/__tests__/index.test.js new file mode 100644 index 0000000..15e5c8c --- /dev/null +++ b/routes/__tests__/index.test.js @@ -0,0 +1,15 @@ +import request from "supertest" +//Fun fact, if you don't require app, you don't get coverage even though the tests run just fine. +import app from "../../app.js" + +describe("Make sure TinyNode demo interface is present. __core", () => { + it("/index.html", async () => { + const response = await request(app) + .get("/index.html") + .then(resp => resp) + .catch(err => err) + console.log(response.header) + expect(response.statusCode).toBe(200) + expect(response.header["content-type"]).toMatch(/html/) + }) +}) \ No newline at end of file diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index a6c5823..bd53493 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -224,4 +224,4 @@ describe("Check that the properly used overwrite endpoints function and interact expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) -}) +}) \ No newline at end of file diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js new file mode 100644 index 0000000..eefef62 --- /dev/null +++ b/routes/__tests__/query.test.js @@ -0,0 +1,187 @@ +import express from "express" +import request from "supertest" +import { jest } from "@jest/globals" +import dotenv from "dotenv" +dotenv.config() +import queryRoute from "../query.js" +import app from "../../app.js" +const routeTester = new express() +routeTester.use(express.json()) +routeTester.use(express.urlencoded({ extended: false })) +routeTester.use("/query", queryRoute) +routeTester.use("/app/query", queryRoute) + +const rerum_uri = `${process.env.RERUM_ID_PATTERN}_not_` + +beforeEach(() => { + /** + * Request/Response Mock Using manual fetch replacement + * This is overruling the fetch(store.rerum.io/v1/api/query) call in query.js + */ + global.fetch = jest.fn(() => + Promise.resolve({ + json: () => Promise.resolve([{ "@id": rerum_uri, "test": "item", "__rerum": { "stuff": "here" } }]) + }) + ) +}) + +/** + * This test suite uses the built app.js app and checks that the expected query endpoints are registered. + * - /query + * - /app/query + */ +describe("Check that the expected TinyNode query route patterns are registered.", () => { + it("'/app/query' and '/query' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/query")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/query")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + + +/** + * This test suite runs the logic of the route file 'query.js' but does not actually communicate with RERUM. + * It will confirm the following: + * - Is the express req/resp sent into the route + * - Can the route read the JSON body + * - Does the route add @id and __rerum + * - Does the route respond 201 + * - Does the route respond with the object that was in the request body + * - Does the route respond with the proper 'Location' header + */ +describe("Check that the request/response behavior of the TinyNode query route functions. Mock the connection to RERUM. __mock_functions", () => { + it("'/query' route request and response behavior is functioning.", async () => { + + const response = await request(routeTester) + .post("/query") + .send({ "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(200) + expect(response.body[0].test).toBe("item") + }) + + it("'/app/query' route request and response behavior is functioning.", async () => { + + const response = await request(routeTester) + .post("/app/query") + .send({ "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(200) + expect(response.body[0].test).toBe("item") + }) +}) + +/** + * This test suite checks the RESTful responses when using the TinyNode query endpoint incorrectly. + * + * - Incorrect HTTP method + * - Invalid JSON body + */ +describe("Check that incorrect TinyNode query route usage results in expected RESTful responses from RERUM. __rest __core", () => { + it("Incorrect '/app/query' route usage has expected RESTful responses.", async () => { + let response = null + // Wrong Method + response = await request(routeTester) + .get("/app/query") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .put("/app/query") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/app/query") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .delete("/app/query") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + // Bad request body + response = await request(routeTester) + .post("/app/query") + .set("Content-Type", "application/json") + .send("not json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + }) + + it("Incorrect '/query' route usage has expected RESTful responses.", async () => { + let response = null + + response = await request(routeTester) + .get("/query") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .put("/query") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .patch("/query") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .delete("/query") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(405) + + response = await request(routeTester) + .post("/query") + .set("Content-Type", "application/json") + .send("not json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(400) + + }) +}) + +/** + * Full integration test. Checks the TinyNode app query endpoint functionality and RERUM connection. + * Note this endpoint also has the '/app/query' alias. + */ +describe("Check that the properly used query endpoints function and interact with RERUM. __e2e", () => { + it("'/query' route can save an object to RERUM.", async () => { + const response = await request(routeTester) + .post("/query") + .send({ "test": "item" }) + .set("Content-Type", "application/json") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(200) + expect(response.body[0].test).toBe("item") + }) +}) \ No newline at end of file diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 69ad98f..7c41807 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -226,4 +226,4 @@ describe("Check that the properly used update endpoints function and interact wi expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) -}) +}) \ No newline at end of file diff --git a/routes/delete.js b/routes/delete.js index 68ac23d..51d2daa 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -23,8 +23,7 @@ router.delete('/', async (req, res, next) => { res.send(result) } catch (err) { - console.log(err) - res.status(500).send("Caught Error:" + err) + next(err) } }) @@ -46,8 +45,7 @@ router.delete('/:id', async (req, res, next) => { res.send(result) } catch (err) { - console.log(err) - res.status(500).send("Caught Error:" + err) + next(err) } }) diff --git a/routes/query.js b/routes/query.js index 6d392fa..a147cc3 100644 --- a/routes/query.js +++ b/routes/query.js @@ -31,8 +31,7 @@ router.post('/', async (req, res, next) => { res.send(results) } catch (err) { // a dumb catch-all for Tiny Stuff - console.log(err) - res.status(500).send("Caught " + err) + next(err) } }) From b585535d3ce3f8d4c319a702818f5910c4f783ed Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Tue, 28 May 2024 15:39:16 -0500 Subject: [PATCH 25/58] Prepare for review. --- routes/__tests__/index.test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/routes/__tests__/index.test.js b/routes/__tests__/index.test.js index 15e5c8c..7cef525 100644 --- a/routes/__tests__/index.test.js +++ b/routes/__tests__/index.test.js @@ -1,5 +1,4 @@ import request from "supertest" -//Fun fact, if you don't require app, you don't get coverage even though the tests run just fine. import app from "../../app.js" describe("Make sure TinyNode demo interface is present. __core", () => { From 31f62c7d422b04582e94b90d2902f11592409107 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 29 May 2024 10:27:06 -0500 Subject: [PATCH 26/58] remove redundant tests and leave a note behind. Make sure documentation is consistent. --- routes/__tests__/create.test.js | 57 +++------------------- routes/__tests__/delete.test.js | 68 +++++--------------------- routes/__tests__/overwrite.test.js | 77 +++--------------------------- routes/__tests__/query.test.js | 57 +++------------------- routes/__tests__/update.test.js | 77 +++--------------------------- 5 files changed, 35 insertions(+), 301 deletions(-) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 16fd3a6..eb4afff 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -68,6 +68,8 @@ describe("Check that the expected TinyNode create route patterns are registered. * - Does the route respond 201 * - Does the route respond with the object that was in the request body * - Does the route respond with the proper 'Location' header + * + * Note: /app/create uses the same logic and would be a redundant test. */ describe("Check that the request/response behavior of the TinyNode create route functions. Mock the connection to RERUM. __mock_functions", () => { it("'/create' route request and response behavior is functioning.", async () => { @@ -82,19 +84,6 @@ describe("Check that the request/response behavior of the TinyNode create route expect(response.statusCode).toBe(201) expect(response.body.test).toBe("item") }) - - it("'/app/create' route request and response behavior is functioning.", async () => { - - const response = await request(routeTester) - .post("/app/create") - .send({ "test": "item" }) - .set("Content-Type", "application/json") - .then(resp => resp) - .catch(err => err) - expect(response.header.location).toBe(rerum_uri) - expect(response.statusCode).toBe(201) - expect(response.body.test).toBe("item") - }) }) /** @@ -102,45 +91,10 @@ describe("Check that the request/response behavior of the TinyNode create route * * - Incorrect HTTP method * - Invalid JSON body + * + * Note: /app/create uses the same logic and would be a redundant test */ describe("Check that incorrect TinyNode create route usage results in expected RESTful responses from RERUM. __rest __core", () => { - it("Incorrect '/app/create' route usage has expected RESTful responses.", async () => { - let response = null - // Wrong Method - response = await request(routeTester) - .get("/app/create") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .put("/app/create") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .patch("/app/create") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .delete("/app/create") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - // Bad request body - response = await request(routeTester) - .post("/app/create") - .set("Content-Type", "application/json") - .send("not json") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(400) - }) - it("Incorrect '/create' route usage has expected RESTful responses.", async () => { let response = null @@ -181,7 +135,8 @@ describe("Check that incorrect TinyNode create route usage results in expected R /** * Full integration test. Checks the TinyNode app create endpoint functionality and RERUM connection. - * Note this endpoint also has the '/app/create' alias. + * + * Note: /app/create uses the same logic and would be a redundant test */ describe("Check that the properly used create endpoints function and interact with RERUM. __e2e", () => { it("'/create' route can save an object to RERUM.", async () => { diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js index 8312dbb..7b7e01a 100644 --- a/routes/__tests__/delete.test.js +++ b/routes/__tests__/delete.test.js @@ -25,6 +25,11 @@ beforeEach(() => { ) }) +/** + * This test suite uses the built app.js app and checks that the expected delete endpoints are registered. + * - /delete + * - /app/delete + */ describe("Combined unit tests for the '/delete' route.", () => { it("'/app/delete' and '/delete' are registered routes in the app. __exists __core", () => { let exists = false @@ -51,11 +56,14 @@ describe("Combined unit tests for the '/delete' route.", () => { * - Is the express req/resp sent into the route * - Can the route read the JSON body * - Does the route respond 204 + * + * Note: /app/delete uses the same logic and would be a redundant test. */ describe("Check that the request/response behavior of the TinyNode delete route functions. Mock the connection to RERUM. __mock_functions", () => { it("'/delete' route request and response behavior is functioning.", async () => { + let response = null - let response = await request(routeTester) + response = await request(routeTester) .delete("/delete") .send({ "@id": rerum_uri, "test": "item" }) .set("Content-Type", "application/json") @@ -69,64 +77,9 @@ describe("Check that the request/response behavior of the TinyNode delete route .catch(err => err) expect(response.statusCode).toBe(204) }) - - it("'/app/delete' route request and response behavior is functioning.", async () => { - - let response = await request(routeTester) - .delete("/app/delete") - .send({ "@id": rerum_uri, "test": "item" }) - .set("Content-Type", "application/json") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(204) - - response = await request(routeTester) - .delete("/app/delete/00000") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(204) - }) }) describe("Check that incorrect TinyNode delete route usage results in expected RESTful responses from RERUM. __rest __core", () => { - it("Incorrect '/app/delete' route usage has expected RESTful responses.", async () => { - let response = null - - // Wrong Method - response = await request(routeTester) - .get("/app/delete") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .put("/app/delete") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .patch("/app/delete") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .post("/app/delete") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - //Bad request body - //FIXME to uncomment: https://github.com/CenterForDigitalHumanities/TinyNode/issues/89 - // response = await request(routeTester) - // .delete("/app/delete") - // .set("Content-Type", "application/json") - // .then(resp => resp) - // .catch(err => err) - // expect(response.statusCode).toBe(400) - }) - it("Incorrect '/delete' route usage has expected RESTful responses.", async () => { let response = null @@ -169,7 +122,8 @@ describe("Check that incorrect TinyNode delete route usage results in expected R /** * TODO - skipped for now. * Full integration test. Checks the TinyNode app delete endpoint functionality and RERUM connection. - * Note this endpoint also has the '/app/delete' alias. + * + * Note: /app/delete uses the same logic and would be a redundant test. */ describe.skip("Check that the properly used delete endpoints function and interact with RERUM. __e2e", () => { it("'/delete' route can delete an object in RERUM. __e2e", async () => { diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index bd53493..1d82c03 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -66,6 +66,8 @@ describe("Check that the expected TinyNode overwrite route patterns are register * - Does the route respond 200 * - Does the route respond with the object that was in the request body * - Does the route respond with the proper 'Location' header + * + * Note: /app/overwrite uses the same logic and would be a redundant test. */ describe("Check that the request/response behavior of the TinyNode overwrite route functions. Mock the connection to RERUM. __mock_functions", () => { it("'/overwrite' route request and response behavior is functioning.", async () => { @@ -80,30 +82,6 @@ describe("Check that the request/response behavior of the TinyNode overwrite rou expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) - - it("'/app/overwrite' route request and response behavior is functioning.", async () => { - - /** - * Request/Response Mock Using manual fetch replacement - * This is overruling the fetch(store.rerum.io/v1/api/overwrite) call in overwrite.js - */ - global.fetch = jest.fn(() => - Promise.resolve({ - json: () => Promise.resolve({ "@id": rerum_tiny_test_obj_id, "testing": "item", "__rerum": { "stuff": "here" } }) - }) - ) - - const response = await request(routeTester) - .put("/app/overwrite") - .send({ "@id": rerum_tiny_test_obj_id, "testing": "item" }) - .set("Content-Type", "application/json") - .then(resp => resp) - .catch(err => err) - //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 - //expect(response.header.location).toBe(rerum_tiny_test_obj_id) - expect(response.statusCode).toBe(200) - expect(response.body.testing).toBe("item") - }) }) /** @@ -111,54 +89,10 @@ describe("Check that the request/response behavior of the TinyNode overwrite rou * * - Incorrect HTTP method * - Invalid JSON body + * + * Note: /app/overwrite uses the same logic and would be a redundant test. */ describe("Check that incorrect TinyNode overwrite route usage results in expected RESTful responses from RERUM. __rest __core", () => { - it("Incorrect '/app/overwrite' route usage has expected RESTful responses.", async () => { - let response = null - // Wrong Method - - response = await request(routeTester) - .get("/app/overwrite") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .post("/app/overwrite") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .patch("/app/overwrite") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .delete("/app/overwrite") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - // Bad request body - response = await request(routeTester) - .put("/app/overwrite") - .set("Content-Type", "application/json") - .send("not json") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(400) - - response = await request(routeTester) - .put("/app/overwrite") - .set("Content-Type", "application/json") - .send({ "no": "@id" }) - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(400) - }) - it("Incorrect '/overwrite' route usage has expected RESTful responses.", async () => { let response = null @@ -208,7 +142,8 @@ describe("Check that incorrect TinyNode overwrite route usage results in expecte /** * Full integration test. Checks the TinyNode app overwrite endpoint functionality and RERUM connection. - * Note this endpoint also has the '/app/overwrite' alias. + * + * Note: /app/overwrite uses the same logic and would be a redundant test. */ describe("Check that the properly used overwrite endpoints function and interact with RERUM. __e2e", () => { it("'/overwrite' route can overwrite an object in RERUM.", async () => { diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js index eefef62..5807e4b 100644 --- a/routes/__tests__/query.test.js +++ b/routes/__tests__/query.test.js @@ -60,10 +60,11 @@ describe("Check that the expected TinyNode query route patterns are registered." * - Does the route respond 201 * - Does the route respond with the object that was in the request body * - Does the route respond with the proper 'Location' header + * + * Note: /app/query uses the same logic and would be a redundant test. */ describe("Check that the request/response behavior of the TinyNode query route functions. Mock the connection to RERUM. __mock_functions", () => { it("'/query' route request and response behavior is functioning.", async () => { - const response = await request(routeTester) .post("/query") .send({ "test": "item" }) @@ -73,18 +74,6 @@ describe("Check that the request/response behavior of the TinyNode query route f expect(response.statusCode).toBe(200) expect(response.body[0].test).toBe("item") }) - - it("'/app/query' route request and response behavior is functioning.", async () => { - - const response = await request(routeTester) - .post("/app/query") - .send({ "test": "item" }) - .set("Content-Type", "application/json") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(200) - expect(response.body[0].test).toBe("item") - }) }) /** @@ -92,45 +81,10 @@ describe("Check that the request/response behavior of the TinyNode query route f * * - Incorrect HTTP method * - Invalid JSON body + * + * Note: /app/query uses the same logic and would be a redundant test. */ describe("Check that incorrect TinyNode query route usage results in expected RESTful responses from RERUM. __rest __core", () => { - it("Incorrect '/app/query' route usage has expected RESTful responses.", async () => { - let response = null - // Wrong Method - response = await request(routeTester) - .get("/app/query") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .put("/app/query") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .patch("/app/query") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .delete("/app/query") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - // Bad request body - response = await request(routeTester) - .post("/app/query") - .set("Content-Type", "application/json") - .send("not json") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(400) - }) - it("Incorrect '/query' route usage has expected RESTful responses.", async () => { let response = null @@ -171,7 +125,8 @@ describe("Check that incorrect TinyNode query route usage results in expected RE /** * Full integration test. Checks the TinyNode app query endpoint functionality and RERUM connection. - * Note this endpoint also has the '/app/query' alias. + * + * Note: /app/query uses the same logic and would be a redundant test. */ describe("Check that the properly used query endpoints function and interact with RERUM. __e2e", () => { it("'/query' route can save an object to RERUM.", async () => { diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 7c41807..8219385 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -68,6 +68,8 @@ describe("Check that the expected TinyNode update route patterns are registered. * - Does the route respond 200 * - Does the route respond with the object that was in the request body * - Does the route respond with the proper 'Location' header + * + * Note: /app/update uses the same logic and would be a redundant test. */ describe("Check that the request/response behavior of the TinyNode update route functions. Mock the connection to RERUM. __mock_functions", () => { it("'/update' route request and response behavior is functioning.", async () => { @@ -82,30 +84,6 @@ describe("Check that the request/response behavior of the TinyNode update route expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) - - it("'/app/update' route request and response behavior is functioning.", async () => { - - /** - * Request/Response Mock Using manual fetch replacement - * This is overruling the fetch(store.rerum.io/v1/api/update) call in update.js - */ - global.fetch = jest.fn(() => - Promise.resolve({ - json: () => Promise.resolve({ "@id": rerum_uri_updated, "testing": "item", "__rerum": { "stuff": "here" } }) - }) - ) - - const response = await request(routeTester) - .put("/app/update") - .send({ "@id": rerum_uri_orig, "testing": "item" }) - .set("Content-Type", "application/json") - .then(resp => resp) - .catch(err => err) - //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 - //expect(response.header.location).toBe(rerum_uri_updated) - expect(response.statusCode).toBe(200) - expect(response.body.testing).toBe("item") - }) }) /** @@ -113,54 +91,10 @@ describe("Check that the request/response behavior of the TinyNode update route * * - Incorrect HTTP method * - Invalid JSON body + * + * Note: /app/update uses the same logic and would be a redundant test. */ describe("Check that incorrect TinyNode update route usage results in expected RESTful responses from RERUM. __rest __core", () => { - it("Incorrect '/app/update' route usage has expected RESTful responses.", async () => { - let response = null - // Wrong Method - - response = await request(routeTester) - .get("/app/update") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .post("/app/update") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .patch("/app/update") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - response = await request(routeTester) - .delete("/app/update") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(405) - - // Bad request body - response = await request(routeTester) - .put("/app/update") - .set("Content-Type", "application/json") - .send("not json") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(400) - - response = await request(routeTester) - .put("/app/update") - .set("Content-Type", "application/json") - .send({ "no": "@id" }) - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(400) - }) - it("Incorrect '/update' route usage has expected RESTful responses.", async () => { let response = null @@ -210,7 +144,8 @@ describe("Check that incorrect TinyNode update route usage results in expected R /** * Full integration test. Checks the TinyNode app update endpoint functionality and RERUM connection. - * Note this endpoint also has the '/app/update' alias. + * + * Note: /app/update uses the same logic and would be a redundant test. */ describe("Check that the properly used update endpoints function and interact with RERUM. __e2e", () => { it("'/update' route can update an object in RERUM.", async () => { From 58b69d0f71bcd32d5897e01116874239c12f698f Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 29 May 2024 10:28:40 -0500 Subject: [PATCH 27/58] Reduce log noise in tests --- jest.config.js | 2 +- routes/__tests__/create.test.js | 1 - routes/__tests__/index.test.js | 1 - routes/delete.js | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/jest.config.js b/jest.config.js index 3b05500..3286333 100644 --- a/jest.config.js +++ b/jest.config.js @@ -47,7 +47,7 @@ const config = { verbose: true, //Don't show console.log and console.debug from the app code - silent: false, + silent: true, // The root directory that Jest should scan for tests and modules within rootDir: "./", diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index eb4afff..3718f7a 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -12,7 +12,6 @@ routeTester.use("/create", createRoute) routeTester.use("/app/create", createRoute) const rerum_uri = `${process.env.RERUM_ID_PATTERN}_not_` -console.log(rerum_uri) beforeEach(() => { /** diff --git a/routes/__tests__/index.test.js b/routes/__tests__/index.test.js index 7cef525..ed0f563 100644 --- a/routes/__tests__/index.test.js +++ b/routes/__tests__/index.test.js @@ -7,7 +7,6 @@ describe("Make sure TinyNode demo interface is present. __core", () => { .get("/index.html") .then(resp => resp) .catch(err => err) - console.log(response.header) expect(response.statusCode).toBe(200) expect(response.header["content-type"]).toMatch(/html/) }) diff --git a/routes/delete.js b/routes/delete.js index 51d2daa..6a4c5e1 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -16,7 +16,6 @@ router.delete('/', async (req, res, next) => { 'Content-Type' : "application/json; charset=utf-8" } } - console.log(body) const deleteURL = `${process.env.RERUM_API_ADDR}delete` const result = await fetch(deleteURL, deleteOptions).then(res => res.text()) res.status(204) From 4e532af41dd7fe176a93243662a1708265516cb2 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Wed, 29 May 2024 10:30:40 -0500 Subject: [PATCH 28/58] Prepared to work on CI/CD and will branch --- .github/workflows/cd_prod.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/cd_prod.yaml b/.github/workflows/cd_prod.yaml index 35b42f9..13b5481 100644 --- a/.github/workflows/cd_prod.yaml +++ b/.github/workflows/cd_prod.yaml @@ -1,4 +1,3 @@ -#https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#release name: TinyNode production deploy on push to release. on: push: From 7265b5bc7f53d94c49363bcf9c354b190d530ad0 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Thu, 30 May 2024 11:14:10 -0500 Subject: [PATCH 29/58] use real main and repoint PR --- .github/workflows/cd_dev.yaml | 12 ++++++------ .github/workflows/ci_dev.yaml | 4 ++-- .github/workflows/test_pushes.yaml | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 7591f87..6e82c28 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -1,7 +1,7 @@ -name: TinyNode Dev Deploy on push to deepfakemain +name: TinyNode Dev Deploy on push to main on: push: - branches: deepfakemain + branches: main jobs: merge-branch: runs-on: ubuntu-latest @@ -12,9 +12,9 @@ jobs: with: type: now from_branch: release - target_branch: deepfakemain + target_branch: main github_token: ${{ secrets.BRY_PAT }} - message: Merge deepfakemain into this branch to deploy to dev for testing. + message: Merge main into this branch to deploy to dev for testing. test: needs: merge-branch strategy: @@ -28,7 +28,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash - git checkout deepfakemain + git checkout main git pull npm install npm run allTests @@ -53,7 +53,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash - git checkout deepfakemain + git checkout main git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/ci_dev.yaml b/.github/workflows/ci_dev.yaml index 5937341..ce09783 100644 --- a/.github/workflows/ci_dev.yaml +++ b/.github/workflows/ci_dev.yaml @@ -1,7 +1,7 @@ -name: TinyNode end to end tests on PR to deepfakemain +name: TinyNode end to end tests on PR to main on: pull_request: - branches: deepfakemain + branches: main jobs: test: strategy: diff --git a/.github/workflows/test_pushes.yaml b/.github/workflows/test_pushes.yaml index 17308b3..3c7b114 100644 --- a/.github/workflows/test_pushes.yaml +++ b/.github/workflows/test_pushes.yaml @@ -3,7 +3,7 @@ on: push: branches: - '*' - - '!deepfakemain' + - '!main' - '!release' jobs: check_for_open_pr: From 78a8e36c9c573e951869b1545b40f37855234a36 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Thu, 30 May 2024 11:18:11 -0500 Subject: [PATCH 30/58] trigger once for good measure --- routes/__tests__/create.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 3718f7a..0c9748b 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -149,4 +149,4 @@ describe("Check that the properly used create endpoints function and interact wi expect(response.statusCode).toBe(201) expect(response.body.test).toBe("item") }) -}) \ No newline at end of file +}) From 49dcbbc5b916881e4656710ff1fcbd9df5e60f69 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Thu, 30 May 2024 11:18:57 -0500 Subject: [PATCH 31/58] trigger twice to see if it is consistent. --- routes/__tests__/create.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 0c9748b..3718f7a 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -149,4 +149,4 @@ describe("Check that the properly used create endpoints function and interact wi expect(response.statusCode).toBe(201) expect(response.body.test).toBe("item") }) -}) +}) \ No newline at end of file From 684cccb2a0c144d2db5da2df61c93c24b79cd275 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 09:58:07 -0600 Subject: [PATCH 32/58] small change to 'id' check in /update /overwrite and /delete. --- package-lock.json | 543 ++++++++++++++++++++--------- routes/__tests__/overwrite.test.js | 10 +- routes/__tests__/update.test.js | 9 +- routes/delete.js | 4 + routes/overwrite.js | 9 +- routes/update.js | 9 +- 6 files changed, 394 insertions(+), 190 deletions(-) diff --git a/package-lock.json b/package-lock.json index dbaf4f1..ba3e515 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1431,9 +1431,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -1443,7 +1443,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -1511,12 +1511,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1578,12 +1578,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1794,6 +1800,14 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -1891,6 +1905,22 @@ "node": ">=0.10.0" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1991,9 +2021,9 @@ "dev": true }, "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "engines": { "node": ">= 0.8" } @@ -2021,6 +2051,25 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2134,36 +2183,36 @@ } }, "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -2174,14 +2223,6 @@ "node": ">= 0.10.0" } }, - "node_modules/express/node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/express/node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -2292,9 +2333,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -2304,12 +2345,12 @@ } }, "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dependencies": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -2429,9 +2470,12 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -2452,13 +2496,18 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2502,6 +2551,17 @@ "node": ">=4" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2512,6 +2572,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -2528,10 +2589,32 @@ "node": ">=8" } }, - "node_modules/has-symbols": { + "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, @@ -2539,6 +2622,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hexoid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", @@ -3642,9 +3736,12 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/merge-stream": { "version": "2.0.0", @@ -3661,12 +3758,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -3835,9 +3932,12 @@ } }, "node_modules/object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3996,9 +4096,9 @@ "dev": true }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, "node_modules/picocolors": { "version": "1.0.0", @@ -4107,11 +4207,11 @@ ] }, "node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -4271,9 +4371,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -4301,6 +4401,14 @@ "node": ">= 0.8" } }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/send/node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -4346,19 +4454,35 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", @@ -4391,13 +4515,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6057,9 +6185,9 @@ } }, "body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.5", @@ -6069,7 +6197,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.11.0", + "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -6123,12 +6251,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -6164,12 +6292,15 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -6308,6 +6439,11 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" + }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", @@ -6380,6 +6516,16 @@ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6452,9 +6598,9 @@ "dev": true }, "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" }, "envfile": { "version": "7.1.0", @@ -6470,6 +6616,19 @@ "is-arrayish": "^0.2.1" } }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -6548,36 +6707,36 @@ } }, "express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "version": "4.21.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", + "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.2", + "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.6.0", + "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.2.0", + "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", + "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", + "path-to-regexp": "0.1.10", "proxy-addr": "~2.0.7", - "qs": "6.11.0", + "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", + "send": "0.19.0", + "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", @@ -6585,11 +6744,6 @@ "vary": "~1.1.2" }, "dependencies": { - "cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" - }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -6663,21 +6817,21 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", @@ -6765,9 +6919,9 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "gensync": { "version": "1.0.0-beta.2", @@ -6782,13 +6936,15 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-package-type": { @@ -6817,6 +6973,14 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -6827,6 +6991,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -6837,10 +7002,31 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-symbols": { + "has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==" + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" + } }, "hexoid": { "version": "1.0.0", @@ -7673,9 +7859,9 @@ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" }, "merge-stream": { "version": "2.0.0", @@ -7689,12 +7875,12 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "requires": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" } }, @@ -7807,9 +7993,9 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-inspect": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", - "integrity": "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==" + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", + "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==" }, "on-finished": { "version": "2.3.0", @@ -7919,9 +8105,9 @@ "dev": true }, "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", + "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==" }, "picocolors": { "version": "1.0.0", @@ -7995,11 +8181,11 @@ "dev": true }, "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "requires": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" } }, "range-parser": { @@ -8116,9 +8302,9 @@ "dev": true }, "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "requires": { "debug": "2.6.9", "depd": "2.0.0", @@ -8140,6 +8326,11 @@ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -8178,14 +8369,27 @@ } }, "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "requires": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" + } + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" } }, "setimmediate": { @@ -8214,13 +8418,14 @@ "dev": true }, "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" } }, "signal-exit": { diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index 1d82c03..ebbbc03 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -77,8 +77,7 @@ describe("Check that the request/response behavior of the TinyNode overwrite rou .set("Content-Type", "application/json") .then(resp => resp) .catch(err => err) - //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 - //expect(response.header.location).toBe(rerum_tiny_test_obj_id) + expect(response.header.location).toBe(rerum_tiny_test_obj_id) expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) @@ -143,7 +142,7 @@ describe("Check that incorrect TinyNode overwrite route usage results in expecte /** * Full integration test. Checks the TinyNode app overwrite endpoint functionality and RERUM connection. * - * Note: /app/overwrite uses the same logic and would be a redundant test. + * Note: /app/update uses the same logic. */ describe("Check that the properly used overwrite endpoints function and interact with RERUM. __e2e", () => { it("'/overwrite' route can overwrite an object in RERUM.", async () => { @@ -153,9 +152,8 @@ describe("Check that the properly used overwrite endpoints function and interact .set("Content-Type", "application/json") .then(resp => resp) .catch(err => err) - //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 - //expect(response.header).toHaveProperty("location") - //expect(response.header.location).toBe(rerum_tiny_test_obj_id) + expect(response.header).toHaveProperty("location") + expect(response.header.location).toBe(rerum_tiny_test_obj_id) expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 8219385..da2a93a 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -18,7 +18,7 @@ const rerum_tiny_test_obj_id = `${process.env.RERUM_ID_PATTERN}tiny_tester` beforeEach(() => { /** * Request/Response Mock Using manual fetch replacement - * This is overruling the fetch(store.rerum.io/v1/api/create) call in create.js + * This is overruling the fetch(store.rerum.io/v1/api/create) call in update.js */ global.fetch = jest.fn(() => Promise.resolve({ @@ -80,7 +80,7 @@ describe("Check that the request/response behavior of the TinyNode update route .then(resp => resp) .catch(err => err) //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 - //expect(response.header.location).toBe(rerum_uri_updated) + expect(response.header.location).toBe(rerum_uri_updated) expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) @@ -155,9 +155,8 @@ describe("Check that the properly used update endpoints function and interact wi .set("Content-Type", "application/json") .then(resp => resp) .catch(err => err) - //FIXME to uncomment these: https://github.com/CenterForDigitalHumanities/TinyNode/issues/88 - //expect(response.header).toHaveProperty("location") - //expect(response.header.location).not().toBe(rerum_tiny_test_obj_id) + expect(response.header).toHaveProperty("location") + expect(response.header.location).not().toBe(rerum_tiny_test_obj_id) expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) diff --git a/routes/delete.js b/routes/delete.js index 6a4c5e1..dda7cde 100644 --- a/routes/delete.js +++ b/routes/delete.js @@ -6,6 +6,10 @@ const router = express.Router() /* DELETE a delete to the thing. */ router.delete('/', async (req, res, next) => { try { + // check for @id in body. Any value is valid. Lack of value is a bad request. + if (!req?.body || !(req.body['@id'] ?? req.body.id)) { + res.status(400).send("No record id to delete! (https://store.rerum.io/v1/API.html#delete)") + } const body = JSON.stringify(req.body) const deleteOptions = { body, diff --git a/routes/overwrite.js b/routes/overwrite.js index c4598a2..784be5d 100644 --- a/routes/overwrite.js +++ b/routes/overwrite.js @@ -6,14 +6,12 @@ import rerumPropertiesWasher from "../preprocessor.js" router.put('/', rerumPropertiesWasher, async (req, res, next) => { try { - // check body for JSON - const body = JSON.stringify(req.body) - // check for @id in body. Any value is valid. Lack of value is a bad request. if (!req?.body || !(req.body['@id'] ?? req.body.id)) { - res.status(400).send("No record id to overwrite! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#overwrite)") + res.status(400).send("No record id to overwrite! (https://store.rerum.io/v1/API.html#overwrite)") } - + // check body for JSON + const body = JSON.stringify(req.body) const overwriteOptions = { method: 'PUT', body, @@ -26,6 +24,7 @@ router.put('/', rerumPropertiesWasher, async (req, res, next) => { const overwriteURL = `${process.env.RERUM_API_ADDR}overwrite` const result = await fetch(overwriteURL, overwriteOptions).then(res=>res.json()) .catch(err=>next(err)) + res.setHeader("Location", result["@id"]) res.status(200) res.send(result) } diff --git a/routes/update.js b/routes/update.js index 7275b12..fc21f01 100644 --- a/routes/update.js +++ b/routes/update.js @@ -6,14 +6,12 @@ import rerumPropertiesWasher from "../preprocessor.js" router.put('/', rerumPropertiesWasher, async (req, res, next) => { try { - // check body for JSON - const body = JSON.stringify(req.body) - // check for @id in body. Any value is valid. Lack of value is a bad request. if (!req?.body || !(req.body['@id'] ?? req.body.id)) { - res.status(400).send("No record id to update! (https://centerfordigitalhumanities.github.io/rerum_server/API.html#update)") + res.status(400).send("No record id to update! (https://store.rerum.io/v1/API.html#update)") } - + // check body for JSON + const body = JSON.stringify(req.body) const updateOptions = { method: 'PUT', body, @@ -26,6 +24,7 @@ router.put('/', rerumPropertiesWasher, async (req, res, next) => { const updateURL = `${process.env.RERUM_API_ADDR}update` const result = await fetch(updateURL, updateOptions).then(res=>res.json()) .catch(err=>next(err)) + res.setHeader("Location", result["@id"]) res.status(200) res.send(result) } From be69867284f5b0ed33d2943a07da12bf1275e961 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:20:28 -0600 Subject: [PATCH 33/58] Simplify because we aren't doing releases at this time. --- .github/workflows/cd_dev.yaml | 44 +++++++------ .github/workflows/cd_dev_later.txt | 61 +++++++++++++++++++ .github/workflows/cd_prod.yaml | 8 +-- .../{ci_dev.yaml => ci_dev_later.txt} | 3 + .../{ci_prod.yaml => ci_prod_later.txt} | 3 + ...test_pushes.yaml => test_pushes_later.txt} | 4 +- 6 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 .github/workflows/cd_dev_later.txt rename .github/workflows/{ci_dev.yaml => ci_dev_later.txt} (92%) rename .github/workflows/{ci_prod.yaml => ci_prod_later.txt} (92%) rename .github/workflows/{test_pushes.yaml => test_pushes_later.txt} (96%) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 6e82c28..394b9f4 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -1,35 +1,41 @@ -name: TinyNode Dev Deploy on push to main +name: TinyNode Dev Deploy on PR to main on: - push: + pull_request: branches: main jobs: merge-branch: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - - name: Merge with release + - name: Merge with main uses: devmasx/merge-branch@master with: type: now - from_branch: release - target_branch: main + from_branch: main + target_branch: ${{ github.head_ref }} github_token: ${{ secrets.BRY_PAT }} message: Merge main into this branch to deploy to dev for testing. test: needs: merge-branch - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Test the app on the server + runs-on: ubuntu-latest + - name: Setup Node.js + uses: actions/setup-node@master + with: + node-version: "20" + - name: Cache node modules + uses: actions/cache@master + env: + cache-name: cache-node-modules + with: + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ + hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + - name: Install dependencies and run the test run: | - cd /srv/node/tiny-node/ - git stash - git checkout main - git pull npm install npm run allTests deploy: @@ -39,6 +45,8 @@ jobs: - test strategy: matrix: + node-version: + - 20 machines: - vlcdhp02 runs-on: ${{ matrix.machines }} @@ -53,7 +61,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash - git checkout main + git checkout ${{ github.head_ref }} git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/cd_dev_later.txt b/.github/workflows/cd_dev_later.txt new file mode 100644 index 0000000..62606b2 --- /dev/null +++ b/.github/workflows/cd_dev_later.txt @@ -0,0 +1,61 @@ +# NOTES for if we want to do releases + +name: TinyNode Dev Deploy on push to main +on: + push: + branches: main +jobs: + merge-branch: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Merge with release + uses: devmasx/merge-branch@master + with: + type: now + from_branch: release + target_branch: main + github_token: ${{ secrets.BRY_PAT }} + message: Merge main into this branch to deploy to dev for testing. + test: + needs: merge-branch + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} + steps: + - uses: actions/checkout@master + - name: Test the app on the server + run: | + cd /srv/node/tiny-node/ + git stash + git checkout main + git pull + npm install + npm run allTests + deploy: + if: github.event.pull_request.draft == false + needs: + - merge-branch + - test + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} + steps: + - uses: actions/checkout@master + - name: Deploy the app on the server + run: | + if [[ ! -e /srv/node/logs/tinynode.txt ]]; then + mkdir -p /srv/node/logs + touch /srv/node/logs/tinynode.txt + fi + cd /srv/node/tiny-node/ + pm2 stop tinyNode + git stash + git checkout main + git pull + npm install + pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/cd_prod.yaml b/.github/workflows/cd_prod.yaml index 13b5481..09ce21d 100644 --- a/.github/workflows/cd_prod.yaml +++ b/.github/workflows/cd_prod.yaml @@ -1,7 +1,7 @@ -name: TinyNode production deploy on push to release. +name: TinyNode production deploy on push to main. on: push: - branches: release + branches: main jobs: test: strategy: @@ -15,7 +15,7 @@ jobs: run: | cd /srv/node/tiny-node/ git stash - git checkout release + git checkout main git pull npm install npm run allTests @@ -38,7 +38,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash - git checkout release + git checkout main git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/ci_dev.yaml b/.github/workflows/ci_dev_later.txt similarity index 92% rename from .github/workflows/ci_dev.yaml rename to .github/workflows/ci_dev_later.txt index ce09783..206ba3b 100644 --- a/.github/workflows/ci_dev.yaml +++ b/.github/workflows/ci_dev_later.txt @@ -1,3 +1,6 @@ +# NOTES for if we want to do releases + + name: TinyNode end to end tests on PR to main on: pull_request: diff --git a/.github/workflows/ci_prod.yaml b/.github/workflows/ci_prod_later.txt similarity index 92% rename from .github/workflows/ci_prod.yaml rename to .github/workflows/ci_prod_later.txt index 9bac65d..40fe52a 100644 --- a/.github/workflows/ci_prod.yaml +++ b/.github/workflows/ci_prod_later.txt @@ -1,3 +1,6 @@ +# NOTES for if we want to do releases + + name: TinyNode end to end tests on PR to release on: pull_request: diff --git a/.github/workflows/test_pushes.yaml b/.github/workflows/test_pushes_later.txt similarity index 96% rename from .github/workflows/test_pushes.yaml rename to .github/workflows/test_pushes_later.txt index 3c7b114..4a689f8 100644 --- a/.github/workflows/test_pushes.yaml +++ b/.github/workflows/test_pushes_later.txt @@ -1,10 +1,12 @@ +# NOTES for if we want to do releases + + name: TinyNode tests on any push to a branch without an open PR on: push: branches: - '*' - '!main' - - '!release' jobs: check_for_open_pr: runs-on: ubuntu-latest From 71491b9780ac31ffab1a3a2d249eaa0965983f0f Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:22:49 -0600 Subject: [PATCH 34/58] hello --- app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.js b/app.js index 1486988..b467a30 100644 --- a/app.js +++ b/app.js @@ -62,4 +62,4 @@ app.use(function(err, req, res, next) { res.send(err.message) }) -export default app +export default app \ No newline at end of file From 395cbc121adaa5ad09922ea8447e1aae1e31ead6 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:25:20 -0600 Subject: [PATCH 35/58] hello --- .github/workflows/cd_dev.yaml | 2 +- routes/__tests__/update.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 394b9f4..1a4da9b 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -61,7 +61,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash - git checkout ${{ github.head_ref }} + git checkout tests-then-deploy git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index da2a93a..60b1b8f 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -156,7 +156,7 @@ describe("Check that the properly used update endpoints function and interact wi .then(resp => resp) .catch(err => err) expect(response.header).toHaveProperty("location") - expect(response.header.location).not().toBe(rerum_tiny_test_obj_id) + expect(response.header.location).not.toBe(rerum_tiny_test_obj_id) expect(response.statusCode).toBe(200) expect(response.body.testing).toBe("item") }) From 50f1e7cf65a1f39670497192f9d08955dece5e1f Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:26:36 -0600 Subject: [PATCH 36/58] clear out workflow folder --- .github/workflows/cd_dev.yaml | 2 +- .github/workflows/cd_dev_later.txt | 61 ------------------------- .github/workflows/ci_dev_later.txt | 26 ----------- .github/workflows/ci_prod_later.txt | 26 ----------- .github/workflows/test_pushes_later.txt | 47 ------------------- 5 files changed, 1 insertion(+), 161 deletions(-) delete mode 100644 .github/workflows/cd_dev_later.txt delete mode 100644 .github/workflows/ci_dev_later.txt delete mode 100644 .github/workflows/ci_prod_later.txt delete mode 100644 .github/workflows/test_pushes_later.txt diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 1a4da9b..394b9f4 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -61,7 +61,7 @@ jobs: cd /srv/node/tiny-node/ pm2 stop tinyNode git stash - git checkout tests-then-deploy + git checkout ${{ github.head_ref }} git pull npm install pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/cd_dev_later.txt b/.github/workflows/cd_dev_later.txt deleted file mode 100644 index 62606b2..0000000 --- a/.github/workflows/cd_dev_later.txt +++ /dev/null @@ -1,61 +0,0 @@ -# NOTES for if we want to do releases - -name: TinyNode Dev Deploy on push to main -on: - push: - branches: main -jobs: - merge-branch: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Merge with release - uses: devmasx/merge-branch@master - with: - type: now - from_branch: release - target_branch: main - github_token: ${{ secrets.BRY_PAT }} - message: Merge main into this branch to deploy to dev for testing. - test: - needs: merge-branch - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Test the app on the server - run: | - cd /srv/node/tiny-node/ - git stash - git checkout main - git pull - npm install - npm run allTests - deploy: - if: github.event.pull_request.draft == false - needs: - - merge-branch - - test - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Deploy the app on the server - run: | - if [[ ! -e /srv/node/logs/tinynode.txt ]]; then - mkdir -p /srv/node/logs - touch /srv/node/logs/tinynode.txt - fi - cd /srv/node/tiny-node/ - pm2 stop tinyNode - git stash - git checkout main - git pull - npm install - pm2 start -i max bin/tinyNode.js diff --git a/.github/workflows/ci_dev_later.txt b/.github/workflows/ci_dev_later.txt deleted file mode 100644 index 206ba3b..0000000 --- a/.github/workflows/ci_dev_later.txt +++ /dev/null @@ -1,26 +0,0 @@ -# NOTES for if we want to do releases - - -name: TinyNode end to end tests on PR to main -on: - pull_request: - branches: main -jobs: - test: - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Test the app on the server - run: | - cd /srv/node/tiny-node/ - git stash - git pull - git checkout $GITHUB_HEAD_REF - git pull - npm install - npm run E2Etests - \ No newline at end of file diff --git a/.github/workflows/ci_prod_later.txt b/.github/workflows/ci_prod_later.txt deleted file mode 100644 index 40fe52a..0000000 --- a/.github/workflows/ci_prod_later.txt +++ /dev/null @@ -1,26 +0,0 @@ -# NOTES for if we want to do releases - - -name: TinyNode end to end tests on PR to release -on: - pull_request: - branches: release -jobs: - test: - strategy: - matrix: - machines: - - vlcdhprdp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Test the app on the server - run: | - cd /srv/node/tiny-node/ - git stash - git pull - git checkout $GITHUB_HEAD_REF - git pull - npm install - npm run E2Etests - \ No newline at end of file diff --git a/.github/workflows/test_pushes_later.txt b/.github/workflows/test_pushes_later.txt deleted file mode 100644 index 4a689f8..0000000 --- a/.github/workflows/test_pushes_later.txt +++ /dev/null @@ -1,47 +0,0 @@ -# NOTES for if we want to do releases - - -name: TinyNode tests on any push to a branch without an open PR -on: - push: - branches: - - '*' - - '!main' -jobs: - check_for_open_pr: - runs-on: ubuntu-latest - steps: - - name: Set the branch name as a processable string by making it an env variable. - run: echo BranchName=${GITHUB_REF##*/} >> $GITHUB_ENV - - name: Find Pull Request - uses: juliangruber/find-pull-request-action@v1 - id: find-pull-request - with: - branch: ${{ env.BranchName }} - - name: Make the PR number a processable string. Output that string for the next job. - run: | - echo Name $BranchName - echo PRnumber=${{steps.find-pull-request.outputs.number}} >> $GITHUB_ENV - outputs: - number: ${{ env.PRnumber }} - test: - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - needs: - - check_for_open_pr - if: needs.check_for_open_pr.outputs.number == '' - steps: - - uses: actions/checkout@master - - name: Test the app on the server - run: | - cd /srv/node/tiny-node/ - git stash - git pull - git checkout $GITHUB_REF - git pull - npm install - npm run coreTests - \ No newline at end of file From e29d7384eb33f56c10296bb27ef221a0d1abac2f Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:30:28 -0600 Subject: [PATCH 37/58] hello --- .github/workflows/cd_dev.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 394b9f4..f5dbcd1 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -17,6 +17,10 @@ jobs: message: Merge main into this branch to deploy to dev for testing. test: needs: merge-branch + strategy: + matrix: + machines: + - vlcdhp02 runs-on: ubuntu-latest - name: Setup Node.js uses: actions/setup-node@master From 3457f9e32bfcc82b6abe1876398da69ffb05834d Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:31:36 -0600 Subject: [PATCH 38/58] hello --- .github/workflows/cd_dev.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index f5dbcd1..78ec98e 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -22,6 +22,7 @@ jobs: machines: - vlcdhp02 runs-on: ubuntu-latest + steps: - name: Setup Node.js uses: actions/setup-node@master with: From d58f68405f77cfd340d300609ece33e1b0fedf94 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:35:34 -0600 Subject: [PATCH 39/58] Noting possible release workflow --- .github/workflows/cd_dev_later.txt | 61 +++++++++++++++++++++++++ .github/workflows/ci_dev_later.txt | 26 +++++++++++ .github/workflows/ci_prod_later.txt | 26 +++++++++++ .github/workflows/test_pushes_later.txt | 47 +++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 .github/workflows/cd_dev_later.txt create mode 100644 .github/workflows/ci_dev_later.txt create mode 100644 .github/workflows/ci_prod_later.txt create mode 100644 .github/workflows/test_pushes_later.txt diff --git a/.github/workflows/cd_dev_later.txt b/.github/workflows/cd_dev_later.txt new file mode 100644 index 0000000..4702d8d --- /dev/null +++ b/.github/workflows/cd_dev_later.txt @@ -0,0 +1,61 @@ +# NOTES for if we want to do releases + +name: TinyNode Dev Deploy on push to main +on: + push: + branches: main +jobs: + merge-branch: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Merge with release + uses: devmasx/merge-branch@master + with: + type: now + from_branch: release + target_branch: main + github_token: ${{ secrets.BRY_PAT }} + message: Merge main into this branch to deploy to dev for testing. + test: + needs: merge-branch + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} + steps: + - uses: actions/checkout@master + - name: Test the app on the server + run: | + cd /srv/node/tiny-node/ + git stash + git checkout main + git pull + npm install + npm run allTests + deploy: + if: github.event.pull_request.draft == false + needs: + - merge-branch + - test + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} + steps: + - uses: actions/checkout@master + - name: Deploy the app on the server + run: | + if [[ ! -e /srv/node/logs/tinynode.txt ]]; then + mkdir -p /srv/node/logs + touch /srv/node/logs/tinynode.txt + fi + cd /srv/node/tiny-node/ + pm2 stop tinyNode + git stash + git checkout main + git pull + npm install + pm2 start -i max bin/tinyNode.js \ No newline at end of file diff --git a/.github/workflows/ci_dev_later.txt b/.github/workflows/ci_dev_later.txt new file mode 100644 index 0000000..206ba3b --- /dev/null +++ b/.github/workflows/ci_dev_later.txt @@ -0,0 +1,26 @@ +# NOTES for if we want to do releases + + +name: TinyNode end to end tests on PR to main +on: + pull_request: + branches: main +jobs: + test: + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} + steps: + - uses: actions/checkout@master + - name: Test the app on the server + run: | + cd /srv/node/tiny-node/ + git stash + git pull + git checkout $GITHUB_HEAD_REF + git pull + npm install + npm run E2Etests + \ No newline at end of file diff --git a/.github/workflows/ci_prod_later.txt b/.github/workflows/ci_prod_later.txt new file mode 100644 index 0000000..40fe52a --- /dev/null +++ b/.github/workflows/ci_prod_later.txt @@ -0,0 +1,26 @@ +# NOTES for if we want to do releases + + +name: TinyNode end to end tests on PR to release +on: + pull_request: + branches: release +jobs: + test: + strategy: + matrix: + machines: + - vlcdhprdp02 + runs-on: ${{ matrix.machines }} + steps: + - uses: actions/checkout@master + - name: Test the app on the server + run: | + cd /srv/node/tiny-node/ + git stash + git pull + git checkout $GITHUB_HEAD_REF + git pull + npm install + npm run E2Etests + \ No newline at end of file diff --git a/.github/workflows/test_pushes_later.txt b/.github/workflows/test_pushes_later.txt new file mode 100644 index 0000000..4a689f8 --- /dev/null +++ b/.github/workflows/test_pushes_later.txt @@ -0,0 +1,47 @@ +# NOTES for if we want to do releases + + +name: TinyNode tests on any push to a branch without an open PR +on: + push: + branches: + - '*' + - '!main' +jobs: + check_for_open_pr: + runs-on: ubuntu-latest + steps: + - name: Set the branch name as a processable string by making it an env variable. + run: echo BranchName=${GITHUB_REF##*/} >> $GITHUB_ENV + - name: Find Pull Request + uses: juliangruber/find-pull-request-action@v1 + id: find-pull-request + with: + branch: ${{ env.BranchName }} + - name: Make the PR number a processable string. Output that string for the next job. + run: | + echo Name $BranchName + echo PRnumber=${{steps.find-pull-request.outputs.number}} >> $GITHUB_ENV + outputs: + number: ${{ env.PRnumber }} + test: + strategy: + matrix: + machines: + - vlcdhp02 + runs-on: ${{ matrix.machines }} + needs: + - check_for_open_pr + if: needs.check_for_open_pr.outputs.number == '' + steps: + - uses: actions/checkout@master + - name: Test the app on the server + run: | + cd /srv/node/tiny-node/ + git stash + git pull + git checkout $GITHUB_REF + git pull + npm install + npm run coreTests + \ No newline at end of file From 5ef9eeac6bd612b74bb4c1ac267aae434c6805ea Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:41:41 -0600 Subject: [PATCH 40/58] try again --- app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app.js b/app.js index b467a30..1486988 100644 --- a/app.js +++ b/app.js @@ -62,4 +62,4 @@ app.use(function(err, req, res, next) { res.send(err.message) }) -export default app \ No newline at end of file +export default app From 78de0d9669585879996cd8ea74d79665ca2fd2fb Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 10:46:52 -0600 Subject: [PATCH 41/58] try again --- .github/workflows/cd_dev.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 78ec98e..6b8a248 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -23,6 +23,7 @@ jobs: - vlcdhp02 runs-on: ubuntu-latest steps: + - uses: actions/checkout@master - name: Setup Node.js uses: actions/setup-node@master with: From 5891757ede6030999e666ea7ed1161bcf7293c1a Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:06:59 -0600 Subject: [PATCH 42/58] try again --- .github/workflows/cd_dev.yaml | 10 +++++++++- routes/__tests__/create.test.js | 4 ++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 6b8a248..4c06fbd 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -24,6 +24,14 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master + - name: Create .env from secrets + uses: SpicyPizza/create-envfile@v2 + with: + RERUM_REGISTRATION_URL: https://store.rerum.io/v1 + RERUM_API_ADDR: https://store.rerum.io/v1/api/ + RERUM_ID_PATTERN: https://store.rerum.io/v1/id/ + RERUM_ACCESS_TOKEN_URL: https://store.rerum.io/client/request-new-access-token + OPEN_API_CORS: true - name: Setup Node.js uses: actions/setup-node@master with: @@ -43,7 +51,7 @@ jobs: - name: Install dependencies and run the test run: | npm install - npm run allTests + npm run functionalTests deploy: if: github.event.pull_request.draft == false needs: diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 3718f7a..0d226f6 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -1,10 +1,10 @@ import express from "express" import request from "supertest" import { jest } from "@jest/globals" -import dotenv from "dotenv" -dotenv.config() + import createRoute from "../create.js" import app from "../../app.js" + const routeTester = new express() routeTester.use(express.json()) routeTester.use(express.urlencoded({ extended: false })) From 16967285d839e5f0ea1fcd648a1a6ea65a889a7a Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:09:44 -0600 Subject: [PATCH 43/58] try again --- .github/workflows/cd_dev.yaml | 8 ++++---- package.json | 2 +- routes/__tests__/create.test.js | 4 +++- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 4c06fbd..c770989 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -27,10 +27,10 @@ jobs: - name: Create .env from secrets uses: SpicyPizza/create-envfile@v2 with: - RERUM_REGISTRATION_URL: https://store.rerum.io/v1 - RERUM_API_ADDR: https://store.rerum.io/v1/api/ - RERUM_ID_PATTERN: https://store.rerum.io/v1/id/ - RERUM_ACCESS_TOKEN_URL: https://store.rerum.io/client/request-new-access-token + RERUM_REGISTRATION_URL: https://devstore.rerum.io/v1 + RERUM_API_ADDR: https://devstore.rerum.io/v1/api/ + RERUM_ID_PATTERN: https://devstore.rerum.io/v1/id/ + RERUM_ACCESS_TOKEN_URL: https://devstore.rerum.io/client/request-new-access-token OPEN_API_CORS: true - name: Setup Node.js uses: actions/setup-node@master diff --git a/package.json b/package.json index 26f3b31..d33cd67 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "E2Etests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __e2e ", "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __exists ", "coreTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __core ", - "functionalTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __mock_functions " + "functionalTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __mock_functions_a " }, "dependencies": { "cors": "^2.8.5", diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 0d226f6..953f4d6 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -23,6 +23,8 @@ beforeEach(() => { json: () => Promise.resolve({ "@id": rerum_uri, "test": "item", "__rerum": { "stuff": "here" } }) }) ) + + global.isTokenExpired = jest.fn(() => {return false}) }) afterEach(() => { @@ -70,7 +72,7 @@ describe("Check that the expected TinyNode create route patterns are registered. * * Note: /app/create uses the same logic and would be a redundant test. */ -describe("Check that the request/response behavior of the TinyNode create route functions. Mock the connection to RERUM. __mock_functions", () => { +describe("Check that the request/response behavior of the TinyNode create route functions. Mock the connection to RERUM. __mock_functions_a", () => { it("'/create' route request and response behavior is functioning.", async () => { const response = await request(routeTester) From 3ce58bbae1021b198da8560da600b93b74b7deb6 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:14:48 -0600 Subject: [PATCH 44/58] try again --- routes/__tests__/create.test.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index 953f4d6..e73e79a 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -3,7 +3,7 @@ import request from "supertest" import { jest } from "@jest/globals" import createRoute from "../create.js" -import app from "../../app.js" +//import app from "../../app.js" const routeTester = new express() routeTester.use(express.json()) @@ -24,7 +24,9 @@ beforeEach(() => { }) ) - global.isTokenExpired = jest.fn(() => {return false}) + global.isTokenExpired = jest.fn(() => { + return false + }) }) afterEach(() => { From 3feabf808710e6efa4c8bddd9e03a9d05a06394a Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:19:48 -0600 Subject: [PATCH 45/58] try again --- routes/__tests__/delete.test.js | 4 ++++ routes/__tests__/overwrite.test.js | 4 ++++ routes/__tests__/query.test.js | 4 ++++ routes/__tests__/update.test.js | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js index 7b7e01a..912f682 100644 --- a/routes/__tests__/delete.test.js +++ b/routes/__tests__/delete.test.js @@ -23,6 +23,10 @@ beforeEach(() => { text: () => Promise.resolve("") }) ) + + global.isTokenExpired = jest.fn(() => { + return false + }) }) /** diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index ebbbc03..2efda0c 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -23,6 +23,10 @@ beforeEach(() => { json: () => Promise.resolve({ "@id": rerum_tiny_test_obj_id, "testing": "item", "__rerum": { "stuff": "here" } }) }) ) + + global.isTokenExpired = jest.fn(() => { + return false + }) }) afterEach(() => { diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js index 5807e4b..d7f3a34 100644 --- a/routes/__tests__/query.test.js +++ b/routes/__tests__/query.test.js @@ -23,6 +23,10 @@ beforeEach(() => { json: () => Promise.resolve([{ "@id": rerum_uri, "test": "item", "__rerum": { "stuff": "here" } }]) }) ) + + global.isTokenExpired = jest.fn(() => { + return false + }) }) /** diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 60b1b8f..23a8228 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -25,6 +25,10 @@ beforeEach(() => { json: () => Promise.resolve({ "@id": rerum_uri_updated, "testing": "item", "__rerum": { "stuff": "here" } }) }) ) + + global.isTokenExpired = jest.fn(() => { + return false + }) }) afterEach(() => { From 9a45aee952d2c1ac11c467d1537d08154071d409 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:30:48 -0600 Subject: [PATCH 46/58] split out for testing --- app.js | 2 +- package.json | 2 +- routes/__tests__/create.test.js | 32 +----- routes/__tests__/delete.test.js | 34 +------ routes/__tests__/index.test.js | 13 --- routes/__tests__/mount.test.js | 152 +++++++++++++++++++++++++++++ routes/__tests__/overwrite.test.js | 34 +------ routes/__tests__/query.test.js | 35 +------ routes/__tests__/update.test.js | 30 +----- routes/create.js | 2 +- routes/update.js | 2 +- 11 files changed, 165 insertions(+), 173 deletions(-) delete mode 100644 routes/__tests__/index.test.js create mode 100644 routes/__tests__/mount.test.js diff --git a/app.js b/app.js index 1486988..55c0936 100644 --- a/app.js +++ b/app.js @@ -16,7 +16,7 @@ import cors from "cors" import {updateExpiredToken } from "./tokens.js" // Check for and update token on app start -updateExpiredToken () +updateExpiredToken() let app = express() diff --git a/package.json b/package.json index d33cd67..26f3b31 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "E2Etests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __e2e ", "existsTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __exists ", "coreTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __core ", - "functionalTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __mock_functions_a " + "functionalTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js -t __mock_functions " }, "dependencies": { "cors": "^2.8.5", diff --git a/routes/__tests__/create.test.js b/routes/__tests__/create.test.js index e73e79a..9b21d83 100644 --- a/routes/__tests__/create.test.js +++ b/routes/__tests__/create.test.js @@ -23,10 +23,6 @@ beforeEach(() => { json: () => Promise.resolve({ "@id": rerum_uri, "test": "item", "__rerum": { "stuff": "here" } }) }) ) - - global.isTokenExpired = jest.fn(() => { - return false - }) }) afterEach(() => { @@ -36,32 +32,6 @@ afterEach(() => { */ }) -/** - * This test suite uses the built app.js app and checks that the expected create endpoints are registered. - * - /create - * - /app/create - */ -describe("Check that the expected TinyNode create route patterns are registered.", () => { - it("'/app/create' and '/create' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for (const middleware of stack) { - if (middleware.regexp && middleware.regexp.toString().includes("/app/create")) { - count++ - } else if (middleware.regexp && middleware.regexp.toString().includes("/create")) { - count++ - } - if (count === 2) { - exists = true - break - } - } - expect(exists).toBe(true) - }) -}) - - /** * This test suite runs the logic of the route file 'create.js' but does not actually communicate with RERUM. * It will confirm the following: @@ -74,7 +44,7 @@ describe("Check that the expected TinyNode create route patterns are registered. * * Note: /app/create uses the same logic and would be a redundant test. */ -describe("Check that the request/response behavior of the TinyNode create route functions. Mock the connection to RERUM. __mock_functions_a", () => { +describe("Check that the request/response behavior of the TinyNode create route functions. Mock the connection to RERUM. __mock_functions", () => { it("'/create' route request and response behavior is functioning.", async () => { const response = await request(routeTester) diff --git a/routes/__tests__/delete.test.js b/routes/__tests__/delete.test.js index 912f682..eeb6e11 100644 --- a/routes/__tests__/delete.test.js +++ b/routes/__tests__/delete.test.js @@ -1,10 +1,9 @@ import express from "express" import request from "supertest" import { jest } from "@jest/globals" -import dotenv from "dotenv" -dotenv.config() import deleteRoute from "../delete.js" -import app from "../../app.js" +//import app from "../../app.js" + const routeTester = new express() routeTester.use(express.json()) routeTester.use(express.urlencoded({ extended: false })) @@ -23,35 +22,6 @@ beforeEach(() => { text: () => Promise.resolve("") }) ) - - global.isTokenExpired = jest.fn(() => { - return false - }) -}) - -/** - * This test suite uses the built app.js app and checks that the expected delete endpoints are registered. - * - /delete - * - /app/delete - */ -describe("Combined unit tests for the '/delete' route.", () => { - it("'/app/delete' and '/delete' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for (const middleware of stack) { - if (middleware.regexp && middleware.regexp.toString().includes("/app/delete")) { - count++ - } else if (middleware.regexp && middleware.regexp.toString().includes("/delete")) { - count++ - } - if (count === 2) { - exists = true - break - } - } - expect(exists).toBe(true) - }) }) /** diff --git a/routes/__tests__/index.test.js b/routes/__tests__/index.test.js deleted file mode 100644 index ed0f563..0000000 --- a/routes/__tests__/index.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import request from "supertest" -import app from "../../app.js" - -describe("Make sure TinyNode demo interface is present. __core", () => { - it("/index.html", async () => { - const response = await request(app) - .get("/index.html") - .then(resp => resp) - .catch(err => err) - expect(response.statusCode).toBe(200) - expect(response.header["content-type"]).toMatch(/html/) - }) -}) \ No newline at end of file diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js new file mode 100644 index 0000000..23c22ea --- /dev/null +++ b/routes/__tests__/mount.test.js @@ -0,0 +1,152 @@ +import request from "supertest" +import app from "../../app.js" + +beforeEach(() => { + global.updateExpiredToken = jest.fn(() => { + return true + }) +}) + +afterEach(() => { + /** + * Food for thought: delete data generated by tests? + * Make a test.store available that uses the same annotationStoreTesting as RERUM tests? + */ +}) + +describe("Make sure TinyNode demo interface is present. __core", () => { + it("/index.html", async () => { + const response = await request(app) + .get("/index.html") + .then(resp => resp) + .catch(err => err) + expect(response.statusCode).toBe(200) + expect(response.header["content-type"]).toMatch(/html/) + }) +}) + +/** + * This test suite uses the built app.js app and checks that the expected create endpoints are registered. + * - /create + * - /app/create + */ +describe("Check that the expected TinyNode create route patterns are registered.", () => { + it("'/app/create' and '/create' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/create")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/create")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + +/** + * This test suite uses the built app.js app and checks that the expected query endpoints are registered. + * - /query + * - /app/query + */ +describe("Check that the expected TinyNode query route patterns are registered.", () => { + it("'/app/query' and '/query' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/query")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/query")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + +/** + * This test suite uses the built app.js app and checks that the expected update endpoints are registered. + * - /update + * - /app/update + */ +describe("Check that the expected TinyNode update route patterns are registered.", () => { + it("'/app/update' and '/update' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/update")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/update")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + + +/** + * This test suite uses the built app.js app and checks that the expected overwrite endpoints are registered. + * - /overwrite + * - /app/overwrite + */ +describe("Check that the expected TinyNode overwrite route patterns are registered.", () => { + it("'/app/overwrite' and '/overwrite' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/overwrite")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/overwrite")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) + +/** + * This test suite uses the built app.js app and checks that the expected delete endpoints are registered. + * - /delete + * - /app/delete + */ +describe("Combined unit tests for the '/delete' route.", () => { + it("'/app/delete' and '/delete' are registered routes in the app. __exists __core", () => { + let exists = false + let count = 0 + const stack = app._router.stack + for (const middleware of stack) { + if (middleware.regexp && middleware.regexp.toString().includes("/app/delete")) { + count++ + } else if (middleware.regexp && middleware.regexp.toString().includes("/delete")) { + count++ + } + if (count === 2) { + exists = true + break + } + } + expect(exists).toBe(true) + }) +}) diff --git a/routes/__tests__/overwrite.test.js b/routes/__tests__/overwrite.test.js index 2efda0c..4caf484 100644 --- a/routes/__tests__/overwrite.test.js +++ b/routes/__tests__/overwrite.test.js @@ -1,10 +1,9 @@ import express from "express" import request from "supertest" import { jest } from "@jest/globals" -import dotenv from "dotenv" -dotenv.config() import overwriteRoute from "../overwrite.js" -import app from "../../app.js" +//import app from "../../app.js" + const routeTester = new express() routeTester.use(express.json()) routeTester.use(express.urlencoded({ extended: false })) @@ -23,10 +22,6 @@ beforeEach(() => { json: () => Promise.resolve({ "@id": rerum_tiny_test_obj_id, "testing": "item", "__rerum": { "stuff": "here" } }) }) ) - - global.isTokenExpired = jest.fn(() => { - return false - }) }) afterEach(() => { @@ -36,31 +31,6 @@ afterEach(() => { */ }) -/** - * This test suite uses the built app.js app and checks that the expected overwrite endpoints are registered. - * - /overwrite - * - /app/overwrite - */ -describe("Check that the expected TinyNode overwrite route patterns are registered.", () => { - it("'/app/overwrite' and '/overwrite' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for (const middleware of stack) { - if (middleware.regexp && middleware.regexp.toString().includes("/app/overwrite")) { - count++ - } else if (middleware.regexp && middleware.regexp.toString().includes("/overwrite")) { - count++ - } - if (count === 2) { - exists = true - break - } - } - expect(exists).toBe(true) - }) -}) - /** * This test suite runs the logic of the route file 'overwrite.js' but does not actually communicate with RERUM. * It will confirm the following: diff --git a/routes/__tests__/query.test.js b/routes/__tests__/query.test.js index d7f3a34..c7caed8 100644 --- a/routes/__tests__/query.test.js +++ b/routes/__tests__/query.test.js @@ -1,10 +1,9 @@ import express from "express" import request from "supertest" import { jest } from "@jest/globals" -import dotenv from "dotenv" -dotenv.config() import queryRoute from "../query.js" -import app from "../../app.js" +//import app from "../../app.js" + const routeTester = new express() routeTester.use(express.json()) routeTester.use(express.urlencoded({ extended: false })) @@ -23,38 +22,8 @@ beforeEach(() => { json: () => Promise.resolve([{ "@id": rerum_uri, "test": "item", "__rerum": { "stuff": "here" } }]) }) ) - - global.isTokenExpired = jest.fn(() => { - return false - }) }) -/** - * This test suite uses the built app.js app and checks that the expected query endpoints are registered. - * - /query - * - /app/query - */ -describe("Check that the expected TinyNode query route patterns are registered.", () => { - it("'/app/query' and '/query' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for (const middleware of stack) { - if (middleware.regexp && middleware.regexp.toString().includes("/app/query")) { - count++ - } else if (middleware.regexp && middleware.regexp.toString().includes("/query")) { - count++ - } - if (count === 2) { - exists = true - break - } - } - expect(exists).toBe(true) - }) -}) - - /** * This test suite runs the logic of the route file 'query.js' but does not actually communicate with RERUM. * It will confirm the following: diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 23a8228..511ccef 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -1,10 +1,9 @@ import express from "express" import request from "supertest" import { jest } from "@jest/globals" -import dotenv from "dotenv" -dotenv.config() import updateRoute from "../update.js" -import app from "../../app.js" +//import app from "../../app.js" + const routeTester = new express() routeTester.use(express.json()) routeTester.use(express.urlencoded({ extended: false })) @@ -38,31 +37,6 @@ afterEach(() => { */ }) -/** - * This test suite uses the built app.js app and checks that the expected update endpoints are registered. - * - /update - * - /app/update - */ -describe("Check that the expected TinyNode update route patterns are registered.", () => { - it("'/app/update' and '/update' are registered routes in the app. __exists __core", () => { - let exists = false - let count = 0 - const stack = app._router.stack - for (const middleware of stack) { - if (middleware.regexp && middleware.regexp.toString().includes("/app/update")) { - count++ - } else if (middleware.regexp && middleware.regexp.toString().includes("/update")) { - count++ - } - if (count === 2) { - exists = true - break - } - } - expect(exists).toBe(true) - }) -}) - /** * This test suite runs the logic of the route file 'update.js' but does not actually communicate with RERUM. * It will confirm the following: diff --git a/routes/create.js b/routes/create.js index a570402..29d327c 100644 --- a/routes/create.js +++ b/routes/create.js @@ -12,7 +12,7 @@ router.post('/', async (req, res, next) => { body, headers: { 'user-agent': 'Tiny-Things/1.0', - 'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`, // not required for query + 'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`, 'Content-Type' : "application/json;charset=utf-8" } } diff --git a/routes/update.js b/routes/update.js index fc21f01..2d20dce 100644 --- a/routes/update.js +++ b/routes/update.js @@ -17,7 +17,7 @@ router.put('/', rerumPropertiesWasher, async (req, res, next) => { body, headers: { 'user-agent': 'Tiny-Things/1.0', - 'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`, // not required for query + 'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`, 'Content-Type' : "application/json;charset=utf-8" } } From 04c460d53ef5c9d3cb6d13d8272ba5e67c220566 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:35:16 -0600 Subject: [PATCH 47/58] hmm --- routes/__tests__/mount.test.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 23c22ea..03fb6b2 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -2,9 +2,22 @@ import request from "supertest" import app from "../../app.js" beforeEach(() => { + + global.updateExpiredToken = jest.fn(() => + Promise.resolve(true) + ) + + global.isTokenExpired = jest.fn(() => + Promise.resolve(false) + ) + global.updateExpiredToken = jest.fn(() => { return true }) + + global.isTokenExpired = jest.fn(() => { + return false + }) }) afterEach(() => { From 1dfcaf7e3ee22ba8a0700602f20ab3abecd696b4 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:44:59 -0600 Subject: [PATCH 48/58] hmm --- routes/__tests__/mount.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 03fb6b2..cc23819 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -3,19 +3,19 @@ import app from "../../app.js" beforeEach(() => { - global.updateExpiredToken = jest.fn(() => + updateExpiredToken = jest.fn(() => Promise.resolve(true) ) - global.isTokenExpired = jest.fn(() => + isTokenExpired = jest.fn(() => Promise.resolve(false) ) - global.updateExpiredToken = jest.fn(() => { + updateExpiredToken = jest.fn(() => { return true }) - global.isTokenExpired = jest.fn(() => { + isTokenExpired = jest.fn(() => { return false }) }) From 67c8ba375c17c217788be783cd87882ba54b86af Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:48:38 -0600 Subject: [PATCH 49/58] hmm --- routes/__tests__/mount.test.js | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index cc23819..52e13b4 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -3,21 +3,14 @@ import app from "../../app.js" beforeEach(() => { - updateExpiredToken = jest.fn(() => - Promise.resolve(true) - ) + jest.mock('app', () => ({ + updateExpiredToken: jest.fn(() => true) + })) - isTokenExpired = jest.fn(() => - Promise.resolve(false) - ) - - updateExpiredToken = jest.fn(() => { - return true - }) - - isTokenExpired = jest.fn(() => { - return false - }) + jest.mock('app', () => ({ + isTokenExpired: jest.fn(() => false) + })) + }) afterEach(() => { From 150cb707c5d883c0dabfbaffb44f202cd82429e5 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 11:54:41 -0600 Subject: [PATCH 50/58] hmm --- .github/workflows/cd_dev.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index c770989..38c31f4 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -27,11 +27,11 @@ jobs: - name: Create .env from secrets uses: SpicyPizza/create-envfile@v2 with: - RERUM_REGISTRATION_URL: https://devstore.rerum.io/v1 - RERUM_API_ADDR: https://devstore.rerum.io/v1/api/ - RERUM_ID_PATTERN: https://devstore.rerum.io/v1/id/ - RERUM_ACCESS_TOKEN_URL: https://devstore.rerum.io/client/request-new-access-token - OPEN_API_CORS: true + envkey_RERUM_REGISTRATION_URL: https://devstore.rerum.io/v1 + envkey_RERUM_API_ADDR: https://devstore.rerum.io/v1/api/ + envkey_RERUM_ID_PATTERN: https://devstore.rerum.io/v1/id/ + envkey_RERUM_ACCESS_TOKEN_URL: https://devstore.rerum.io/client/request-new-access-token + envkey_ACCESS_TOKEN: babababababababababababababa - name: Setup Node.js uses: actions/setup-node@master with: From ec15661a7d6cb47c1501e43b87203cfcafedbcd9 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 12:03:00 -0600 Subject: [PATCH 51/58] hmm --- .github/workflows/cd_dev.yaml | 2 +- app.js | 2 +- routes/__tests__/mount.test.js | 15 ++++++++------- routes/__tests__/update.test.js | 4 ---- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 38c31f4..f0b2194 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -31,7 +31,7 @@ jobs: envkey_RERUM_API_ADDR: https://devstore.rerum.io/v1/api/ envkey_RERUM_ID_PATTERN: https://devstore.rerum.io/v1/id/ envkey_RERUM_ACCESS_TOKEN_URL: https://devstore.rerum.io/client/request-new-access-token - envkey_ACCESS_TOKEN: babababababababababababababa + envkey_ACCESS_TOKEN: babababababab.abababababababa - name: Setup Node.js uses: actions/setup-node@master with: diff --git a/app.js b/app.js index 55c0936..20aa838 100644 --- a/app.js +++ b/app.js @@ -13,7 +13,7 @@ import updateRouter from "./routes/update.js" import deleteRouter from "./routes/delete.js" import overwriteRouter from "./routes/overwrite.js" import cors from "cors" -import {updateExpiredToken } from "./tokens.js" +import { updateExpiredToken } from "./tokens.js" // Check for and update token on app start updateExpiredToken() diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 52e13b4..412c0fc 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -1,16 +1,17 @@ import request from "supertest" +import { jest } from "@jest/globals" import app from "../../app.js" + beforeEach(() => { - jest.mock('app', () => ({ - updateExpiredToken: jest.fn(() => true) - })) + updateExpiredToken = jest.fn(() => { + return true + }) - jest.mock('app', () => ({ - isTokenExpired: jest.fn(() => false) - })) - + isTokenExpired = jest.fn((tok) => { + return false + }) }) afterEach(() => { diff --git a/routes/__tests__/update.test.js b/routes/__tests__/update.test.js index 511ccef..c9357a6 100644 --- a/routes/__tests__/update.test.js +++ b/routes/__tests__/update.test.js @@ -24,10 +24,6 @@ beforeEach(() => { json: () => Promise.resolve({ "@id": rerum_uri_updated, "testing": "item", "__rerum": { "stuff": "here" } }) }) ) - - global.isTokenExpired = jest.fn(() => { - return false - }) }) afterEach(() => { From d95d03d54baed6448ba396f7ada026820a1467a6 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 12:06:31 -0600 Subject: [PATCH 52/58] hmm --- .github/workflows/cd_dev.yaml | 2 +- routes/__tests__/mount.test.js | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index f0b2194..960ea68 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -31,7 +31,7 @@ jobs: envkey_RERUM_API_ADDR: https://devstore.rerum.io/v1/api/ envkey_RERUM_ID_PATTERN: https://devstore.rerum.io/v1/id/ envkey_RERUM_ACCESS_TOKEN_URL: https://devstore.rerum.io/client/request-new-access-token - envkey_ACCESS_TOKEN: babababababab.abababababababa + envkey_ACCESS_TOKEN: babababababab.abababababababa.eeeeeffffff - name: Setup Node.js uses: actions/setup-node@master with: diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 412c0fc..9f70d8f 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -4,14 +4,16 @@ import app from "../../app.js" beforeEach(() => { + global.updateExpiredToken = jest.fn(() => true) + global.isTokenExpired = jest.fn((tok) => false) - updateExpiredToken = jest.fn(() => { - return true - }) + // updateExpiredToken = jest.fn(() => { + // return true + // }) - isTokenExpired = jest.fn((tok) => { - return false - }) + // isTokenExpired = jest.fn((tok) => { + // return false + // }) }) afterEach(() => { From 9c1f23251c087591b75f52facfc689c6ab84407f Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 12:15:49 -0600 Subject: [PATCH 53/58] hmm --- routes/__tests__/mount.test.js | 16 +++++----------- tokens.js | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 9f70d8f..6873a2e 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -1,19 +1,13 @@ import request from "supertest" import { jest } from "@jest/globals" +import { updateExpiredToken } from "./tokens.js" import app from "../../app.js" - beforeEach(() => { - global.updateExpiredToken = jest.fn(() => true) - global.isTokenExpired = jest.fn((tok) => false) - - // updateExpiredToken = jest.fn(() => { - // return true - // }) - - // isTokenExpired = jest.fn((tok) => { - // return false - // }) + updateExpiredToken = jest.fn().mockReturnValue(true); + //updateExpiredToken = jest.fn(() => true) + //global.updateExpiredToken = jest.fn().mockReturnValue(true); + //global.updateExpiredToken = jest.fn(() => true) }) afterEach(() => { diff --git a/tokens.js b/tokens.js index 871c245..3d29730 100644 --- a/tokens.js +++ b/tokens.js @@ -44,7 +44,7 @@ async function generateNewAccessToken() { * This does not validate your access token, so you may still be rejected by * your RERUM instance as unauthorized. */ -function updateExpiredToken () { +function updateExpiredToken() { if (isTokenExpired(process.env.ACCESS_TOKEN)) { console.log("TinyNode detected an expired access token. Updating the token now.") generateNewAccessToken() From 10103e4a26069eefbcd04b11c486c3da9d6846d4 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 12:17:18 -0600 Subject: [PATCH 54/58] hmm --- routes/__tests__/mount.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 6873a2e..69581de 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -1,6 +1,6 @@ import request from "supertest" import { jest } from "@jest/globals" -import { updateExpiredToken } from "./tokens.js" +import { updateExpiredToken } from "../../tokens.js" import app from "../../app.js" beforeEach(() => { From 136d5ba07261bb28be47e18588bea0dfbc18c419 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 12:20:06 -0600 Subject: [PATCH 55/58] hmm --- routes/__tests__/mount.test.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 69581de..3433397 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -1,12 +1,11 @@ import request from "supertest" import { jest } from "@jest/globals" -import { updateExpiredToken } from "../../tokens.js" import app from "../../app.js" beforeEach(() => { - updateExpiredToken = jest.fn().mockReturnValue(true); + //updateExpiredToken = jest.fn().mockReturnValue(true); //updateExpiredToken = jest.fn(() => true) - //global.updateExpiredToken = jest.fn().mockReturnValue(true); + global.updateExpiredToken = jest.fn().mockReturnValue(true); //global.updateExpiredToken = jest.fn(() => true) }) From 1dd425a2d91d14a64eaeab7749c15a2002ab80b7 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 12:50:23 -0600 Subject: [PATCH 56/58] Oh boy this is super sneaky...I think I got around the tokens problem --- app.js | 2 +- jest.config.js | 2 +- routes/__tests__/mount.test.js | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app.js b/app.js index 20aa838..c8bdb7d 100644 --- a/app.js +++ b/app.js @@ -16,7 +16,7 @@ import cors from "cors" import { updateExpiredToken } from "./tokens.js" // Check for and update token on app start -updateExpiredToken() +//updateExpiredToken() let app = express() diff --git a/jest.config.js b/jest.config.js index 3286333..130df2f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -188,7 +188,7 @@ const config = { // timers: "real", // A map from regular expressions to paths to transformers - // transform: undefined, + transform: {}, // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation // transformIgnorePatterns: [ diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 3433397..685259d 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -1,12 +1,10 @@ import request from "supertest" import { jest } from "@jest/globals" import app from "../../app.js" +import { updateExpiredToken } from "../../tokens.js" beforeEach(() => { - //updateExpiredToken = jest.fn().mockReturnValue(true); - //updateExpiredToken = jest.fn(() => true) - global.updateExpiredToken = jest.fn().mockReturnValue(true); - //global.updateExpiredToken = jest.fn(() => true) + updateExpiredToken = jest.fn(() => true) }) afterEach(() => { From 31e2e11dac237b518c5dce217af4c389baddb006 Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 12:52:15 -0600 Subject: [PATCH 57/58] Oh boy this is super sneaky...I think I got around the tokens problem --- routes/__tests__/mount.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 685259d..025a3b6 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -1,9 +1,9 @@ import request from "supertest" import { jest } from "@jest/globals" import app from "../../app.js" -import { updateExpiredToken } from "../../tokens.js" beforeEach(() => { + // This comes from tokens.js in the app.js import. We have to mock it, we don't do tokens here. updateExpiredToken = jest.fn(() => true) }) From d8d00c2a47028a83eb94eff7ffca20c88947070f Mon Sep 17 00:00:00 2001 From: Bryan Haberberger Date: Fri, 8 Nov 2024 13:27:21 -0600 Subject: [PATCH 58/58] This is it --- .github/workflows/cd_dev.yaml | 1 - .github/workflows/cd_dev_later.txt | 61 ------------------------- .github/workflows/ci_dev_later.txt | 26 ----------- .github/workflows/ci_prod_later.txt | 26 ----------- .github/workflows/test_pushes_later.txt | 47 ------------------- routes/__tests__/mount.test.js | 4 +- 6 files changed, 3 insertions(+), 162 deletions(-) delete mode 100644 .github/workflows/cd_dev_later.txt delete mode 100644 .github/workflows/ci_dev_later.txt delete mode 100644 .github/workflows/ci_prod_later.txt delete mode 100644 .github/workflows/test_pushes_later.txt diff --git a/.github/workflows/cd_dev.yaml b/.github/workflows/cd_dev.yaml index 960ea68..7f696b5 100644 --- a/.github/workflows/cd_dev.yaml +++ b/.github/workflows/cd_dev.yaml @@ -31,7 +31,6 @@ jobs: envkey_RERUM_API_ADDR: https://devstore.rerum.io/v1/api/ envkey_RERUM_ID_PATTERN: https://devstore.rerum.io/v1/id/ envkey_RERUM_ACCESS_TOKEN_URL: https://devstore.rerum.io/client/request-new-access-token - envkey_ACCESS_TOKEN: babababababab.abababababababa.eeeeeffffff - name: Setup Node.js uses: actions/setup-node@master with: diff --git a/.github/workflows/cd_dev_later.txt b/.github/workflows/cd_dev_later.txt deleted file mode 100644 index 4702d8d..0000000 --- a/.github/workflows/cd_dev_later.txt +++ /dev/null @@ -1,61 +0,0 @@ -# NOTES for if we want to do releases - -name: TinyNode Dev Deploy on push to main -on: - push: - branches: main -jobs: - merge-branch: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - name: Merge with release - uses: devmasx/merge-branch@master - with: - type: now - from_branch: release - target_branch: main - github_token: ${{ secrets.BRY_PAT }} - message: Merge main into this branch to deploy to dev for testing. - test: - needs: merge-branch - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Test the app on the server - run: | - cd /srv/node/tiny-node/ - git stash - git checkout main - git pull - npm install - npm run allTests - deploy: - if: github.event.pull_request.draft == false - needs: - - merge-branch - - test - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Deploy the app on the server - run: | - if [[ ! -e /srv/node/logs/tinynode.txt ]]; then - mkdir -p /srv/node/logs - touch /srv/node/logs/tinynode.txt - fi - cd /srv/node/tiny-node/ - pm2 stop tinyNode - git stash - git checkout main - git pull - npm install - pm2 start -i max bin/tinyNode.js \ No newline at end of file diff --git a/.github/workflows/ci_dev_later.txt b/.github/workflows/ci_dev_later.txt deleted file mode 100644 index 206ba3b..0000000 --- a/.github/workflows/ci_dev_later.txt +++ /dev/null @@ -1,26 +0,0 @@ -# NOTES for if we want to do releases - - -name: TinyNode end to end tests on PR to main -on: - pull_request: - branches: main -jobs: - test: - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Test the app on the server - run: | - cd /srv/node/tiny-node/ - git stash - git pull - git checkout $GITHUB_HEAD_REF - git pull - npm install - npm run E2Etests - \ No newline at end of file diff --git a/.github/workflows/ci_prod_later.txt b/.github/workflows/ci_prod_later.txt deleted file mode 100644 index 40fe52a..0000000 --- a/.github/workflows/ci_prod_later.txt +++ /dev/null @@ -1,26 +0,0 @@ -# NOTES for if we want to do releases - - -name: TinyNode end to end tests on PR to release -on: - pull_request: - branches: release -jobs: - test: - strategy: - matrix: - machines: - - vlcdhprdp02 - runs-on: ${{ matrix.machines }} - steps: - - uses: actions/checkout@master - - name: Test the app on the server - run: | - cd /srv/node/tiny-node/ - git stash - git pull - git checkout $GITHUB_HEAD_REF - git pull - npm install - npm run E2Etests - \ No newline at end of file diff --git a/.github/workflows/test_pushes_later.txt b/.github/workflows/test_pushes_later.txt deleted file mode 100644 index 4a689f8..0000000 --- a/.github/workflows/test_pushes_later.txt +++ /dev/null @@ -1,47 +0,0 @@ -# NOTES for if we want to do releases - - -name: TinyNode tests on any push to a branch without an open PR -on: - push: - branches: - - '*' - - '!main' -jobs: - check_for_open_pr: - runs-on: ubuntu-latest - steps: - - name: Set the branch name as a processable string by making it an env variable. - run: echo BranchName=${GITHUB_REF##*/} >> $GITHUB_ENV - - name: Find Pull Request - uses: juliangruber/find-pull-request-action@v1 - id: find-pull-request - with: - branch: ${{ env.BranchName }} - - name: Make the PR number a processable string. Output that string for the next job. - run: | - echo Name $BranchName - echo PRnumber=${{steps.find-pull-request.outputs.number}} >> $GITHUB_ENV - outputs: - number: ${{ env.PRnumber }} - test: - strategy: - matrix: - machines: - - vlcdhp02 - runs-on: ${{ matrix.machines }} - needs: - - check_for_open_pr - if: needs.check_for_open_pr.outputs.number == '' - steps: - - uses: actions/checkout@master - - name: Test the app on the server - run: | - cd /srv/node/tiny-node/ - git stash - git pull - git checkout $GITHUB_REF - git pull - npm install - npm run coreTests - \ No newline at end of file diff --git a/routes/__tests__/mount.test.js b/routes/__tests__/mount.test.js index 025a3b6..ccb043b 100644 --- a/routes/__tests__/mount.test.js +++ b/routes/__tests__/mount.test.js @@ -3,8 +3,10 @@ import { jest } from "@jest/globals" import app from "../../app.js" beforeEach(() => { - // This comes from tokens.js in the app.js import. We have to mock it, we don't do tokens here. + // This comes from tokens.js in the app.js import. This apps tries to read env.ACCESS_TOKEN to refresh expired tokens. + // We don't care whether or not the token is expired here, so let's just state we don't care about tokens in tests. updateExpiredToken = jest.fn(() => true) + isTokenExpired = jest.fn(() => false) }) afterEach(() => {