add istanbul for coverage, unit tests for resposne bodies, add coverage here and there
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -24,4 +24,5 @@ vite.config.ts.timestamp-*
|
||||
|
||||
# Development
|
||||
cert
|
||||
.vscode
|
||||
.vscode
|
||||
coverage
|
463
package-lock.json
generated
463
package-lock.json
generated
@ -21,6 +21,7 @@
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/jsonwebtoken": "^9.0.7",
|
||||
"@types/node": "^22.10.7",
|
||||
"@vitest/coverage-istanbul": "^2.1.8",
|
||||
"@vitest/coverage-v8": "^2.1.8",
|
||||
"eslint": "^9.7.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
@ -50,10 +51,169 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.2.tgz",
|
||||
"integrity": "sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/core": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.1.tgz",
|
||||
"integrity": "sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.0",
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.27.1",
|
||||
"@babel/helper-compilation-targets": "^7.27.1",
|
||||
"@babel/helper-module-transforms": "^7.27.1",
|
||||
"@babel/helpers": "^7.27.1",
|
||||
"@babel/parser": "^7.27.1",
|
||||
"@babel/template": "^7.27.1",
|
||||
"@babel/traverse": "^7.27.1",
|
||||
"@babel/types": "^7.27.1",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.2",
|
||||
"json5": "^2.2.3",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/babel"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/core/node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.1.tgz",
|
||||
"integrity": "sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.27.1",
|
||||
"@babel/types": "^7.27.1",
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25",
|
||||
"jsesc": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-compilation-targets": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
|
||||
"integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.27.2",
|
||||
"@babel/helper-validator-option": "^7.27.1",
|
||||
"browserslist": "^4.24.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/@babel/helper-module-imports": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
|
||||
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/traverse": "^7.27.1",
|
||||
"@babel/types": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-module-transforms": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz",
|
||||
"integrity": "sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"@babel/traverse": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
|
||||
"integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@ -61,23 +221,47 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.25.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
|
||||
"integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
|
||||
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.26.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz",
|
||||
"integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==",
|
||||
"node_modules/@babel/helper-validator-option": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
|
||||
"integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.1.tgz",
|
||||
"integrity": "sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.26.7"
|
||||
"@babel/template": "^7.27.1",
|
||||
"@babel/types": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz",
|
||||
"integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.27.1"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@ -86,15 +270,59 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.26.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz",
|
||||
"integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==",
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
|
||||
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.25.9",
|
||||
"@babel/helper-validator-identifier": "^7.25.9"
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/parser": "^7.27.2",
|
||||
"@babel/types": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.1.tgz",
|
||||
"integrity": "sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.27.1",
|
||||
"@babel/parser": "^7.27.1",
|
||||
"@babel/template": "^7.27.1",
|
||||
"@babel/types": "^7.27.1",
|
||||
"debug": "^4.3.1",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse/node_modules/globals": {
|
||||
"version": "11.12.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
|
||||
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz",
|
||||
"integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -1567,6 +1795,31 @@
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-istanbul": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-istanbul/-/coverage-istanbul-2.1.8.tgz",
|
||||
"integrity": "sha512-cSaCd8KcWWvgDwEJSXm0NEWZ1YTiJzjicKHy+zOEbUm0gjbbkz+qJf1p8q71uBzSlS7vdnZA8wRLeiwVE3fFTA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@istanbuljs/schema": "^0.1.3",
|
||||
"debug": "^4.3.7",
|
||||
"istanbul-lib-coverage": "^3.2.2",
|
||||
"istanbul-lib-instrument": "^6.0.3",
|
||||
"istanbul-lib-report": "^3.0.1",
|
||||
"istanbul-lib-source-maps": "^5.0.6",
|
||||
"istanbul-reports": "^3.1.7",
|
||||
"magicast": "^0.3.5",
|
||||
"test-exclude": "^7.0.1",
|
||||
"tinyrainbow": "^1.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vitest": "2.1.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-v8": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.8.tgz",
|
||||
@ -1906,6 +2159,39 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.24.5",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.5.tgz",
|
||||
"integrity": "sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001716",
|
||||
"electron-to-chromium": "^1.5.149",
|
||||
"node-releases": "^2.0.19",
|
||||
"update-browserslist-db": "^1.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"browserslist": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||
}
|
||||
},
|
||||
"node_modules/bson": {
|
||||
"version": "6.10.1",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-6.10.1.tgz",
|
||||
@ -1941,6 +2227,27 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001718",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz",
|
||||
"integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/chai": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz",
|
||||
@ -2061,6 +2368,13 @@
|
||||
"integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
||||
@ -2181,6 +2495,13 @@
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.152",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.152.tgz",
|
||||
"integrity": "sha512-xBOfg/EBaIlVsHipHl2VdTPJRSvErNUaqW8ejTq5OlOlIYx1wOllCHsAvAIrr55jD1IYEfdR86miUEt8H5IeJg==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
@ -2233,6 +2554,16 @@
|
||||
"@esbuild/win32-x64": "0.21.5"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
@ -2737,6 +3068,16 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
@ -2975,6 +3316,23 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/istanbul-lib-instrument": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
|
||||
"integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/parser": "^7.23.9",
|
||||
"@istanbuljs/schema": "^0.1.3",
|
||||
"istanbul-lib-coverage": "^3.2.0",
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/istanbul-lib-report": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
|
||||
@ -3051,6 +3409,13 @@
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
@ -3064,6 +3429,19 @@
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsesc": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
|
||||
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jsesc": "bin/jsesc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
@ -3085,6 +3463,19 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonwebtoken": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
|
||||
@ -3568,6 +3959,13 @@
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
||||
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nopt": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
|
||||
@ -4689,6 +5087,37 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
||||
"integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"escalade": "^3.2.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"update-browserslist-db": "cli.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"browserslist": ">= 4.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uri-js": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
|
||||
|
@ -23,6 +23,7 @@
|
||||
"@types/bcrypt": "^5.0.2",
|
||||
"@types/jsonwebtoken": "^9.0.7",
|
||||
"@types/node": "^22.10.7",
|
||||
"@vitest/coverage-istanbul": "^2.1.8",
|
||||
"@vitest/coverage-v8": "^2.1.8",
|
||||
"eslint": "^9.7.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { hasProperty } from "./validation";
|
||||
import { hasProperty, hasOnlyKeys } from "./validation";
|
||||
|
||||
export interface Me {
|
||||
id: string;
|
||||
@ -10,5 +10,6 @@ export function isMe(target: unknown): target is Me {
|
||||
if (!hasProperty(target, "id", "string")) return false;
|
||||
if (!hasProperty(target, "role", "string")) return false;
|
||||
if (!hasProperty(target, "username", "string")) return false;
|
||||
if (!hasOnlyKeys(target, ["id", "role", "username"])) return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -1,19 +1,21 @@
|
||||
import { describe, it } from "vitest";
|
||||
import { Game } from "$lib/server/Game";
|
||||
import { deepEqual, ok, throws } from "node:assert/strict";
|
||||
import { createId, idFromString, stringFromId } from "$lib/Id";
|
||||
import { equal } from "node:assert";
|
||||
import { ok, throws } from "node:assert/strict";
|
||||
import { createId } from "$lib/Id";
|
||||
import { equal, deepEqual } from "node:assert";
|
||||
|
||||
describe("Game", () => {
|
||||
const idString = stringFromId(createId());
|
||||
const idString = createId();
|
||||
describe("addPlayer", () => {
|
||||
it("should push a player id into the player array", () => {
|
||||
const game = new Game();
|
||||
deepEqual(game.players, []);
|
||||
const user = "Mr. User";
|
||||
|
||||
game.addPlayer(idFromString(idString));
|
||||
equal(game.players.length, 0);
|
||||
|
||||
game.addPlayer(idString, user);
|
||||
equal(game.players.length, 1);
|
||||
equal(stringFromId(game.players[0]), idString);
|
||||
deepEqual(game.players[0], { id: idString, username: user });
|
||||
});
|
||||
});
|
||||
|
||||
|
98
src/lib/server/test/responseBodies.spec.ts
Normal file
98
src/lib/server/test/responseBodies.spec.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { describe, it } from "vitest";
|
||||
import {
|
||||
listResponse,
|
||||
singleResponse,
|
||||
createdResponse,
|
||||
tokenResponse,
|
||||
badRequestResponse,
|
||||
notFoundResponse,
|
||||
serverErrorResponse,
|
||||
unauthorizedResponse,
|
||||
forbiddenResponse,
|
||||
} from "../responseBodies";
|
||||
import { deepEqual, equal } from "assert";
|
||||
import { createId } from "$lib/Id";
|
||||
|
||||
describe("responseBodies", () => {
|
||||
describe("the following response body functions return expected response", () => {
|
||||
it("listResponse", async () => {
|
||||
const expected = [{ some: "item", another: "thing" }];
|
||||
const { body, status } = await unwrapResponse(listResponse, expected);
|
||||
|
||||
deepEqual(body, { items: expected });
|
||||
equal(status, 200);
|
||||
});
|
||||
|
||||
it("singleResponse", async () => {
|
||||
const expected = { some: "item" };
|
||||
const { body, status } = await unwrapResponse(singleResponse, expected);
|
||||
|
||||
deepEqual(body, { item: expected });
|
||||
equal(status, 200);
|
||||
});
|
||||
|
||||
it("createdResponse", async () => {
|
||||
const expectedId = createId();
|
||||
const { body, status } = await unwrapResponse(createdResponse, expectedId);
|
||||
|
||||
deepEqual(body, { item: expectedId });
|
||||
equal(status, 201);
|
||||
});
|
||||
|
||||
it("tokenResponse", async () => {
|
||||
const token = "some-generated-token";
|
||||
const { body, status } = await unwrapResponse(tokenResponse, token);
|
||||
|
||||
deepEqual(body, { access_token: token });
|
||||
equal(status, 200);
|
||||
});
|
||||
|
||||
it("badRequestResponse", async () => {
|
||||
const errorString = "something bad happened";
|
||||
let { body, status } = await unwrapResponse(badRequestResponse, errorString);
|
||||
|
||||
deepEqual(body, { error: errorString });
|
||||
equal(status, 400);
|
||||
|
||||
const res = await unwrapResponse(badRequestResponse);
|
||||
body = res.body;
|
||||
status = res.status;
|
||||
|
||||
deepEqual(body, { error: "Bad Request" });
|
||||
equal(status, 400);
|
||||
});
|
||||
|
||||
it("notFoundResponse", async () => {
|
||||
const { body, status } = await unwrapResponse(notFoundResponse);
|
||||
|
||||
deepEqual(body, { error: "Not Found" });
|
||||
equal(status, 404);
|
||||
});
|
||||
|
||||
it("serverErrorResponse", async () => {
|
||||
const { body, status } = await unwrapResponse(serverErrorResponse);
|
||||
|
||||
deepEqual(body, { error: "Unexpected Server Error" });
|
||||
equal(status, 500);
|
||||
});
|
||||
|
||||
it("unauthorizedResponse", async () => {
|
||||
const { body, status } = await unwrapResponse(unauthorizedResponse);
|
||||
|
||||
deepEqual(body, { error: "Unauthorized" });
|
||||
equal(status, 401);
|
||||
});
|
||||
|
||||
it("forbiddenResponse", async () => {
|
||||
const { body, status } = await unwrapResponse(forbiddenResponse);
|
||||
|
||||
deepEqual(body, { error: "Forbidden" });
|
||||
equal(status, 403);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function unwrapResponse(fn: Function, body?: unknown) {
|
||||
const res = fn(body);
|
||||
return { status: res.status, body: await res.json() };
|
||||
}
|
@ -1,34 +1,44 @@
|
||||
import { describe, it } from "vitest";
|
||||
import { type GameData, isGameData } from "$lib/GameData";
|
||||
import { isGameData } from "$lib/GameData";
|
||||
import { equal, ok } from "node:assert/strict";
|
||||
import { createId, idFromString, stringFromId } from "$lib/Id";
|
||||
import { createId } from "$lib/Id";
|
||||
|
||||
describe("GameData", () => {
|
||||
const idString = stringFromId(createId());
|
||||
const idString = createId();
|
||||
|
||||
describe("isGameData", () => {
|
||||
it("rejects a malformed object", () => {
|
||||
let data: unknown = {
|
||||
players: [idFromString(idString), idString],
|
||||
players: [idString, idString],
|
||||
isStarted: false,
|
||||
state: {},
|
||||
};
|
||||
equal(isGameData(data), false);
|
||||
|
||||
data = {
|
||||
players: [idFromString(idString)],
|
||||
players: [idString],
|
||||
isStarted: null,
|
||||
state: {},
|
||||
};
|
||||
equal(isGameData(data), false);
|
||||
|
||||
data = {
|
||||
players: [idFromString(idString)],
|
||||
players: [{ username: "Mr. User", id: idString }],
|
||||
isStarted: false,
|
||||
};
|
||||
equal(isGameData(data), false);
|
||||
});
|
||||
|
||||
it("rejects an object with a malformed players array", () => {
|
||||
const data: unknown = {
|
||||
players: [{ id: idString }],
|
||||
state: {},
|
||||
isStarted: false,
|
||||
};
|
||||
|
||||
equal(isGameData(data), false);
|
||||
});
|
||||
|
||||
it("rejects an object without a players property", () => {
|
||||
const data: unknown = {
|
||||
state: {},
|
||||
@ -40,7 +50,7 @@ describe("GameData", () => {
|
||||
|
||||
it("rejects an object with extra properties", () => {
|
||||
const data: unknown = {
|
||||
players: [idFromString(idString)],
|
||||
players: [{ username: "Mr. User", id: idString }],
|
||||
isStarted: false,
|
||||
state: {},
|
||||
extra: true,
|
||||
@ -50,8 +60,8 @@ describe("GameData", () => {
|
||||
});
|
||||
|
||||
it("should accept a proper GameData object", () => {
|
||||
const data: GameData = {
|
||||
players: [idFromString(idString)],
|
||||
const data: unknown = {
|
||||
players: [{ username: "Mr. User", id: idString }],
|
||||
state: {},
|
||||
isStarted: false,
|
||||
};
|
||||
|
@ -15,7 +15,7 @@ import type { GameData } from "$lib/GameData";
|
||||
import { describe, it } from "vitest";
|
||||
import type { State } from "$lib/State";
|
||||
import { doesNotThrow, deepStrictEqual, equal, ok, throws } from "assert";
|
||||
import { createId, idFromString, stringFromId } from "$lib/Id";
|
||||
import { createId } from "$lib/Id";
|
||||
|
||||
describe("Game Events", () => {
|
||||
describe("isGameEventData", () => {
|
||||
@ -55,13 +55,20 @@ describe("Game Events", () => {
|
||||
});
|
||||
|
||||
describe("getGameEvent", () => {
|
||||
const idString = stringFromId(createId());
|
||||
const anotherIdString = stringFromId(createId());
|
||||
const playerOne = {
|
||||
id: createId(),
|
||||
username: "Player One",
|
||||
};
|
||||
|
||||
const playerTwo = {
|
||||
id: createId(),
|
||||
username: "Player Two",
|
||||
};
|
||||
|
||||
it("should throw if the kind is unkown", () => {
|
||||
const data: GameData = {
|
||||
isStarted: false,
|
||||
players: [idFromString(idString), idFromString(anotherIdString)],
|
||||
players: [playerOne, playerTwo],
|
||||
state: {},
|
||||
};
|
||||
|
||||
@ -77,7 +84,7 @@ describe("Game Events", () => {
|
||||
it("should throw when SeatPlayers has the wrong number of players", () => {
|
||||
const data: GameData = {
|
||||
isStarted: true,
|
||||
players: [idFromString(idString), idFromString(anotherIdString)],
|
||||
players: [playerOne, playerTwo],
|
||||
state: {},
|
||||
};
|
||||
|
||||
@ -92,7 +99,7 @@ describe("Game Events", () => {
|
||||
it("should return a SeatPlayers object when the number of players is correct", () => {
|
||||
const data: GameData = {
|
||||
isStarted: true,
|
||||
players: [idFromString(idString), idFromString(anotherIdString)],
|
||||
players: [playerOne, playerTwo],
|
||||
state: {},
|
||||
};
|
||||
|
||||
@ -107,7 +114,7 @@ describe("Game Events", () => {
|
||||
it("should throw an error if the player passes a full roll with Roll", () => {
|
||||
const data: GameData = {
|
||||
isStarted: true,
|
||||
players: [idFromString(idString), idFromString(anotherIdString)],
|
||||
players: [playerOne, playerTwo],
|
||||
state: {},
|
||||
};
|
||||
|
||||
@ -123,7 +130,7 @@ describe("Game Events", () => {
|
||||
it("should return a Roll object with dice values when the player passes a die count as a value", () => {
|
||||
const data: GameData = {
|
||||
isStarted: true,
|
||||
players: [idFromString(idString), idFromString(anotherIdString)],
|
||||
players: [playerOne, playerTwo],
|
||||
state: {},
|
||||
};
|
||||
|
||||
@ -143,7 +150,7 @@ describe("Game Events", () => {
|
||||
it("should return the class that corresponds with a given kind", () => {
|
||||
const data: GameData = {
|
||||
isStarted: true,
|
||||
players: [idFromString(idString), idFromString(anotherIdString)],
|
||||
players: [playerOne, playerTwo],
|
||||
state: {},
|
||||
};
|
||||
|
||||
@ -754,7 +761,7 @@ describe("Game Events", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow the player to hold 2 threes of a kind for 1,500 points", () => {
|
||||
it("should allow the player to hold 2 threes of a kind for 1,600 points", () => {
|
||||
const state: State = {
|
||||
dice: [2, 2, 2, 3, 3, 3],
|
||||
playing: 0,
|
||||
@ -770,7 +777,7 @@ describe("Game Events", () => {
|
||||
|
||||
deepStrictEqual(state, {
|
||||
dieCount: 6,
|
||||
heldScore: 1_500,
|
||||
heldScore: 1_600,
|
||||
playing: 0,
|
||||
scores: [0, 0, 0],
|
||||
});
|
||||
|
30
src/lib/test/me.spec.ts
Normal file
30
src/lib/test/me.spec.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { createId } from "$lib/Id";
|
||||
import { isMe, type Me } from "$lib/me";
|
||||
import { equal, ok } from "assert";
|
||||
import { describe, it } from "vitest";
|
||||
|
||||
describe("me", () => {
|
||||
describe("isMe", () => {
|
||||
const target: Me = {
|
||||
id: createId(),
|
||||
role: "test-role",
|
||||
username: "Ms. User",
|
||||
};
|
||||
|
||||
it("returns true when the target is shaped like a 'Me'", () => {
|
||||
ok(isMe(target));
|
||||
});
|
||||
|
||||
it("returns false when the target is missing a property", () => {
|
||||
const { id, role, username } = target;
|
||||
equal(isMe({ role, username }), false);
|
||||
equal(isMe({ id, username }), false);
|
||||
equal(isMe({ id, role }), false);
|
||||
});
|
||||
|
||||
it("returns false when the target has an extra property", () => {
|
||||
const { id, role, username } = target;
|
||||
equal(isMe({ id, role, username, extra: "something" }), false);
|
||||
});
|
||||
});
|
||||
});
|
@ -16,6 +16,7 @@ export default defineConfig({
|
||||
test: {
|
||||
include: ["src/**/*.{test,spec}.{js,ts}"],
|
||||
coverage: {
|
||||
provider: "istanbul",
|
||||
exclude: [...coverageConfigDefaults.exclude, "svelte.config.js"],
|
||||
},
|
||||
environment: "jsdom",
|
||||
|
Reference in New Issue
Block a user