From 0d3451752628fe6341aded962a83de8a0c035ecd Mon Sep 17 00:00:00 2001 From: bikilaketema Date: Mon, 14 Apr 2025 12:09:01 +0300 Subject: [PATCH 1/8] initial commit --- package-lock.json | 1262 ++++++++++++++++- package.json | 6 +- .../admin/mentor/mentor.service.spec.ts | 43 +- test/jest-e2e.json | 7 +- test/setupTests.e2e.ts | 53 + tsconfig.json | 3 + 6 files changed, 1356 insertions(+), 18 deletions(-) create mode 100644 test/setupTests.e2e.ts diff --git a/package-lock.json b/package-lock.json index dea1c069..aac61625 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50,6 +50,7 @@ "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", + "@testcontainers/postgresql": "^10.24.2", "@types/bcrypt": "^5.0.2", "@types/express": "^4.17.17", "@types/faker": "^6.6.8", @@ -64,11 +65,12 @@ "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", - "jest": "^29.5.0", + "jest": "^29.7.0", "prettier": "^3.4.2", "source-map-support": "^0.5.21", "supertest": "^6.3.3", - "ts-jest": "^29.1.0", + "testcontainers": "^10.24.2", + "ts-jest": "^29.3.2", "ts-loader": "^9.4.3", "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", @@ -815,6 +817,13 @@ "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, + "license": "Apache-2.0" + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -1165,6 +1174,16 @@ "npm": ">=9.0.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, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/@graphql-tools/merge": { "version": "9.0.8", "resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-9.0.8.tgz", @@ -1226,6 +1245,39 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, + "node_modules/@grpc/grpc-js": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.3.tgz", + "integrity": "sha512-FTXHdOoPbZrBjlVLHuKbDZnsTxXv2BlHF57xw6LuThXacXvtkahEPED0CKMk6obZDf65Hv4k3z62eyPNpvinIg==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz", + "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -1909,6 +1961,17 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "devOptional": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/@ljharb/through": { "version": "2.3.13", "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", @@ -2632,6 +2695,80 @@ "@prisma/debug": "5.22.0" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "devOptional": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "devOptional": true, + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "devOptional": true, + "license": "BSD-3-Clause" + }, "node_modules/@redis/bloom": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz", @@ -2751,6 +2888,16 @@ "license": "MIT", "peer": true }, + "node_modules/@testcontainers/postgresql": { + "version": "10.24.2", + "resolved": "https://registry.npmjs.org/@testcontainers/postgresql/-/postgresql-10.24.2.tgz", + "integrity": "sha512-s4k/QVSmpXFzxNBeft84x172Hx5tNiGeDRWwU8iOAHjtcnyXd4aBORF0GruNojTo7TOIuAM0ArBZUMqRBLJKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "testcontainers": "^10.24.2" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", @@ -2877,6 +3024,29 @@ "@types/node": "*" } }, + "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, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/ssh2": "*" + } + }, + "node_modules/@types/dockerode": { + "version": "3.3.37", + "resolved": "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.37.tgz", + "integrity": "sha512-r+IoKpE5MLKaeD8CvoEh39ckWMLHR/+WBMoRQxrkL+apJqEWLMhBHh+93KIfyPWGd6gK7Q21jpoULKgNoRI0YA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/docker-modem": "*", + "@types/node": "*", + "@types/ssh2": "*" + } + }, "node_modules/@types/ejs": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/@types/ejs/-/ejs-3.1.5.tgz", @@ -3163,6 +3333,43 @@ "@types/send": "*" } }, + "node_modules/@types/ssh2": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/ssh2/-/ssh2-1.15.5.tgz", + "integrity": "sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ssh2/node_modules/@types/node": { + "version": "18.19.86", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.86.tgz", + "integrity": "sha512-fifKayi175wLyKyc5qUfyENhQ1dCNI1UNjp653d8kuYcPQN5JhX3dGuP/XmvPTg/xRBn1VTLpbmi+H/Mr7tLfQ==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT" + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -3648,6 +3855,19 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -3923,6 +4143,148 @@ "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", "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, + "license": "MIT", + "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, + "license": "MIT", + "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/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/archiver/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/archiver/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/archiver/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", @@ -3967,6 +4329,16 @@ "devOptional": 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, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, "node_modules/assert-never": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", @@ -3981,6 +4353,13 @@ "devOptional": true, "license": "MIT" }, + "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, + "license": "MIT" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -3988,6 +4367,13 @@ "dev": true, "license": "MIT" }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -4139,6 +4525,83 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, + "node_modules/bare-events": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", + "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-fs": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.2.tgz", + "integrity": "sha512-8wSeOia5B7LwD4+h465y73KOdj5QHsbbuoUfPBi+pXgFJIPuG7SsiOdJuijWMyfid49eD+WivpfY7KT8gbAzBA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", + "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", + "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -4177,6 +4640,16 @@ "node": ">=6.0.0" } }, + "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, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, "node_modules/bcryptjs": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", @@ -4380,6 +4853,16 @@ "ieee754": "^1.1.13" } }, + "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, + "license": "MIT", + "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", @@ -4398,6 +4881,16 @@ "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==", "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/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -4409,6 +4902,16 @@ "node": ">=10.16.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, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -4654,6 +5157,13 @@ "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, + "license": "ISC" + }, "node_modules/chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", @@ -4996,6 +5506,75 @@ "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, + "license": "MIT", + "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/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/compress-commons/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/compress-commons/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5142,6 +5721,100 @@ } } }, + "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, + "license": "Apache-2.0", + "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, + "license": "MIT", + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/crc32-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/crc32-stream/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/crc32-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -5446,6 +6119,114 @@ "node": ">=4" } }, + "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, + "license": "MIT", + "dependencies": { + "yaml": "^2.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/docker-modem": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-5.0.6.tgz", + "integrity": "sha512-ens7BiayssQz/uAxGzH8zGXCtiV24rRWXdjNha5V4zSOcxmAZsfGVm/PPFbwQdqEkDnhG+SyR9E3zSHUbOKXBQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.1", + "readable-stream": "^3.5.0", + "split-ca": "^1.0.1", + "ssh2": "^1.15.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, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/dockerode": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/dockerode/-/dockerode-4.0.5.tgz", + "integrity": "sha512-ZPmKSr1k1571Mrh7oIBS/j0AqAccoecY2yH420ni5j1KyNMgnoTh4Nu4FWunh0HZIJmRSmSysJjBIpa/zyWUEA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@grpc/grpc-js": "^1.11.1", + "@grpc/proto-loader": "^0.7.13", + "docker-modem": "^5.0.6", + "protobufjs": "^7.3.2", + "tar-fs": "~2.1.2", + "uuid": "^10.0.0" + }, + "engines": { + "node": ">= 8.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": ">= 6" + } + }, + "node_modules/dockerode/node_modules/tar-fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", + "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "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": "MIT", + "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": ">=6" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -5696,6 +6477,16 @@ "node": ">=8.10.0" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/engine.io": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", @@ -6194,6 +6985,16 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", @@ -6379,6 +7180,13 @@ "dev": true, "license": "Apache-2.0" }, + "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, + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -6730,6 +7538,13 @@ "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, + "license": "MIT" + }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -8999,6 +9814,19 @@ "node": ">=6" } }, + "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, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, "node_modules/leac": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", @@ -9159,6 +9987,13 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "devOptional": true, + "license": "MIT" + }, "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -9244,6 +10079,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/long": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.1.tgz", + "integrity": "sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==", + "devOptional": true, + "license": "Apache-2.0" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -10007,6 +10849,13 @@ "mkdirp": "bin/cmd.js" } }, + "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, + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -10050,6 +10899,14 @@ "thenify-all": "^1.0.0" } }, + "node_modules/nan": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.2.tgz", + "integrity": "sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -11081,6 +11938,16 @@ "fsevents": "2.3.3" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "license": "MIT", + "engines": { + "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", @@ -11129,6 +11996,55 @@ "react-is": "^16.13.1" } }, + "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, + "license": "MIT", + "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, + "license": "ISC" + }, + "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, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/properties?sponsor=1" + } + }, + "node_modules/properties-reader/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/proto-list": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", @@ -11136,6 +12052,31 @@ "license": "ISC", "optional": true }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "devOptional": true, + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -11285,6 +12226,17 @@ "license": "MIT", "optional": true }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -11465,6 +12417,29 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, + "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, + "license": "Apache-2.0", + "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, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -11698,6 +12673,16 @@ "dev": true, "license": "ISC" }, + "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, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -12051,9 +13036,9 @@ } }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -12358,6 +13343,13 @@ "node": ">=0.10.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, + "license": "ISC" + }, "node_modules/split2": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", @@ -12374,6 +13366,46 @@ "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, + "license": "MIT", + "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, + "license": "MIT", + "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/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -12420,6 +13452,20 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", + "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -12705,6 +13751,33 @@ "node": ">=6" } }, + "node_modules/tar-fs": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.8.tgz", + "integrity": "sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.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, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/terser": { "version": "5.36.0", "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", @@ -12858,6 +13931,63 @@ "node": "*" } }, + "node_modules/testcontainers": { + "version": "10.24.2", + "resolved": "https://registry.npmjs.org/testcontainers/-/testcontainers-10.24.2.tgz", + "integrity": "sha512-Don3EXEQuSw14+nFG9pj48fL9ck/jXDfR9Rb0K3acOyn/gg97+gsnfZaLzpdejl9GcPJVKxACNRe3SYVC2uWqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@balena/dockerignore": "^1.0.2", + "@types/dockerode": "^3.3.35", + "archiver": "^7.0.1", + "async-lock": "^1.4.1", + "byline": "^5.0.0", + "debug": "^4.3.5", + "docker-compose": "^0.24.8", + "dockerode": "^4.0.5", + "get-port": "^7.1.0", + "proper-lockfile": "^4.1.2", + "properties-reader": "^2.3.0", + "ssh-remote-port-forward": "^1.0.4", + "tar-fs": "^3.0.7", + "tmp": "^0.2.3", + "undici": "^5.28.5" + } + }, + "node_modules/testcontainers/node_modules/get-port": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", + "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/testcontainers/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -12996,9 +14126,9 @@ } }, "node_modules/ts-jest": { - "version": "29.2.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", - "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==", + "version": "29.3.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.2.tgz", + "integrity": "sha512-bJJkrWc6PjFVz5g2DGCNUo8z7oFEYaz1xP1NpeDU7KNLMWPpEyV8Chbpkn8xjzgRDpQhnGMyvyldoL7h8JXyug==", "dev": true, "license": "MIT", "dependencies": { @@ -13009,7 +14139,8 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.6.3", + "semver": "^7.7.1", + "type-fest": "^4.39.1", "yargs-parser": "^21.1.1" }, "bin": { @@ -13044,6 +14175,19 @@ } } }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.39.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.39.1.tgz", + "integrity": "sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ts-loader": { "version": "9.5.1", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", @@ -13155,6 +14299,13 @@ "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "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, + "license": "Unlicense" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -13431,6 +14582,19 @@ "integrity": "sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==", "license": "MIT" }, + "node_modules/undici": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", + "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -14050,6 +15214,19 @@ "dev": true, "license": "ISC" }, + "node_modules/yaml": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", + "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -14116,6 +15293,73 @@ "dependencies": { "zen-observable": "0.8.15" } + }, + "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, + "license": "MIT", + "dependencies": { + "archiver-utils": "^5.0.0", + "compress-commons": "^6.0.2", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/zip-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/zip-stream/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "dev": true, + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/zip-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } } } } diff --git a/package.json b/package.json index 0872a862..edd27af3 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "@nestjs/cli": "^10.0.0", "@nestjs/schematics": "^10.0.0", "@nestjs/testing": "^10.0.0", + "@testcontainers/postgresql": "^10.24.2", "@types/bcrypt": "^5.0.2", "@types/express": "^4.17.17", "@types/faker": "^6.6.8", @@ -77,11 +78,12 @@ "eslint": "^8.57.1", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", - "jest": "^29.5.0", + "jest": "^29.7.0", "prettier": "^3.4.2", "source-map-support": "^0.5.21", "supertest": "^6.3.3", - "ts-jest": "^29.1.0", + "testcontainers": "^10.24.2", + "ts-jest": "^29.3.2", "ts-loader": "^9.4.3", "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", diff --git a/src/modules/admin/mentor/mentor.service.spec.ts b/src/modules/admin/mentor/mentor.service.spec.ts index 4e7999c8..ef7331db 100644 --- a/src/modules/admin/mentor/mentor.service.spec.ts +++ b/src/modules/admin/mentor/mentor.service.spec.ts @@ -1,18 +1,49 @@ import { Test, TestingModule } from '@nestjs/testing'; import { MentorService } from './mentor.service'; +import { PrismaService } from 'src/modules/prisma/prisma.service'; +import { postgresClient, prismaService } from '../../../../test/setupTests.e2e'; describe('MentorService', () => { let service: MentorService; - beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [MentorService], - }).compile(); - + providers: [MentorService, PrismaService], + }) + .overrideProvider(PrismaService) + .useValue(prismaService) + .compile(); service = module.get(MentorService); }); - it('should be defined', () => { - expect(service).toBeDefined(); + it('should create a mentor', async () => { + // Start a transaction + await postgresClient.query('BEGIN'); + try { + // Perform the create operation + const createResult = await service.create({ + email: 'test@gmail.com', + accountId: '12dse3ded8y3di3d3d', + name: 'Bikila Ketema', + }); + // Commit the transaction + await postgresClient.query('COMMIT'); + // Query the database for the newly created car + const result = await postgresClient.query( + 'SELECT * FROM "public"."Mentor"', + ); + // Log the results + console.log(result.rows); + // Assert the create result + expect(createResult).toEqual({ + id: 1, + email: 'test@gmail.com', + accountId: '12dse3ded8y3di3d3d', + name: 'Bikila Ketema', + }); + } catch (error) { + // Rollback the transaction in case of an error + await postgresClient.query('ROLLBACK'); + throw error; + } }); }); diff --git a/test/jest-e2e.json b/test/jest-e2e.json index e9d912f3..490dbf34 100644 --- a/test/jest-e2e.json +++ b/test/jest-e2e.json @@ -1,9 +1,14 @@ { "moduleFileExtensions": ["js", "json", "ts"], - "rootDir": ".", + "rootDir": "../", + "roots": ["/src"], + "setupFilesAfterEnv": ["/test/setupTests.e2e.ts"], "testEnvironment": "node", "testRegex": ".e2e-spec.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" + }, + "moduleNameMapper": { + "^src/(.*)$": "/src/$1" } } diff --git a/test/setupTests.e2e.ts b/test/setupTests.e2e.ts new file mode 100644 index 00000000..05a83dbf --- /dev/null +++ b/test/setupTests.e2e.ts @@ -0,0 +1,53 @@ +import { + PostgreSqlContainer, + StartedPostgreSqlContainer, +} from '@testcontainers/postgresql'; +import { Client } from 'pg'; +import { PrismaService } from '../src/modules/prisma/prisma.service'; +import { execSync } from 'child_process'; +import 'tsconfig-paths/register'; + +let postgresContainer: StartedPostgreSqlContainer; +let postgresClient: Client; +let prismaService: PrismaService; + +beforeAll(async () => { + // Connect our container + postgresContainer = await new PostgreSqlContainer().start(); + postgresClient = new Client({ + host: postgresContainer.getHost(), + port: postgresContainer.getPort(), + database: postgresContainer.getDatabase(), + user: postgresContainer.getUsername(), + password: postgresContainer.getPassword(), + }); + await postgresClient.connect(); + + // Set the new database URL + const databaseUrl = `postgresql://${postgresClient.user}:${postgresClient.password}@${postgresClient.host}:${postgresClient.port}/${postgresClient.database}`; + + // Execute Prisma migrations + execSync('npx prisma migrate dev', { + env: { + ...process.env, // Preserve existing environment variables + DATABASE_URL: databaseUrl, // Set the DATABASE_URL for Prisma + }, + }); + + // Set prisma instance (no need to pass datasources to PrismaService constructor) + prismaService = new PrismaService(); + + console.log('connected to test db...'); +}); + +afterAll(async () => { + // Stop container as well as postgresClient + await postgresClient.end(); + await postgresContainer.stop(); + console.log('test db stopped...'); +}); + +// Set a timeout for jest to allow the containers to initialize +jest.setTimeout(300000); + +export { postgresClient, prismaService }; diff --git a/tsconfig.json b/tsconfig.json index 95f5641c..111e1306 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,9 @@ "sourceMap": true, "outDir": "./dist", "baseUrl": "./", + "paths": { + "src/*": ["src/*"] + }, "incremental": true, "skipLibCheck": true, "strictNullChecks": false, From b67681ba6b7e5dc0a198c78c8a0a95325e628bc9 Mon Sep 17 00:00:00 2001 From: bikilaketema Date: Wed, 23 Apr 2025 20:54:01 +0300 Subject: [PATCH 2/8] the test worked --- src/modules/admin/mentor/dto/mentor.dto.ts | 2 +- .../admin/mentor/mentor.controller.spec.ts | 125 +++++++++- src/modules/admin/mentor/mentor.controller.ts | 4 +- .../admin/mentor/mentor.service.spec.ts | 230 +++++++++++++++--- src/modules/admin/mentor/mentor.service.ts | 6 +- test/prisma.extension.ts | 16 ++ test/setupTests.e2e.ts | 26 +- 7 files changed, 351 insertions(+), 58 deletions(-) create mode 100644 test/prisma.extension.ts diff --git a/src/modules/admin/mentor/dto/mentor.dto.ts b/src/modules/admin/mentor/dto/mentor.dto.ts index 0c6843c7..347c8fdd 100644 --- a/src/modules/admin/mentor/dto/mentor.dto.ts +++ b/src/modules/admin/mentor/dto/mentor.dto.ts @@ -1,7 +1,7 @@ // src/posts/dto/post.dto.ts import { Expose, Type } from 'class-transformer'; -import { UserDto } from 'src/modules/admin/user/dto/user.dto'; +import { UserDto } from '../../user/dto/user.dto'; export class MentorDto { @Expose() diff --git a/src/modules/admin/mentor/mentor.controller.spec.ts b/src/modules/admin/mentor/mentor.controller.spec.ts index 5e2153c3..e596383a 100644 --- a/src/modules/admin/mentor/mentor.controller.spec.ts +++ b/src/modules/admin/mentor/mentor.controller.spec.ts @@ -1,18 +1,137 @@ import { Test, TestingModule } from '@nestjs/testing'; import { MentorController } from './mentor.controller'; +import { MentorService } from './mentor.service'; +import { CreateMentorDto } from './dto/create-mentor.dto'; +import { UpdateMentorDto } from './dto/update-mentor.dto'; +import { GetMentorDto } from './dto/get-mentor.dto'; +import { NotFoundException, ExecutionContext } from '@nestjs/common'; +import { AuthGuard } from '../../auth/guard/auth/auth.guard'; describe('MentorController', () => { let controller: MentorController; + let service: MentorService; + + const mockMentorService = { + findAll: jest.fn(), + findOne: jest.fn(), + create: jest.fn(), + update: jest.fn(), + delete: jest.fn(), + }; + + const mockAuthGuard = { + canActivate: jest.fn((context: ExecutionContext) => true), + }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [MentorController], - }).compile(); + providers: [ + { + provide: MentorService, + useValue: mockMentorService, + }, + ], + }) + .overrideGuard(AuthGuard) + .useValue(mockAuthGuard) + .compile(); controller = module.get(MentorController); + service = module.get(MentorService); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe('getMentors', () => { + it('should return a list of mentors', async () => { + const result = { data: [], meta: { total: 0, page: 1, limit: 10 } }; + mockMentorService.findAll.mockResolvedValue(result); + + expect(await controller.getMentors({})).toEqual(result); + expect(mockMentorService.findAll).toHaveBeenCalledWith({}); + }); + }); + + describe('findOne', () => { + it('should return a mentor', async () => { + const mentor = { id: '1', name: 'John Doe' }; + mockMentorService.findOne.mockResolvedValue(mentor); + + expect(await controller.findOne('1', new GetMentorDto())).toEqual(mentor); + expect(mockMentorService.findOne).toHaveBeenCalledWith( + '1', + expect.any(GetMentorDto), + ); + }); + + it('should throw NotFoundException if mentor not found', async () => { + mockMentorService.findOne.mockRejectedValue( + new NotFoundException('Mentor not found'), + ); + + await expect(controller.findOne('1', new GetMentorDto())).rejects.toThrow( + NotFoundException, + ); + }); }); - it('should be defined', () => { - expect(controller).toBeDefined(); + describe('create', () => { + it('should create and return a mentor', async () => { + const createDto: CreateMentorDto = { + name: 'Jane Doe', + email: 'jane@example.com', + accountId: 'acc1', + }; + const mentor = { id: '1', ...createDto }; + mockMentorService.create.mockResolvedValue(mentor); + + expect(await controller.create(createDto)).toEqual(mentor); + expect(mockMentorService.create).toHaveBeenCalledWith(createDto); + }); + }); + + describe('update', () => { + it('should update and return a mentor', async () => { + const updateDto: UpdateMentorDto = { + name: 'Jane Smith', + email: 'jane.smith@example.com', + }; + const mentor = { id: '1', ...updateDto }; + mockMentorService.update.mockResolvedValue(mentor); + + expect(await controller.update('1', updateDto)).toEqual(mentor); + expect(mockMentorService.update).toHaveBeenCalledWith('1', updateDto); + }); + + it('should throw NotFoundException if mentor not found', async () => { + mockMentorService.update.mockRejectedValue( + new NotFoundException('Mentor not found'), + ); + + await expect( + controller.update('1', new UpdateMentorDto()), + ).rejects.toThrow(NotFoundException); + }); + }); + + describe('delete', () => { + it('should delete a mentor and return status', async () => { + const result = { status: true }; + mockMentorService.delete.mockResolvedValue(result); + + expect(await controller.delete('1')).toEqual(result); + expect(mockMentorService.delete).toHaveBeenCalledWith('1'); + }); + + it('should throw NotFoundException if mentor not found', async () => { + mockMentorService.delete.mockRejectedValue( + new NotFoundException('Mentor not found'), + ); + + await expect(controller.delete('1')).rejects.toThrow(NotFoundException); + }); }); }); diff --git a/src/modules/admin/mentor/mentor.controller.ts b/src/modules/admin/mentor/mentor.controller.ts index 71e1c1b5..c4b21c1b 100644 --- a/src/modules/admin/mentor/mentor.controller.ts +++ b/src/modules/admin/mentor/mentor.controller.ts @@ -11,8 +11,8 @@ import { ValidationPipe, } from '@nestjs/common'; import { MentorService } from './mentor.service'; -import { Roles } from 'src/modules/auth/auth.decorator'; -import { AuthGuard } from 'src/modules/auth/guard/auth/auth.guard'; +import { Roles } from '../../auth/auth.decorator'; +import { AuthGuard } from '../../auth/guard/auth/auth.guard'; import { GetMentorDto } from './dto/get-mentor.dto'; import { CreateMentorDto } from './dto/create-mentor.dto'; import { UpdateMentorDto } from './dto/update-mentor.dto'; diff --git a/src/modules/admin/mentor/mentor.service.spec.ts b/src/modules/admin/mentor/mentor.service.spec.ts index ef7331db..7fab6eba 100644 --- a/src/modules/admin/mentor/mentor.service.spec.ts +++ b/src/modules/admin/mentor/mentor.service.spec.ts @@ -1,49 +1,207 @@ import { Test, TestingModule } from '@nestjs/testing'; import { MentorService } from './mentor.service'; -import { PrismaService } from 'src/modules/prisma/prisma.service'; -import { postgresClient, prismaService } from '../../../../test/setupTests.e2e'; +import { prismaService } from '../../../../test/setupTests.e2e'; +import { PrismaService } from '../../prisma/prisma.service'; +import { RoleType } from '@prisma/client'; +import { REQUEST } from '@nestjs/core'; +import { CreateMentorDto } from './dto/create-mentor.dto'; +import { UpdateMentorDto } from './dto/update-mentor.dto'; +import { NotFoundException } from '@nestjs/common'; -describe('MentorService', () => { +describe('MentorService (Integration)', () => { let service: MentorService; - beforeEach(async () => { + + const mockRequest = { + user: { + id: 'mock-user-id', + accountId: 'mock-account-id', + }, + }; + + beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [MentorService, PrismaService], - }) - .overrideProvider(PrismaService) - .useValue(prismaService) - .compile(); + providers: [ + MentorService, + { + provide: PrismaService, + useValue: prismaService, + }, + { provide: REQUEST, useValue: mockRequest }, + ], + }).compile(); + service = module.get(MentorService); + + await prismaService.role.create({ + data: { + name: 'Mentor', + type: RoleType.MENTOR, + isDefault: true, + }, + }); }); - it('should create a mentor', async () => { - // Start a transaction - await postgresClient.query('BEGIN'); - try { - // Perform the create operation - const createResult = await service.create({ - email: 'test@gmail.com', - accountId: '12dse3ded8y3di3d3d', - name: 'Bikila Ketema', - }); - // Commit the transaction - await postgresClient.query('COMMIT'); - // Query the database for the newly created car - const result = await postgresClient.query( - 'SELECT * FROM "public"."Mentor"', - ); - // Log the results - console.log(result.rows); - // Assert the create result - expect(createResult).toEqual({ - id: 1, - email: 'test@gmail.com', - accountId: '12dse3ded8y3di3d3d', - name: 'Bikila Ketema', + afterEach(async () => { + await prismaService.accountUser.deleteMany(); + await prismaService.mentor.deleteMany(); + await prismaService.user.deleteMany(); + }); + + it('should create a mentor with a default role', async () => { + const account = await prismaService.account.create({ + data: { + name: 'Test Account', + }, + }); + + const result = await service.create({ + name: 'Bikila Ketema', + email: 'test@mentor.com', + accountId: account.id, + }); + + expect(result.email).toBe('test@mentor.com'); + expect(result.user).toBeDefined(); + + const accountUser = await prismaService.accountUser.findFirst({ + where: { userId: result.user.id }, + include: { Role: true }, + }); + + expect(accountUser?.Role?.type).toBe(RoleType.MENTOR); + }); + + it('should find a mentor by id with the associated user', async () => { + const account = await prismaService.account.create({ + data: { + name: 'FindOne Test Account', + }, + }); + + const mentor = await prismaService.mentor.create({ + data: { + name: 'Test Mentor', + email: 'findone@mentor.com', + accountId: account.id, + }, + }); + + const user = await prismaService.user.create({ + data: { + name: 'Test Mentor', + email: 'findone@mentor.com', + password: '', + }, + }); + + const result = await service.findOne(mentor.id, { accountId: account.id }); + + expect(result).toBeDefined(); + expect(result.id).toBe(mentor.id); + expect(result.user).toBeDefined(); + expect(result.user.email).toBe('findone@mentor.com'); + }); + + it('should return a paginated list of mentors for the given accountId', async () => { + const account = await prismaService.account.create({ + data: { name: 'FindAll Account' }, + }); + + for (let i = 1; i <= 5; i++) { + await prismaService.mentor.create({ + data: { + name: `Mentor ${i}`, + email: `mentor${i}@test.com`, + accountId: account.id, + }, }); + } + + const result = await service.findAll({ + accountId: account.id, + page: 1, + limit: 3, + }); + + expect(result).toBeDefined(); + expect(result.data.length).toBeLessThanOrEqual(3); + expect(result.meta.total).toBeGreaterThanOrEqual(5); + expect(result.meta.page).toBe(1); + expect(result.meta.limit).toBe(3); + }); + + it('should update a mentor successfully', async () => { + const account = await prismaService.account.create({ + data: { + name: 'FindOne Test Account', + }, + }); + + const createMentorDto: CreateMentorDto = { + name: 'John Doe', + email: 'johndoe@test.com', + accountId: account.id, + }; + + const createdMentor = await service.create(createMentorDto); + + const updateMentorDto: UpdateMentorDto = { + name: 'John Updated', + email: 'johnupdated@test.com', + availability: JSON.stringify(['Monday', 'Wednesday']), + }; + + const updatedMentor = await service.update( + createdMentor.id, + updateMentorDto, + ); + + expect(updatedMentor).toBeDefined(); + expect(updatedMentor.name).toBe(updateMentorDto.name); + expect(updatedMentor.email).toBe(updateMentorDto.email); + expect(updatedMentor.availability).toEqual( + JSON.parse(updateMentorDto.availability), + ); + }); + + it('should throw an error if mentor is not found', async () => { + const updateMentorDto: UpdateMentorDto = { + name: 'Non-Existent Mentor', + email: 'nonexistent@test.com', + availability: JSON.stringify(['Monday']), + }; + + try { + await service.update('nonexistent-id', updateMentorDto); } catch (error) { - // Rollback the transaction in case of an error - await postgresClient.query('ROLLBACK'); - throw error; + expect(error).toBeInstanceOf(NotFoundException); + expect(error.message).toBe('Mentor not found'); } }); + + it('should delete a mentor successfully', async () => { + const account = await prismaService.account.create({ + data: { + name: 'FindOne Test Account', + }, + }); + + const createMentorDto: CreateMentorDto = { + name: 'John Doe', + email: 'johndoe@test.com', + accountId: account.id, + }; + + const createdMentor = await service.create(createMentorDto); + + const deletedResponse = await service.delete(createdMentor.id); + + expect(deletedResponse.status).toBe(true); + + const deletedMentor = await prismaService.mentor.findUnique({ + where: { id: createdMentor.id }, + }); + + expect(deletedMentor.deletedAt).toBeDefined(); + }); }); diff --git a/src/modules/admin/mentor/mentor.service.ts b/src/modules/admin/mentor/mentor.service.ts index cdb41365..6f2bab32 100644 --- a/src/modules/admin/mentor/mentor.service.ts +++ b/src/modules/admin/mentor/mentor.service.ts @@ -1,13 +1,13 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; -import { PrismaService } from 'src/modules/prisma/prisma.service'; +import { PrismaService } from '../../prisma/prisma.service'; import { REQUEST } from '@nestjs/core'; import { MentorDto } from './dto/mentor.dto'; import { GetMentorDto } from './dto/get-mentor.dto'; import { CreateMentorDto } from './dto/create-mentor.dto'; import { UpdateMentorDto } from './dto/update-mentor.dto'; import { RoleType } from '@prisma/client'; -import { PaginationResult, paginate } from 'src/common/helpers/pagination'; -import { PaginationDto } from 'src/common/dto/pagination.dto'; +import { PaginationResult, paginate } from '../../../common/helpers/pagination'; +import { PaginationDto } from '../../../common/dto/pagination.dto'; @Injectable() export class MentorService { constructor( diff --git a/test/prisma.extension.ts b/test/prisma.extension.ts new file mode 100644 index 00000000..7ffd32da --- /dev/null +++ b/test/prisma.extension.ts @@ -0,0 +1,16 @@ +import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; +import { PrismaClient } from '@prisma/client'; + +@Injectable() +export class PrismaService + extends PrismaClient + implements OnModuleInit, OnModuleDestroy +{ + async onModuleInit() { + await this.$connect(); + } + + async onModuleDestroy() { + await this.$disconnect(); + } +} diff --git a/test/setupTests.e2e.ts b/test/setupTests.e2e.ts index 05a83dbf..b189095c 100644 --- a/test/setupTests.e2e.ts +++ b/test/setupTests.e2e.ts @@ -3,17 +3,16 @@ import { StartedPostgreSqlContainer, } from '@testcontainers/postgresql'; import { Client } from 'pg'; -import { PrismaService } from '../src/modules/prisma/prisma.service'; +import { PrismaService } from './prisma.extension'; import { execSync } from 'child_process'; -import 'tsconfig-paths/register'; let postgresContainer: StartedPostgreSqlContainer; let postgresClient: Client; let prismaService: PrismaService; beforeAll(async () => { - // Connect our container postgresContainer = await new PostgreSqlContainer().start(); + postgresClient = new Client({ host: postgresContainer.getHost(), port: postgresContainer.getPort(), @@ -21,33 +20,34 @@ beforeAll(async () => { user: postgresContainer.getUsername(), password: postgresContainer.getPassword(), }); + await postgresClient.connect(); - // Set the new database URL const databaseUrl = `postgresql://${postgresClient.user}:${postgresClient.password}@${postgresClient.host}:${postgresClient.port}/${postgresClient.database}`; - // Execute Prisma migrations execSync('npx prisma migrate dev', { env: { - ...process.env, // Preserve existing environment variables - DATABASE_URL: databaseUrl, // Set the DATABASE_URL for Prisma + ...process.env, + DATABASE_URL: databaseUrl, }, }); - // Set prisma instance (no need to pass datasources to PrismaService constructor) - prismaService = new PrismaService(); + prismaService = new PrismaService({ + datasources: { + db: { + url: databaseUrl, + }, + }, + }); console.log('connected to test db...'); }); afterAll(async () => { - // Stop container as well as postgresClient await postgresClient.end(); await postgresContainer.stop(); console.log('test db stopped...'); }); -// Set a timeout for jest to allow the containers to initialize -jest.setTimeout(300000); - +jest.setTimeout(10000); export { postgresClient, prismaService }; From 9524caba958eaf1f515b01147aa2c79f45139b87 Mon Sep 17 00:00:00 2001 From: bikilaketema Date: Thu, 29 May 2025 10:49:26 +0300 Subject: [PATCH 3/8] removed th changes come from the 185 branch --- .../admin/mentor/mentor.controller.spec.ts | 125 +----------------- src/modules/admin/mentor/mentor.controller.ts | 4 +- src/modules/admin/mentor/mentor.service.ts | 6 +- 3 files changed, 8 insertions(+), 127 deletions(-) diff --git a/src/modules/admin/mentor/mentor.controller.spec.ts b/src/modules/admin/mentor/mentor.controller.spec.ts index e596383a..5e2153c3 100644 --- a/src/modules/admin/mentor/mentor.controller.spec.ts +++ b/src/modules/admin/mentor/mentor.controller.spec.ts @@ -1,137 +1,18 @@ import { Test, TestingModule } from '@nestjs/testing'; import { MentorController } from './mentor.controller'; -import { MentorService } from './mentor.service'; -import { CreateMentorDto } from './dto/create-mentor.dto'; -import { UpdateMentorDto } from './dto/update-mentor.dto'; -import { GetMentorDto } from './dto/get-mentor.dto'; -import { NotFoundException, ExecutionContext } from '@nestjs/common'; -import { AuthGuard } from '../../auth/guard/auth/auth.guard'; describe('MentorController', () => { let controller: MentorController; - let service: MentorService; - - const mockMentorService = { - findAll: jest.fn(), - findOne: jest.fn(), - create: jest.fn(), - update: jest.fn(), - delete: jest.fn(), - }; - - const mockAuthGuard = { - canActivate: jest.fn((context: ExecutionContext) => true), - }; beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [MentorController], - providers: [ - { - provide: MentorService, - useValue: mockMentorService, - }, - ], - }) - .overrideGuard(AuthGuard) - .useValue(mockAuthGuard) - .compile(); + }).compile(); controller = module.get(MentorController); - service = module.get(MentorService); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - describe('getMentors', () => { - it('should return a list of mentors', async () => { - const result = { data: [], meta: { total: 0, page: 1, limit: 10 } }; - mockMentorService.findAll.mockResolvedValue(result); - - expect(await controller.getMentors({})).toEqual(result); - expect(mockMentorService.findAll).toHaveBeenCalledWith({}); - }); - }); - - describe('findOne', () => { - it('should return a mentor', async () => { - const mentor = { id: '1', name: 'John Doe' }; - mockMentorService.findOne.mockResolvedValue(mentor); - - expect(await controller.findOne('1', new GetMentorDto())).toEqual(mentor); - expect(mockMentorService.findOne).toHaveBeenCalledWith( - '1', - expect.any(GetMentorDto), - ); - }); - - it('should throw NotFoundException if mentor not found', async () => { - mockMentorService.findOne.mockRejectedValue( - new NotFoundException('Mentor not found'), - ); - - await expect(controller.findOne('1', new GetMentorDto())).rejects.toThrow( - NotFoundException, - ); - }); }); - describe('create', () => { - it('should create and return a mentor', async () => { - const createDto: CreateMentorDto = { - name: 'Jane Doe', - email: 'jane@example.com', - accountId: 'acc1', - }; - const mentor = { id: '1', ...createDto }; - mockMentorService.create.mockResolvedValue(mentor); - - expect(await controller.create(createDto)).toEqual(mentor); - expect(mockMentorService.create).toHaveBeenCalledWith(createDto); - }); - }); - - describe('update', () => { - it('should update and return a mentor', async () => { - const updateDto: UpdateMentorDto = { - name: 'Jane Smith', - email: 'jane.smith@example.com', - }; - const mentor = { id: '1', ...updateDto }; - mockMentorService.update.mockResolvedValue(mentor); - - expect(await controller.update('1', updateDto)).toEqual(mentor); - expect(mockMentorService.update).toHaveBeenCalledWith('1', updateDto); - }); - - it('should throw NotFoundException if mentor not found', async () => { - mockMentorService.update.mockRejectedValue( - new NotFoundException('Mentor not found'), - ); - - await expect( - controller.update('1', new UpdateMentorDto()), - ).rejects.toThrow(NotFoundException); - }); - }); - - describe('delete', () => { - it('should delete a mentor and return status', async () => { - const result = { status: true }; - mockMentorService.delete.mockResolvedValue(result); - - expect(await controller.delete('1')).toEqual(result); - expect(mockMentorService.delete).toHaveBeenCalledWith('1'); - }); - - it('should throw NotFoundException if mentor not found', async () => { - mockMentorService.delete.mockRejectedValue( - new NotFoundException('Mentor not found'), - ); - - await expect(controller.delete('1')).rejects.toThrow(NotFoundException); - }); + it('should be defined', () => { + expect(controller).toBeDefined(); }); }); diff --git a/src/modules/admin/mentor/mentor.controller.ts b/src/modules/admin/mentor/mentor.controller.ts index c4b21c1b..71e1c1b5 100644 --- a/src/modules/admin/mentor/mentor.controller.ts +++ b/src/modules/admin/mentor/mentor.controller.ts @@ -11,8 +11,8 @@ import { ValidationPipe, } from '@nestjs/common'; import { MentorService } from './mentor.service'; -import { Roles } from '../../auth/auth.decorator'; -import { AuthGuard } from '../../auth/guard/auth/auth.guard'; +import { Roles } from 'src/modules/auth/auth.decorator'; +import { AuthGuard } from 'src/modules/auth/guard/auth/auth.guard'; import { GetMentorDto } from './dto/get-mentor.dto'; import { CreateMentorDto } from './dto/create-mentor.dto'; import { UpdateMentorDto } from './dto/update-mentor.dto'; diff --git a/src/modules/admin/mentor/mentor.service.ts b/src/modules/admin/mentor/mentor.service.ts index 6f2bab32..cdb41365 100644 --- a/src/modules/admin/mentor/mentor.service.ts +++ b/src/modules/admin/mentor/mentor.service.ts @@ -1,13 +1,13 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; -import { PrismaService } from '../../prisma/prisma.service'; +import { PrismaService } from 'src/modules/prisma/prisma.service'; import { REQUEST } from '@nestjs/core'; import { MentorDto } from './dto/mentor.dto'; import { GetMentorDto } from './dto/get-mentor.dto'; import { CreateMentorDto } from './dto/create-mentor.dto'; import { UpdateMentorDto } from './dto/update-mentor.dto'; import { RoleType } from '@prisma/client'; -import { PaginationResult, paginate } from '../../../common/helpers/pagination'; -import { PaginationDto } from '../../../common/dto/pagination.dto'; +import { PaginationResult, paginate } from 'src/common/helpers/pagination'; +import { PaginationDto } from 'src/common/dto/pagination.dto'; @Injectable() export class MentorService { constructor( From c715aa12e860a2a1305c537e3c2aafac80cba7b2 Mon Sep 17 00:00:00 2001 From: bikilaketema Date: Thu, 29 May 2025 10:51:59 +0300 Subject: [PATCH 4/8] removed anoter change --- src/modules/admin/mentor/dto/mentor.dto.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/admin/mentor/dto/mentor.dto.ts b/src/modules/admin/mentor/dto/mentor.dto.ts index 347c8fdd..0c6843c7 100644 --- a/src/modules/admin/mentor/dto/mentor.dto.ts +++ b/src/modules/admin/mentor/dto/mentor.dto.ts @@ -1,7 +1,7 @@ // src/posts/dto/post.dto.ts import { Expose, Type } from 'class-transformer'; -import { UserDto } from '../../user/dto/user.dto'; +import { UserDto } from 'src/modules/admin/user/dto/user.dto'; export class MentorDto { @Expose() From 809e20b6bc8e77dfb15e89cbbb9fe532dd9a3de7 Mon Sep 17 00:00:00 2001 From: bikilaketema Date: Thu, 29 May 2025 10:54:09 +0300 Subject: [PATCH 5/8] removed another change --- .../admin/mentor/mentor.service.spec.ts | 199 +----------------- 1 file changed, 5 insertions(+), 194 deletions(-) diff --git a/src/modules/admin/mentor/mentor.service.spec.ts b/src/modules/admin/mentor/mentor.service.spec.ts index 7fab6eba..4e7999c8 100644 --- a/src/modules/admin/mentor/mentor.service.spec.ts +++ b/src/modules/admin/mentor/mentor.service.spec.ts @@ -1,207 +1,18 @@ import { Test, TestingModule } from '@nestjs/testing'; import { MentorService } from './mentor.service'; -import { prismaService } from '../../../../test/setupTests.e2e'; -import { PrismaService } from '../../prisma/prisma.service'; -import { RoleType } from '@prisma/client'; -import { REQUEST } from '@nestjs/core'; -import { CreateMentorDto } from './dto/create-mentor.dto'; -import { UpdateMentorDto } from './dto/update-mentor.dto'; -import { NotFoundException } from '@nestjs/common'; -describe('MentorService (Integration)', () => { +describe('MentorService', () => { let service: MentorService; - const mockRequest = { - user: { - id: 'mock-user-id', - accountId: 'mock-account-id', - }, - }; - - beforeAll(async () => { + beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [ - MentorService, - { - provide: PrismaService, - useValue: prismaService, - }, - { provide: REQUEST, useValue: mockRequest }, - ], + providers: [MentorService], }).compile(); service = module.get(MentorService); - - await prismaService.role.create({ - data: { - name: 'Mentor', - type: RoleType.MENTOR, - isDefault: true, - }, - }); - }); - - afterEach(async () => { - await prismaService.accountUser.deleteMany(); - await prismaService.mentor.deleteMany(); - await prismaService.user.deleteMany(); - }); - - it('should create a mentor with a default role', async () => { - const account = await prismaService.account.create({ - data: { - name: 'Test Account', - }, - }); - - const result = await service.create({ - name: 'Bikila Ketema', - email: 'test@mentor.com', - accountId: account.id, - }); - - expect(result.email).toBe('test@mentor.com'); - expect(result.user).toBeDefined(); - - const accountUser = await prismaService.accountUser.findFirst({ - where: { userId: result.user.id }, - include: { Role: true }, - }); - - expect(accountUser?.Role?.type).toBe(RoleType.MENTOR); }); - it('should find a mentor by id with the associated user', async () => { - const account = await prismaService.account.create({ - data: { - name: 'FindOne Test Account', - }, - }); - - const mentor = await prismaService.mentor.create({ - data: { - name: 'Test Mentor', - email: 'findone@mentor.com', - accountId: account.id, - }, - }); - - const user = await prismaService.user.create({ - data: { - name: 'Test Mentor', - email: 'findone@mentor.com', - password: '', - }, - }); - - const result = await service.findOne(mentor.id, { accountId: account.id }); - - expect(result).toBeDefined(); - expect(result.id).toBe(mentor.id); - expect(result.user).toBeDefined(); - expect(result.user.email).toBe('findone@mentor.com'); - }); - - it('should return a paginated list of mentors for the given accountId', async () => { - const account = await prismaService.account.create({ - data: { name: 'FindAll Account' }, - }); - - for (let i = 1; i <= 5; i++) { - await prismaService.mentor.create({ - data: { - name: `Mentor ${i}`, - email: `mentor${i}@test.com`, - accountId: account.id, - }, - }); - } - - const result = await service.findAll({ - accountId: account.id, - page: 1, - limit: 3, - }); - - expect(result).toBeDefined(); - expect(result.data.length).toBeLessThanOrEqual(3); - expect(result.meta.total).toBeGreaterThanOrEqual(5); - expect(result.meta.page).toBe(1); - expect(result.meta.limit).toBe(3); - }); - - it('should update a mentor successfully', async () => { - const account = await prismaService.account.create({ - data: { - name: 'FindOne Test Account', - }, - }); - - const createMentorDto: CreateMentorDto = { - name: 'John Doe', - email: 'johndoe@test.com', - accountId: account.id, - }; - - const createdMentor = await service.create(createMentorDto); - - const updateMentorDto: UpdateMentorDto = { - name: 'John Updated', - email: 'johnupdated@test.com', - availability: JSON.stringify(['Monday', 'Wednesday']), - }; - - const updatedMentor = await service.update( - createdMentor.id, - updateMentorDto, - ); - - expect(updatedMentor).toBeDefined(); - expect(updatedMentor.name).toBe(updateMentorDto.name); - expect(updatedMentor.email).toBe(updateMentorDto.email); - expect(updatedMentor.availability).toEqual( - JSON.parse(updateMentorDto.availability), - ); - }); - - it('should throw an error if mentor is not found', async () => { - const updateMentorDto: UpdateMentorDto = { - name: 'Non-Existent Mentor', - email: 'nonexistent@test.com', - availability: JSON.stringify(['Monday']), - }; - - try { - await service.update('nonexistent-id', updateMentorDto); - } catch (error) { - expect(error).toBeInstanceOf(NotFoundException); - expect(error.message).toBe('Mentor not found'); - } - }); - - it('should delete a mentor successfully', async () => { - const account = await prismaService.account.create({ - data: { - name: 'FindOne Test Account', - }, - }); - - const createMentorDto: CreateMentorDto = { - name: 'John Doe', - email: 'johndoe@test.com', - accountId: account.id, - }; - - const createdMentor = await service.create(createMentorDto); - - const deletedResponse = await service.delete(createdMentor.id); - - expect(deletedResponse.status).toBe(true); - - const deletedMentor = await prismaService.mentor.findUnique({ - where: { id: createdMentor.id }, - }); - - expect(deletedMentor.deletedAt).toBeDefined(); + it('should be defined', () => { + expect(service).toBeDefined(); }); }); From c5839ab89d0a380e58385e2ea0e6e019bf10ae3a Mon Sep 17 00:00:00 2001 From: bikilaketema Date: Thu, 29 May 2025 10:56:04 +0300 Subject: [PATCH 6/8] restored the ts config --- tsconfig.json | 3 --- 1 file changed, 3 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 111e1306..95f5641c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,9 +10,6 @@ "sourceMap": true, "outDir": "./dist", "baseUrl": "./", - "paths": { - "src/*": ["src/*"] - }, "incremental": true, "skipLibCheck": true, "strictNullChecks": false, From 7506af728b42360d661be483772456239b0bb86e Mon Sep 17 00:00:00 2001 From: bikilaketema Date: Thu, 29 May 2025 10:56:59 +0300 Subject: [PATCH 7/8] removed another change --- test/jest-e2e.json | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/test/jest-e2e.json b/test/jest-e2e.json index 490dbf34..ac432d93 100644 --- a/test/jest-e2e.json +++ b/test/jest-e2e.json @@ -1,14 +1,9 @@ { "moduleFileExtensions": ["js", "json", "ts"], - "rootDir": "../", - "roots": ["/src"], - "setupFilesAfterEnv": ["/test/setupTests.e2e.ts"], + "rootDir": ".", "testEnvironment": "node", "testRegex": ".e2e-spec.ts$", "transform": { "^.+\\.(t|j)s$": "ts-jest" - }, - "moduleNameMapper": { - "^src/(.*)$": "/src/$1" } -} +} \ No newline at end of file From 05ce4cba25c224c3bc6f27330f48a320abb2dd86 Mon Sep 17 00:00:00 2001 From: bikilaketema Date: Thu, 29 May 2025 11:00:57 +0300 Subject: [PATCH 8/8] added jest --- jest.config.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 jest.config.ts diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 00000000..ce9e05b2 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,17 @@ +// jest.config.ts +import { Config } from 'jest'; + +const config: Config = { + moduleFileExtensions: ['js', 'json', 'ts'], + rootDir: '.', + testRegex: '.spec.ts$', + transform: { + '^.+\\.(t|j)s$': 'ts-jest', + }, + moduleNameMapper: { + '^src/(.*)$': '/src/$1', + }, + testEnvironment: 'node', +}; + +export default config;