From 7e40251a4529c6f90af390a7985109989b9b8546 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Mon, 11 Nov 2024 11:11:17 +0000 Subject: [PATCH 01/42] testcontainers in a helper --- Dockerfile | 2 +- README.md | 18 + package-lock.json | 991 ++++++++++++++++++++- package.json | 3 + test/helpers/cloudagent.ts | 16 +- test/helpers/routeHelper.ts | 14 + test/init.ts | 13 + test/integration/newConnection.test.ts | 8 +- test/mocharc.json | 2 +- test/testcontainers/settings.test.ts | 210 +++++ test/testcontainers/testcontainersSetup.ts | 369 ++++++++ 11 files changed, 1617 insertions(+), 29 deletions(-) create mode 100644 test/testcontainers/settings.test.ts create mode 100644 test/testcontainers/testcontainersSetup.ts diff --git a/Dockerfile b/Dockerfile index 16da64c3..3ec27fc0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,7 @@ RUN npx playwright install --with-deps CMD ["npm", "run", "test:playwright"] -# service +# # service FROM node:current-alpine AS service WORKDIR /veritable-ui diff --git a/README.md b/README.md index f1041515..382b2d3b 100644 --- a/README.md +++ b/README.md @@ -212,6 +212,24 @@ docker compose -f docker-compose.e2e.yml up Then you'll find the test results in directory `playwright-report` at root level. +### Testcontainers + +so see logs from a container e.g. if it is dying on startup add: + +``` +.withLogConsumer((stream) => { + stream.on('data', (line) => console.log(line)) + stream.on('err', (line) => console.error(line)) + stream.on('end', () => console.log('Stream closed')) +}) +``` + +and run with + +``` +DEBUG=testcontainers* npm run test:testcontainers +``` + ## Database This service is dependant on postgreSQL which will sync up across all nodes and will update cloudagent when needed. We use `knex` wrapper for wrapping [create, read, write, update] database quries. We also have different models for inserting and returning data which gives us a control of sensitive data or data we do not want to get along the record. We also use **zod** for enchanted validation. It's currently used in `src/models/db/types.ts` file. diff --git a/package-lock.json b/package-lock.json index 877567d6..ec6f9504 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,6 +71,8 @@ "prettier-plugin-organize-imports": "^4.1.0", "sinon": "^19.0.2", "supertest": "^7.0.0", + "testcontainers": "^10.13.2", + "ts-node": "^10.9.2", "typescript": "^5.6.3", "undici": "^6.20.1" }, @@ -299,6 +301,34 @@ "node": ">=6.9.0" } }, + "node_modules/@balena/dockerignore": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", + "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==", + "dev": true + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@digicatapult/tsoa-oauth-express": { "version": "0.1.67", "resolved": "https://registry.npmjs.org/@digicatapult/tsoa-oauth-express/-/tsoa-oauth-express-0.1.67.tgz", @@ -535,6 +565,15 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@hapi/accept": { "version": "6.0.3", "license": "BSD-3-Clause", @@ -1876,6 +1915,30 @@ "dev": true, "license": "MIT" }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true + }, "node_modules/@tsoa/cli": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@tsoa/cli/-/cli-6.5.1.tgz", @@ -2104,6 +2167,27 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/docker-modem": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.6.tgz", + "integrity": "sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/ssh2": "*" + } + }, + "node_modules/@types/dockerode": { + "version": "3.3.31", + "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.31.tgz", + "integrity": "sha512-42R9eoVqJDSvVspV89g7RwRqfNExgievLNWoHkg7NoWIqAmavIbgQBb4oc0qRtHkxE+I3Xxvqv7qVXFABKPBTg==", + "dev": true, + "dependencies": { + "@types/docker-modem": "*", + "@types/node": "*", + "@types/ssh2": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -2352,6 +2436,39 @@ "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", "dev": true }, + "node_modules/@types/ssh2": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.1.tgz", + "integrity": "sha512-ZIbEqKAsi5gj35y4P4vkJYly642wIbY6PqoN0xiyQGshKUGXR9WQjF/iF9mXBQ8uBKy3ezfsCkcoHKhd0BzuDA==", + "dev": true, + "dependencies": { + "@types/node": "^18.11.18" + } + }, + "node_modules/@types/ssh2-streams": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@types/ssh2-streams/-/ssh2-streams-0.1.12.tgz", + "integrity": "sha512-Sy8tpEmCce4Tq0oSOYdfqaBpA3hDM8SoxoFh5vzFsu2oL+znzGz8oVWW7xb4K920yYMUY+PIG31qZnFMfPWNCg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ssh2/node_modules/@types/node": { + "version": "18.19.64", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.64.tgz", + "integrity": "sha512-955mDqvO2vFf/oL7V3WiUtiz+BugyX8uVbaT2H8oj3+8dRyH2FLiNdowe7eNqRM7IOIZvzDH76EoAT+gwm6aIQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/ssh2/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/@types/superagent": { "version": "8.1.7", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.7.tgz", @@ -2709,6 +2826,18 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2790,6 +2919,60 @@ ], "license": "MIT" }, + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "dev": true, + "dependencies": { + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "dev": true, + "dependencies": { + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/archiver-utils/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "node_modules/argon2": { "version": "0.41.1", "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.41.1.tgz", @@ -2848,6 +3031,15 @@ "dev": true, "license": "MIT" }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, "node_modules/assertion-error": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", @@ -2857,6 +3049,18 @@ "node": ">=12" } }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true + }, + "node_modules/async-lock": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.1.tgz", + "integrity": "sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==", + "dev": true + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2871,10 +3075,62 @@ "node": ">=8.0.0" } }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true + }, "node_modules/balanced-match": { "version": "1.0.2", "license": "MIT" }, + "node_modules/bare-events": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", + "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", + "dev": true, + "optional": true + }, + "node_modules/bare-fs": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "dev": true, + "optional": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.0.0" + } + }, + "node_modules/bare-os": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", + "dev": true, + "optional": true + }, + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "node_modules/bare-stream": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", + "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", + "dev": true, + "optional": true, + "dependencies": { + "streamx": "^2.20.0" + } + }, "node_modules/base64-js": { "version": "1.5.1", "dev": true, @@ -2894,6 +3150,15 @@ ], "license": "MIT" }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/bin-check": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", @@ -3026,6 +3291,55 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/body-parser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.0.1.tgz", @@ -3124,6 +3438,15 @@ "ieee754": "^1.2.1" } }, + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -3136,6 +3459,25 @@ "dev": true, "license": "MIT" }, + "node_modules/buildcheck": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz", + "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "license": "MIT", @@ -3319,6 +3661,12 @@ "fsevents": "~2.3.2" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, "node_modules/cliui": { "version": "7.0.4", "dev": true, @@ -3392,6 +3740,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/compress-commons/node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/compressible": { "version": "2.0.18", "license": "MIT", @@ -3588,6 +3964,12 @@ "dev": true, "license": "MIT" }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "node_modules/cosmiconfig": { "version": "7.1.0", "dev": true, @@ -3603,6 +3985,52 @@ "node": ">=10" } }, + "node_modules/cpu-features": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz", + "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "dependencies": { + "buildcheck": "~0.0.6", + "nan": "^2.19.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "dev": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "license": "MIT", @@ -3799,37 +4227,146 @@ "version": "1.2.0", "license": "MIT", "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/docker-compose": { + "version": "0.24.8", + "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.8.tgz", + "integrity": "sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==", + "dev": true, + "dependencies": { + "yaml": "^2.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/docker-compose/node_modules/yaml": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "dev": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/docker-modem": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.8.tgz", + "integrity": "sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "readable-stream": "^3.5.0", + "split-ca": "^1.0.1", + "ssh2": "^1.11.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/docker-modem/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/dockerode": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-3.3.5.tgz", + "integrity": "sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA==", + "dev": true, + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "docker-modem": "^3.0.0", + "tar-fs": "~2.0.1" + }, + "engines": { + "node": ">= 8.0" } }, - "node_modules/detect-file": { - "version": "1.0.0", + "node_modules/dockerode/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, - "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/dezalgo": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", - "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "node_modules/dockerode/node_modules/tar-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz", + "integrity": "sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==", "dev": true, - "license": "ISC", "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.0.0" } }, - "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "node_modules/dockerode/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "dev": true, - "license": "BSD-3-Clause", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, "engines": { - "node": ">=0.3.1" + "node": ">=6" } }, "node_modules/dotenv": { @@ -4513,6 +5050,12 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "dev": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -4806,6 +5349,12 @@ "node": ">= 0.6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4875,6 +5424,18 @@ "node": ">=8.0.0" } }, + "node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", @@ -5398,6 +5959,12 @@ "node": ">=0.10.0" } }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "license": "ISC" @@ -5878,6 +6445,42 @@ } } }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -6057,6 +6660,12 @@ "node": ">=12" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "license": "MIT", @@ -6199,6 +6808,24 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, "node_modules/mocha": { "version": "10.8.2", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", @@ -6369,6 +6996,13 @@ "concat-map": "0.0.1" } }, + "node_modules/nan": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz", + "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==", + "dev": true, + "optional": true + }, "node_modules/nanoid": { "version": "3.3.7", "dev": true, @@ -7357,12 +7991,51 @@ "node": ">= 0.6.0" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "node_modules/process-warning": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-4.0.0.tgz", "integrity": "sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==", "license": "MIT" }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/proper-lockfile/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/properties-reader": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/properties-reader/-/properties-reader-2.3.0.tgz", + "integrity": "sha512-z597WicA7nDZxK12kZqHr2TcvwNU1GCfA5UwfDY/HDp3hXPoPlb5rlEx9bwGTiJnc0OqbBTkU975jDToth8Gxw==", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/properties?sponsor=1" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "license": "MIT", @@ -7433,6 +8106,12 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, "node_modules/quick-format-unescaped": { "version": "4.0.4", "license": "MIT" @@ -7529,6 +8208,27 @@ "node": ">= 6" } }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/readdirp": { "version": "3.6.0", "dev": true, @@ -7628,6 +8328,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -8013,6 +8722,12 @@ "source-map": "^0.6.0" } }, + "node_modules/split-ca": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz", + "integrity": "sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==", + "dev": true + }, "node_modules/split2": { "version": "4.2.0", "license": "ISC", @@ -8025,6 +8740,44 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/ssh-remote-port-forward": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ssh-remote-port-forward/-/ssh-remote-port-forward-1.0.4.tgz", + "integrity": "sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ==", + "dev": true, + "dependencies": { + "@types/ssh2": "^0.5.48", + "ssh2": "^1.4.0" + } + }, + "node_modules/ssh-remote-port-forward/node_modules/@types/ssh2": { + "version": "0.5.52", + "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-0.5.52.tgz", + "integrity": "sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/ssh2-streams": "*" + } + }, + "node_modules/ssh2": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz", + "integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.10", + "nan": "^2.20.0" + } + }, "node_modules/statuses": { "version": "2.0.1", "license": "MIT", @@ -8032,6 +8785,20 @@ "node": ">= 0.8" } }, + "node_modules/streamx": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -8254,6 +9021,31 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tar-fs": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "dev": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/tarn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", @@ -8262,6 +9054,70 @@ "node": ">=8.0.0" } }, + "node_modules/testcontainers": { + "version": "10.13.2", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.13.2.tgz", + "integrity": "sha512-LfEll+AG/1Ks3n4+IA5lpyBHLiYh/hSfI4+ERa6urwfQscbDU+M2iW1qPQrHQi+xJXQRYy4whyK1IEHdmxWa3Q==", + "dev": true, + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@types/dockerode": "^3.3.29", + "archiver": "^7.0.1", + "async-lock": "^1.4.1", + "byline": "^5.0.0", + "debug": "^4.3.5", + "docker-compose": "^0.24.8", + "dockerode": "^3.3.5", + "get-port": "^5.1.1", + "proper-lockfile": "^4.1.2", + "properties-reader": "^2.3.0", + "ssh-remote-port-forward": "^1.0.4", + "tar-fs": "^3.0.6", + "tmp": "^0.2.3", + "undici": "^5.28.4" + } + }, + "node_modules/testcontainers/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/testcontainers/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/testcontainers/node_modules/undici": { + "version": "5.28.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", + "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", + "dev": true, + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/text-decoder": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", + "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", + "dev": true + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8285,6 +9141,15 @@ "node": ">=8" } }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "engines": { + "node": ">=14.14" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "dev": true, @@ -8388,6 +9253,58 @@ "node": ">=14.13.1" } }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/tslib": { "version": "2.6.2", "license": "0BSD" @@ -8423,6 +9340,12 @@ "version": "1.14.1", "license": "0BSD" }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8459,7 +9382,6 @@ "version": "5.6.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8532,6 +9454,12 @@ "node": ">= 0.4.0" } }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, "node_modules/validator": { "version": "13.12.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", @@ -8690,6 +9618,15 @@ "node": ">=10" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -8702,6 +9639,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zip-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", + "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", + "dev": true, + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/zod": { "version": "3.23.8", "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", diff --git a/package.json b/package.json index 6717c365..1be61dd8 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "depcheck": "depcheck", "test:unit": "NODE_ENV=test ./node_modules/.bin/mocha --config ./test/mocharc.json ./src/**/*.test.ts", "test:integration": "NODE_ENV=test ./node_modules/.bin/mocha --config ./test/mocharc.json ./test/**/*.test.ts", + "test:testcontainers": "NODE_ENV=test ./node_modules/.bin/mocha --config ./test/mocharc.json ./test/testcontainers/*.test.ts", "test:e2e": "playwright test --ui", "test:playwright": "playwright test --trace on --max-failures=1", "check": "npm run tsoa:build && tsc --noEmit", @@ -95,6 +96,8 @@ "prettier-plugin-organize-imports": "^4.1.0", "sinon": "^19.0.2", "supertest": "^7.0.0", + "testcontainers": "^10.13.2", + "ts-node": "^10.9.2", "typescript": "^5.6.3", "undici": "^6.20.1" } diff --git a/test/helpers/cloudagent.ts b/test/helpers/cloudagent.ts index 6af3bb06..1f66e09b 100644 --- a/test/helpers/cloudagent.ts +++ b/test/helpers/cloudagent.ts @@ -6,9 +6,19 @@ import { validCompanyName, validCompanyNumber } from './fixtures.js' import { mockLogger } from './logger.js' const cleanupShared = async function (agent: VeritableCloudagent) { - const connections = await agent.getConnections() - for (const connection of connections) { - await agent.deleteConnection(connection.id) + try { + const connections = await agent.getConnections() // fails here in the after loop the clou + for (const connection of connections) { + await agent.deleteConnection(connection.id) + } + } catch (err) { + console.log(err) + console.log(err.name) + console.log(err.message) + console.log(`all errrors: `) + console.log(err.errors) + + throw new Error(err) } } diff --git a/test/helpers/routeHelper.ts b/test/helpers/routeHelper.ts index aee9232e..126a99ca 100644 --- a/test/helpers/routeHelper.ts +++ b/test/helpers/routeHelper.ts @@ -92,3 +92,17 @@ export const fetchPost = async ( return res } + +export const fetchGet = async (endpoint: string, headers: Record = {}): Promise => { + const token = await getToken() + const res = await fetch(endpoint, { + method: 'GET', + headers: { + ...headers, + authorization: `bearer ${token}`, + 'content-type': 'application/json', + }, + }) + + return res +} diff --git a/test/init.ts b/test/init.ts index dbf27e01..6ef86592 100644 --- a/test/init.ts +++ b/test/init.ts @@ -2,12 +2,25 @@ import { use } from 'chai' import 'reflect-metadata' import chaiJestSnapshot from 'chai-jest-snapshot' +import { StartedTestContainer } from 'testcontainers' +import { bringUpAllContainers } from './testcontainers/testcontainersSetup' +let containers: StartedTestContainer[] before(async function () { + containers = await bringUpAllContainers() + // helper for migrating db use(chaiJestSnapshot) chaiJestSnapshot.resetSnapshotRegistry() }) +// after(async function () { +// await Promise.all( +// containers.map(async function (container) { +// await container.stop({ remove: false }) +// }) +// ) +// }) + beforeEach(function () { chaiJestSnapshot.configureUsingMochaContext(this) }) diff --git a/test/integration/newConnection.test.ts b/test/integration/newConnection.test.ts index f1f58411..39bf0679 100644 --- a/test/integration/newConnection.test.ts +++ b/test/integration/newConnection.test.ts @@ -17,7 +17,7 @@ import { delay } from '../helpers/util.js' const db = container.resolve(Database) -describe('NewConnectionController', () => { +describe.only('NewConnectionController', () => { let server: { app: express.Express; cloudagentEvents: VeritableCloudagentEvents } afterEach(async () => { @@ -27,7 +27,6 @@ describe('NewConnectionController', () => { describe('create invitation (happy path)', function () { let response: Awaited> - beforeEach(async () => { await cleanup() await cleanupCloudagent() @@ -37,14 +36,15 @@ describe('NewConnectionController', () => { email: 'alice@example.com', action: 'submit', }) + console.log(response) }) afterEach(async () => { - await cleanupCloudagent() + await cleanupCloudagent() //errors here server.cloudagentEvents.stop() }) - it('should return success', async () => { + it.only('should return success', async () => { expect(response.status).to.equal(200) }) diff --git a/test/mocharc.json b/test/mocharc.json index fa92123d..433b1bf4 100644 --- a/test/mocharc.json +++ b/test/mocharc.json @@ -1,5 +1,5 @@ { - "timeout": 5000, + "timeout": 1000000, "exit": true, "extension": "ts", "file": ["test/init.ts"], diff --git a/test/testcontainers/settings.test.ts b/test/testcontainers/settings.test.ts new file mode 100644 index 00000000..9852ee24 --- /dev/null +++ b/test/testcontainers/settings.test.ts @@ -0,0 +1,210 @@ +import { expect } from 'chai' +import path from 'path' +import { fileURLToPath } from 'url' + +import { GenericContainer, Network, Wait } from 'testcontainers' +import { fetchGet } from '../helpers/routeHelper.js' + +const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) + +describe('integration tests for settings page', function () { + let aliceVeritableUIPostgres + let aliceVeritableCloudagentPostgres + let smtp4dev + let cloudAgentContainer + let ipfsContainer + let keycloakContainer + let aliceVeritableUIContainer + const __filename = fileURLToPath(import.meta.url) + const __dirname = path.dirname(__filename) + + const keycloakDataPath = path.resolve(__dirname, '../../docker/keycloak') + + console.log('here') + before(async () => { + console.log('before all') + const network = await new Network().start() + keycloakContainer = await new GenericContainer('quay.io/keycloak/keycloak:26.0.5') + .withName('keycloak') + .withExposedPorts({ + container: 8080, + host: 3080, + }) + .withEnvironment({ + KEYCLOAK_ADMIN: 'admin', + KEYCLOAK_ADMIN_PASSWORD: 'admin', + }) + .withBindMounts([{ source: keycloakDataPath, target: '/opt/keycloak/data/import' }]) + .withCommand(['start-dev', '--import-realm']) + .withWaitStrategy(Wait.forLogMessage('Running the server in development mode')) + .withNetwork(network) + .start() + const keycloakPort = keycloakContainer.getMappedPort(8080) + console.log(`Keycloak container started on port ${keycloakPort}`) + + ipfsContainer = await new GenericContainer('ipfs/kubo:release') + .withName('ipfs') + // .withTmpFs({ '/var/lib/ipfs/data': 'rw' }) + .withWaitStrategy(Wait.forLogMessage('Gateway server listening on')) + .withNetwork(network) + .start() + + console.log(`IPFS container started`) + + // change to rel path + aliceVeritableUIPostgres = await new GenericContainer('postgres:17.0-alpine') + .withName('postgres-veritable-ui-alice') + // .withBindMounts([ + // { source: '/var/lib/docker/volumes/postgres-veritable-ui-alice/_data', target: '/var/lib/postgresql/data' }, + // ]) + .withExposedPorts({ + container: 5432, + host: 5432, + }) + .withEnvironment({ POSTGRES_PASSWORD: 'postgres', POSTGRES_USER: 'postgres', POSTGRES_DB: 'veritable-ui' }) + .withNetwork(network) + .withWaitStrategy(Wait.forLogMessage('database system is ready to accept connections')) + .start() + + console.log(`Alice UI postgres container started on port ${aliceVeritableUIPostgres.getMappedPort(5432)}`) + + aliceVeritableCloudagentPostgres = await new GenericContainer('postgres:17.0-alpine') + .withName('postgres-veritable-cloudagent-alice') + // .withBindMounts([ + // { + // source: '/var/lib/docker/volumes/postgres-veritable-cloudagent-alice/_data', + // target: '/var/lib/postgresql/data', + // }, + // ]) + .withEnvironment({ + POSTGRES_PASSWORD: 'postgres', + POSTGRES_USER: 'postgres', + POSTGRES_DB: 'postgres-veritable-cloudagent', + }) + .withNetwork(network) + .withWaitStrategy(Wait.forLogMessage('database system is ready to accept connections')) + .start() + console.log(`Alice cloudagent postgres container started `) + + cloudAgentContainer = await new GenericContainer('digicatapult/veritable-cloudagent') + .withName('veritable-cloudagent-alice') + .withExposedPorts({ + container: 3000, + host: 3100, + }) + .withEnvironment({ + ENDPOINT: 'ws://veritable-cloudagent-alice:5003', + POSTGRES_HOST: 'postgres-veritable-cloudagent-alice', + WALLET_ID: 'alice', + WALLET_KEY: 'alice-key', + LOG_LEVEL: 'debug', + INBOUND_TRANSPORT: '[{"transport": "http", "port": 5002}, {"transport": "ws", "port": 5003}]', + OUTBOUND_TRANSPORT: 'http,ws', + ADMIN_PORT: '3000', + IPFS_ORIGIN: 'http://ipfs:5001', + POSTGRES_PORT: '5432', + POSTGRES_USERNAME: 'postgres', + POSTGRES_PASSWORD: 'postgres', + LABEL: 'veritable-cloudagent', + }) + .withWaitStrategy(Wait.forListeningPorts()) + .withNetwork(network) + .start() + + console.log(`Alice Cloudagent container started on port ${cloudAgentContainer.getMappedPort(3000)}`) + + smtp4dev = await new GenericContainer('rnwood/smtp4dev') + .withName('smtp4dev') + .withExposedPorts({ + container: 80, + host: 5001, // Host port for accessing the web interface + }) + .withExposedPorts({ + container: 25, + host: 2525, // Host port for SMTP connections + }) + .withNetwork(network) + .withWaitStrategy(Wait.forListeningPorts()) + .start() + console.log(`Smtp4dev started on ${smtp4dev.getMappedPort(80)}`) + + const alicebase = await GenericContainer.fromDockerfile('./').withTarget('test').build() + console.log('after build') + aliceVeritableUIContainer = await alicebase + .withName('veritable-ui-alice') + .withLogConsumer((stream) => { + stream.on('data', (line) => console.log(line)) + stream.on('err', (line) => console.error(line)) + stream.on('end', () => console.log('Stream closed')) + }) + .withExposedPorts({ + container: 3000, + host: 3000, + }) + .withEnvironment({ + NODE_ENV: 'production', + LOG_LEVEL: 'debug', + DB_HOST: 'postgres-veritable-ui-alice', + DB_NAME: 'veritable-ui', + DB_USERNAME: 'postgres', + DB_PASSWORD: 'postgres', + DB_PORT: aliceVeritableUIPostgres.getMappedPort(5432).toString(), + COOKIE_SESSION_KEYS: 'secret', + PUBLIC_URL: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3000', + IDP_CLIENT_ID: 'veritable-ui', + IDP_PUBLIC_URL_PREFIX: + process.env.VERITABLE_IDP_PUBLIC_URL_PREFIX || + 'http://localhost:3080/realms/veritable/protocol/openid-connect', + IDP_INTERNAL_URL_PREFIX: 'http://keycloak:8080/realms/veritable/protocol/openid-connect', + CLOUDAGENT_ADMIN_ORIGIN: 'http://veritable-cloudagent-alice:3000', + CLOUDAGENT_ADMIN_WS_ORIGIN: 'ws://veritable-cloudagent-alice:3000', + INVITATION_PIN_SECRET: 'secret', + INVITATION_FROM_COMPANY_NUMBER: '07964699', + ISSUANCE_DID_POLICY: 'EXISTING_OR_NEW', + ISSUANCE_SCHEMA_POLICY: 'EXISTING_OR_NEW', + ISSUANCE_CRED_DEF_POLICY: 'EXISTING_OR_NEW', + SMTP_HOST: 'smtp4dev', + SMTP_PASS: '', + SMTP_PORT: '25', + SMTP_USER: '', + EMAIL_TRANSPORT: 'SMTP_EMAIL', + API_SWAGGER_TITLE: 'Alice', + API_SWAGGER_BG_COLOR: '#ff3131', + COMPANY_HOUSE_API_URL: 'https://api.company-information.service.gov.uk', + DEMO_MODE: 'true', + SMTP_SECURE: 'false', + COMPANY_PROFILE_API_KEY: process.env.VERITABLE_COMPANY_PROFILE_API_KEY || 'API_KEY', + }) + .withCommand([ + 'sh', + '-c', + 'npm i -g pino-colada; node ./node_modules/.bin/knex migrate:latest; npm start | pino-colada', + ]) + .withWaitStrategy(Wait.forListeningPorts()) + .withNetwork(network) + .start() + + const veritableUIPort = aliceVeritableUIContainer.getMappedPort(3000) + console.log(`Veritable UI Alice container started on port ${veritableUIPort}`) + }) + + after(async () => { + await ipfsContainer.stop({ remove: false }) + await aliceVeritableUIPostgres.stop({ remove: false }) + await aliceVeritableCloudagentPostgres.stop({ remove: false }) + await aliceVeritableUIContainer.stop({ remove: false }) + await smtp4dev.stop({ remove: false }) + }) + + it('returns success', async function () { + const baseUrlAlice = process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3000' + console.log('in the actual test') + await delay(3000) + console.log('after delay') + const response = await fetchGet(`${baseUrlAlice}/settings`) + console.log(response) + expect(response.status).to.equal(200) + + console.log('in test') + }) +}) diff --git a/test/testcontainers/testcontainersSetup.ts b/test/testcontainers/testcontainersSetup.ts new file mode 100644 index 00000000..f7e035ee --- /dev/null +++ b/test/testcontainers/testcontainersSetup.ts @@ -0,0 +1,369 @@ +import path from 'path' +import { GenericContainer, Network, StartedNetwork, StartedTestContainer, Wait } from 'testcontainers' +import { fileURLToPath } from 'url' + +interface PostgresPasswordAndUser { + postgresPassword?: string + postgresUser?: string +} + +interface PostgresValuesInterface extends PostgresPasswordAndUser { + postgresDb: string +} +interface ExposedPortsInterface { + containerPort: number + hostPort: number +} + +interface VeritableCloudAgentEnvConfig extends PostgresPasswordAndUser { + endpoint: string + walletId: string + walletKey: string + postgresHost: string + logLevel?: 'debug' | 'info' | 'warn' | 'error' + inboundTransport?: string + outboundTransport?: string + adminPort?: string + ipfsOrigin?: string + postgresPort?: string + label?: string +} + +interface VeritableUIConfig extends PostgresValuesInterface { + dbHost: string + postgresPort: string + idpPublicUrlPrefix: string + cloudagentAdminOrigin: string + cloudagentAdminWsOrigin: string + invitationPinSecret?: string + invitationFromCompanyNumber: string + publicUrl: string + apiSwaggerTitle: string + apiSwaggerBgColor: string + companyProfileApiKey: string + companyHouseApiUrl?: string + idpInternalUrlPrefix?: string + smtpHost?: string + smtpPass?: string + smtpPort?: string + smtpUser?: string + demoMode?: string + smtpSecure?: string + emailTransport?: string + cookieSessionKeys?: string + idpClientId?: string + nodeEnv?: 'production' | 'development' | 'test' + logLevel?: 'debug' | 'info' | 'warn' | 'error' + issuanceDidPolicy?: string + issuanceSchemaPolicy?: string + issuanceCredDefPolicy?: string +} + +export async function bringUpAllContainers() { + let aliceVeritableUIPostgres: StartedTestContainer + let aliceVeritableCloudagentPostgres: StartedTestContainer + let smtp4dev: StartedTestContainer + let aliceCloudAgentContainer: StartedTestContainer + let ipfsContainer: StartedTestContainer + let keycloakContainer: StartedTestContainer + let aliceVeritableUIContainer: StartedTestContainer + const __filename = fileURLToPath(import.meta.url) + const __dirname = path.dirname(__filename) + + const keycloakDataPath = path.resolve(__dirname, '../../docker/keycloak') + const network = await new Network().start() + + // assign containers + keycloakContainer = await composeKeycloakContainer(network, keycloakDataPath) + ipfsContainer = await composeIpfsContainer(network) + smtp4dev = await composeSmtp4dev(network) + + // Alice containers + aliceVeritableUIPostgres = await veritableUIPostgresDbContainer( + network, + 'postgres-veritable-ui-alice', + { containerPort: 5432, hostPort: 5432 }, + { postgresDb: 'veritable-ui' } + ) + aliceVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( + network, + 'postgres-veritable-cloudagent-alice', + { postgresDb: 'postgres-veritable-cloudagent' } + ) + + const aliceCloudagentEnvConfig: VeritableCloudAgentEnvConfig = { + endpoint: 'ws://veritable-cloudagent-alice:5003', + walletId: 'alice', + walletKey: 'alice-key', + postgresHost: 'postgres-veritable-cloudagent-alice', + } + aliceCloudAgentContainer = await cloudagentContainer( + network, + 'veritable-cloudagent-alice', + { + containerPort: 3000, + hostPort: 3100, + }, + aliceCloudagentEnvConfig + ) + + const aliceVeritableUIConfig: VeritableUIConfig = { + dbHost: 'postgres-veritable-ui-alice', + postgresPort: '5432', + idpPublicUrlPrefix: + process.env.VERITABLE_IDP_PUBLIC_URL_PREFIX || 'http://localhost:3080/realms/veritable/protocol/openid-connect', + cloudagentAdminOrigin: 'http://veritable-cloudagent-alice:3000', + cloudagentAdminWsOrigin: 'ws://veritable-cloudagent-alice:3000', + invitationFromCompanyNumber: '07964699', + publicUrl: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3000', + apiSwaggerBgColor: '#ff3131', + apiSwaggerTitle: 'Alice', + companyProfileApiKey: 'https://api.company-information.service.gov.uk', + postgresDb: 'veritable-ui', + } + aliceVeritableUIContainer = await veritableUIContainer(network, aliceVeritableUIConfig) + + return [ + keycloakContainer, + ipfsContainer, + smtp4dev, + aliceVeritableUIPostgres, + aliceVeritableCloudagentPostgres, + aliceCloudAgentContainer, + aliceVeritableUIContainer, + ] +} + +export async function composeKeycloakContainer( + network: StartedNetwork, + keycloakDataPath: string +): Promise { + const keycloakContainer = await new GenericContainer('quay.io/keycloak/keycloak:26.0.5') + .withName('keycloak') + .withExposedPorts({ + container: 8080, + host: 3080, + }) + .withEnvironment({ + KEYCLOAK_ADMIN: 'admin', + KEYCLOAK_ADMIN_PASSWORD: 'admin', + }) + .withBindMounts([{ source: keycloakDataPath, target: '/opt/keycloak/data/import' }]) //this seems necessary + .withCommand(['start-dev', '--import-realm']) + .withWaitStrategy(Wait.forLogMessage('Running the server in development mode')) + .withNetwork(network) + .withReuse() + .start() + return keycloakContainer +} + +export async function composeIpfsContainer(network: StartedNetwork): Promise { + const ipfsContainer = await new GenericContainer('ipfs/kubo:release') + .withName('ipfs') + .withWaitStrategy(Wait.forLogMessage('Gateway server listening on')) + .withNetwork(network) + .withReuse() + .start() + return ipfsContainer +} + +export async function veritableUIPostgresDbContainer( + network: StartedNetwork, + name: string, + exposedPorts: ExposedPortsInterface, + postgresValues: PostgresValuesInterface +) { + const { postgresPassword = 'postgres', postgresUser = 'postgres', postgresDb } = postgresValues + const veritableUIPostgresContainer = await new GenericContainer('postgres:17.0-alpine') + .withName(name) + .withExposedPorts({ + container: exposedPorts.containerPort, + host: exposedPorts.hostPort, + }) + .withEnvironment({ + POSTGRES_PASSWORD: postgresPassword, + POSTGRES_USER: postgresUser, + POSTGRES_DB: postgresDb, + }) + .withNetwork(network) + .withWaitStrategy(Wait.forLogMessage('database system is ready to accept connections')) + .withReuse() + .start() + return veritableUIPostgresContainer +} + +export async function veritableCloudagentPostgresContainer( + network: StartedNetwork, + name: string, + postgresValues: PostgresValuesInterface +) { + const { postgresPassword = 'postgres', postgresUser = 'postgres', postgresDb } = postgresValues + const veritableCloudagentPostgres = await new GenericContainer('postgres:17.0-alpine') + .withName(name) + .withEnvironment({ + POSTGRES_PASSWORD: postgresPassword, + POSTGRES_USER: postgresUser, + POSTGRES_DB: postgresDb, + }) + .withNetwork(network) + .withWaitStrategy(Wait.forLogMessage('database system is ready to accept connections')) + .withReuse() + .start() + return veritableCloudagentPostgres +} + +export async function cloudagentContainer( + network: StartedNetwork, + name: string, + exposedPorts: ExposedPortsInterface, + env: VeritableCloudAgentEnvConfig +) { + const { + endpoint, + walletId, + walletKey, + postgresHost, + postgresPassword = 'postgres', + postgresUser = 'postgres', + logLevel = 'trace', + inboundTransport = '[{"transport": "http", "port": 5002}, {"transport": "ws", "port": 5003}]', + outboundTransport = 'http,ws', + adminPort = '3000', + ipfsOrigin = 'http://ipfs:5001', + postgresPort = '5432', + label = 'veritable-cloudagent', + } = env + const cloudagentContainer = await new GenericContainer('digicatapult/veritable-cloudagent') + .withName(name) + .withExposedPorts({ + container: exposedPorts.containerPort, + host: exposedPorts.hostPort, + }) + .withEnvironment({ + ENDPOINT: endpoint, + POSTGRES_HOST: postgresHost, + WALLET_ID: walletId, + WALLET_KEY: walletKey, + LOG_LEVEL: logLevel, + INBOUND_TRANSPORT: inboundTransport, + OUTBOUND_TRANSPORT: outboundTransport, + ADMIN_PORT: adminPort, + IPFS_ORIGIN: ipfsOrigin, + POSTGRES_PORT: postgresPort, + POSTGRES_USERNAME: postgresUser, + POSTGRES_PASSWORD: postgresPassword, + LABEL: label, + }) + .withWaitStrategy(Wait.forListeningPorts()) + .withNetwork(network) + .withReuse() + .start() + return cloudagentContainer +} + +// would we ever want to change anything about this? +export async function composeSmtp4dev(network: StartedNetwork) { + const smtp4dev = await new GenericContainer('rnwood/smtp4dev') + .withName('smtp4dev') + .withExposedPorts({ + container: 80, + host: 5001, + }) + .withExposedPorts({ + container: 25, + host: 2525, + }) + .withNetwork(network) + .withWaitStrategy(Wait.forListeningPorts()) + .withReuse() + .start() + return smtp4dev +} +export async function veritableUIContainer(network: StartedNetwork, env: VeritableUIConfig) { + const { + dbHost, + postgresPort, + publicUrl, + idpPublicUrlPrefix, + invitationFromCompanyNumber, + cloudagentAdminOrigin, + cloudagentAdminWsOrigin, + apiSwaggerTitle, + apiSwaggerBgColor, + companyProfileApiKey, + postgresDb, + nodeEnv = 'production', + logLevel = 'debug', + postgresUser = 'postgres', + postgresPassword = 'postgres', + cookieSessionKeys = 'secret', + idpClientId = 'veritable-ui', + idpInternalUrlPrefix = 'http://keycloak:8080/realms/veritable/protocol/openid-connect', + invitationPinSecret = 'secret', + issuanceDidPolicy = 'EXISTING_OR_NEW', + issuanceSchemaPolicy = 'EXISTING_OR_NEW', + issuanceCredDefPolicy = 'EXISTING_OR_NEW', + smtpHost = 'smtp4dev', + smtpPass = '', + smtpPort = '25', + smtpUser = '', + emailTransport = 'SMTP_EMAIL', + companyHouseApiUrl = 'https://api.company-information.service.gov.uk', + demoMode = 'true', + smtpSecure = 'false', + } = env + const base = await GenericContainer.fromDockerfile('./').withTarget('test').build() + const veritableUIContainer = await base + .withName('veritable-ui-alice') + .withLogConsumer((stream) => { + stream.on('data', (line) => console.log(line)) + stream.on('err', (line) => console.error(line)) + stream.on('end', () => console.log('Stream closed')) + }) + .withExposedPorts({ + container: 3000, + host: 3000, + }) + .withEnvironment({ + NODE_ENV: nodeEnv, + LOG_LEVEL: logLevel, + DB_HOST: dbHost, + DB_NAME: postgresDb, + DB_USERNAME: postgresUser, + DB_PASSWORD: postgresPassword, + DB_PORT: postgresPort, + COOKIE_SESSION_KEYS: cookieSessionKeys, + PUBLIC_URL: publicUrl, + IDP_CLIENT_ID: idpClientId, + IDP_PUBLIC_URL_PREFIX: idpPublicUrlPrefix, + IDP_INTERNAL_URL_PREFIX: idpInternalUrlPrefix, + CLOUDAGENT_ADMIN_ORIGIN: cloudagentAdminOrigin, + CLOUDAGENT_ADMIN_WS_ORIGIN: cloudagentAdminWsOrigin, + INVITATION_PIN_SECRET: invitationPinSecret, + INVITATION_FROM_COMPANY_NUMBER: invitationFromCompanyNumber, + ISSUANCE_DID_POLICY: issuanceDidPolicy, + ISSUANCE_SCHEMA_POLICY: issuanceSchemaPolicy, + ISSUANCE_CRED_DEF_POLICY: issuanceCredDefPolicy, + SMTP_HOST: smtpHost, + SMTP_PASS: smtpPass, + SMTP_PORT: smtpPort, + SMTP_USER: smtpUser, + EMAIL_TRANSPORT: emailTransport, + API_SWAGGER_TITLE: apiSwaggerTitle, + API_SWAGGER_BG_COLOR: apiSwaggerBgColor, + COMPANY_HOUSE_API_URL: companyHouseApiUrl, + DEMO_MODE: demoMode, + SMTP_SECURE: smtpSecure, + COMPANY_PROFILE_API_KEY: companyProfileApiKey, + }) + .withCommand([ + 'sh', + '-c', + 'npm i -g pino-colada; node ./node_modules/.bin/knex migrate:latest; npm start | pino-colada', + ]) + .withWaitStrategy(Wait.forListeningPorts()) + .withNetwork(network) + .withReuse() + .start() + return veritableUIContainer +} From bdd099867a7567d1cfe4802a12af1c0d39e74cfd Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Mon, 11 Nov 2024 12:02:11 +0000 Subject: [PATCH 02/42] Add after block for cleanp and use lts node instead of current --- Dockerfile | 6 +++--- test/init.ts | 14 +++++++------- test/testcontainers/settings.test.ts | 1 - 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3ec27fc0..0e7b0b88 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.11 -FROM node:current-alpine AS builder +FROM node:lts-alpine AS builder WORKDIR /veritable-ui @@ -14,7 +14,7 @@ COPY . . RUN npm run build # Test stage -FROM node:current-bookworm-slim AS test +FROM node:lts-bookworm-slim AS test WORKDIR /veritable-ui @@ -37,7 +37,7 @@ CMD ["npm", "run", "test:playwright"] # # service -FROM node:current-alpine AS service +FROM node:lts-alpine AS service WORKDIR /veritable-ui diff --git a/test/init.ts b/test/init.ts index 6ef86592..f37aed98 100644 --- a/test/init.ts +++ b/test/init.ts @@ -13,13 +13,13 @@ before(async function () { chaiJestSnapshot.resetSnapshotRegistry() }) -// after(async function () { -// await Promise.all( -// containers.map(async function (container) { -// await container.stop({ remove: false }) -// }) -// ) -// }) +after(async function () { + await Promise.all( + containers.map(async function (container) { + await container.stop({}) + }) + ) +}) beforeEach(function () { chaiJestSnapshot.configureUsingMochaContext(this) diff --git a/test/testcontainers/settings.test.ts b/test/testcontainers/settings.test.ts index 9852ee24..d595f524 100644 --- a/test/testcontainers/settings.test.ts +++ b/test/testcontainers/settings.test.ts @@ -20,7 +20,6 @@ describe('integration tests for settings page', function () { const keycloakDataPath = path.resolve(__dirname, '../../docker/keycloak') - console.log('here') before(async () => { console.log('before all') const network = await new Network().start() From a51b1b7fb7c99d128bbcb8d3123856c2b1c6dd22 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:40:41 +0000 Subject: [PATCH 03/42] bob and charlie --- test/helpers/cloudagent.ts | 4 - test/helpers/db.ts | 32 +++++ test/init.ts | 38 ++++- test/integration/newConnection.test.ts | 5 +- test/testcontainers/testcontainersSetup.ts | 156 +++++++++++++++++---- 5 files changed, 200 insertions(+), 35 deletions(-) diff --git a/test/helpers/cloudagent.ts b/test/helpers/cloudagent.ts index 1f66e09b..334a29d5 100644 --- a/test/helpers/cloudagent.ts +++ b/test/helpers/cloudagent.ts @@ -13,10 +13,6 @@ const cleanupShared = async function (agent: VeritableCloudagent) { } } catch (err) { console.log(err) - console.log(err.name) - console.log(err.message) - console.log(`all errrors: `) - console.log(err.errors) throw new Error(err) } diff --git a/test/helpers/db.ts b/test/helpers/db.ts index 4d638325..775af2c8 100644 --- a/test/helpers/db.ts +++ b/test/helpers/db.ts @@ -1,5 +1,7 @@ import { container } from 'tsyringe' +import knex from 'knex' +import { Env } from '../../src/env/index.js' import Database from '../../src/models/db/index.js' const db = container.resolve(Database) @@ -9,3 +11,33 @@ export const cleanup = async () => { await db.delete('connection', {}) await db.delete('settings', {}) } + +const env = container.resolve(Env) + +const database = knex({ + client: 'pg', + connection: { + host: env.get('DB_HOST'), + database: env.get('DB_NAME'), + user: env.get('DB_USERNAME'), + password: env.get('DB_PASSWORD'), + port: env.get('DB_PORT'), + }, + pool: { + min: 2, + max: 10, + }, + migrations: { + tableName: 'migrations', + directory: 'src/models/db/migrations', + }, +}) + +export async function migrateDatabase() { + try { + await database.migrate.latest() + console.log('Database migrations completed.') + } catch (error) { + console.error('Error running migrations:', error) + } +} diff --git a/test/init.ts b/test/init.ts index f37aed98..037521e9 100644 --- a/test/init.ts +++ b/test/init.ts @@ -3,19 +3,47 @@ import 'reflect-metadata' import chaiJestSnapshot from 'chai-jest-snapshot' import { StartedTestContainer } from 'testcontainers' -import { bringUpAllContainers } from './testcontainers/testcontainersSetup' -let containers: StartedTestContainer[] +import { migrateDatabase } from './helpers/db.js' +import { + bringUpAliceDependenciesContainers, + bringUpBobContainers, + bringUpCharlieContainers, + bringUpSharedContainers, +} from './testcontainers/testcontainersSetup.js' +let sharedContainers: StartedTestContainer[] +let aliceDepsContainers: StartedTestContainer[] +let bobContainers: StartedTestContainer[] +let charlieContainers: StartedTestContainer[] before(async function () { - containers = await bringUpAllContainers() - // helper for migrating db + sharedContainers = await bringUpSharedContainers() + aliceDepsContainers = await bringUpAliceDependenciesContainers() + bobContainers = await bringUpBobContainers() + charlieContainers = await bringUpCharlieContainers() + + await migrateDatabase() use(chaiJestSnapshot) chaiJestSnapshot.resetSnapshotRegistry() }) after(async function () { await Promise.all( - containers.map(async function (container) { + aliceDepsContainers.map(async function (container) { + await container.stop({}) + }) + ) + await Promise.all( + bobContainers.map(async function (container) { + await container.stop({}) + }) + ) + await Promise.all( + charlieContainers.map(async function (container) { + await container.stop({}) + }) + ) + await Promise.all( + sharedContainers.map(async function (container) { await container.stop({}) }) ) diff --git a/test/integration/newConnection.test.ts b/test/integration/newConnection.test.ts index 39bf0679..8b41124b 100644 --- a/test/integration/newConnection.test.ts +++ b/test/integration/newConnection.test.ts @@ -17,7 +17,7 @@ import { delay } from '../helpers/util.js' const db = container.resolve(Database) -describe.only('NewConnectionController', () => { +describe('NewConnectionController', () => { let server: { app: express.Express; cloudagentEvents: VeritableCloudagentEvents } afterEach(async () => { @@ -44,7 +44,7 @@ describe.only('NewConnectionController', () => { server.cloudagentEvents.stop() }) - it.only('should return success', async () => { + it('should return success', async () => { expect(response.status).to.equal(200) }) @@ -67,6 +67,7 @@ describe.only('NewConnectionController', () => { const context: { invite: string } = { invite: '' } withBobCloudAgentInvite(context) + console.log(context.invite) beforeEach(async () => { await cleanup() diff --git a/test/testcontainers/testcontainersSetup.ts b/test/testcontainers/testcontainersSetup.ts index f7e035ee..47a428d6 100644 --- a/test/testcontainers/testcontainersSetup.ts +++ b/test/testcontainers/testcontainersSetup.ts @@ -30,6 +30,7 @@ interface VeritableCloudAgentEnvConfig extends PostgresPasswordAndUser { } interface VeritableUIConfig extends PostgresValuesInterface { + containerName: string dbHost: string postgresPort: string idpPublicUrlPrefix: string @@ -58,25 +59,48 @@ interface VeritableUIConfig extends PostgresValuesInterface { issuanceSchemaPolicy?: string issuanceCredDefPolicy?: string } +const network = await new Network().start() -export async function bringUpAllContainers() { - let aliceVeritableUIPostgres: StartedTestContainer - let aliceVeritableCloudagentPostgres: StartedTestContainer - let smtp4dev: StartedTestContainer - let aliceCloudAgentContainer: StartedTestContainer +export async function bringUpSharedContainers() { let ipfsContainer: StartedTestContainer let keycloakContainer: StartedTestContainer - let aliceVeritableUIContainer: StartedTestContainer + let smtp4dev: StartedTestContainer const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const keycloakDataPath = path.resolve(__dirname, '../../docker/keycloak') - const network = await new Network().start() - // assign containers keycloakContainer = await composeKeycloakContainer(network, keycloakDataPath) ipfsContainer = await composeIpfsContainer(network) smtp4dev = await composeSmtp4dev(network) + return [keycloakContainer, ipfsContainer, smtp4dev] +} +export async function bringUpAliceUIContainer() { + let aliceVeritableUIContainer: StartedTestContainer + + const aliceVeritableUIConfig: VeritableUIConfig = { + containerName: 'veritable-ui-alice', + dbHost: 'postgres-veritable-ui-alice', + postgresPort: '5432', + idpPublicUrlPrefix: + process.env.VERITABLE_IDP_PUBLIC_URL_PREFIX || 'http://localhost:3080/realms/veritable/protocol/openid-connect', + cloudagentAdminOrigin: 'http://veritable-cloudagent-alice:3000', + cloudagentAdminWsOrigin: 'ws://veritable-cloudagent-alice:3000', + invitationFromCompanyNumber: '07964699', + publicUrl: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3000', + apiSwaggerBgColor: '#ff3131', + apiSwaggerTitle: 'Alice', + companyProfileApiKey: 'https://api.company-information.service.gov.uk', + postgresDb: 'veritable-ui', + } + aliceVeritableUIContainer = await veritableUIContainer(network, aliceVeritableUIConfig) + return [aliceVeritableUIContainer] +} + +export async function bringUpAliceDependenciesContainers() { + let aliceVeritableUIPostgres: StartedTestContainer + let aliceVeritableCloudagentPostgres: StartedTestContainer + let aliceCloudAgentContainer: StartedTestContainer // Alice containers aliceVeritableUIPostgres = await veritableUIPostgresDbContainer( @@ -107,30 +131,113 @@ export async function bringUpAllContainers() { aliceCloudagentEnvConfig ) - const aliceVeritableUIConfig: VeritableUIConfig = { - dbHost: 'postgres-veritable-ui-alice', + return [aliceVeritableUIPostgres, aliceVeritableCloudagentPostgres, aliceCloudAgentContainer] +} + +export async function bringUpBobContainers() { + let bobVeritableUIPostgres: StartedTestContainer + let bobVeritableCloudagentPostgres: StartedTestContainer + let bobCloudAgentContainer: StartedTestContainer + let bobVeritableUIContainer: StartedTestContainer + + bobVeritableUIPostgres = await veritableUIPostgresDbContainer( + network, + 'postgres-veritable-ui-bob', + { containerPort: 5432, hostPort: 5433 }, + { postgresDb: 'veritable-ui' } + ) + bobVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( + network, + 'postgres-veritable-cloudagent-bob', + { postgresDb: 'postgres-veritable-cloudagent' } + ) + const aliceCloudagentEnvConfig: VeritableCloudAgentEnvConfig = { + endpoint: 'ws://veritable-cloudagent-bob:5003', + walletId: 'bob', + walletKey: 'bob-key', + postgresHost: 'postgres-veritable-cloudagent-bob', + } + bobCloudAgentContainer = await cloudagentContainer( + network, + 'veritable-cloudagent-bob', + { + containerPort: 3000, + hostPort: 3101, + }, + aliceCloudagentEnvConfig + ) + const bobVeritableUIConfig: VeritableUIConfig = { + containerName: 'veritable-ui-bob', + dbHost: 'postgres-veritable-ui-bob', postgresPort: '5432', idpPublicUrlPrefix: process.env.VERITABLE_IDP_PUBLIC_URL_PREFIX || 'http://localhost:3080/realms/veritable/protocol/openid-connect', - cloudagentAdminOrigin: 'http://veritable-cloudagent-alice:3000', - cloudagentAdminWsOrigin: 'ws://veritable-cloudagent-alice:3000', - invitationFromCompanyNumber: '07964699', - publicUrl: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3000', + cloudagentAdminOrigin: 'http://veritable-cloudagent-bob:3000', + cloudagentAdminWsOrigin: 'ws://veritable-cloudagent-bob:3000', + invitationFromCompanyNumber: '04659351', + publicUrl: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3001', apiSwaggerBgColor: '#ff3131', - apiSwaggerTitle: 'Alice', + apiSwaggerTitle: 'Bob', companyProfileApiKey: 'https://api.company-information.service.gov.uk', postgresDb: 'veritable-ui', } - aliceVeritableUIContainer = await veritableUIContainer(network, aliceVeritableUIConfig) + bobVeritableUIContainer = await veritableUIContainer(network, bobVeritableUIConfig) + return [bobVeritableUIPostgres, bobVeritableCloudagentPostgres, bobCloudAgentContainer, bobVeritableUIContainer] +} + +export async function bringUpCharlieContainers() { + let charlieVeritableUIPostgres: StartedTestContainer + let charlieVeritableCloudagentPostgres: StartedTestContainer + let charlieCloudAgentContainer: StartedTestContainer + let charlieVeritableUIContainer: StartedTestContainer + charlieVeritableUIPostgres = await veritableUIPostgresDbContainer( + network, + 'postgres-veritable-ui-charlie', + { containerPort: 5432, hostPort: 5434 }, + { postgresDb: 'veritable-ui' } + ) + charlieVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( + network, + 'postgres-veritable-cloudagent-charlie', + { postgresDb: 'postgres-veritable-cloudagent' } + ) + const charlieCloudagentEnvConfig: VeritableCloudAgentEnvConfig = { + endpoint: 'ws://veritable-cloudagent-charlie:5003', + walletId: 'charlie', + walletKey: 'charlie-key', + postgresHost: 'postgres-veritable-cloudagent-charlie', + } + charlieCloudAgentContainer = await cloudagentContainer( + network, + 'veritable-cloudagent-charlie', + { + containerPort: 3000, + hostPort: 3102, + }, + charlieCloudagentEnvConfig + ) + const charlieVeritableUIConfig: VeritableUIConfig = { + containerName: 'veritable-ui-charlie', + dbHost: 'postgres-veritable-ui-charlie', + postgresPort: '5432', + idpPublicUrlPrefix: + process.env.VERITABLE_IDP_PUBLIC_URL_PREFIX || 'http://localhost:3080/realms/veritable/protocol/openid-connect', + cloudagentAdminOrigin: 'http://veritable-cloudagent-charlie:3000', + cloudagentAdminWsOrigin: 'ws://veritable-cloudagent-charlie:3000', + invitationFromCompanyNumber: '10016023', + publicUrl: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3002', + apiSwaggerBgColor: '#ffbd59', + apiSwaggerTitle: 'Charlie', + companyProfileApiKey: 'https://api.company-information.service.gov.uk', + postgresDb: 'veritable-ui', + } + charlieVeritableUIContainer = await veritableUIContainer(network, charlieVeritableUIConfig) return [ - keycloakContainer, - ipfsContainer, - smtp4dev, - aliceVeritableUIPostgres, - aliceVeritableCloudagentPostgres, - aliceCloudAgentContainer, - aliceVeritableUIContainer, + charlieVeritableUIPostgres, + charlieVeritableCloudagentPostgres, + charlieCloudAgentContainer, + charlieVeritableUIContainer, ] } @@ -281,6 +388,7 @@ export async function composeSmtp4dev(network: StartedNetwork) { } export async function veritableUIContainer(network: StartedNetwork, env: VeritableUIConfig) { const { + containerName, dbHost, postgresPort, publicUrl, @@ -314,7 +422,7 @@ export async function veritableUIContainer(network: StartedNetwork, env: Veritab } = env const base = await GenericContainer.fromDockerfile('./').withTarget('test').build() const veritableUIContainer = await base - .withName('veritable-ui-alice') + .withName(containerName) .withLogConsumer((stream) => { stream.on('data', (line) => console.log(line)) stream.on('err', (line) => console.error(line)) From ded208717ffd3695deb06edb62ea85f2bbdd0381 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:15:28 +0000 Subject: [PATCH 04/42] passing integr and e2e --- Dockerfile | 8 +- playwright.config.ts | 1 + test/globalSetup.ts | 31 +++ test/init.ts | 40 ++-- test/integration/pinVerification.test.ts | 2 +- test/integration/query.test.ts | 2 +- test/integration/settings.test.ts | 34 +++- test/testcontainers/settings.test.ts | 209 --------------------- test/testcontainers/testcontainersSetup.ts | 14 +- 9 files changed, 94 insertions(+), 247 deletions(-) create mode 100644 test/globalSetup.ts delete mode 100644 test/testcontainers/settings.test.ts diff --git a/Dockerfile b/Dockerfile index 0e7b0b88..16da64c3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.11 -FROM node:lts-alpine AS builder +FROM node:current-alpine AS builder WORKDIR /veritable-ui @@ -14,7 +14,7 @@ COPY . . RUN npm run build # Test stage -FROM node:lts-bookworm-slim AS test +FROM node:current-bookworm-slim AS test WORKDIR /veritable-ui @@ -36,8 +36,8 @@ RUN npx playwright install --with-deps CMD ["npm", "run", "test:playwright"] -# # service -FROM node:lts-alpine AS service +# service +FROM node:current-alpine AS service WORKDIR /veritable-ui diff --git a/playwright.config.ts b/playwright.config.ts index 64e4697e..b0fec600 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -4,6 +4,7 @@ import { defineConfig, devices } from '@playwright/test' * See https://playwright.dev/docs/test-configuration. */ export default defineConfig({ + globalSetup: './test/globalSetup.ts', testDir: './test/e2e', /* Run tests in files in parallel */ fullyParallel: false, diff --git a/test/globalSetup.ts b/test/globalSetup.ts new file mode 100644 index 00000000..a87e9878 --- /dev/null +++ b/test/globalSetup.ts @@ -0,0 +1,31 @@ +import 'reflect-metadata' +import { StartedTestContainer } from 'testcontainers' +import { + bringUpAliceDependenciesContainers, + bringUpAliceUIContainer, + bringUpBobContainers, + bringUpCharlieContainers, + bringUpSharedContainers, +} from './testcontainers/testcontainersSetup' + +let sharedContainers: StartedTestContainer[] +let aliceDepsContainers: StartedTestContainer[] +let bobContainers: StartedTestContainer[] +let charlieContainers: StartedTestContainer[] +let aliceUIContainer: StartedTestContainer[] + +async function globalSetup() { + // const __filename = fileURLToPath(import.meta.url) + // const __dirname = path.dirname(__filename) + + // const envFilePath = path.resolve(__dirname, '../../docker/e2e.env') + // loadEnv({ path: envFilePath }) + + sharedContainers = await bringUpSharedContainers() + aliceDepsContainers = await bringUpAliceDependenciesContainers() + aliceUIContainer = await bringUpAliceUIContainer() + bobContainers = await bringUpBobContainers() + charlieContainers = await bringUpCharlieContainers() +} + +export default globalSetup diff --git a/test/init.ts b/test/init.ts index 037521e9..a65103e2 100644 --- a/test/init.ts +++ b/test/init.ts @@ -27,26 +27,26 @@ before(async function () { }) after(async function () { - await Promise.all( - aliceDepsContainers.map(async function (container) { - await container.stop({}) - }) - ) - await Promise.all( - bobContainers.map(async function (container) { - await container.stop({}) - }) - ) - await Promise.all( - charlieContainers.map(async function (container) { - await container.stop({}) - }) - ) - await Promise.all( - sharedContainers.map(async function (container) { - await container.stop({}) - }) - ) + // await Promise.all( + // aliceDepsContainers.map(async function (container) { + // await container.stop({ remove: false }) + // }) + // ) + // await Promise.all( + // bobContainers.map(async function (container) { + // await container.stop({ remove: false }) + // }) + // ) + // await Promise.all( + // charlieContainers.map(async function (container) { + // await container.stop({ remove: false }) + // }) + // ) + // await Promise.all( + // sharedContainers.map(async function (container) { + // await container.stop({ remove: false }) + // }) + // ) }) beforeEach(function () { diff --git a/test/integration/pinVerification.test.ts b/test/integration/pinVerification.test.ts index be77eb05..672dc4b8 100644 --- a/test/integration/pinVerification.test.ts +++ b/test/integration/pinVerification.test.ts @@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe } from 'mocha' import { container } from 'tsyringe' import Database from '../../src/models/db/index.js' -import VeritableCloudagent from '../../src/models/veritableCloudagent.js' +import VeritableCloudagent from '../../src/models/veritableCloudagent/index.js' import createHttpServer from '../../src/server.js' import VeritableCloudagentEvents from '../../src/services/veritableCloudagentEvents.js' import { cleanupCloudagent } from '../helpers/cloudagent.js' diff --git a/test/integration/query.test.ts b/test/integration/query.test.ts index 11797ed4..e4ee3791 100644 --- a/test/integration/query.test.ts +++ b/test/integration/query.test.ts @@ -4,7 +4,7 @@ import { afterEach, beforeEach, describe } from 'mocha' import { container } from 'tsyringe' import Database from '../../src/models/db/index.js' -import VeritableCloudagent from '../../src/models/veritableCloudagent.js' +import VeritableCloudagent from '../../src/models/veritableCloudagent/index.js' import { cleanupCloudagent } from '../helpers/cloudagent.js' import { withCompanyHouseMock } from '../helpers/companyHouse.js' import { cleanup } from '../helpers/db.js' diff --git a/test/integration/settings.test.ts b/test/integration/settings.test.ts index 631b19db..a1052d42 100644 --- a/test/integration/settings.test.ts +++ b/test/integration/settings.test.ts @@ -2,16 +2,26 @@ import { expect } from 'chai' import express from 'express' import { container } from 'tsyringe' import Database from '../../src/models/db/index.js' +import VeritableCloudagent from '../../src/models/veritableCloudagent/index.js' import createHttpServer from '../../src/server.js' import VeritableCloudagentEvents from '../../src/services/veritableCloudagentEvents.js' +import { withCompanyHouseMock } from '../helpers/companyHouse.js' import { cleanup } from '../helpers/db.js' import { get, post } from '../helpers/routeHelper.js' import { withAdminEmail } from '../helpers/settings.js' describe('integration tests for settings page', function () { const db = container.resolve(Database) - let server: { app: express.Express; cloudagentEvents: VeritableCloudagentEvents } - + type Context = { + app: express.Express + cloudagentEvents: VeritableCloudagentEvents + remoteDatabase: Database + remoteCloudagent: VeritableCloudagent + remoteConnectionId: string + localConnectionId: string + response: Awaited> + } + const context: Context = {} as Context const testBody = { company_name: 'Test Company Name', companies_house_number: '0000000', @@ -27,21 +37,25 @@ describe('integration tests for settings page', function () { admin_email: 'madmin@testmail.com', action: 'updateSettings', } - + withCompanyHouseMock() beforeEach(async () => { await cleanup() await withAdminEmail(db) - server = await createHttpServer() + const server = await createHttpServer() + Object.assign(context, { + ...server, + }) }) afterEach(async () => { - server.cloudagentEvents.stop() + context.cloudagentEvents.stop() await cleanup() }) describe('happy path', function () { it('returns success', async function () { - const response = await get(server.app, '/settings', {}) + const response = await get(context.app, '/settings', {}) + console.log(response) expect(response.status).to.equal(200) expect(response.text.length).to.be.greaterThan(0) }) @@ -49,7 +63,7 @@ describe('integration tests for settings page', function () { const setting = await db.get('settings') expect(setting.length).to.equal(1) expect(setting[0].setting_value).to.contain('admin@testmail.com') - const response = await post(server.app, '/settings/?edit=true', testEditBody) + const response = await post(context.app, '/settings/?edit=true', testEditBody) const setting1 = await db.get('settings') expect(setting1.length).to.equal(1) expect(setting1[0].setting_value).to.contain('madmin@testmail.com') @@ -60,15 +74,15 @@ describe('integration tests for settings page', function () { describe('sad path', function () { it('returns fail on edit mode being false', async function () { - const response = await post(server.app, '/settings/?edit=false', testEditBody) + const response = await post(context.app, '/settings/?edit=false', testEditBody) expect(response.status).to.equal(501) }) it('returns fail on missing property and false edit mode', async function () { - const response = await post(server.app, '/settings/?edit=false', testBody) + const response = await post(context.app, '/settings/?edit=false', testBody) expect(response.status).to.equal(501) }) it('returns fail on missing property even if edit is turned on', async function () { - const response = await post(server.app, '/settings/?edit=true', testBody) + const response = await post(context.app, '/settings/?edit=true', testBody) expect(response.status).to.equal(501) }) }) diff --git a/test/testcontainers/settings.test.ts b/test/testcontainers/settings.test.ts deleted file mode 100644 index d595f524..00000000 --- a/test/testcontainers/settings.test.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { expect } from 'chai' -import path from 'path' -import { fileURLToPath } from 'url' - -import { GenericContainer, Network, Wait } from 'testcontainers' -import { fetchGet } from '../helpers/routeHelper.js' - -const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)) - -describe('integration tests for settings page', function () { - let aliceVeritableUIPostgres - let aliceVeritableCloudagentPostgres - let smtp4dev - let cloudAgentContainer - let ipfsContainer - let keycloakContainer - let aliceVeritableUIContainer - const __filename = fileURLToPath(import.meta.url) - const __dirname = path.dirname(__filename) - - const keycloakDataPath = path.resolve(__dirname, '../../docker/keycloak') - - before(async () => { - console.log('before all') - const network = await new Network().start() - keycloakContainer = await new GenericContainer('quay.io/keycloak/keycloak:26.0.5') - .withName('keycloak') - .withExposedPorts({ - container: 8080, - host: 3080, - }) - .withEnvironment({ - KEYCLOAK_ADMIN: 'admin', - KEYCLOAK_ADMIN_PASSWORD: 'admin', - }) - .withBindMounts([{ source: keycloakDataPath, target: '/opt/keycloak/data/import' }]) - .withCommand(['start-dev', '--import-realm']) - .withWaitStrategy(Wait.forLogMessage('Running the server in development mode')) - .withNetwork(network) - .start() - const keycloakPort = keycloakContainer.getMappedPort(8080) - console.log(`Keycloak container started on port ${keycloakPort}`) - - ipfsContainer = await new GenericContainer('ipfs/kubo:release') - .withName('ipfs') - // .withTmpFs({ '/var/lib/ipfs/data': 'rw' }) - .withWaitStrategy(Wait.forLogMessage('Gateway server listening on')) - .withNetwork(network) - .start() - - console.log(`IPFS container started`) - - // change to rel path - aliceVeritableUIPostgres = await new GenericContainer('postgres:17.0-alpine') - .withName('postgres-veritable-ui-alice') - // .withBindMounts([ - // { source: '/var/lib/docker/volumes/postgres-veritable-ui-alice/_data', target: '/var/lib/postgresql/data' }, - // ]) - .withExposedPorts({ - container: 5432, - host: 5432, - }) - .withEnvironment({ POSTGRES_PASSWORD: 'postgres', POSTGRES_USER: 'postgres', POSTGRES_DB: 'veritable-ui' }) - .withNetwork(network) - .withWaitStrategy(Wait.forLogMessage('database system is ready to accept connections')) - .start() - - console.log(`Alice UI postgres container started on port ${aliceVeritableUIPostgres.getMappedPort(5432)}`) - - aliceVeritableCloudagentPostgres = await new GenericContainer('postgres:17.0-alpine') - .withName('postgres-veritable-cloudagent-alice') - // .withBindMounts([ - // { - // source: '/var/lib/docker/volumes/postgres-veritable-cloudagent-alice/_data', - // target: '/var/lib/postgresql/data', - // }, - // ]) - .withEnvironment({ - POSTGRES_PASSWORD: 'postgres', - POSTGRES_USER: 'postgres', - POSTGRES_DB: 'postgres-veritable-cloudagent', - }) - .withNetwork(network) - .withWaitStrategy(Wait.forLogMessage('database system is ready to accept connections')) - .start() - console.log(`Alice cloudagent postgres container started `) - - cloudAgentContainer = await new GenericContainer('digicatapult/veritable-cloudagent') - .withName('veritable-cloudagent-alice') - .withExposedPorts({ - container: 3000, - host: 3100, - }) - .withEnvironment({ - ENDPOINT: 'ws://veritable-cloudagent-alice:5003', - POSTGRES_HOST: 'postgres-veritable-cloudagent-alice', - WALLET_ID: 'alice', - WALLET_KEY: 'alice-key', - LOG_LEVEL: 'debug', - INBOUND_TRANSPORT: '[{"transport": "http", "port": 5002}, {"transport": "ws", "port": 5003}]', - OUTBOUND_TRANSPORT: 'http,ws', - ADMIN_PORT: '3000', - IPFS_ORIGIN: 'http://ipfs:5001', - POSTGRES_PORT: '5432', - POSTGRES_USERNAME: 'postgres', - POSTGRES_PASSWORD: 'postgres', - LABEL: 'veritable-cloudagent', - }) - .withWaitStrategy(Wait.forListeningPorts()) - .withNetwork(network) - .start() - - console.log(`Alice Cloudagent container started on port ${cloudAgentContainer.getMappedPort(3000)}`) - - smtp4dev = await new GenericContainer('rnwood/smtp4dev') - .withName('smtp4dev') - .withExposedPorts({ - container: 80, - host: 5001, // Host port for accessing the web interface - }) - .withExposedPorts({ - container: 25, - host: 2525, // Host port for SMTP connections - }) - .withNetwork(network) - .withWaitStrategy(Wait.forListeningPorts()) - .start() - console.log(`Smtp4dev started on ${smtp4dev.getMappedPort(80)}`) - - const alicebase = await GenericContainer.fromDockerfile('./').withTarget('test').build() - console.log('after build') - aliceVeritableUIContainer = await alicebase - .withName('veritable-ui-alice') - .withLogConsumer((stream) => { - stream.on('data', (line) => console.log(line)) - stream.on('err', (line) => console.error(line)) - stream.on('end', () => console.log('Stream closed')) - }) - .withExposedPorts({ - container: 3000, - host: 3000, - }) - .withEnvironment({ - NODE_ENV: 'production', - LOG_LEVEL: 'debug', - DB_HOST: 'postgres-veritable-ui-alice', - DB_NAME: 'veritable-ui', - DB_USERNAME: 'postgres', - DB_PASSWORD: 'postgres', - DB_PORT: aliceVeritableUIPostgres.getMappedPort(5432).toString(), - COOKIE_SESSION_KEYS: 'secret', - PUBLIC_URL: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3000', - IDP_CLIENT_ID: 'veritable-ui', - IDP_PUBLIC_URL_PREFIX: - process.env.VERITABLE_IDP_PUBLIC_URL_PREFIX || - 'http://localhost:3080/realms/veritable/protocol/openid-connect', - IDP_INTERNAL_URL_PREFIX: 'http://keycloak:8080/realms/veritable/protocol/openid-connect', - CLOUDAGENT_ADMIN_ORIGIN: 'http://veritable-cloudagent-alice:3000', - CLOUDAGENT_ADMIN_WS_ORIGIN: 'ws://veritable-cloudagent-alice:3000', - INVITATION_PIN_SECRET: 'secret', - INVITATION_FROM_COMPANY_NUMBER: '07964699', - ISSUANCE_DID_POLICY: 'EXISTING_OR_NEW', - ISSUANCE_SCHEMA_POLICY: 'EXISTING_OR_NEW', - ISSUANCE_CRED_DEF_POLICY: 'EXISTING_OR_NEW', - SMTP_HOST: 'smtp4dev', - SMTP_PASS: '', - SMTP_PORT: '25', - SMTP_USER: '', - EMAIL_TRANSPORT: 'SMTP_EMAIL', - API_SWAGGER_TITLE: 'Alice', - API_SWAGGER_BG_COLOR: '#ff3131', - COMPANY_HOUSE_API_URL: 'https://api.company-information.service.gov.uk', - DEMO_MODE: 'true', - SMTP_SECURE: 'false', - COMPANY_PROFILE_API_KEY: process.env.VERITABLE_COMPANY_PROFILE_API_KEY || 'API_KEY', - }) - .withCommand([ - 'sh', - '-c', - 'npm i -g pino-colada; node ./node_modules/.bin/knex migrate:latest; npm start | pino-colada', - ]) - .withWaitStrategy(Wait.forListeningPorts()) - .withNetwork(network) - .start() - - const veritableUIPort = aliceVeritableUIContainer.getMappedPort(3000) - console.log(`Veritable UI Alice container started on port ${veritableUIPort}`) - }) - - after(async () => { - await ipfsContainer.stop({ remove: false }) - await aliceVeritableUIPostgres.stop({ remove: false }) - await aliceVeritableCloudagentPostgres.stop({ remove: false }) - await aliceVeritableUIContainer.stop({ remove: false }) - await smtp4dev.stop({ remove: false }) - }) - - it('returns success', async function () { - const baseUrlAlice = process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3000' - console.log('in the actual test') - await delay(3000) - console.log('after delay') - const response = await fetchGet(`${baseUrlAlice}/settings`) - console.log(response) - expect(response.status).to.equal(200) - - console.log('in test') - }) -}) diff --git a/test/testcontainers/testcontainersSetup.ts b/test/testcontainers/testcontainersSetup.ts index 47a428d6..4d3507b7 100644 --- a/test/testcontainers/testcontainersSetup.ts +++ b/test/testcontainers/testcontainersSetup.ts @@ -32,6 +32,8 @@ interface VeritableCloudAgentEnvConfig extends PostgresPasswordAndUser { interface VeritableUIConfig extends PostgresValuesInterface { containerName: string dbHost: string + hostPort: number + containerPort: number postgresPort: string idpPublicUrlPrefix: string cloudagentAdminOrigin: string @@ -81,6 +83,8 @@ export async function bringUpAliceUIContainer() { const aliceVeritableUIConfig: VeritableUIConfig = { containerName: 'veritable-ui-alice', dbHost: 'postgres-veritable-ui-alice', + hostPort: 3000, + containerPort: 3000, postgresPort: '5432', idpPublicUrlPrefix: process.env.VERITABLE_IDP_PUBLIC_URL_PREFIX || 'http://localhost:3080/realms/veritable/protocol/openid-connect', @@ -168,6 +172,8 @@ export async function bringUpBobContainers() { ) const bobVeritableUIConfig: VeritableUIConfig = { containerName: 'veritable-ui-bob', + hostPort: 3001, + containerPort: 3000, dbHost: 'postgres-veritable-ui-bob', postgresPort: '5432', idpPublicUrlPrefix: @@ -219,6 +225,8 @@ export async function bringUpCharlieContainers() { ) const charlieVeritableUIConfig: VeritableUIConfig = { containerName: 'veritable-ui-charlie', + hostPort: 3002, + containerPort: 3000, dbHost: 'postgres-veritable-ui-charlie', postgresPort: '5432', idpPublicUrlPrefix: @@ -390,6 +398,8 @@ export async function veritableUIContainer(network: StartedNetwork, env: Veritab const { containerName, dbHost, + containerPort, + hostPort, postgresPort, publicUrl, idpPublicUrlPrefix, @@ -429,8 +439,8 @@ export async function veritableUIContainer(network: StartedNetwork, env: Veritab stream.on('end', () => console.log('Stream closed')) }) .withExposedPorts({ - container: 3000, - host: 3000, + container: containerPort, + host: hostPort, }) .withEnvironment({ NODE_ENV: nodeEnv, From 4a4ccbcfa7e2456a86658cdcfd2c437d5f825ae2 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:29:47 +0000 Subject: [PATCH 05/42] accidentaly removed, putting back --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 16da64c3..b5ec2906 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1.11 -FROM node:current-alpine AS builder +FROM node:lts-alpine AS builder WORKDIR /veritable-ui @@ -14,7 +14,7 @@ COPY . . RUN npm run build # Test stage -FROM node:current-bookworm-slim AS test +FROM node:lts-bookworm-slim AS test WORKDIR /veritable-ui @@ -37,7 +37,7 @@ CMD ["npm", "run", "test:playwright"] # service -FROM node:current-alpine AS service +FROM node:lts-alpine AS service WORKDIR /veritable-ui From 0bc96e86aadba443127d89e1bbaf5bc0c919c7e4 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:57:04 +0000 Subject: [PATCH 06/42] test workflow --- .github/workflows/test.yml | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee509a0c..931b14b7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -94,17 +94,22 @@ jobs: uses: docker/setup-buildx-action@v3 with: buildkitd-flags: '--debug' - - uses: actions/checkout@v4 - - name: Build e2e containers - uses: docker/bake-action@v5 - with: - builder: ${{ steps.buildx.outputs.name }} - files: ./docker-compose.e2e.yml + # - uses: actions/checkout@v4 + # - name: Build e2e containers + # uses: docker/bake-action@v5 + # with: + # builder: ${{ steps.buildx.outputs.name }} + # files: ./docker-compose.e2e.yml - name: Run e2e tests env: VERITABLE_COMPANY_PROFILE_API_KEY: ${{ secrets.COMPANIES_HOUSE_API }} VERITABLE_E2E_OUT_DIR: ${{ runner.temp }} - run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull + VERITABLE_ALICE_PUBLIC_URL: http://veritable-ui-alice:3000 + VERITABLE_BOB_PUBLIC_URL: http://veritable-ui-bob:3000 + VERITABLE_CHARLIE_PUBLIC_URL: http://veritable-ui-charlie:3000 + VERITABLE_IDP_PUBLIC_URL_PREFIX: http://keycloak:8080/realms/veritable/protocol/openid-connect + run: npm run test:playwright + # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull - uses: actions/upload-artifact@v4 if: always() with: From f655c48b7e0ea91361af3a571c4acd18d4c63fe9 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:09:09 +0000 Subject: [PATCH 07/42] testing test workflow --- .github/workflows/test.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 931b14b7..866eeec8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -73,27 +73,27 @@ jobs: run: npm run tsoa:build - name: touch env run: touch .env - - name: Setup dependencies - run: docker compose -f docker-compose.yml up -d - - name: Sleep - uses: kibertoad/wait-action@1.0.1 - with: - time: '30s' - - name: Run database migrations - run: npm run db:migrate - env: - NODE_ENV: test + # - name: Setup dependencies + # run: docker compose -f docker-compose.yml up -d + # - name: Sleep + # uses: kibertoad/wait-action@1.0.1 + # with: + # time: '30s' + # - name: Run database migrations + # run: npm run db:migrate + # env: + # NODE_ENV: test - name: Run tests run: npm run ${{ matrix.command }} e2e-tests: timeout-minutes: 60 runs-on: ubuntu-latest steps: - - name: Setup Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - with: - buildkitd-flags: '--debug' + # - name: Setup Docker Buildx + # id: buildx + # uses: docker/setup-buildx-action@v3 + # with: + # buildkitd-flags: '--debug' # - uses: actions/checkout@v4 # - name: Build e2e containers # uses: docker/bake-action@v5 @@ -108,7 +108,7 @@ jobs: VERITABLE_BOB_PUBLIC_URL: http://veritable-ui-bob:3000 VERITABLE_CHARLIE_PUBLIC_URL: http://veritable-ui-charlie:3000 VERITABLE_IDP_PUBLIC_URL_PREFIX: http://keycloak:8080/realms/veritable/protocol/openid-connect - run: npm run test:playwright + run: npm run tests:playwright # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull - uses: actions/upload-artifact@v4 if: always() From 142b238d60dd00b78dbaaff7de26448c13b90535 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:11:34 +0000 Subject: [PATCH 08/42] checkout --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 866eeec8..a83ce9be 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -94,7 +94,7 @@ jobs: # uses: docker/setup-buildx-action@v3 # with: # buildkitd-flags: '--debug' - # - uses: actions/checkout@v4 + - uses: actions/checkout@v4 # - name: Build e2e containers # uses: docker/bake-action@v5 # with: From 344c143548d33cc2aec5c8c85b0cdaaa21e02eac Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:12:26 +0000 Subject: [PATCH 09/42] typo --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a83ce9be..fe011906 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,7 +108,7 @@ jobs: VERITABLE_BOB_PUBLIC_URL: http://veritable-ui-bob:3000 VERITABLE_CHARLIE_PUBLIC_URL: http://veritable-ui-charlie:3000 VERITABLE_IDP_PUBLIC_URL_PREFIX: http://keycloak:8080/realms/veritable/protocol/openid-connect - run: npm run tests:playwright + run: npm run test:playwright # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull - uses: actions/upload-artifact@v4 if: always() From 25293c85f947fc516c0744e04a3c2ac2be247b04 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:14:17 +0000 Subject: [PATCH 10/42] install playwright --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fe011906..50bd9bf1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -100,6 +100,8 @@ jobs: # with: # builder: ${{ steps.buildx.outputs.name }} # files: ./docker-compose.e2e.yml + - name: Install Playwright browsers + run: npx playwright install - name: Run e2e tests env: VERITABLE_COMPANY_PROFILE_API_KEY: ${{ secrets.COMPANIES_HOUSE_API }} From 2b0a838bce8cc8127c9914f0e2de1263e2a33884 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:20:37 +0000 Subject: [PATCH 11/42] saving playwright as a devDep --- .github/workflows/test.yml | 4 ++-- package-lock.json | 1 + package.json | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 50bd9bf1..4a6bad0a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -100,8 +100,8 @@ jobs: # with: # builder: ${{ steps.buildx.outputs.name }} # files: ./docker-compose.e2e.yml - - name: Install Playwright browsers - run: npx playwright install + - name: Install Dependencies + run: npm ci - name: Run e2e tests env: VERITABLE_COMPANY_PROFILE_API_KEY: ${{ secrets.COMPANIES_HOUSE_API }} diff --git a/package-lock.json b/package-lock.json index ec6f9504..d998d73a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -66,6 +66,7 @@ "globals": "^15.11.0", "mocha": "^10.8.2", "pino-colada": "^2.2.2", + "playwright": "^1.48.2", "playwright-ctrf-json-reporter": "^0.0.18", "prettier": "^3.3.3", "prettier-plugin-organize-imports": "^4.1.0", diff --git a/package.json b/package.json index 1be61dd8..92737322 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "globals": "^15.11.0", "mocha": "^10.8.2", "pino-colada": "^2.2.2", + "playwright": "^1.48.2", "playwright-ctrf-json-reporter": "^0.0.18", "prettier": "^3.3.3", "prettier-plugin-organize-imports": "^4.1.0", From f378fda713407af55939c0b0c2c5dc493beea1ad Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 15:41:14 +0000 Subject: [PATCH 12/42] test workflow --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4a6bad0a..797e95ab 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -110,7 +110,8 @@ jobs: VERITABLE_BOB_PUBLIC_URL: http://veritable-ui-bob:3000 VERITABLE_CHARLIE_PUBLIC_URL: http://veritable-ui-charlie:3000 VERITABLE_IDP_PUBLIC_URL_PREFIX: http://keycloak:8080/realms/veritable/protocol/openid-connect - run: npm run test:playwright + run: | + DEBUG=testcontainers* npm run test:playwright || exit 0 # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull - uses: actions/upload-artifact@v4 if: always() From c3bccc268c50a3783e7afe82782809f926b1d755 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:05:12 +0000 Subject: [PATCH 13/42] no debug --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 797e95ab..be04e9ab 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -111,7 +111,7 @@ jobs: VERITABLE_CHARLIE_PUBLIC_URL: http://veritable-ui-charlie:3000 VERITABLE_IDP_PUBLIC_URL_PREFIX: http://keycloak:8080/realms/veritable/protocol/openid-connect run: | - DEBUG=testcontainers* npm run test:playwright || exit 0 + npm run test:playwright || exit 0 # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull - uses: actions/upload-artifact@v4 if: always() From f1570270f3ab980b471086fe0b535f742213a46e Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:06:25 +0000 Subject: [PATCH 14/42] test --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index be04e9ab..832def3d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -111,7 +111,7 @@ jobs: VERITABLE_CHARLIE_PUBLIC_URL: http://veritable-ui-charlie:3000 VERITABLE_IDP_PUBLIC_URL_PREFIX: http://keycloak:8080/realms/veritable/protocol/openid-connect run: | - npm run test:playwright || exit 0 + npm run test:playwright || exit 1 # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull - uses: actions/upload-artifact@v4 if: always() From 86777d2adbe3dffed7d8cec52585519afa6b7005 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:13:06 +0000 Subject: [PATCH 15/42] debug on --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 832def3d..f8fd1668 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -111,7 +111,7 @@ jobs: VERITABLE_CHARLIE_PUBLIC_URL: http://veritable-ui-charlie:3000 VERITABLE_IDP_PUBLIC_URL_PREFIX: http://keycloak:8080/realms/veritable/protocol/openid-connect run: | - npm run test:playwright || exit 1 + DEBUG=testcontainers* npm run test:playwright || exit 1 # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull - uses: actions/upload-artifact@v4 if: always() From 1897f8c8cd19c90613450499128098934a92b7e2 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:44:22 +0000 Subject: [PATCH 16/42] playwright report path --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f8fd1668..3877f36c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -117,7 +117,7 @@ jobs: if: always() with: name: playwright-report - path: ${{ runner.temp }}/playwright-report/ + path: ./playwright-report retention-days: 90 - name: Publish CTRF Test Summary Results run: npx github-actions-ctrf ${{ runner.temp }}/playwright-report/ctrf-report.json From e7a349881741bf2d05068a51c6b5392aaa23c516 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 12 Nov 2024 16:58:03 +0000 Subject: [PATCH 17/42] adding browsers --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3877f36c..1fab01a8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -102,6 +102,8 @@ jobs: # files: ./docker-compose.e2e.yml - name: Install Dependencies run: npm ci + - name: Install Playwright Browsers + run: npx playwright install - name: Run e2e tests env: VERITABLE_COMPANY_PROFILE_API_KEY: ${{ secrets.COMPANIES_HOUSE_API }} From a3a3caf1d80e872791515ff11d4ff53b809d7540 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:49:01 +0000 Subject: [PATCH 18/42] testing sht --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1fab01a8..d5486ff6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -89,6 +89,9 @@ jobs: timeout-minutes: 60 runs-on: ubuntu-latest steps: + - uses: actions/setup-node@v4 + with: + node-version: 20.x # - name: Setup Docker Buildx # id: buildx # uses: docker/setup-buildx-action@v3 From b35ec31646cdfab7b32dd4cef917775f7084346e Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:11:29 +0000 Subject: [PATCH 19/42] wrong envars --- test/testcontainers/testcontainersSetup.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/testcontainers/testcontainersSetup.ts b/test/testcontainers/testcontainersSetup.ts index 4d3507b7..a6fee92c 100644 --- a/test/testcontainers/testcontainersSetup.ts +++ b/test/testcontainers/testcontainersSetup.ts @@ -181,7 +181,7 @@ export async function bringUpBobContainers() { cloudagentAdminOrigin: 'http://veritable-cloudagent-bob:3000', cloudagentAdminWsOrigin: 'ws://veritable-cloudagent-bob:3000', invitationFromCompanyNumber: '04659351', - publicUrl: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3001', + publicUrl: process.env.VERITABLE_BOB_PUBLIC_URL || 'http://localhost:3001', apiSwaggerBgColor: '#ff3131', apiSwaggerTitle: 'Bob', companyProfileApiKey: 'https://api.company-information.service.gov.uk', @@ -234,7 +234,7 @@ export async function bringUpCharlieContainers() { cloudagentAdminOrigin: 'http://veritable-cloudagent-charlie:3000', cloudagentAdminWsOrigin: 'ws://veritable-cloudagent-charlie:3000', invitationFromCompanyNumber: '10016023', - publicUrl: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3002', + publicUrl: process.env.VERITABLE_CHARLIE_PUBLIC_URL || 'http://localhost:3002', apiSwaggerBgColor: '#ffbd59', apiSwaggerTitle: 'Charlie', companyProfileApiKey: 'https://api.company-information.service.gov.uk', @@ -411,7 +411,7 @@ export async function veritableUIContainer(network: StartedNetwork, env: Veritab companyProfileApiKey, postgresDb, nodeEnv = 'production', - logLevel = 'debug', + logLevel = 'trace', postgresUser = 'postgres', postgresPassword = 'postgres', cookieSessionKeys = 'secret', From a42fa99d27a85dd84fa272e5f9ea3811a5838a3c Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:55:44 +0000 Subject: [PATCH 20/42] chromium disabled --- playwright.config.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index b0fec600..676ec2d9 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -30,10 +30,10 @@ export default defineConfig({ /* Configure projects for major browsers */ projects: [ - { - name: 'chromium', - use: { ...devices['Desktop Chrome'] }, - }, + // { + // name: 'chromium', + // use: { ...devices['Desktop Chrome'] }, + // }, { name: 'firefox', use: { ...devices['Desktop Firefox'] }, From 31613825a9a7c22def41759a92eb66b354218db9 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 13:43:14 +0000 Subject: [PATCH 21/42] testing sth --- .github/workflows/test.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d5486ff6..8e68346b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -111,10 +111,6 @@ jobs: env: VERITABLE_COMPANY_PROFILE_API_KEY: ${{ secrets.COMPANIES_HOUSE_API }} VERITABLE_E2E_OUT_DIR: ${{ runner.temp }} - VERITABLE_ALICE_PUBLIC_URL: http://veritable-ui-alice:3000 - VERITABLE_BOB_PUBLIC_URL: http://veritable-ui-bob:3000 - VERITABLE_CHARLIE_PUBLIC_URL: http://veritable-ui-charlie:3000 - VERITABLE_IDP_PUBLIC_URL_PREFIX: http://keycloak:8080/realms/veritable/protocol/openid-connect run: | DEBUG=testcontainers* npm run test:playwright || exit 1 # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull From 0bd3d886dd465073de65da5432be1f28aa2c3f65 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:34:44 +0000 Subject: [PATCH 22/42] node versioin --- .github/workflows/test.yml | 4 ++-- playwright.config.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8e68346b..a4bdafad 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x - name: Cache Node.js modules uses: actions/cache@v4 with: @@ -58,7 +58,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x - name: Cache Node.js modules uses: actions/cache@v4 with: diff --git a/playwright.config.ts b/playwright.config.ts index 676ec2d9..b0fec600 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -30,10 +30,10 @@ export default defineConfig({ /* Configure projects for major browsers */ projects: [ - // { - // name: 'chromium', - // use: { ...devices['Desktop Chrome'] }, - // }, + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, { name: 'firefox', use: { ...devices['Desktop Firefox'] }, From 2436dcac610e191c59b33be04cf83b088eb82fb5 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:49:35 +0000 Subject: [PATCH 23/42] sth --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a4bdafad..957642a5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -58,7 +58,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 22.x + node-version: 20.x - name: Cache Node.js modules uses: actions/cache@v4 with: From 84ac94e40c22538ac28ca93442203755784d4afe Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:51:33 +0000 Subject: [PATCH 24/42] trying node v 22 again --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 957642a5..666b82aa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -58,7 +58,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x - name: Cache Node.js modules uses: actions/cache@v4 with: @@ -91,7 +91,7 @@ jobs: steps: - uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x # - name: Setup Docker Buildx # id: buildx # uses: docker/setup-buildx-action@v3 From 36c7d626d4559ceb7a2925a4097db8696dab1e17 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:09:31 +0000 Subject: [PATCH 25/42] revert test.yml --- .github/workflows/test.yml | 28 +++++++++++++++++++++++----- package-lock.json | 7 +++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 73897f88..666b82aa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,5 @@ -name: Test (NPM) +name: Lint and Test + on: push: branches-ignore: ['main'] @@ -135,7 +136,24 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} build-docker: - uses: digicatapult/shared-workflows/.github/workflows/build-docker.yml@main - permissions: - packages: write - contents: write + name: 'Build docker image' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: all + - name: Setup Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + with: + buildkitd-flags: '--debug' + - name: Build image + uses: docker/build-push-action@v6 + with: + builder: ${{ steps.buildx.outputs.name }} + context: . + file: ./Dockerfile + platforms: linux/amd64, linux/arm64 + push: false diff --git a/package-lock.json b/package-lock.json index 40ea92b7..27b21113 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6458,6 +6458,13 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, "node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", From c2b8fc6ce6a1fd6ca319d5edb8de81f912c2538c Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:19:56 +0000 Subject: [PATCH 26/42] bigger timeouts --- playwright.config.ts | 2 +- test/e2e/connection-alice-to-bob.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index b0fec600..d94e6d29 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -25,7 +25,7 @@ export default defineConfig({ trace: 'on-first-retry', }, expect: { - timeout: 10 * 1000, + timeout: 100 * 1000, }, /* Configure projects for major browsers */ diff --git a/test/e2e/connection-alice-to-bob.spec.ts b/test/e2e/connection-alice-to-bob.spec.ts index a3dda91a..d15a315b 100644 --- a/test/e2e/connection-alice-to-bob.spec.ts +++ b/test/e2e/connection-alice-to-bob.spec.ts @@ -32,7 +32,7 @@ test.describe('Connection from Alice to Bob', () => { }) // End-to-end process: Alice registers, invites Bob, Bob submits invite & pin, Alice submits pin test('Connection from Alice to Bob', async () => { - test.setTimeout(100000) + test.setTimeout(1000000) await test.step('Alice invites Bob to connect', async () => { await page.goto(`${baseUrlAlice}`) From 2b8792b9f930d6ee7988bb88e93aba8e57144de4 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:31:06 +0000 Subject: [PATCH 27/42] lint --- test/globalSetup.ts | 23 ++------ test/helpers/cloudagent.ts | 12 ++--- test/helpers/db.ts | 3 +- test/init.ts | 14 ++--- test/integration/newConnection.test.ts | 2 - test/integration/settings.test.ts | 1 - test/testcontainers/testcontainersSetup.ts | 63 ++++++++-------------- 7 files changed, 37 insertions(+), 81 deletions(-) diff --git a/test/globalSetup.ts b/test/globalSetup.ts index a87e9878..200e20df 100644 --- a/test/globalSetup.ts +++ b/test/globalSetup.ts @@ -1,5 +1,4 @@ import 'reflect-metadata' -import { StartedTestContainer } from 'testcontainers' import { bringUpAliceDependenciesContainers, bringUpAliceUIContainer, @@ -8,24 +7,12 @@ import { bringUpSharedContainers, } from './testcontainers/testcontainersSetup' -let sharedContainers: StartedTestContainer[] -let aliceDepsContainers: StartedTestContainer[] -let bobContainers: StartedTestContainer[] -let charlieContainers: StartedTestContainer[] -let aliceUIContainer: StartedTestContainer[] - async function globalSetup() { - // const __filename = fileURLToPath(import.meta.url) - // const __dirname = path.dirname(__filename) - - // const envFilePath = path.resolve(__dirname, '../../docker/e2e.env') - // loadEnv({ path: envFilePath }) - - sharedContainers = await bringUpSharedContainers() - aliceDepsContainers = await bringUpAliceDependenciesContainers() - aliceUIContainer = await bringUpAliceUIContainer() - bobContainers = await bringUpBobContainers() - charlieContainers = await bringUpCharlieContainers() + await bringUpSharedContainers() + await bringUpAliceDependenciesContainers() + await bringUpAliceUIContainer() + await bringUpBobContainers() + await bringUpCharlieContainers() } export default globalSetup diff --git a/test/helpers/cloudagent.ts b/test/helpers/cloudagent.ts index 334a29d5..6af3bb06 100644 --- a/test/helpers/cloudagent.ts +++ b/test/helpers/cloudagent.ts @@ -6,15 +6,9 @@ import { validCompanyName, validCompanyNumber } from './fixtures.js' import { mockLogger } from './logger.js' const cleanupShared = async function (agent: VeritableCloudagent) { - try { - const connections = await agent.getConnections() // fails here in the after loop the clou - for (const connection of connections) { - await agent.deleteConnection(connection.id) - } - } catch (err) { - console.log(err) - - throw new Error(err) + const connections = await agent.getConnections() + for (const connection of connections) { + await agent.deleteConnection(connection.id) } } diff --git a/test/helpers/db.ts b/test/helpers/db.ts index 775af2c8..e2642392 100644 --- a/test/helpers/db.ts +++ b/test/helpers/db.ts @@ -36,8 +36,7 @@ const database = knex({ export async function migrateDatabase() { try { await database.migrate.latest() - console.log('Database migrations completed.') } catch (error) { - console.error('Error running migrations:', error) + throw new Error(`Unknown error in db migratiion ${error}`) } } diff --git a/test/init.ts b/test/init.ts index a65103e2..766170a2 100644 --- a/test/init.ts +++ b/test/init.ts @@ -2,7 +2,6 @@ import { use } from 'chai' import 'reflect-metadata' import chaiJestSnapshot from 'chai-jest-snapshot' -import { StartedTestContainer } from 'testcontainers' import { migrateDatabase } from './helpers/db.js' import { bringUpAliceDependenciesContainers, @@ -10,22 +9,19 @@ import { bringUpCharlieContainers, bringUpSharedContainers, } from './testcontainers/testcontainersSetup.js' -let sharedContainers: StartedTestContainer[] -let aliceDepsContainers: StartedTestContainer[] -let bobContainers: StartedTestContainer[] -let charlieContainers: StartedTestContainer[] before(async function () { - sharedContainers = await bringUpSharedContainers() - aliceDepsContainers = await bringUpAliceDependenciesContainers() - bobContainers = await bringUpBobContainers() - charlieContainers = await bringUpCharlieContainers() + await bringUpSharedContainers() + await bringUpAliceDependenciesContainers() + await bringUpBobContainers() + await bringUpCharlieContainers() await migrateDatabase() use(chaiJestSnapshot) chaiJestSnapshot.resetSnapshotRegistry() }) +// do we want to keep this for debugging? after(async function () { // await Promise.all( // aliceDepsContainers.map(async function (container) { diff --git a/test/integration/newConnection.test.ts b/test/integration/newConnection.test.ts index 8b41124b..c4d9090a 100644 --- a/test/integration/newConnection.test.ts +++ b/test/integration/newConnection.test.ts @@ -36,7 +36,6 @@ describe('NewConnectionController', () => { email: 'alice@example.com', action: 'submit', }) - console.log(response) }) afterEach(async () => { @@ -67,7 +66,6 @@ describe('NewConnectionController', () => { const context: { invite: string } = { invite: '' } withBobCloudAgentInvite(context) - console.log(context.invite) beforeEach(async () => { await cleanup() diff --git a/test/integration/settings.test.ts b/test/integration/settings.test.ts index a1052d42..9af07efa 100644 --- a/test/integration/settings.test.ts +++ b/test/integration/settings.test.ts @@ -55,7 +55,6 @@ describe('integration tests for settings page', function () { describe('happy path', function () { it('returns success', async function () { const response = await get(context.app, '/settings', {}) - console.log(response) expect(response.status).to.equal(200) expect(response.text.length).to.be.greaterThan(0) }) diff --git a/test/testcontainers/testcontainersSetup.ts b/test/testcontainers/testcontainersSetup.ts index a6fee92c..054acf8c 100644 --- a/test/testcontainers/testcontainersSetup.ts +++ b/test/testcontainers/testcontainersSetup.ts @@ -64,22 +64,17 @@ interface VeritableUIConfig extends PostgresValuesInterface { const network = await new Network().start() export async function bringUpSharedContainers() { - let ipfsContainer: StartedTestContainer - let keycloakContainer: StartedTestContainer - let smtp4dev: StartedTestContainer const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) const keycloakDataPath = path.resolve(__dirname, '../../docker/keycloak') - keycloakContainer = await composeKeycloakContainer(network, keycloakDataPath) - ipfsContainer = await composeIpfsContainer(network) - smtp4dev = await composeSmtp4dev(network) + const keycloakContainer = await composeKeycloakContainer(network, keycloakDataPath) + const ipfsContainer = await composeIpfsContainer(network) + const smtp4dev = await composeSmtp4dev(network) return [keycloakContainer, ipfsContainer, smtp4dev] } export async function bringUpAliceUIContainer() { - let aliceVeritableUIContainer: StartedTestContainer - const aliceVeritableUIConfig: VeritableUIConfig = { containerName: 'veritable-ui-alice', dbHost: 'postgres-veritable-ui-alice', @@ -97,23 +92,19 @@ export async function bringUpAliceUIContainer() { companyProfileApiKey: 'https://api.company-information.service.gov.uk', postgresDb: 'veritable-ui', } - aliceVeritableUIContainer = await veritableUIContainer(network, aliceVeritableUIConfig) + const aliceVeritableUIContainer = await veritableUIContainer(network, aliceVeritableUIConfig) return [aliceVeritableUIContainer] } +// Dependencies for Alice, but not her UI container export async function bringUpAliceDependenciesContainers() { - let aliceVeritableUIPostgres: StartedTestContainer - let aliceVeritableCloudagentPostgres: StartedTestContainer - let aliceCloudAgentContainer: StartedTestContainer - - // Alice containers - aliceVeritableUIPostgres = await veritableUIPostgresDbContainer( + const aliceVeritableUIPostgres = await veritableUIPostgresDbContainer( network, 'postgres-veritable-ui-alice', { containerPort: 5432, hostPort: 5432 }, { postgresDb: 'veritable-ui' } ) - aliceVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( + const aliceVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( network, 'postgres-veritable-cloudagent-alice', { postgresDb: 'postgres-veritable-cloudagent' } @@ -125,7 +116,7 @@ export async function bringUpAliceDependenciesContainers() { walletKey: 'alice-key', postgresHost: 'postgres-veritable-cloudagent-alice', } - aliceCloudAgentContainer = await cloudagentContainer( + const aliceCloudAgentContainer = await cloudagentContainer( network, 'veritable-cloudagent-alice', { @@ -139,18 +130,13 @@ export async function bringUpAliceDependenciesContainers() { } export async function bringUpBobContainers() { - let bobVeritableUIPostgres: StartedTestContainer - let bobVeritableCloudagentPostgres: StartedTestContainer - let bobCloudAgentContainer: StartedTestContainer - let bobVeritableUIContainer: StartedTestContainer - - bobVeritableUIPostgres = await veritableUIPostgresDbContainer( + const bobVeritableUIPostgres = await veritableUIPostgresDbContainer( network, 'postgres-veritable-ui-bob', { containerPort: 5432, hostPort: 5433 }, { postgresDb: 'veritable-ui' } ) - bobVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( + const bobVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( network, 'postgres-veritable-cloudagent-bob', { postgresDb: 'postgres-veritable-cloudagent' } @@ -161,7 +147,7 @@ export async function bringUpBobContainers() { walletKey: 'bob-key', postgresHost: 'postgres-veritable-cloudagent-bob', } - bobCloudAgentContainer = await cloudagentContainer( + const bobCloudAgentContainer = await cloudagentContainer( network, 'veritable-cloudagent-bob', { @@ -187,23 +173,18 @@ export async function bringUpBobContainers() { companyProfileApiKey: 'https://api.company-information.service.gov.uk', postgresDb: 'veritable-ui', } - bobVeritableUIContainer = await veritableUIContainer(network, bobVeritableUIConfig) + const bobVeritableUIContainer = await veritableUIContainer(network, bobVeritableUIConfig) return [bobVeritableUIPostgres, bobVeritableCloudagentPostgres, bobCloudAgentContainer, bobVeritableUIContainer] } export async function bringUpCharlieContainers() { - let charlieVeritableUIPostgres: StartedTestContainer - let charlieVeritableCloudagentPostgres: StartedTestContainer - let charlieCloudAgentContainer: StartedTestContainer - let charlieVeritableUIContainer: StartedTestContainer - - charlieVeritableUIPostgres = await veritableUIPostgresDbContainer( + const charlieVeritableUIPostgres = await veritableUIPostgresDbContainer( network, 'postgres-veritable-ui-charlie', { containerPort: 5432, hostPort: 5434 }, { postgresDb: 'veritable-ui' } ) - charlieVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( + const charlieVeritableCloudagentPostgres = await veritableCloudagentPostgresContainer( network, 'postgres-veritable-cloudagent-charlie', { postgresDb: 'postgres-veritable-cloudagent' } @@ -214,7 +195,7 @@ export async function bringUpCharlieContainers() { walletKey: 'charlie-key', postgresHost: 'postgres-veritable-cloudagent-charlie', } - charlieCloudAgentContainer = await cloudagentContainer( + const charlieCloudAgentContainer = await cloudagentContainer( network, 'veritable-cloudagent-charlie', { @@ -240,7 +221,7 @@ export async function bringUpCharlieContainers() { companyProfileApiKey: 'https://api.company-information.service.gov.uk', postgresDb: 'veritable-ui', } - charlieVeritableUIContainer = await veritableUIContainer(network, charlieVeritableUIConfig) + const charlieVeritableUIContainer = await veritableUIContainer(network, charlieVeritableUIConfig) return [ charlieVeritableUIPostgres, charlieVeritableCloudagentPostgres, @@ -431,13 +412,15 @@ export async function veritableUIContainer(network: StartedNetwork, env: Veritab smtpSecure = 'false', } = env const base = await GenericContainer.fromDockerfile('./').withTarget('test').build() + + // Commented out is for logs from containers const veritableUIContainer = await base .withName(containerName) - .withLogConsumer((stream) => { - stream.on('data', (line) => console.log(line)) - stream.on('err', (line) => console.error(line)) - stream.on('end', () => console.log('Stream closed')) - }) + // .withLogConsumer((stream) => { + // stream.on('data', (line) => console.log(line)) + // stream.on('err', (line) => console.error(line)) + // stream.on('end', () => console.log('Stream closed')) + // }) .withExposedPorts({ container: containerPort, host: hostPort, From d7a22a908553ba665fad5aceb976a3b758f721e3 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:32:11 +0000 Subject: [PATCH 28/42] depcheck --- package-lock.json | 144 ---------------------------------------------- package.json | 1 - 2 files changed, 145 deletions(-) diff --git a/package-lock.json b/package-lock.json index 27b21113..cf52bcd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,7 +73,6 @@ "sinon": "^19.0.2", "supertest": "^7.0.0", "testcontainers": "^10.13.2", - "ts-node": "^10.9.2", "typescript": "^5.6.3", "undici": "^6.20.1" }, @@ -308,28 +307,6 @@ "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==", "dev": true }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, "node_modules/@digicatapult/tsoa-oauth-express": { "version": "0.1.69", "resolved": "https://registry.npmjs.org/@digicatapult/tsoa-oauth-express/-/tsoa-oauth-express-0.1.69.tgz", @@ -1917,30 +1894,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, "node_modules/@tsoa/cli": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/@tsoa/cli/-/cli-6.5.1.tgz", @@ -2829,18 +2782,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2970,12 +2911,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, "node_modules/argon2": { "version": "0.41.1", "resolved": "https://registry.npmjs.org/argon2/-/argon2-0.41.1.tgz", @@ -4017,12 +3952,6 @@ "node": ">= 14" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "license": "MIT", @@ -6653,12 +6582,6 @@ "node": ">=12" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, "node_modules/media-typer": { "version": "0.3.0", "license": "MIT", @@ -9242,58 +9165,6 @@ "node": ">=14.13.1" } }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, "node_modules/tslib": { "version": "2.6.2", "license": "0BSD" @@ -9443,12 +9314,6 @@ "node": ">= 0.4.0" } }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, "node_modules/validator": { "version": "13.12.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz", @@ -9607,15 +9472,6 @@ "node": ">=10" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 1ab6b103..a93f4032 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,6 @@ "sinon": "^19.0.2", "supertest": "^7.0.0", "testcontainers": "^10.13.2", - "ts-node": "^10.9.2", "typescript": "^5.6.3", "undici": "^6.20.1" } From 9fcf51be0c65569e178cda35a5ee1782382f4ef3 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 16:49:45 +0000 Subject: [PATCH 29/42] api key --- playwright.config.ts | 2 +- test/e2e/connection-alice-to-bob.spec.ts | 2 +- test/testcontainers/testcontainersSetup.ts | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/playwright.config.ts b/playwright.config.ts index d94e6d29..b0fec600 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -25,7 +25,7 @@ export default defineConfig({ trace: 'on-first-retry', }, expect: { - timeout: 100 * 1000, + timeout: 10 * 1000, }, /* Configure projects for major browsers */ diff --git a/test/e2e/connection-alice-to-bob.spec.ts b/test/e2e/connection-alice-to-bob.spec.ts index d15a315b..a3dda91a 100644 --- a/test/e2e/connection-alice-to-bob.spec.ts +++ b/test/e2e/connection-alice-to-bob.spec.ts @@ -32,7 +32,7 @@ test.describe('Connection from Alice to Bob', () => { }) // End-to-end process: Alice registers, invites Bob, Bob submits invite & pin, Alice submits pin test('Connection from Alice to Bob', async () => { - test.setTimeout(1000000) + test.setTimeout(100000) await test.step('Alice invites Bob to connect', async () => { await page.goto(`${baseUrlAlice}`) diff --git a/test/testcontainers/testcontainersSetup.ts b/test/testcontainers/testcontainersSetup.ts index 054acf8c..9e3a0a19 100644 --- a/test/testcontainers/testcontainersSetup.ts +++ b/test/testcontainers/testcontainersSetup.ts @@ -89,7 +89,7 @@ export async function bringUpAliceUIContainer() { publicUrl: process.env.VERITABLE_ALICE_PUBLIC_URL || 'http://localhost:3000', apiSwaggerBgColor: '#ff3131', apiSwaggerTitle: 'Alice', - companyProfileApiKey: 'https://api.company-information.service.gov.uk', + companyProfileApiKey: process.env.VERITABLE_COMPANY_PROFILE_API_KEY || 'API_KEY', postgresDb: 'veritable-ui', } const aliceVeritableUIContainer = await veritableUIContainer(network, aliceVeritableUIConfig) @@ -170,7 +170,7 @@ export async function bringUpBobContainers() { publicUrl: process.env.VERITABLE_BOB_PUBLIC_URL || 'http://localhost:3001', apiSwaggerBgColor: '#ff3131', apiSwaggerTitle: 'Bob', - companyProfileApiKey: 'https://api.company-information.service.gov.uk', + companyProfileApiKey: process.env.VERITABLE_COMPANY_PROFILE_API_KEY || 'API_KEY', postgresDb: 'veritable-ui', } const bobVeritableUIContainer = await veritableUIContainer(network, bobVeritableUIConfig) @@ -218,7 +218,7 @@ export async function bringUpCharlieContainers() { publicUrl: process.env.VERITABLE_CHARLIE_PUBLIC_URL || 'http://localhost:3002', apiSwaggerBgColor: '#ffbd59', apiSwaggerTitle: 'Charlie', - companyProfileApiKey: 'https://api.company-information.service.gov.uk', + companyProfileApiKey: process.env.VERITABLE_COMPANY_PROFILE_API_KEY || 'API_KEY', postgresDb: 'veritable-ui', } const charlieVeritableUIContainer = await veritableUIContainer(network, charlieVeritableUIConfig) From 4bbc3e378dcc7ccd8954dfba3483d00e87bbdb96 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Wed, 13 Nov 2024 17:07:24 +0000 Subject: [PATCH 30/42] missing deps --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 666b82aa..cb0be216 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -105,6 +105,8 @@ jobs: # files: ./docker-compose.e2e.yml - name: Install Dependencies run: npm ci + - name: Install Playwright dependencies + run: npx playwright install-deps - name: Install Playwright Browsers run: npx playwright install - name: Run e2e tests From 0df26c4d86601b49a5d31ce62b4646c2482c70c4 Mon Sep 17 00:00:00 2001 From: "dc-autobot[bot]" <181364585+dc-autobot[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:05:05 +0000 Subject: [PATCH 31/42] Updating version to 0.15.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf52bcd5..f766bf31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "veritable-ui", - "version": "0.14.15", + "version": "0.15.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "veritable-ui", - "version": "0.14.15", + "version": "0.15.0", "license": "Apache-2.0", "dependencies": { "@digicatapult/tsoa-oauth-express": "^0.1.69", diff --git a/package.json b/package.json index a93f4032..deef3d47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "veritable-ui", - "version": "0.14.15", + "version": "0.15.0", "description": "UI for Veritable", "main": "src/index.ts", "type": "module", From 2ebad328ecd3789c2c790a935fc07dcfcc06a648 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:53:53 +0000 Subject: [PATCH 32/42] test workflow --- .github/workflows/test.yml | 179 +++++-------------------------------- 1 file changed, 23 insertions(+), 156 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cb0be216..135966e9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,161 +1,28 @@ -name: Lint and Test - +name: Test (NPM) on: push: branches-ignore: ['main'] jobs: - repo_ids: - runs-on: ubuntu-latest - outputs: - repo_name: ${{ steps.repo_ids.outputs.REPO_NAME }} - org_name: ${{ steps.repo_ids.outputs.ORG_NAME }} - steps: - - name: Checkout - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - name: Get repository identifiers - id: repo_ids - run: | - REPO_NAME=$(echo "${{ github.event.repository.name }}" | tr '[:upper:]' '[:lower:]') - ORG_NAME=$(echo "${{ github.event.repository.owner.name }}" | tr '[:upper:]' '[:lower:]') - echo "REPO_NAME=$REPO_NAME" >> $GITHUB_OUTPUT - echo "ORG_NAME=$ORG_NAME" >> $GITHUB_OUTPUT - - static-checks: - name: Run Static Analysis Checks - strategy: - fail-fast: false - matrix: - command: [lint, depcheck, xss-scan, check] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 22.x - - name: Cache Node.js modules - uses: actions/cache@v4 - with: - path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS - key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.OS }}-node- - ${{ runner.OS }}- - - name: Install Packages - run: npm ci - - name: Lint - run: npm run ${{ matrix.command }} - - tests: - name: Run tests - strategy: - fail-fast: false - matrix: - command: ['test:unit', 'test:integration'] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 - with: - node-version: 22.x - - name: Cache Node.js modules - uses: actions/cache@v4 - with: - path: ~/.npm # npm cache files are stored in `~/.npm` on Linux/macOS - key: ${{ runner.OS }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.OS }}-node- - ${{ runner.OS }}- - - name: Install Packages - run: npm ci - - name: Build tsoa - run: npm run tsoa:build - - name: touch env - run: touch .env - # - name: Setup dependencies - # run: docker compose -f docker-compose.yml up -d - # - name: Sleep - # uses: kibertoad/wait-action@1.0.1 - # with: - # time: '30s' - # - name: Run database migrations - # run: npm run db:migrate - # env: - # NODE_ENV: test - - name: Run tests - run: npm run ${{ matrix.command }} - e2e-tests: - timeout-minutes: 60 - runs-on: ubuntu-latest - steps: - - uses: actions/setup-node@v4 - with: - node-version: 22.x - # - name: Setup Docker Buildx - # id: buildx - # uses: docker/setup-buildx-action@v3 - # with: - # buildkitd-flags: '--debug' - - uses: actions/checkout@v4 - # - name: Build e2e containers - # uses: docker/bake-action@v5 - # with: - # builder: ${{ steps.buildx.outputs.name }} - # files: ./docker-compose.e2e.yml - - name: Install Dependencies - run: npm ci - - name: Install Playwright dependencies - run: npx playwright install-deps - - name: Install Playwright Browsers - run: npx playwright install - - name: Run e2e tests - env: - VERITABLE_COMPANY_PROFILE_API_KEY: ${{ secrets.COMPANIES_HOUSE_API }} - VERITABLE_E2E_OUT_DIR: ${{ runner.temp }} - run: | - DEBUG=testcontainers* npm run test:playwright || exit 1 - # run: docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull - - uses: actions/upload-artifact@v4 - if: always() - with: - name: playwright-report - path: ./playwright-report - retention-days: 90 - - name: Publish CTRF Test Summary Results - run: npx github-actions-ctrf ${{ runner.temp }}/playwright-report/ctrf-report.json - if: always() - - check-version: - name: 'Check version' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Check version - id: get_version - uses: digicatapult/check-version@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - + static-checks-npm: + uses: digicatapult/shared-workflows/.github/workflows/static-checks-npm.yml@main + with: + matrix_commands: '["lint", "depcheck", "check", "xss-scan"]' + tests-npm: + uses: digicatapult/shared-workflows/.github/workflows/tests-npm.yml@main + with: + docker_compose_file: '' + npm_build_command: 'npm run tsoa:build' + # pre_test_command: 'npm run db:migrate' + e2e-tests-npm: + uses: digicatapult/shared-workflows/.github/workflows/tests-e2e-npm.yml@main + with: + docker_compose_file: '' + test_command: 'npm run test:e2e' + permissions: + contents: write + secrets: inherit build-docker: - name: 'Build docker image' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Setup QEMU - uses: docker/setup-qemu-action@v3 - with: - platforms: all - - name: Setup Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v3 - with: - buildkitd-flags: '--debug' - - name: Build image - uses: docker/build-push-action@v6 - with: - builder: ${{ steps.buildx.outputs.name }} - context: . - file: ./Dockerfile - platforms: linux/amd64, linux/arm64 - push: false + uses: digicatapult/shared-workflows/.github/workflows/build-docker.yml@main + permissions: + packages: write + contents: write From b9a17286df7dcdb00d3841b448e8ebd6afe6e39e Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Mon, 18 Nov 2024 09:57:01 +0000 Subject: [PATCH 33/42] test --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 135966e9..39e50232 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,7 @@ jobs: uses: digicatapult/shared-workflows/.github/workflows/tests-e2e-npm.yml@main with: docker_compose_file: '' + pre_test_command: 'npm ci && npx playwright install-deps && npx playwright install' test_command: 'npm run test:e2e' permissions: contents: write From 017b66eaa4b96f50745d31d92d2ff2f23b63ccee Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Mon, 18 Nov 2024 10:30:43 +0000 Subject: [PATCH 34/42] updated test --- .github/workflows/test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 39e50232..9265650b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -12,13 +12,11 @@ jobs: with: docker_compose_file: '' npm_build_command: 'npm run tsoa:build' - # pre_test_command: 'npm run db:migrate' e2e-tests-npm: uses: digicatapult/shared-workflows/.github/workflows/tests-e2e-npm.yml@main with: docker_compose_file: '' pre_test_command: 'npm ci && npx playwright install-deps && npx playwright install' - test_command: 'npm run test:e2e' permissions: contents: write secrets: inherit From 1793574978e7c7660bccda423bc5c121a8f0c412 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Mon, 18 Nov 2024 10:36:42 +0000 Subject: [PATCH 35/42] wrong test cmd --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9265650b..0e916032 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,7 @@ jobs: with: docker_compose_file: '' pre_test_command: 'npm ci && npx playwright install-deps && npx playwright install' + test_command: 'npm run test:playwright || exit 1' permissions: contents: write secrets: inherit From cb1df0986f7f332cc741d1a9f2133a9abe7a8801 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Mon, 18 Nov 2024 11:04:11 +0000 Subject: [PATCH 36/42] releae workflow --- .github/workflows/release.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 32415497..8f38241b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,14 +10,14 @@ jobs: tests-npm: uses: digicatapult/shared-workflows/.github/workflows/tests-npm.yml@main with: + docker_compose_file: '' npm_build_command: 'npm run tsoa:build' - pre_test_command: 'npm run db:migrate' - docker_compose_file: docker-compose.yml e2e-tests-npm: uses: digicatapult/shared-workflows/.github/workflows/tests-e2e-npm.yml@main with: - docker_compose_file: docker-compose.e2e.yml - test_command: 'docker compose -f docker-compose.e2e.yml up --exit-code-from e2e-tests --abort-on-container-exit --quiet-pull' + docker_compose_file: '' + pre_test_command: 'npm ci && npx playwright install-deps && npx playwright install' + test_command: 'npm run test:playwright || exit 1' permissions: contents: write secrets: inherit @@ -38,4 +38,4 @@ jobs: uses: digicatapult/shared-workflows/.github/workflows/release-github.yml@main permissions: contents: write - secrets: inherit \ No newline at end of file + secrets: inherit From b3d4f5718b39f02f32351c042d91bf2d7ef08335 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:26:05 +0000 Subject: [PATCH 37/42] containers removed --- README.md | 6 ++++++ test/init.ts | 24 ------------------------ test/integration/newConnection.test.ts | 2 +- 3 files changed, 7 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 382b2d3b..31faecf9 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,12 @@ and run with DEBUG=testcontainers* npm run test:testcontainers ``` +Normally the containers are removed after a run, however you can keep them for further inspection by adding this: + +``` +await container.stop({ remove: false }) +``` + ## Database This service is dependant on postgreSQL which will sync up across all nodes and will update cloudagent when needed. We use `knex` wrapper for wrapping [create, read, write, update] database quries. We also have different models for inserting and returning data which gives us a control of sensitive data or data we do not want to get along the record. We also use **zod** for enchanted validation. It's currently used in `src/models/db/types.ts` file. diff --git a/test/init.ts b/test/init.ts index 766170a2..31cbecd1 100644 --- a/test/init.ts +++ b/test/init.ts @@ -21,30 +21,6 @@ before(async function () { chaiJestSnapshot.resetSnapshotRegistry() }) -// do we want to keep this for debugging? -after(async function () { - // await Promise.all( - // aliceDepsContainers.map(async function (container) { - // await container.stop({ remove: false }) - // }) - // ) - // await Promise.all( - // bobContainers.map(async function (container) { - // await container.stop({ remove: false }) - // }) - // ) - // await Promise.all( - // charlieContainers.map(async function (container) { - // await container.stop({ remove: false }) - // }) - // ) - // await Promise.all( - // sharedContainers.map(async function (container) { - // await container.stop({ remove: false }) - // }) - // ) -}) - beforeEach(function () { chaiJestSnapshot.configureUsingMochaContext(this) }) diff --git a/test/integration/newConnection.test.ts b/test/integration/newConnection.test.ts index c4d9090a..7b99e734 100644 --- a/test/integration/newConnection.test.ts +++ b/test/integration/newConnection.test.ts @@ -39,7 +39,7 @@ describe('NewConnectionController', () => { }) afterEach(async () => { - await cleanupCloudagent() //errors here + await cleanupCloudagent() server.cloudagentEvents.stop() }) From 6ce4a5eccc7d99cc854a7bc14eacabb01988c03c Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:28:51 +0000 Subject: [PATCH 38/42] comments --- test/testcontainers/testcontainersSetup.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/testcontainers/testcontainersSetup.ts b/test/testcontainers/testcontainersSetup.ts index 9e3a0a19..869a22b7 100644 --- a/test/testcontainers/testcontainersSetup.ts +++ b/test/testcontainers/testcontainersSetup.ts @@ -413,14 +413,8 @@ export async function veritableUIContainer(network: StartedNetwork, env: Veritab } = env const base = await GenericContainer.fromDockerfile('./').withTarget('test').build() - // Commented out is for logs from containers const veritableUIContainer = await base .withName(containerName) - // .withLogConsumer((stream) => { - // stream.on('data', (line) => console.log(line)) - // stream.on('err', (line) => console.error(line)) - // stream.on('end', () => console.log('Stream closed')) - // }) .withExposedPorts({ container: containerPort, host: hostPort, From 99f7e395ef9432b706d8a19f6f89210115929980 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:33:57 +0000 Subject: [PATCH 39/42] docs --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 31faecf9..ffffcb40 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,13 @@ so see logs from a container e.g. if it is dying on startup add: and run with ``` -DEBUG=testcontainers* npm run test:testcontainers +DEBUG=testcontainers* npm run test:integration +``` + +or + +``` +DEBUG=testcontainers* npm run test:e2e ``` Normally the containers are removed after a run, however you can keep them for further inspection by adding this: From c861ea236a4b616ee9bf0e097b401becc5980d21 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:38:13 +0000 Subject: [PATCH 40/42] docs --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ffffcb40..21ff325b 100644 --- a/README.md +++ b/README.md @@ -168,7 +168,7 @@ npm run test:unit Integration tests are placed at the root level of a repository and can be found at the root level `test/` folder along with mock services and helpers and a test environment variables that will be in `test/test.env`. -Integration tests can be run locally by executing the below command +Integration tests can be run locally by executing the below command (it is recommended to add debugging so you can follow the logs in the console, refer to [testcontainers section](#testcontainers)) ```sh npm run test:integration @@ -196,6 +196,7 @@ Then run: npm run test:e2e ``` +(it is recommended to add debugging so you can follow the logs in the console, refer to [testcontainers section](#testcontainers)) A browser window will pop up where you can run tests and follow their progress. Alternatively you can run: ```sh From 3fb559cb7ed2e01b6440a0894d64962755765b47 Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:53:23 +0000 Subject: [PATCH 41/42] cleanup containers --- test/init.ts | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/test/init.ts b/test/init.ts index 31cbecd1..b155ff2b 100644 --- a/test/init.ts +++ b/test/init.ts @@ -2,6 +2,7 @@ import { use } from 'chai' import 'reflect-metadata' import chaiJestSnapshot from 'chai-jest-snapshot' +import { StartedTestContainer } from 'testcontainers' import { migrateDatabase } from './helpers/db.js' import { bringUpAliceDependenciesContainers, @@ -10,17 +11,45 @@ import { bringUpSharedContainers, } from './testcontainers/testcontainersSetup.js' +let sharedContainers: StartedTestContainer[] +let aliceDepsContainers: StartedTestContainer[] +let bobContainers: StartedTestContainer[] +let charlieContainers: StartedTestContainer[] + before(async function () { - await bringUpSharedContainers() - await bringUpAliceDependenciesContainers() - await bringUpBobContainers() - await bringUpCharlieContainers() + sharedContainers = await bringUpSharedContainers() + aliceDepsContainers = await bringUpAliceDependenciesContainers() + bobContainers = await bringUpBobContainers() + charlieContainers = await bringUpCharlieContainers() await migrateDatabase() use(chaiJestSnapshot) chaiJestSnapshot.resetSnapshotRegistry() }) +after(async function () { + await Promise.all( + aliceDepsContainers.map(async function (container) { + await container.stop() + }) + ) + await Promise.all( + bobContainers.map(async function (container) { + await container.stop() + }) + ) + await Promise.all( + charlieContainers.map(async function (container) { + await container.stop() + }) + ) + await Promise.all( + sharedContainers.map(async function (container) { + await container.stop() + }) + ) +}) + beforeEach(function () { chaiJestSnapshot.configureUsingMochaContext(this) }) From f65c724563aaef061b78a3b99baf6f2ee3e002ef Mon Sep 17 00:00:00 2001 From: Helena Adamkova <58051865+Ellenn-A@users.noreply.github.com> Date: Tue, 19 Nov 2024 10:07:46 +0000 Subject: [PATCH 42/42] test update --- test/integration/smtpEmail.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/integration/smtpEmail.test.ts b/test/integration/smtpEmail.test.ts index 2925ce58..d9a2c478 100644 --- a/test/integration/smtpEmail.test.ts +++ b/test/integration/smtpEmail.test.ts @@ -76,8 +76,7 @@ describe('SMTP email', () => { const parsedMessages = EmailResponseSchema.parse(messages) const results = parsedMessages['results'] expect(results).to.be.an('array') - expect(results[0]).to.have.property('deliveredTo').that.is.equal('admin@veritable.com') - expect(results[1]).to.have.property('deliveredTo').that.is.equal('alice@example.com') + expect(results).length(2) // Invite email assertions const inviteEmail = results.find(