From 7911859d3f1d81903bfc653fd75883b95c4824fb Mon Sep 17 00:00:00 2001 From: BrandonSokolowskiWSU Date: Thu, 11 Apr 2024 23:08:46 -0400 Subject: [PATCH 1/2] Unit testing for functions in weather page. --- package-lock.json | 248 ++++++++++++++++------- package.json | 4 +- src/test/api/databaseManager.test.js | 113 ----------- src/test/api/userVerification.test.js | 150 -------------- src/test/components/TripSelector.test.js | 45 ---- src/test/weather_funct.test.js | 31 +++ src/views/Weather.vue | 13 ++ 7 files changed, 222 insertions(+), 382 deletions(-) delete mode 100644 src/test/api/databaseManager.test.js delete mode 100644 src/test/api/userVerification.test.js delete mode 100644 src/test/components/TripSelector.test.js create mode 100644 src/test/weather_funct.test.js diff --git a/package-lock.json b/package-lock.json index bc911e4..8784276 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,6 @@ "aws-sdk": "^2.1550.0", "axios": "^1.6.7", "bootstrap": "^5.3.2", - "vitest": "^1.3.1", "vue": "^3.4.15", "vue-router": "^4.2.5", "vuex": "^4.0.2", @@ -27,7 +26,8 @@ "@vue/test-utils": "^2.4.4", "happy-dom": "^13.7.3", "sass": "^1.70.0", - "vite": "^5.0.11" + "vite": "^5.0.11", + "vitest": "^1.5.0" } }, "node_modules/@aws-crypto/sha256-js": { @@ -98,6 +98,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "aix" @@ -113,6 +114,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -128,6 +130,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -143,6 +146,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "android" @@ -158,6 +162,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -173,6 +178,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -188,6 +194,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -203,6 +210,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "freebsd" @@ -218,6 +226,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -233,6 +242,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -248,6 +258,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "linux" @@ -263,6 +274,7 @@ "cpu": [ "loong64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -278,6 +290,7 @@ "cpu": [ "mips64el" ], + "dev": true, "optional": true, "os": [ "linux" @@ -293,6 +306,7 @@ "cpu": [ "ppc64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -308,6 +322,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -323,6 +338,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -338,6 +354,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -353,6 +370,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "netbsd" @@ -368,6 +386,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "openbsd" @@ -383,6 +402,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "sunos" @@ -398,6 +418,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -413,6 +434,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -428,6 +450,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -496,6 +519,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -540,6 +564,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "android" @@ -552,6 +577,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "android" @@ -564,6 +590,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -576,6 +603,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "darwin" @@ -588,6 +616,7 @@ "cpu": [ "arm" ], + "dev": true, "optional": true, "os": [ "linux" @@ -600,6 +629,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -612,6 +642,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -624,6 +655,7 @@ "cpu": [ "ppc64le" ], + "dev": true, "optional": true, "os": [ "linux" @@ -636,6 +668,7 @@ "cpu": [ "riscv64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -648,6 +681,7 @@ "cpu": [ "s390x" ], + "dev": true, "optional": true, "os": [ "linux" @@ -660,6 +694,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -672,6 +707,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "linux" @@ -684,6 +720,7 @@ "cpu": [ "arm64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -696,6 +733,7 @@ "cpu": [ "ia32" ], + "dev": true, "optional": true, "os": [ "win32" @@ -708,6 +746,7 @@ "cpu": [ "x64" ], + "dev": true, "optional": true, "os": [ "win32" @@ -716,7 +755,8 @@ "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true }, "node_modules/@smithy/types": { "version": "2.11.0", @@ -737,7 +777,8 @@ "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true }, "node_modules/@vitejs/plugin-vue": { "version": "5.0.4", @@ -753,12 +794,13 @@ } }, "node_modules/@vitest/expect": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.3.1.tgz", - "integrity": "sha512-xofQFwIzfdmLLlHa6ag0dPV8YsnKOCP1KdAeVVh34vSjN2dcUiXYCD9htu/9eM7t8Xln4v03U9HLxLpPlsXdZw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.0.tgz", + "integrity": "sha512-0pzuCI6KYi2SIC3LQezmxujU9RK/vwC1U9R0rLuGlNGcOuDWxqWKu6nUdFsX9tH1WU0SXtAxToOsEjeUn1s3hA==", + "dev": true, "dependencies": { - "@vitest/spy": "1.3.1", - "@vitest/utils": "1.3.1", + "@vitest/spy": "1.5.0", + "@vitest/utils": "1.5.0", "chai": "^4.3.10" }, "funding": { @@ -766,11 +808,12 @@ } }, "node_modules/@vitest/runner": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.3.1.tgz", - "integrity": "sha512-5FzF9c3jG/z5bgCnjr8j9LNq/9OxV2uEBAITOXfoe3rdZJTdO7jzThth7FXv/6b+kdY65tpRQB7WaKhNZwX+Kg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.0.tgz", + "integrity": "sha512-7HWwdxXP5yDoe7DTpbif9l6ZmDwCzcSIK38kTSIt6CFEpMjX4EpCgT6wUmS0xTXqMI6E/ONmfgRKmaujpabjZQ==", + "dev": true, "dependencies": { - "@vitest/utils": "1.3.1", + "@vitest/utils": "1.5.0", "p-limit": "^5.0.0", "pathe": "^1.1.1" }, @@ -779,9 +822,10 @@ } }, "node_modules/@vitest/snapshot": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.3.1.tgz", - "integrity": "sha512-EF++BZbt6RZmOlE3SuTPu/NfwBF6q4ABS37HHXzs2LUVPBLx2QoY/K0fKpRChSo8eLiuxcbCVfqKgx/dplCDuQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.0.tgz", + "integrity": "sha512-qpv3fSEuNrhAO3FpH6YYRdaECnnRjg9VxbhdtPwPRnzSfHVXnNzzrpX4cJxqiwgRMo7uRMWDFBlsBq4Cr+rO3A==", + "dev": true, "dependencies": { "magic-string": "^0.30.5", "pathe": "^1.1.1", @@ -792,9 +836,10 @@ } }, "node_modules/@vitest/spy": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.3.1.tgz", - "integrity": "sha512-xAcW+S099ylC9VLU7eZfdT9myV67Nor9w9zhf0mGCYJSO+zM2839tOeROTdikOi/8Qeusffvxb/MyBSOja1Uig==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.0.tgz", + "integrity": "sha512-vu6vi6ew5N5MMHJjD5PoakMRKYdmIrNJmyfkhRpQt5d9Ewhw9nZ5Aqynbi3N61bvk9UvZ5UysMT6ayIrZ8GA9w==", + "dev": true, "dependencies": { "tinyspy": "^2.2.0" }, @@ -803,9 +848,10 @@ } }, "node_modules/@vitest/utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.3.1.tgz", - "integrity": "sha512-d3Waie/299qqRyHTm2DjADeTaNdNSVsnwHPWrs20JMpjh6eiVq7ggggweO8rc4arhf6rRkWuHKwvxGvejUXZZQ==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.0.tgz", + "integrity": "sha512-BDU0GNL8MWkRkSRdNFvCUCAVOeHaUlVJ9Tx0TYBZyXaaOTmGtUFObzchCivIBrIwKzvZA7A9sCejVhXM2aY98A==", + "dev": true, "dependencies": { "diff-sequences": "^29.6.3", "estree-walker": "^3.0.3", @@ -953,6 +999,7 @@ "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "dev": true, "bin": { "acorn": "bin/acorn" }, @@ -964,6 +1011,7 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "dev": true, "engines": { "node": ">=0.4.0" } @@ -996,6 +1044,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, "engines": { "node": ">=10" }, @@ -1007,7 +1056,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "devOptional": true, + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1020,6 +1069,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, "engines": { "node": "*" } @@ -1103,7 +1153,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8" } @@ -1139,7 +1189,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "devOptional": true, + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -1161,6 +1211,7 @@ "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, "engines": { "node": ">=8" } @@ -1187,6 +1238,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", + "dev": true, "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.3", @@ -1204,6 +1256,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, "dependencies": { "get-func-name": "^2.0.2" }, @@ -1215,7 +1268,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "devOptional": true, + "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -1287,6 +1340,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1305,6 +1359,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1321,6 +1376,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", + "dev": true, "dependencies": { "type-detect": "^4.0.0" }, @@ -1364,6 +1420,7 @@ "version": "29.6.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } @@ -1432,6 +1489,7 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -1469,6 +1527,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -1485,6 +1544,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dev": true, "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", @@ -1512,7 +1572,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "devOptional": true, + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1585,6 +1645,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -1606,6 +1667,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, "engines": { "node": "*" } @@ -1632,6 +1694,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, "engines": { "node": ">=16" }, @@ -1665,7 +1728,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "devOptional": true, + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -1688,7 +1751,7 @@ "version": "13.7.3", "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-13.7.3.tgz", "integrity": "sha512-xMwilTgO34BGEX0TAoM369wwwAy0fK/Jq6BGaRYhSjxLtfQ740nqxHfjFyBqPjCVmKiPUS4npBnMrGLii7eCOg==", - "devOptional": true, + "dev": true, "dependencies": { "entities": "^4.5.0", "webidl-conversions": "^7.0.0", @@ -1760,6 +1823,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, "engines": { "node": ">=16.17.0" } @@ -1773,7 +1837,7 @@ "version": "4.3.5", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==", - "devOptional": true + "dev": true }, "node_modules/inherits": { "version": "2.0.4", @@ -1805,7 +1869,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "devOptional": true, + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1828,7 +1892,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1860,7 +1924,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "devOptional": true, + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -1872,7 +1936,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.12.0" } @@ -1881,6 +1945,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "dev": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -1910,7 +1975,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "node_modules/isomorphic-unfetch": { "version": "3.1.0", @@ -1985,17 +2051,20 @@ "node_modules/js-tokens": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-8.0.3.tgz", - "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==" + "integrity": "sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==", + "dev": true }, "node_modules/jsonc-parser": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==" + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true }, "node_modules/local-pkg": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, "dependencies": { "mlly": "^1.4.2", "pkg-types": "^1.0.3" @@ -2011,6 +2080,7 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, "dependencies": { "get-func-name": "^2.0.1" } @@ -2038,7 +2108,8 @@ "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "node_modules/mime-db": { "version": "1.52.0", @@ -2063,6 +2134,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, "engines": { "node": ">=12" }, @@ -2098,6 +2170,7 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", + "dev": true, "dependencies": { "acorn": "^8.11.3", "pathe": "^1.1.2", @@ -2108,7 +2181,8 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/nanoid": { "version": "3.3.7", @@ -2165,7 +2239,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2174,6 +2248,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dev": true, "dependencies": { "path-key": "^4.0.0" }, @@ -2188,6 +2263,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, "engines": { "node": ">=12" }, @@ -2199,6 +2275,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dev": true, "dependencies": { "mimic-fn": "^4.0.0" }, @@ -2213,6 +2290,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz", "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==", + "dev": true, "dependencies": { "yocto-queue": "^1.0.0" }, @@ -2227,6 +2305,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "engines": { "node": ">=8" } @@ -2250,12 +2329,14 @@ "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true }, "node_modules/pathval": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, "engines": { "node": "*" } @@ -2269,7 +2350,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "devOptional": true, + "dev": true, "engines": { "node": ">=8.6" }, @@ -2281,6 +2362,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", + "dev": true, "dependencies": { "jsonc-parser": "^3.2.0", "mlly": "^1.2.0", @@ -2326,6 +2408,7 @@ "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", @@ -2363,13 +2446,14 @@ "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "devOptional": true, + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -2381,6 +2465,7 @@ "version": "4.14.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.14.0.tgz", "integrity": "sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==", + "dev": true, "dependencies": { "@types/estree": "1.0.5" }, @@ -2414,7 +2499,7 @@ "version": "1.71.1", "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.1.tgz", "integrity": "sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg==", - "devOptional": true, + "dev": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -2479,6 +2564,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -2490,6 +2576,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "engines": { "node": ">=8" } @@ -2497,12 +2584,14 @@ "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==" + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "engines": { "node": ">=14" }, @@ -2521,12 +2610,14 @@ "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==" + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true }, "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" + "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "dev": true }, "node_modules/string-width": { "version": "5.1.2", @@ -2628,6 +2719,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "dev": true, "engines": { "node": ">=12" }, @@ -2639,6 +2731,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.0.0.tgz", "integrity": "sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==", + "dev": true, "dependencies": { "js-tokens": "^8.0.2" }, @@ -2649,12 +2742,14 @@ "node_modules/tinybench": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", - "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==" + "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", + "dev": true }, "node_modules/tinypool": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.2.tgz", - "integrity": "sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.3.tgz", + "integrity": "sha512-Ud7uepAklqRH1bvwy22ynrliC7Dljz7Tm8M/0RBUW+YRa4YHhZ6e4PpgE+fu1zr/WqB1kbeuVrdfeuyIBpy4tw==", + "dev": true, "engines": { "node": ">=14.0.0" } @@ -2663,6 +2758,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", + "dev": true, "engines": { "node": ">=14.0.0" } @@ -2671,7 +2767,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "devOptional": true, + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -2693,6 +2789,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, "engines": { "node": ">=4" } @@ -2700,7 +2797,8 @@ "node_modules/ufo": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.4.0.tgz", - "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==" + "integrity": "sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ==", + "dev": true }, "node_modules/unfetch": { "version": "4.2.0", @@ -2740,6 +2838,7 @@ "version": "5.2.8", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.8.tgz", "integrity": "sha512-OyZR+c1CE8yeHw5V5t59aXsUPPVTHMDjEZz8MgguLL/Q7NblxhZUlTu9xSPqlsUO/y+X7dlU05jdhvyycD55DA==", + "dev": true, "dependencies": { "esbuild": "^0.20.1", "postcss": "^8.4.38", @@ -2791,9 +2890,10 @@ } }, "node_modules/vite-node": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.3.1.tgz", - "integrity": "sha512-azbRrqRxlWTJEVbzInZCTchx0X69M/XPTCz4H+TLvlTcR/xH/3hkRqhOakT41fMJCMzXTu4UvegkZiEoJAWvng==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.0.tgz", + "integrity": "sha512-tV8h6gMj6vPzVCa7l+VGq9lwoJjW8Y79vst8QZZGiuRAfijU+EEWuc0kFpmndQrWhMMhet1jdSF+40KSZUqIIw==", + "dev": true, "dependencies": { "cac": "^6.7.14", "debug": "^4.3.4", @@ -2812,15 +2912,16 @@ } }, "node_modules/vitest": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.3.1.tgz", - "integrity": "sha512-/1QJqXs8YbCrfv/GPQ05wAZf2eakUPLPa18vkJAKE7RXOKfVHqMZZ1WlTjiwl6Gcn65M5vpNUB6EFLnEdRdEXQ==", - "dependencies": { - "@vitest/expect": "1.3.1", - "@vitest/runner": "1.3.1", - "@vitest/snapshot": "1.3.1", - "@vitest/spy": "1.3.1", - "@vitest/utils": "1.3.1", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.0.tgz", + "integrity": "sha512-d8UKgR0m2kjdxDWX6911uwxout6GHS0XaGH1cksSIVVG8kRlE7G7aBw7myKQCvDI5dT4j7ZMa+l706BIORMDLw==", + "dev": true, + "dependencies": { + "@vitest/expect": "1.5.0", + "@vitest/runner": "1.5.0", + "@vitest/snapshot": "1.5.0", + "@vitest/spy": "1.5.0", + "@vitest/utils": "1.5.0", "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", @@ -2832,9 +2933,9 @@ "std-env": "^3.5.0", "strip-literal": "^2.0.0", "tinybench": "^2.5.1", - "tinypool": "^0.8.2", + "tinypool": "^0.8.3", "vite": "^5.0.0", - "vite-node": "1.3.1", + "vite-node": "1.5.0", "why-is-node-running": "^2.2.2" }, "bin": { @@ -2849,8 +2950,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.3.1", - "@vitest/ui": "1.3.1", + "@vitest/browser": "1.5.0", + "@vitest/ui": "1.5.0", "happy-dom": "*", "jsdom": "*" }, @@ -2942,7 +3043,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "devOptional": true, + "dev": true, "engines": { "node": ">=12" } @@ -2951,7 +3052,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "devOptional": true, + "dev": true, "engines": { "node": ">=12" } @@ -2974,6 +3075,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -3006,6 +3108,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", + "dev": true, "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" @@ -3150,6 +3253,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, "engines": { "node": ">=12.20" }, diff --git a/package.json b/package.json index cc5fc75..e1ce645 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,6 @@ "aws-sdk": "^2.1550.0", "axios": "^1.6.7", "bootstrap": "^5.3.2", - "vitest": "^1.3.1", "vue": "^3.4.15", "vue-router": "^4.2.5", "vuex": "^4.0.2", @@ -29,6 +28,7 @@ "@vue/test-utils": "^2.4.4", "happy-dom": "^13.7.3", "sass": "^1.70.0", - "vite": "^5.0.11" + "vite": "^5.0.11", + "vitest": "^1.5.0" } } diff --git a/src/test/api/databaseManager.test.js b/src/test/api/databaseManager.test.js deleted file mode 100644 index 38509b2..0000000 --- a/src/test/api/databaseManager.test.js +++ /dev/null @@ -1,113 +0,0 @@ -import DatabaseAdapter from '@/api/databaseManager'; - -// mocking the databse calls to prevent actual reads and writes -vi.mock('aws-sdk', () => ({ - default: class AWS { - static config = { - update: vi.fn() - }; - static CognitoIdentityCredentials = vi.fn(); - static DynamoDB = class DynamoDB { - static Converter = { - marshall: vi.fn((trip) => ({username: trip.username, tripName: trip.tripName, timestamp: trip.timestamp})), - unmarshall: vi.fn((trip) => ({username: trip.username, tripName: trip.tripName})) - }; - putItem = vi.fn(); - deleteItem = vi.fn(); - query = vi.fn(); - }; - } -})); - -// mock return a username -vi.mock('@/main.js', () => ({ - default: { - getters: { - getUsername: 'testuser', - } - } -})); - -describe('DatabaseAdapter', () => { - const adapter = new DatabaseAdapter(); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('saveTrip', () => { - const putSpy = vi.spyOn(adapter.ddb, "putItem"); - - test('should save a trip to the database', () => { - const trip = { tripName: 'Test Trip' }; - adapter.saveTrip(trip); - - expect(putSpy).toHaveBeenCalledWith(expect.objectContaining({ - TableName: 'UserTrips', - Item: expect.objectContaining({username: "testuser", tripName: "Test Trip"}) - }), expect.anything()); - }); - - test('should throw an error for invalid trip', () => { - const trip = { tripName: '' }; - - expect(putSpy).not.toHaveBeenCalled(); - expect(() => adapter.saveTrip(trip)).toThrow('Invalid trip'); - }); - }); - - describe('deleteTrip', () => { - const deleteSpy = vi.spyOn(adapter.ddb, "deleteItem"); - - test('should delete a trip from the database', () => { - const trip = { tripName: 'Test Trip', username: 'testuser', timestamp: 123}; - adapter.deleteTrip(trip); - - expect(deleteSpy).toHaveBeenCalledWith(expect.objectContaining({ - TableName: 'UserTrips', - Key: expect.objectContaining({timestamp: 123, username: "testuser"}) - }), expect.anything()); - }); - }); - - describe('getAllTrips', () => { - const querySpy = vi.spyOn(adapter.ddb, "query"); - - test('should retrieve all trips for current user', async () => { - const mockItems = [{ tripName: 'Test Trip 1' }, { tripName: 'Test Trip 2' }]; - adapter.ddb.query.mockImplementation((params, callback) => { - callback(null, { Items: mockItems }); - }); - - const trips = await adapter.getAllTrips(); - - expect(trips).toEqual(mockItems.reverse()); - expect(querySpy).toHaveBeenCalledWith(expect.objectContaining({ - TableName: "UserTrips", KeyConditionExpression: 'username = :username', - ExpressionAttributeValues: { - ':username': { 'S': 'testuser' } - } - }), expect.anything()); - }); - - test('should return null if no trips found for current user', async () => { - adapter.ddb.query.mockImplementation((params, callback) => { - callback(null, { Items: [] }); - }); - const trips = await adapter.getAllTrips(); - - expect(trips).toBeNull(); - expect(querySpy).toHaveBeenCalled(); - }); - - test('should throw an error if query fails', async () => { - const mockError = new Error('Query error'); - adapter.ddb.query.mockImplementation((params, callback) => { - callback(mockError); - }); - - await expect(adapter.getAllTrips()).rejects.toThrow(mockError); - expect(querySpy).toHaveBeenCalled(); - }); - }); -}); diff --git a/src/test/api/userVerification.test.js b/src/test/api/userVerification.test.js deleted file mode 100644 index 4518262..0000000 --- a/src/test/api/userVerification.test.js +++ /dev/null @@ -1,150 +0,0 @@ -import UserVerificationAdapter from '@/api/userVerification'; -import { AuthenticationDetails, CognitoUser } from 'amazon-cognito-identity-js'; - -// mocking the authentication service calls -vi.mock('amazon-cognito-identity-js', () => ({ - AuthenticationDetails: vi.fn(), - CognitoUserAttribute: vi.fn(), - CognitoUserPool: vi.fn(), - CognitoUser: vi.fn(), -})); - -// mock so we can detect commit calls -vi.mock('@/main.js', () => ({ - default: { - commit: vi.fn() - } -})); - -vi.mock('@/router/index', () => ({ - default: { - push: vi.fn(), - } -})); - -describe('UserVerificationAdapter', () => { - const adapter = new UserVerificationAdapter(); - - afterEach(() => { - vi.clearAllMocks(); - }); - - describe('isUserSignedIn', () => { - test('returns true if user is signed in', () => { - adapter.userPool.getCurrentUser = vi.fn(() => ({ username: 'testuser' })); - expect(adapter.isUserSignedIn()).toBe(true); - }); - - test('returns false if user is not signed in', () => { - adapter.userPool.getCurrentUser = vi.fn(() => null); - expect(adapter.isUserSignedIn()).toBe(false); - }); - }); - - describe('getUserAccount', () => { - test('returns the username if user is signed in', () => { - adapter.userPool.getCurrentUser = vi.fn(() => ({ username: 'testuser' })); - expect(adapter.getUserAccount()).toBe('testuser'); - }); - - test('returns an empty string if user is not signed in', () => { - adapter.userPool.getCurrentUser = vi.fn(() => null); - expect(adapter.getUserAccount()).toBe(''); - }); - }); - - describe('createNewUser', () => { - test('creates a new user account', async () => { - const verifyCredentialsSpy = vi.spyOn(adapter, 'verifyCredentials'); - adapter.userPool.signUp = vi.fn((username, password, attributeList, nullValue, callback) => { - callback(null, 'success'); - }); - - await expect(adapter.createNewUser('testuser', 'password', 'test@example.com')).resolves.toBe('success'); - expect(verifyCredentialsSpy).toHaveBeenCalled(); - }); - - test('rejects with an error if sign up fails', async () => { - const verifyCredentialsSpy = vi.spyOn(adapter, 'verifyCredentials'); - const signUpMock = vi.fn((username, password, attributeList, nullValue, callback) => { - callback(new Error('Sign up failed'), null); - }); - adapter.userPool.signUp = signUpMock; - - await expect(adapter.createNewUser('testuser', 'password', 'test@example.com')).rejects.toThrowError('Sign up failed'); - expect(verifyCredentialsSpy).not.toHaveBeenCalled(); - }); - }); - - describe('verifyCredentials', () => { - test('authenticates user on success', async () => { - const authenticationDetailsMock = { Username: 'testuser', Password: 'testpassword' }; - const authenticateUserMock = vi.fn((authenticationDetails, callbacks) => { - callbacks.onSuccess({ getIdToken: vi.fn(() => ({ - payload: { - aiKey: 'testAiKey', - currencyKey: 'testCurrencyKey', - locationKey: 'testLocationKey', - translationKey: 'testTranslationKey', - weatherKey: 'testWeatherKey', - } - })) }); - }); - - const getCurrentUserMock = vi.fn(() => ({ username: 'testuser' })); - adapter.userPool = { - getCurrentUser: getCurrentUserMock - }; - - AuthenticationDetails.mockImplementation(() => authenticationDetailsMock); - CognitoUser.mockImplementation(() => ({ authenticateUser: authenticateUserMock })); - - await adapter.verifyCredentials('testuser', 'testpassword'); - - expect(AuthenticationDetails).toHaveBeenCalledWith(authenticationDetailsMock); - expect(CognitoUser).toHaveBeenCalledWith({ Username: 'testuser', Pool: adapter.userPool }); - expect(authenticateUserMock).toHaveBeenCalledWith(authenticationDetailsMock, { - onSuccess: expect.any(Function), - onFailure: expect.any(Function) - }); - }); - - test('handles authentication failure', async () => { - const authenticateUserMock = vi.fn((authenticationDetails, callbacks) => { - callbacks.onFailure('Authentication failed'); - }); - - CognitoUser.mockImplementation(() => ({ authenticateUser: authenticateUserMock })); - - await expect(adapter.verifyCredentials('testuser', 'testpassword')).rejects.toThrow('Authentication failed'); - - expect(CognitoUser).toHaveBeenCalledWith({ Username: 'testuser', Pool: adapter.userPool }); - expect(authenticateUserMock).toHaveBeenCalledWith(expect.any(Object), { - onSuccess: expect.any(Function), - onFailure: expect.any(Function) - }); - }); - }); - - describe('signCurrentUserOut', () => { - test('signs the current user out', () => { - const signOutMock = vi.fn(); - const getCurrentUserMock = vi.fn(() => ({ signOut: signOutMock, username: 'testuser' })); - - adapter.userPool = { - getCurrentUser: getCurrentUserMock - }; - - adapter.signCurrentUserOut(); - - expect(getCurrentUserMock).toHaveBeenCalled(); - expect(signOutMock).toHaveBeenCalled(); - }); - - test('no current user', () => { - adapter.userPool.getCurrentUser = vi.fn(() => null); - adapter.signCurrentUserOut(); - expect(adapter.userPool.getCurrentUser).toHaveBeenCalled() - }); - }); -}); diff --git a/src/test/components/TripSelector.test.js b/src/test/components/TripSelector.test.js deleted file mode 100644 index 77857d6..0000000 --- a/src/test/components/TripSelector.test.js +++ /dev/null @@ -1,45 +0,0 @@ -import { mount } from '@vue/test-utils'; -import store from '@/main'; - -import TripSelector from '@/components/TripSelector.vue'; - -const $route = { name: 'test-route' }; - -const sampleTrip = { - timestamp: 1710103091000, - tripName: 'testTrip' -} - -describe('TripSelector', () => { - test('closing modal clears name', () => { - // mount the vue component to interact with it - const wrapper = mount(TripSelector, { - global: { - plugins: [store] - }, - mocks: { - $route - } - }); - - wrapper.vm.newTripName = "newTrip"; - expect(wrapper.vm.newTripName).toEqual("newTrip"); - - wrapper.vm.clearCreateModal(); - expect(wrapper.vm.newTripName).toEqual(null); - }); - - test('set current trip', () => { - const wrapper = mount(TripSelector, { - global: { - plugins: [store] - }, - mocks: { - $route - } - }); - - wrapper.vm.setCurrentTrip(sampleTrip); - expect(wrapper.vm.currentTrip.tripName).toEqual("testTrip"); - }); -}); diff --git a/src/test/weather_funct.test.js b/src/test/weather_funct.test.js new file mode 100644 index 0000000..af4c5a2 --- /dev/null +++ b/src/test/weather_funct.test.js @@ -0,0 +1,31 @@ +import { expect, test } from 'vitest'; +import { convert_kelvin_to_celsius, convert_kelvin_to_fahrenheit, convert_mps_to_mph, getWindDirectionLetter } from '../views/Weather.vue'; + + +test('converts Kelvin to Celsius', () => +{ + const result = convert_kelvin_to_celsius(300); + console.log('Result:', result); + expect(result).toBe('26.85'); +}); + +test('converts Kelvin to Fahrenheit', () => +{ + const result = convert_kelvin_to_fahrenheit(300); + console.log('Result:', result); + expect(result).toBe('80.33'); +}); + +test('converts Miles Per Second to Miles Per Hour', () => +{ + const result = convert_mps_to_mph(10); + console.log('Result:', result); + expect(result).toBe('22.37'); +}); + +test('Gets direction from heading', () => +{ + const result = getWindDirectionLetter(180); + console.log('Result:', result); + expect(result).toBe('S'); +}); \ No newline at end of file diff --git a/src/views/Weather.vue b/src/views/Weather.vue index 663f367..82b7f9f 100644 --- a/src/views/Weather.vue +++ b/src/views/Weather.vue @@ -42,6 +42,18 @@ import axios from 'axios' // Import MapView component import MapView from '@/components/MapView.vue' + + export function convert_kelvin_to_celsius(kelvin) { return (kelvin - 273.15).toFixed(2); } //OpenWeatherMap's API typically outputs in Kelvin, so we have to convert it. Here's the functions containing the formulas to do so + export function convert_kelvin_to_fahrenheit(kelvin) { return ((kelvin - 273.15) * 1.8 + 32).toFixed(2); } + export function convert_mps_to_mph(mps) { const mph = (mps * 2.23694).toFixed(2); return mph; } //converting the default meters/second to miles/hour + // Method to get wind direction letter based on degrees + export function getWindDirectionLetter(degrees) + { + const directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']; + const index = Math.round(degrees / 45) % 8; + return directions[index]; + } + export default { components: { @@ -73,6 +85,7 @@ return directions[index]; }, + async getWeather() { if (!this.city) return; try { From 45be59ab10d8d3f29c7a2cbd3937a5335b7a3eb6 Mon Sep 17 00:00:00 2001 From: Michael Rago Date: Thu, 18 Apr 2024 11:01:56 -0400 Subject: [PATCH 2/2] Fix failing unit tests --- src/test/api/databaseManager.test.js | 113 ++++++++++++++++ src/test/api/userVerification.test.js | 150 ++++++++++++++++++++++ src/test/components/TripSelector.test.js | 45 +++++++ src/test/components/weather_funct.test.js | 53 ++++++++ src/test/weather_funct.test.js | 31 ----- 5 files changed, 361 insertions(+), 31 deletions(-) create mode 100644 src/test/api/databaseManager.test.js create mode 100644 src/test/api/userVerification.test.js create mode 100644 src/test/components/TripSelector.test.js create mode 100644 src/test/components/weather_funct.test.js delete mode 100644 src/test/weather_funct.test.js diff --git a/src/test/api/databaseManager.test.js b/src/test/api/databaseManager.test.js new file mode 100644 index 0000000..38509b2 --- /dev/null +++ b/src/test/api/databaseManager.test.js @@ -0,0 +1,113 @@ +import DatabaseAdapter from '@/api/databaseManager'; + +// mocking the databse calls to prevent actual reads and writes +vi.mock('aws-sdk', () => ({ + default: class AWS { + static config = { + update: vi.fn() + }; + static CognitoIdentityCredentials = vi.fn(); + static DynamoDB = class DynamoDB { + static Converter = { + marshall: vi.fn((trip) => ({username: trip.username, tripName: trip.tripName, timestamp: trip.timestamp})), + unmarshall: vi.fn((trip) => ({username: trip.username, tripName: trip.tripName})) + }; + putItem = vi.fn(); + deleteItem = vi.fn(); + query = vi.fn(); + }; + } +})); + +// mock return a username +vi.mock('@/main.js', () => ({ + default: { + getters: { + getUsername: 'testuser', + } + } +})); + +describe('DatabaseAdapter', () => { + const adapter = new DatabaseAdapter(); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('saveTrip', () => { + const putSpy = vi.spyOn(adapter.ddb, "putItem"); + + test('should save a trip to the database', () => { + const trip = { tripName: 'Test Trip' }; + adapter.saveTrip(trip); + + expect(putSpy).toHaveBeenCalledWith(expect.objectContaining({ + TableName: 'UserTrips', + Item: expect.objectContaining({username: "testuser", tripName: "Test Trip"}) + }), expect.anything()); + }); + + test('should throw an error for invalid trip', () => { + const trip = { tripName: '' }; + + expect(putSpy).not.toHaveBeenCalled(); + expect(() => adapter.saveTrip(trip)).toThrow('Invalid trip'); + }); + }); + + describe('deleteTrip', () => { + const deleteSpy = vi.spyOn(adapter.ddb, "deleteItem"); + + test('should delete a trip from the database', () => { + const trip = { tripName: 'Test Trip', username: 'testuser', timestamp: 123}; + adapter.deleteTrip(trip); + + expect(deleteSpy).toHaveBeenCalledWith(expect.objectContaining({ + TableName: 'UserTrips', + Key: expect.objectContaining({timestamp: 123, username: "testuser"}) + }), expect.anything()); + }); + }); + + describe('getAllTrips', () => { + const querySpy = vi.spyOn(adapter.ddb, "query"); + + test('should retrieve all trips for current user', async () => { + const mockItems = [{ tripName: 'Test Trip 1' }, { tripName: 'Test Trip 2' }]; + adapter.ddb.query.mockImplementation((params, callback) => { + callback(null, { Items: mockItems }); + }); + + const trips = await adapter.getAllTrips(); + + expect(trips).toEqual(mockItems.reverse()); + expect(querySpy).toHaveBeenCalledWith(expect.objectContaining({ + TableName: "UserTrips", KeyConditionExpression: 'username = :username', + ExpressionAttributeValues: { + ':username': { 'S': 'testuser' } + } + }), expect.anything()); + }); + + test('should return null if no trips found for current user', async () => { + adapter.ddb.query.mockImplementation((params, callback) => { + callback(null, { Items: [] }); + }); + const trips = await adapter.getAllTrips(); + + expect(trips).toBeNull(); + expect(querySpy).toHaveBeenCalled(); + }); + + test('should throw an error if query fails', async () => { + const mockError = new Error('Query error'); + adapter.ddb.query.mockImplementation((params, callback) => { + callback(mockError); + }); + + await expect(adapter.getAllTrips()).rejects.toThrow(mockError); + expect(querySpy).toHaveBeenCalled(); + }); + }); +}); diff --git a/src/test/api/userVerification.test.js b/src/test/api/userVerification.test.js new file mode 100644 index 0000000..4518262 --- /dev/null +++ b/src/test/api/userVerification.test.js @@ -0,0 +1,150 @@ +import UserVerificationAdapter from '@/api/userVerification'; +import { AuthenticationDetails, CognitoUser } from 'amazon-cognito-identity-js'; + +// mocking the authentication service calls +vi.mock('amazon-cognito-identity-js', () => ({ + AuthenticationDetails: vi.fn(), + CognitoUserAttribute: vi.fn(), + CognitoUserPool: vi.fn(), + CognitoUser: vi.fn(), +})); + +// mock so we can detect commit calls +vi.mock('@/main.js', () => ({ + default: { + commit: vi.fn() + } +})); + +vi.mock('@/router/index', () => ({ + default: { + push: vi.fn(), + } +})); + +describe('UserVerificationAdapter', () => { + const adapter = new UserVerificationAdapter(); + + afterEach(() => { + vi.clearAllMocks(); + }); + + describe('isUserSignedIn', () => { + test('returns true if user is signed in', () => { + adapter.userPool.getCurrentUser = vi.fn(() => ({ username: 'testuser' })); + expect(adapter.isUserSignedIn()).toBe(true); + }); + + test('returns false if user is not signed in', () => { + adapter.userPool.getCurrentUser = vi.fn(() => null); + expect(adapter.isUserSignedIn()).toBe(false); + }); + }); + + describe('getUserAccount', () => { + test('returns the username if user is signed in', () => { + adapter.userPool.getCurrentUser = vi.fn(() => ({ username: 'testuser' })); + expect(adapter.getUserAccount()).toBe('testuser'); + }); + + test('returns an empty string if user is not signed in', () => { + adapter.userPool.getCurrentUser = vi.fn(() => null); + expect(adapter.getUserAccount()).toBe(''); + }); + }); + + describe('createNewUser', () => { + test('creates a new user account', async () => { + const verifyCredentialsSpy = vi.spyOn(adapter, 'verifyCredentials'); + adapter.userPool.signUp = vi.fn((username, password, attributeList, nullValue, callback) => { + callback(null, 'success'); + }); + + await expect(adapter.createNewUser('testuser', 'password', 'test@example.com')).resolves.toBe('success'); + expect(verifyCredentialsSpy).toHaveBeenCalled(); + }); + + test('rejects with an error if sign up fails', async () => { + const verifyCredentialsSpy = vi.spyOn(adapter, 'verifyCredentials'); + const signUpMock = vi.fn((username, password, attributeList, nullValue, callback) => { + callback(new Error('Sign up failed'), null); + }); + adapter.userPool.signUp = signUpMock; + + await expect(adapter.createNewUser('testuser', 'password', 'test@example.com')).rejects.toThrowError('Sign up failed'); + expect(verifyCredentialsSpy).not.toHaveBeenCalled(); + }); + }); + + describe('verifyCredentials', () => { + test('authenticates user on success', async () => { + const authenticationDetailsMock = { Username: 'testuser', Password: 'testpassword' }; + const authenticateUserMock = vi.fn((authenticationDetails, callbacks) => { + callbacks.onSuccess({ getIdToken: vi.fn(() => ({ + payload: { + aiKey: 'testAiKey', + currencyKey: 'testCurrencyKey', + locationKey: 'testLocationKey', + translationKey: 'testTranslationKey', + weatherKey: 'testWeatherKey', + } + })) }); + }); + + const getCurrentUserMock = vi.fn(() => ({ username: 'testuser' })); + adapter.userPool = { + getCurrentUser: getCurrentUserMock + }; + + AuthenticationDetails.mockImplementation(() => authenticationDetailsMock); + CognitoUser.mockImplementation(() => ({ authenticateUser: authenticateUserMock })); + + await adapter.verifyCredentials('testuser', 'testpassword'); + + expect(AuthenticationDetails).toHaveBeenCalledWith(authenticationDetailsMock); + expect(CognitoUser).toHaveBeenCalledWith({ Username: 'testuser', Pool: adapter.userPool }); + expect(authenticateUserMock).toHaveBeenCalledWith(authenticationDetailsMock, { + onSuccess: expect.any(Function), + onFailure: expect.any(Function) + }); + }); + + test('handles authentication failure', async () => { + const authenticateUserMock = vi.fn((authenticationDetails, callbacks) => { + callbacks.onFailure('Authentication failed'); + }); + + CognitoUser.mockImplementation(() => ({ authenticateUser: authenticateUserMock })); + + await expect(adapter.verifyCredentials('testuser', 'testpassword')).rejects.toThrow('Authentication failed'); + + expect(CognitoUser).toHaveBeenCalledWith({ Username: 'testuser', Pool: adapter.userPool }); + expect(authenticateUserMock).toHaveBeenCalledWith(expect.any(Object), { + onSuccess: expect.any(Function), + onFailure: expect.any(Function) + }); + }); + }); + + describe('signCurrentUserOut', () => { + test('signs the current user out', () => { + const signOutMock = vi.fn(); + const getCurrentUserMock = vi.fn(() => ({ signOut: signOutMock, username: 'testuser' })); + + adapter.userPool = { + getCurrentUser: getCurrentUserMock + }; + + adapter.signCurrentUserOut(); + + expect(getCurrentUserMock).toHaveBeenCalled(); + expect(signOutMock).toHaveBeenCalled(); + }); + + test('no current user', () => { + adapter.userPool.getCurrentUser = vi.fn(() => null); + adapter.signCurrentUserOut(); + expect(adapter.userPool.getCurrentUser).toHaveBeenCalled() + }); + }); +}); diff --git a/src/test/components/TripSelector.test.js b/src/test/components/TripSelector.test.js new file mode 100644 index 0000000..77857d6 --- /dev/null +++ b/src/test/components/TripSelector.test.js @@ -0,0 +1,45 @@ +import { mount } from '@vue/test-utils'; +import store from '@/main'; + +import TripSelector from '@/components/TripSelector.vue'; + +const $route = { name: 'test-route' }; + +const sampleTrip = { + timestamp: 1710103091000, + tripName: 'testTrip' +} + +describe('TripSelector', () => { + test('closing modal clears name', () => { + // mount the vue component to interact with it + const wrapper = mount(TripSelector, { + global: { + plugins: [store] + }, + mocks: { + $route + } + }); + + wrapper.vm.newTripName = "newTrip"; + expect(wrapper.vm.newTripName).toEqual("newTrip"); + + wrapper.vm.clearCreateModal(); + expect(wrapper.vm.newTripName).toEqual(null); + }); + + test('set current trip', () => { + const wrapper = mount(TripSelector, { + global: { + plugins: [store] + }, + mocks: { + $route + } + }); + + wrapper.vm.setCurrentTrip(sampleTrip); + expect(wrapper.vm.currentTrip.tripName).toEqual("testTrip"); + }); +}); diff --git a/src/test/components/weather_funct.test.js b/src/test/components/weather_funct.test.js new file mode 100644 index 0000000..1c7cab3 --- /dev/null +++ b/src/test/components/weather_funct.test.js @@ -0,0 +1,53 @@ +import { mount } from '@vue/test-utils'; +import Weather from '@/views/Weather.vue'; + +const mockStore = { + state: {}, + commit: vi.fn(), + getters: { + getLocationApiKey: vi.fn() + } +}; + +describe('Weather', () => { + let wrapper; + + beforeEach(() => { + wrapper = mount(Weather, { + global: { + mocks: { + $store: mockStore + } + } + }); + }); + + test('converts Kelvin to Celsius', () => + { + const result = wrapper.vm.convert_kelvin_to_celsius(300); + console.log('Result:', result); + expect(result).toBe('26.85'); + }); + + test('converts Kelvin to Fahrenheit', () => + { + const result = wrapper.vm.convert_kelvin_to_fahrenheit(300); + console.log('Result:', result); + expect(result).toBe('80.33'); + }); + + test('converts Miles Per Second to Miles Per Hour', () => + { + const result = wrapper.vm.convert_mps_to_mph(10); + console.log('Result:', result); + expect(result).toBe('22.37'); + }); + + test('Gets direction from heading', () => + { + const result = wrapper.vm.getWindDirectionLetter(180); + console.log('Result:', result); + expect(result).toBe('S'); + }); +}) + diff --git a/src/test/weather_funct.test.js b/src/test/weather_funct.test.js deleted file mode 100644 index af4c5a2..0000000 --- a/src/test/weather_funct.test.js +++ /dev/null @@ -1,31 +0,0 @@ -import { expect, test } from 'vitest'; -import { convert_kelvin_to_celsius, convert_kelvin_to_fahrenheit, convert_mps_to_mph, getWindDirectionLetter } from '../views/Weather.vue'; - - -test('converts Kelvin to Celsius', () => -{ - const result = convert_kelvin_to_celsius(300); - console.log('Result:', result); - expect(result).toBe('26.85'); -}); - -test('converts Kelvin to Fahrenheit', () => -{ - const result = convert_kelvin_to_fahrenheit(300); - console.log('Result:', result); - expect(result).toBe('80.33'); -}); - -test('converts Miles Per Second to Miles Per Hour', () => -{ - const result = convert_mps_to_mph(10); - console.log('Result:', result); - expect(result).toBe('22.37'); -}); - -test('Gets direction from heading', () => -{ - const result = getWindDirectionLetter(180); - console.log('Result:', result); - expect(result).toBe('S'); -}); \ No newline at end of file