diff --git a/jest.config.js b/jest.config.js index bfb4bf71f..f6178df61 100644 --- a/jest.config.js +++ b/jest.config.js @@ -15,9 +15,10 @@ module.exports = { "!src/layouts/vehicle-damage/windshield-options/windshield-options.vue", "!src/layouts/reveal/**/*.vue", "!src/ux-components/text-link/**/*.vue", - "!src/common-components/date-picker/**/*.vue", + "!src/common-components/date-picker/**/*.vue", // Temp until unit tests completed "!src/layouts/vin-lookup/**/*.vue", //Temporary for Quote page testing "!src/common-components/funnel-header/menu-modal/**/*.vue", + "!src/layouts/schedule/*.vue", // Temp test exclusion while in development // END ], // ! means exclude from coverage. testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"], diff --git a/package-lock.json b/package-lock.json index a838afe8f..8d4b6e08d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5785,13 +5785,13 @@ "dev": true }, "node_modules/accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "dependencies": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { "node": ">= 0.6" @@ -6857,24 +6857,27 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "dependencies": { - "bytes": "3.1.1", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/body-parser/node_modules/debug": { @@ -6886,17 +6889,29 @@ "ms": "2.0.0" } }, + "node_modules/body-parser/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "node_modules/body-parser/node_modules/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" }, @@ -7196,9 +7211,9 @@ "dev": true }, "node_modules/bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "engines": { "node": ">= 0.8" @@ -8074,9 +8089,9 @@ } }, "node_modules/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true, "engines": { "node": ">= 0.6" @@ -8828,9 +8843,9 @@ } }, "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true, "engines": { "node": ">=0.10" @@ -9113,10 +9128,14 @@ } }, "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, "node_modules/detect-newline": { "version": "2.1.0", @@ -9404,7 +9423,7 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, "node_modules/ejs": { @@ -9462,7 +9481,7 @@ "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, "engines": { "node": ">= 0.8" @@ -9993,7 +10012,7 @@ "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "engines": { "node": ">= 0.6" @@ -10024,13 +10043,10 @@ } }, "node_modules/eventsource": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", - "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", + "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==", "dev": true, - "dependencies": { - "original": "^1.0.0" - }, "engines": { "node": ">=0.12.0" } @@ -10230,38 +10246,39 @@ } }, "node_modules/express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "dependencies": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.1", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.1", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.6", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -10279,6 +10296,15 @@ "ms": "2.0.0" } }, + "node_modules/express/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -10286,10 +10312,13 @@ "dev": true }, "node_modules/express/node_modules/qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" }, @@ -10317,6 +10346,15 @@ } ] }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -10672,17 +10710,17 @@ } }, "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { @@ -10701,9 +10739,18 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/find-babel-config": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", @@ -10882,7 +10929,7 @@ "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true, "engines": { "node": ">= 0.6" @@ -11612,19 +11659,37 @@ "dev": true }, "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "dependencies": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" } }, "node_modules/http-parser-js": { @@ -16707,7 +16772,7 @@ "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "engines": { "node": ">= 0.6" @@ -16890,9 +16955,9 @@ "dev": true }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -17125,9 +17190,9 @@ "dev": true }, "node_modules/negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "engines": { "node": ">= 0.6" @@ -17593,9 +17658,9 @@ "dev": true }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "dependencies": { "ee-first": "1.1.1" @@ -17780,15 +17845,6 @@ "node": ">=6" } }, - "node_modules/original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "dependencies": { - "url-parse": "^1.4.3" - } - }, "node_modules/os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -19150,9 +19206,9 @@ } }, "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, "engines": { "node": ">=0.6" @@ -19225,13 +19281,13 @@ } }, "node_modules/raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dev": true, "dependencies": { - "bytes": "3.1.1", - "http-errors": "1.8.1", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -20173,24 +20229,24 @@ } }, "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" @@ -20208,9 +20264,18 @@ "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/send/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -20229,6 +20294,15 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/serialize-javascript": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", @@ -20299,15 +20373,15 @@ "dev": true }, "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" @@ -21443,9 +21517,9 @@ } }, "node_modules/terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", "dev": true, "dependencies": { "commander": "^2.20.0", @@ -22178,7 +22252,7 @@ "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "engines": { "node": ">= 0.8" @@ -28975,13 +29049,13 @@ "dev": true }, "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "acorn": { @@ -29828,21 +29902,23 @@ "dev": true }, "body-parser": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz", - "integrity": "sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dev": true, "requires": { - "bytes": "3.1.1", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.6", - "raw-body": "2.4.2", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "dependencies": { "debug": { @@ -29854,17 +29930,26 @@ "ms": "2.0.0" } }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", - "dev": true + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } } } }, @@ -30123,9 +30208,9 @@ "dev": true }, "bytes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz", - "integrity": "sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, "cacache": { @@ -30822,9 +30907,9 @@ } }, "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true }, "cookie-signature": { @@ -31432,9 +31517,9 @@ "dev": true }, "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", "dev": true }, "deep-equal": { @@ -31651,9 +31736,9 @@ } }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, "detect-newline": { @@ -31897,7 +31982,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, "ejs": { @@ -31950,7 +32035,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true }, "end-of-stream": { @@ -32343,7 +32428,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true }, "event-pubsub": { @@ -32365,13 +32450,10 @@ "dev": true }, "eventsource": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", - "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", - "dev": true, - "requires": { - "original": "^1.0.0" - } + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.2.tgz", + "integrity": "sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==", + "dev": true }, "evp_bytestokey": { "version": "1.0.3", @@ -32541,38 +32623,39 @@ } }, "express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.2.tgz", - "integrity": "sha512-oxlxJxcQlYwqPWKVJJtvQiwHgosH/LrLSPA+H4UxpyvSS6jC5aH+5MoHFM+KABgTOt0APue4w66Ha8jCUo9QGg==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dev": true, "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.1", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.1", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.6", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -32587,6 +32670,12 @@ "ms": "2.0.0" } }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -32594,16 +32683,25 @@ "dev": true }, "qs": { - "version": "6.9.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz", - "integrity": "sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ==", - "dev": true + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true } } }, @@ -32897,17 +32995,17 @@ } }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "dependencies": { @@ -32923,7 +33021,13 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true } } @@ -33057,7 +33161,7 @@ "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, "from2": { @@ -33627,16 +33731,30 @@ "dev": true }, "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "requires": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } } }, "http-parser-js": { @@ -37747,7 +37865,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true }, "memory-fs": { @@ -37894,9 +38012,9 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -38096,9 +38214,9 @@ "dev": true }, "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true }, "neo-async": { @@ -38471,9 +38589,9 @@ "dev": true }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "requires": { "ee-first": "1.1.1" @@ -38616,15 +38734,6 @@ } } }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", @@ -39784,9 +39893,9 @@ "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true }, "query-string": { @@ -39843,13 +39952,13 @@ "dev": true }, "raw-body": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz", - "integrity": "sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dev": true, "requires": { - "bytes": "3.1.1", - "http-errors": "1.8.1", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } @@ -40586,24 +40695,24 @@ "dev": true }, "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { "debug": { @@ -40618,11 +40727,17 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -40634,6 +40749,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true } } }, @@ -40703,15 +40824,15 @@ } }, "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" } }, "set-blocking": { @@ -41668,9 +41789,9 @@ "dev": true }, "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz", + "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==", "dev": true, "requires": { "commander": "^2.20.0", @@ -42250,7 +42371,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, "unquote": { diff --git a/src/common-components/date-picker/date-picker.vue b/src/common-components/date-picker/date-picker.vue deleted file mode 100644 index 1c83c0a4e..000000000 --- a/src/common-components/date-picker/date-picker.vue +++ /dev/null @@ -1,439 +0,0 @@ - - - - - diff --git a/src/constants/application-config.js b/src/constants/application-config.js index 8f12760fc..4c5305783 100644 --- a/src/constants/application-config.js +++ b/src/constants/application-config.js @@ -7,8 +7,9 @@ const applicationConfig = { CURRENT_ENVIRONMENT: process.env.VUE_APP_CURRENT_ENVIRONMENT, // "Localhost", "Dev", "QA", and "Prod" APPLICATION_NAME: "FixMyGlass", APPLICATION_ABBREVIATION: "fmg", + PAGE_QUERYSTRING: "fmgPage", SITE_ENTRY_TRIGGER_VALUE: "FixMyGlass", - CASH_ACCOUNT_NUMBER: 167132, + CASH_PARENT_ACCOUNT_NUMBER: 167132, }; export { applicationConfig }; diff --git a/src/constants/endpoints.js b/src/constants/endpoints.js index a2f9b38be..f7038a9b4 100644 --- a/src/constants/endpoints.js +++ b/src/constants/endpoints.js @@ -78,6 +78,14 @@ const endpoints = { url: "/parts/api/v1/parts/rain-defense", method: "GET", }, + GetMobileFeePart: { + url: "/parts/api/v1/parts/mobile-fee", + method: "GET", + }, + GetServiceabilityDetails: { + url: "/location/api/v1/location/serviceability-details", + method: "GET", + }, GetSupportingItems: { url: "/parts/api/v1/parts/supporting-items", method: "POST", diff --git a/src/constants/error-messages.js b/src/constants/error-messages.js index 5631b44c7..810929d20 100644 --- a/src/constants/error-messages.js +++ b/src/constants/error-messages.js @@ -25,6 +25,8 @@ const errorMessages = { "Invalid VIN. Please make sure that you entered the correct 17-digit, alpha-numeric number. VINs do not contain the letters I, O, or Q", OPTION_REQUIRED: "Please select an option", VEHICLE_REQUIRED: "Please select a vehicle", + MOBILE_LOCATION_REQUIRED: "Please enter your service address", + DATE_REQUIRED: "Please select a date", }; export { errorMessages }; diff --git a/src/constants/scheduling.js b/src/constants/scheduling.js new file mode 100644 index 000000000..c656ac60a --- /dev/null +++ b/src/constants/scheduling.js @@ -0,0 +1,16 @@ +const monthsOfYear = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", +]; + +export { monthsOfYear }; diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js index 96fc64ac8..480626349 100644 --- a/src/constants/store-actions.js +++ b/src/constants/store-actions.js @@ -29,11 +29,13 @@ const storeActions = { GET_CAPABILITY_QUESTIONS: "getCapabilityQuestions", GET_PART_FROM_CAPABILITY_QUESTION_ANSWER: "getPartFromCapabilityQuestionAnswer", GET_MOLDING_QUESTIONS: "getMoldingQuestions", + GET_MOBILE_FEE_PART: "getMobileFeePart", + GET_SERVICEABILITY_DETAILS: "getServiceabilityDetails", SAVE_SESSION: "saveSession", LOAD_SESSION: "loadSession", UPDATE_STORE_WITH_SAVE_SESSION_RESPONSE: "updateStoreWithSaveSessionResponse", VALIDATE_ZIP: "validateZip", - PRICE_ORDER_ITEMS: "priceOrderItems", + PRICE_ORDER_ITEMS_AND_SAVE_SERVER_DATA: "priceOrderItemsAndSaveServerData", LOG_EXPERIMENT_EXPOSURE: "logExperimentExposure", LOG_PAGE_VIEW: "logPageView", LOG_CUSTOM_EVENT: "logCustomEvent", @@ -68,7 +70,7 @@ const storeActions = { SAVE_MOLDING_QUESTION_ANSWERS: "saveMoldingQuestionAnswers", SAVE_CAPABILITY_QUESTION_ANSWERS: "saveCapabilityQuestionAnswers", SAVE_PAYMENT_TYPE: "savePaymentType", - SAVE_ACCOUNT_NUMBER: "saveAccountNumber", + SAVE_PARENT_ACCOUNT_NUMBER: "saveParentAccountNumber", SAVE_SUPPORTING_ITEMS: "saveSupportingItems", SAVE_VAPS: "saveVaps", }; diff --git a/src/common-components/base-input-button/base-input-button.spec.js b/src/digital-components/base-input-button/base-input-button.spec.js similarity index 100% rename from src/common-components/base-input-button/base-input-button.spec.js rename to src/digital-components/base-input-button/base-input-button.spec.js diff --git a/src/common-components/base-input-button/base-input-button.vue b/src/digital-components/base-input-button/base-input-button.vue similarity index 98% rename from src/common-components/base-input-button/base-input-button.vue rename to src/digital-components/base-input-button/base-input-button.vue index 91b36c348..e9b5e6411 100644 --- a/src/common-components/base-input-button/base-input-button.vue +++ b/src/digital-components/base-input-button/base-input-button.vue @@ -33,7 +33,7 @@ import { handleButtonComponentFocus, handleInputComponentBlur, } from "@/helpers/button-question-focus-helper"; -import { inputButtonProps } from "@/common-components/base-input-button/button-functionality-props"; +import { inputButtonProps } from "@/digital-components/base-input-button/button-functionality-props"; export default { name: "base-input-button", @@ -207,5 +207,6 @@ input { opacity: 0; height: 0.1px; // NOTE: cannot be zero or Safari can't put focus on it width: 0; + position: absolute; } diff --git a/src/common-components/base-input-button/button-functionality-props.js b/src/digital-components/base-input-button/button-functionality-props.js similarity index 70% rename from src/common-components/base-input-button/button-functionality-props.js rename to src/digital-components/base-input-button/button-functionality-props.js index 9a4aef5c9..fe2104457 100644 --- a/src/common-components/base-input-button/button-functionality-props.js +++ b/src/digital-components/base-input-button/button-functionality-props.js @@ -4,8 +4,15 @@ export const inputButtonProps = { required: true, }, modelValue: { - type: [Array, String, Number], required: true, + validator: function (prop) { + return ( + prop === null || + Array.isArray(prop) || + typeof prop === "string" || + (typeof prop === "number" && !Number.isNaN(prop)) + ); + }, }, isMultiSelect: Boolean, groupName: { diff --git a/src/common-components/button-question/button-question.spec.js b/src/digital-components/button-question/button-question.spec.js similarity index 99% rename from src/common-components/button-question/button-question.spec.js rename to src/digital-components/button-question/button-question.spec.js index eb2308ca0..ce8d87fab 100644 --- a/src/common-components/button-question/button-question.spec.js +++ b/src/digital-components/button-question/button-question.spec.js @@ -1,6 +1,9 @@ import { shallowMount, mount } from "@vue/test-utils"; -import buttonQuestion from "@/common-components/button-question/button-question"; +import buttonQuestion from "./button-question"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import crypto from "crypto"; + +global.crypto = crypto; describe("buttonQuestion.vue", () => { it("Should show overflow classes on fieldset if isOverflowScrollable is true", () => { diff --git a/src/common-components/button-question/button-question.vue b/src/digital-components/button-question/button-question.vue similarity index 80% rename from src/common-components/button-question/button-question.vue rename to src/digital-components/button-question/button-question.vue index 646b244be..ec7b165a0 100644 --- a/src/common-components/button-question/button-question.vue +++ b/src/digital-components/button-question/button-question.vue @@ -1,10 +1,14 @@ - + @@ -78,7 +86,7 @@ import listButton from "@/ux-components/list-button/list-button"; import listButtonHorizontal from "@/ux-components/list-button-horizontal/list-button-horizontal"; import listCard from "@/ux-components/list-card/list-card"; import radio from "@/ux-components/radio/radio"; -import { ErrorMessage } from "vee-validate"; +import { useField, ErrorMessage } from "vee-validate"; export default { name: "buttonQuestion", @@ -119,6 +127,30 @@ export default { useTextForValue: Boolean, valueToLogType: String, additionalButtonStyling: String, + isSmallQuestionText: Boolean, + customButtonQuestionId: String, + }, + setup(props) { + const propsClone = Object.assign({}, props); + const modelValue = propsClone.modelValue; + + const fieldOptions = { + value: modelValue, + initialValue: modelValue, + }; + + const { errorMessage, handleBlur, handleChange, meta, validate, errors, resetField } = + useField(props.groupName, props.validationRules, fieldOptions); + + return { + errorMessage, + handleBlur, + handleChange, + validate, + meta, + errors, + resetField, + }; }, beforeMount() { if (this.buttonTypeObject) { @@ -132,13 +164,15 @@ export default { }, computed: { getFieldSetClasses() { - if (this.isOverflowScrollable) { - return "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"; - } else if (this.buttonTypeString == "listCard") { - return "w-100"; - } else { - return ""; - } + const baseClasses = this.isOverflowScrollable + ? "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0" + : this.buttonTypeString == "listCard" + ? "w-100" + : ""; + const withSmallQuestionClass = this.isSmallQuestionText + ? baseClasses + " small-question-text" + : baseClasses; + return withSmallQuestionClass; }, getComponentLoopWrapperClasses() { let classes; @@ -205,11 +239,20 @@ export default { }, methods: { formatString(str) { - return str?.replaceAll(" ", "-"); + return String(str).replaceAll(" ", "-"); }, setLastValuePushedToGa(lastValuePushedToGa) { this.lastValuePushedToGa = lastValuePushedToGa; }, + handleButtonEvent(event) { + const eventName = event.eventName; + this.$emit(`buttonEvent.${eventName}`, event.args); + }, + }, + watch: { + modelValue() { + this.resetField(); + }, }, components: { listButton, @@ -251,19 +294,18 @@ export default { text-align: center; } } - -.vehicle-parts { - .question-text { +.small-question-text { + &.question-text { span { font-size: 0.875rem; text-align: left; - margin: 0 0 0.5rem 0; + margin: 1rem 0 0.5rem 0; } } - .question-text { + &.question-text { margin: 0; } - fieldset { + & fieldset { .ui-radio { margin: 0; } diff --git a/src/common-components/date-picker/date-picker-spec.js1 b/src/digital-components/date-picker/date-picker-spec.js1 similarity index 100% rename from src/common-components/date-picker/date-picker-spec.js1 rename to src/digital-components/date-picker/date-picker-spec.js1 diff --git a/src/digital-components/date-picker/date-picker.spec.js b/src/digital-components/date-picker/date-picker.spec.js new file mode 100644 index 000000000..f140e9adb --- /dev/null +++ b/src/digital-components/date-picker/date-picker.spec.js @@ -0,0 +1,437 @@ +import datePicker from "./date-picker"; + +// Supporting Files +import { shallowMount } from "@vue/test-utils"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; + +describe("date-picker.vue", () => { + describe("initial setup", () => { + test("Creates a date object from today", () => { + // Arrange + const { wrapper } = setupMocks({}); + + // Act + const testResult = wrapper.vm.todayDate instanceof Date; + + // Assert + expect(testResult).toEqual(true); + + wrapper.unmount(); + }); + }); + // describe("formatNumberToSetDigits", () => { + // const testScenarios = [ + // [0, 3, "000"], + // [8, 2, "08"], + // [345, 2, "345"], + // [4567, 0, "4567"], + // ]; + // test.each(testScenarios)( + // "when num is %s and digits is %s, formatNumberToSetDigits should return %s", + // async (num, digits, expectedReturn) => { + // // Arrange + // const { wrapper } = setupMocks({}); + + // // Act + // const fnReturn = wrapper.vm.formatNumberToSetDigits(num, digits); + + // // Assert + // expect(fnReturn).toEqual(expectedReturn); + // } + // ); + // }); + // describe("formatDate", () => { + // test("Can format a date as MM/dd/yyyy", () => { + // // Arrange + // const { wrapper } = setupMocks({}); + // const testDate = new Date("01-26-2023"); + + // // Act + // const testResult = wrapper.vm.formatDate(testDate); + + // // Assert + // expect(testResult).toEqual("01/26/2023"); + + // wrapper.unmount(); + // }); + + // // test("Can get correct initialFirstDate from today", () => { + // // // Arrange + // // const { wrapper } = setupMocks({ + // // propsData: { + // // todayDate: "Thu Jan 26 2023", + // // }, + // // }); + + // // // Act + // // const testResult = wrapper.vm.initialFirstDate; + // // const testResultAsDateString = testResult.toDateString(); + + // // // Assert + // // expect(testResultAsDateString).toEqual("Sun Jan 22 2023"); + + // // wrapper.unmount(); + // // }); + // }); + // describe("calendarData", () => { + // test("should return an array", async () => { + // // Arrange + // const { wrapper } = setupMocks({}); + + // // Act + // const testResult = await wrapper.vm.calendarData; + + // // Assert + // expect(Array.isArray(testResult)).toBe(true); + + // wrapper.unmount(); + // }); + // describe("each month should have keys monthLabel, yearNum, dates, firstDateDayIndex", () => { + // const testScenarios = [ + // ["monthLabel", true, "string"], + // ["yearNum", true, "number"], + // ["dates", true, "object"], + // ["firstDateDayIndex", true, "number"], + // ["monthClass", true, "string"], + // ]; + + // test.each(testScenarios)( + // "test for %s key should return %s and be type %s", + // async (label, test, type) => { + // // Arrange + // const { wrapper } = setupMocks({}); + // const containsMonthLabel = (obj) => Object.hasOwn(obj, label); + // const isCorrectType = (obj) => typeof obj[label] === type; + // const isTruthyOrZero = (obj) => (obj[label] || obj[label] === 0 ? true : false); + + // // Act + // const calendarData = await wrapper.vm.calendarData; + // // console.log("calendarData: ", calendarData); + + // // Assert + // expect(calendarData.every(containsMonthLabel)).toBe(true); + // expect(calendarData.every(isCorrectType)).toBe(true); + // expect(calendarData.every(isTruthyOrZero)).toBe(true); + + // wrapper.unmount(); + // } + // ); + // }); + + // describe("the current month's week which includes today", () => { + // const testScenarios = [ + // ["2022-02-05T03:00:00", 1, 2, true], + // ["2024-02-05T03:00:00", 4, 0, true], + // ["2020-01-15T03:00:00", 12, 0, true], + // ]; + + // test.each(testScenarios)( + // "the first date of the week including the date %s should be the date number %s and be day index %s", + // async (todayDateString, startDate, dayOfWeekIndex) => { + // // Arrange + // const { wrapper } = setupMocks({ + // propsData: { + // todayOverrideDateString: todayDateString, + // }, + // }); + + // // Act + // const calendarData = await wrapper.vm.calendarData; + // const currentMonthIndex = calendarData.findIndex((month) => { + // console.log("month: ", month); + // return month.monthClass === "currentMonth"; + // }); + // console.log("calendarData ", calendarData); + // console.log("currentMonthIndex ", currentMonthIndex); + + // // Assert + // expect(calendarData[currentMonthIndex].dates[0].dateNum === startDate).toBe( + // true + // ); + // expect( + // calendarData[currentMonthIndex].dates[0].firstDateDayIndex === + // dayOfWeekIndex + // ).toBe(true); + + // wrapper.unmount(); + // } + // ); + // }); + + // test("the current month's dates array should start with the first day of the week which includes today", async () => { + // // Arrange + // const { wrapper } = setupMocks({}); + // const hasAFirstInDates = (obj) => obj?.dates[0].dateNum === 1; + + // // Act + // const calendarData = await wrapper.vm.calendarData; + // const currentMonthIndex = calendarData.findIndex((month) => { + // return month.monthClass === "currentMonth"; + // }); + + // // Assert + // expect(calendarData[currentMonthIndex].dates[0].dateNum === 1).toBe(true); + + // wrapper.unmount(); + // }); + + // test("for each month (other than current month), the dates array should have the 1st of the month", async () => { + // // Arrange + // const { wrapper } = setupMocks({}); + // const hasAFirstInDates = (obj) => obj?.dates[0].dateNum === 1; + + // // Act + // const calendarData = await wrapper.vm.calendarData; + + // // Assert + // expect(calendarData.every(hasAFirstInDates)).toBe(true); + + // wrapper.unmount(); + // }); + + // describe("for the current month in calendarData, the dates array should have correct days of month", () => { + // const testScenarios = [ + // ["2022-02-05T03:00:00", 28, true], + // ["2024-02-05T03:00:00", 29, true], + // ["2020-01-15T03:00:00", 31, true], + // ]; + + // test.each(testScenarios)( + // "the current month including the date %s should have %s days in its dates array", + // async (dateString, noOfDays) => { + // // Arrange + // const { wrapper } = setupMocks({ + // propsData: { + // todayOverrideDateString: dateString, + // }, + // }); + + // // Act + // const calendarData = await wrapper.vm.calendarData; + // const currentMonthIndex = calendarData.findIndex((month) => { + // return month.monthClass === "currentMonth"; + // }); + + // // Assert + // expect(calendarData[currentMonthIndex].dates.length === noOfDays).toBe(true); + + // wrapper.unmount(); + // } + // ); + + // // test.each(testScenarios)( + // // "the date %s should have %s days in dates array", + // // async (dateString, noOfDays) => { + // // // Arrange + // // const { wrapper } = setupMocks({ + // // propsData: { + // // todayOverrideDateString: dateString, + // // }, + // // }); + // // const hasCorrectNumberOfDates = (obj) => obj?.dates.length === noOfDays; + + // // // Act + // // const calendarData = await wrapper.vm.calendarData; + + // // // Assert + // // expect(calendarData.every(hasCorrectNumberOfDates)).toBe(true); + + // // wrapper.unmount(); + // // } + // // ); + // }); + + // // describe("for each object in array, the dates array should have correct days of month", () => { + // // const testScenarios = [ + // // ["2022-02-05T03:00:00", 28, true], + // // ["2024-02-05T03:00:00", 29, true], + // // ["2020-01-15T03:00:00", 31, true], + // // ]; + + // // test.each(testScenarios)( + // // "the date %s should have %s days in dates array", + // // async (dateString, noOfDays) => { + // // // Arrange + // // const { wrapper } = setupMocks({ + // // propsData: { + // // todayOverrideDateString: dateString, + // // }, + // // }); + // // const hasCorrectNumberOfDates = (obj) => obj?.dates.length === noOfDays; + + // // // Act + // // const calendarData = await wrapper.vm.calendarData; + + // // // Assert + // // expect(calendarData.every(hasCorrectNumberOfDates)).toBe(true); + + // // wrapper.unmount(); + // // } + // // ); + // // }); + + // // test.only("each object in array should have a monthLabel", () => { + // // // Arrange + // // const { wrapper } = setupMocks({}); + // // // const testTodayDate = new Date("01-26-2023"); + + // // // Act + // // const testResult = wrapper.vm.calendarData; + // // const containsMonthLabel = (month) => Object.hasOwn(month, 'monthLabel'); + + // // // Assert + // // expect(testResult.every(containsMonthLabel)).toBe(true); + + // // }); + + // // test.only("array should have a month object with same month as today", () => { + // // // Arrange + // // const { wrapper } = setupMocks({}); + // // // const testTodayDate = new Date("01-26-2023"); + + // // // Act + // // // const testResult = wrapper.vm.calendarData; + // // console.log("wrapper.vm.calendarData: ", wrapper.vm.calendarData) + + // // // Assert + // // // expect(wrapper.vm.calendarData).toEqual("something"); + // // // expect(wrapper.vm.calendarDataOld).toEqual("something"); + + // // expect(wrapper.vm.calendarData[1]).toMatchObject({ + // // "dates": [ + // // { + // // "dateNum": 1 + // // }, + // // { + // // "dateNum": 2 + // // }, + // // { + // // "dateNum": 3 + // // }, + // // { + // // "dateNum": 4 + // // }, + // // { + // // "dateNum": 5 + // // }, + // // { + // // "dateNum": 6 + // // }, + // // { + // // "dateNum": 7 + // // }, + // // { + // // "dateNum": 8 + // // }, + // // { + // // "dateNum": 9 + // // }, + // // { + // // "dateNum": 10 + // // }, + // // { + // // "dateNum": 11 + // // }, + // // { + // // "dateNum": 12 + // // }, + // // { + // // "dateNum": 13 + // // }, + // // { + // // "dateNum": 14 + // // }, + // // { + // // "dateNum": 15 + // // }, + // // { + // // "dateNum": 16 + // // }, + // // { + // // "dateNum": 17 + // // }, + // // { + // // "dateNum": 18 + // // }, + // // { + // // "dateNum": 19 + // // }, + // // { + // // "dateNum": 20 + // // }, + // // { + // // "dateNum": 21 + // // }, + // // { + // // "dateNum": 22 + // // }, + // // { + // // "dateNum": 23 + // // }, + // // { + // // "dateNum": 24 + // // }, + // // { + // // "dateNum": 25 + // // }, + // // { + // // "dateNum": 26 + // // }, + // // { + // // "dateNum": 27 + // // }, + // // { + // // "dateNum": 28 + // // }, + // // { + // // "dateNum": 29 + // // }, + // // { + // // "dateNum": 30 + // // }, + // // { + // // "dateNum": 31 + // // } + // // ], + // // "monthLabel": "January", + // // "yearNum": 2023 + // // }); + + // // wrapper.unmount(); + // // }); + // }); +}); + +function setupMocks(mountOptionsMockData = {}) { + const initialMountOptionsMockData = { + // router: { + // navigate: jest.fn(), + // navigateWithSaving: jest.fn(), + // navigateWithoutSaving: jest.fn(), + // }, + // actionList: [ + // // { + // // actionName: storeActions.SAVE_PART_QUESTION_ANSWERS, + // // data: {}, + // // }, + // // { + // // actionName: storeActions.GET_PARTS, + // // data: {}, + // // }, + // ], + // store: { + // // getters: store.getters, + // // commit: store.commit, + // }, + }; + + const mountOptions = getMountOptions( + Object.assign(initialMountOptionsMockData, mountOptionsMockData) + ); + + // console.log("mountOptions: ", mountOptions) + + const wrapper = shallowMount(datePicker, mountOptions); + + return { wrapper }; +} diff --git a/src/digital-components/date-picker/date-picker.vue b/src/digital-components/date-picker/date-picker.vue new file mode 100644 index 000000000..008fae9fa --- /dev/null +++ b/src/digital-components/date-picker/date-picker.vue @@ -0,0 +1,640 @@ + + + + + diff --git a/src/common-components/dropdown-question/dropdown-question.spec.js b/src/digital-components/dropdown-question/dropdown-question.spec.js similarity index 86% rename from src/common-components/dropdown-question/dropdown-question.spec.js rename to src/digital-components/dropdown-question/dropdown-question.spec.js index a606e3d19..654709926 100644 --- a/src/common-components/dropdown-question/dropdown-question.spec.js +++ b/src/digital-components/dropdown-question/dropdown-question.spec.js @@ -1,5 +1,6 @@ import { shallowMount } from "@vue/test-utils"; import dropdownQuestion from "./dropdown-question"; +import crypto from "crypto"; // Mock CMS content const questionText = "Question Text"; @@ -11,6 +12,8 @@ const mockMixin = { }, }; +global.crypto = crypto; + // TODO: Remove the following from dropdown-question.vue -> :class="(errors && errors.length) || hasError ? 'has-error' : ''" // It is not being used. describe("dropdownQuestion.vue", () => { @@ -46,23 +49,6 @@ describe("dropdownQuestion.vue", () => { expect(label.text()).toContain(questionText); }); - it("Should return input id as the id of the select field", async () => { - // Arrange - const wrapper = shallowMount(dropdownQuestion, { - propsData: { - inputId: "input ID", - options: {}, - }, - mixins: [mockMixin], - }); - - // Act - const select = wrapper.find("select"); - - // Assert - expect(select.attributes().id).toEqual("input ID"); - }); - it("Should render the 'questionText' data value as the aria-label attribute.", async () => { // Arrange const wrapper = shallowMount(dropdownQuestion, { @@ -118,7 +104,7 @@ describe("dropdownQuestion.vue", () => { const wrapper = shallowMount(dropdownQuestion, { propsData: { options: {}, - modelValue: 0, + modelValue: "0", }, mixins: [mockMixin], }); diff --git a/src/common-components/dropdown-question/dropdown-question.vue b/src/digital-components/dropdown-question/dropdown-question.vue similarity index 72% rename from src/common-components/dropdown-question/dropdown-question.vue rename to src/digital-components/dropdown-question/dropdown-question.vue index e7c183e49..5c32b298c 100644 --- a/src/common-components/dropdown-question/dropdown-question.vue +++ b/src/digital-components/dropdown-question/dropdown-question.vue @@ -1,19 +1,23 @@ @@ -92,9 +122,17 @@ export default { .modal-header { border-bottom: none; .btn-close { + position: absolute; + right: 1rem; + top: 1rem; background-image: url("data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15.6874 1.82179L9.50889 8L15.6874 14.1782C16.1042 14.595 16.1042 15.2707 15.6874 15.6875C15.4843 15.8907 15.2146 16 14.9328 16C14.6514 16 14.3818 15.8906 14.1787 15.6875L8.00017 9.50934L1.82171 15.6875C1.6182 15.8907 1.34876 16 1.06708 16C0.785733 16 0.516056 15.8906 0.312965 15.6875C-0.10429 15.2706 -0.10429 14.5952 0.312797 14.1784L6.03276 8.45867L6.49146 8L0.312945 1.82177C-0.10429 1.40483 -0.10429 0.729418 0.312797 0.31262C0.728936 -0.104145 1.40489 -0.104051 1.82185 0.31262L7.54152 6.03202L8.00017 6.49065L14.1786 0.312472C14.5955 -0.104107 15.2707 -0.104201 15.6874 0.312452C16.1042 0.729289 16.1042 1.40496 15.6874 1.82179Z' fill='%231574A1'/%3E%3C/svg%3E%0A"); opacity: 1; } + + .modal-title { + font-weight: 500; + color: rgb(0, 0, 0); + } } &.modal-component { .modal-dialog { diff --git a/src/digital-components/modal/ux-components/modal-button-main/modal-button-main.spec.js b/src/digital-components/modal/ux-components/modal-button-main/modal-button-main.spec.js new file mode 100644 index 000000000..f212d8ec3 --- /dev/null +++ b/src/digital-components/modal/ux-components/modal-button-main/modal-button-main.spec.js @@ -0,0 +1,187 @@ +import { shallowMount } from "@vue/test-utils"; +import modalButtonMain from "./modal-button-main"; +import { getMountOptions } from "@/helpers/unit-test-helper.js"; +import { nextTick } from "vue"; + +describe("modal-button-main.vue", () => { + it("Should return btn-primary class", () => { + // Arrange/Act + const wrapper = shallowMount( + modalButtonMain, + setupMocks({ + propsData: { + isPrimary: true, + }, + }) + ); + const button = wrapper.find("button"); + + // Assert + expect(button.attributes("class")).toContain("btn-primary"); + }); + + it("Should return aria-disabled state", () => { + // Arrange/Act + const wrapper = shallowMount( + modalButtonMain, + setupMocks({ + propsData: { + isDisabled: true, + }, + }) + ); + const button = wrapper.find("button"); + + // Assert + expect(button.attributes()["aria-disabled"]).toEqual("true"); + }); + + it("Should return loader color", async () => { + // Arrange + const wrapper = shallowMount( + modalButtonMain, + setupMocks({ + propsData: { + loaderColor: "blue", + loaderEnabled: true, + }, + }) + ); + + // Act + wrapper.vm.clicked(); + await nextTick(); + + // Assert + const loader = wrapper.find("loader-stub"); + expect(loader.attributes("class")).toContain("blue"); + }); + + it("Should return loader position", async () => { + // Arrange + const wrapper = shallowMount( + modalButtonMain, + setupMocks({ + propsData: { + loaderPosition: "right", + loaderEnabled: true, + }, + }) + ); + + // Act + wrapper.vm.clicked(); + await nextTick(); + + // Assert + const loader = wrapper.find("loader-stub"); + expect(loader.attributes("class")).toContain("right"); + }); + + it("Should set 'isLoaderDisplayed' to false when calling 'removeLoader'", async () => { + // Arrange + const wrapper = shallowMount( + modalButtonMain, + setupMocks({ + propsData: { + loaderPosition: "right", + loaderEnabled: true, + }, + }) + ); + + wrapper.setData({ + isLoaderDisplayed: true, + }); + + // Act + wrapper.vm.removeLoader(); + await nextTick(); + + // Assert + const loader = wrapper.find("loader-stub"); + expect(wrapper.vm.isLoaderDisplayed).toBe(false); + }); + + it("Should set 'isLoaderDisplayed' to false when calling 'resetButtonStyle'", async () => { + // Arrange + const wrapper = shallowMount( + modalButtonMain, + setupMocks({ + propsData: { + loaderPosition: "right", + loaderEnabled: true, + }, + }) + ); + + wrapper.setData({ + isLoaderDisplayed: true, + }); + + // Act + wrapper.vm.resetButtonStyle(); + await nextTick(); + + // Assert + expect(wrapper.vm.isLoaderDisplayed).toBe(false); + }); + + it("Should emit 'click-event' event when clicking if the button is enabled", async () => { + // Arrange + const wrapper = shallowMount( + modalButtonMain, + setupMocks({ + propsData: { + loaderPosition: "right", + loaderEnabled: true, + isDisabled: false, + }, + }) + ); + + const buttonElement = wrapper.find("button"); + + // Act + buttonElement.trigger("click"); + + await nextTick(); + + // Assert + expect(wrapper.emitted("click-event")).toBeTruthy(); + }); + + it("Should not emit 'click-event' event when clicking if the button is disabled", async () => { + // Arrange + const wrapper = shallowMount( + modalButtonMain, + setupMocks({ + propsData: { + loaderPosition: "right", + loaderEnabled: true, + isDisabled: true, + }, + }) + ); + + const buttonElement = wrapper.find("button"); + + // Act + buttonElement.trigger("click"); + + await nextTick(); + + // Assert + expect(wrapper.emitted("click-event")).toBeFalsy(); + }); +}); + +function setupMocks(mountOptionsMockData = {}) { + const defaultMountOptions = { route: { query: { fmgPage: "page-name" } } }; + const baseMountOptions = getMountOptions( + Object.assign(defaultMountOptions, mountOptionsMockData) + ); + const allMountOptions = Object.assign(defaultMountOptions, baseMountOptions); + + return allMountOptions; +} diff --git a/src/digital-components/modal/ux-components/modal-button-main/modal-button-main.vue b/src/digital-components/modal/ux-components/modal-button-main/modal-button-main.vue new file mode 100644 index 000000000..eaffdf2d0 --- /dev/null +++ b/src/digital-components/modal/ux-components/modal-button-main/modal-button-main.vue @@ -0,0 +1,153 @@ + + + + + diff --git a/src/common-components/question-chain/question-chain.spec.js b/src/digital-components/question-chain/question-chain.spec.js similarity index 99% rename from src/common-components/question-chain/question-chain.spec.js rename to src/digital-components/question-chain/question-chain.spec.js index 8288f351c..2444fd22d 100644 --- a/src/common-components/question-chain/question-chain.spec.js +++ b/src/digital-components/question-chain/question-chain.spec.js @@ -1,5 +1,5 @@ import { shallowMount } from "@vue/test-utils"; -import questionChain from "@/common-components/question-chain/question-chain.vue"; +import questionChain from "./question-chain.vue"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { nextTick } from "vue"; diff --git a/src/common-components/question-chain/question-chain.vue b/src/digital-components/question-chain/question-chain.vue similarity index 98% rename from src/common-components/question-chain/question-chain.vue rename to src/digital-components/question-chain/question-chain.vue index bf68a4363..d72cec9c8 100644 --- a/src/common-components/question-chain/question-chain.vue +++ b/src/digital-components/question-chain/question-chain.vue @@ -17,7 +17,7 @@ + + diff --git a/src/common-components/funnel-footer/funnel-footer.spec.js b/src/fmg-components/funnel-footer/funnel-footer.spec.js similarity index 100% rename from src/common-components/funnel-footer/funnel-footer.spec.js rename to src/fmg-components/funnel-footer/funnel-footer.spec.js diff --git a/src/common-components/funnel-footer/funnel-footer.vue b/src/fmg-components/funnel-footer/funnel-footer.vue similarity index 97% rename from src/common-components/funnel-footer/funnel-footer.vue rename to src/fmg-components/funnel-footer/funnel-footer.vue index 2a6119681..f1900596b 100644 --- a/src/common-components/funnel-footer/funnel-footer.vue +++ b/src/fmg-components/funnel-footer/funnel-footer.vue @@ -34,6 +34,7 @@ import buttonMain from "@/ux-components/button-main/button-main"; export default { name: "funnelFooter", + emits: ["BackClicked", "ForwardClicked"], // <--- should remove oodles of warnings in dev tools props: { isForwardActionDisabled: Boolean, isBackButtonHidden: { type: Boolean, default: false }, diff --git a/src/common-components/funnel-header/funnel-header.spec.js b/src/fmg-components/funnel-header/funnel-header.spec.js similarity index 100% rename from src/common-components/funnel-header/funnel-header.spec.js rename to src/fmg-components/funnel-header/funnel-header.spec.js diff --git a/src/common-components/funnel-header/funnel-header.vue b/src/fmg-components/funnel-header/funnel-header.vue similarity index 96% rename from src/common-components/funnel-header/funnel-header.vue rename to src/fmg-components/funnel-header/funnel-header.vue index f952b94a8..acfacd709 100644 --- a/src/common-components/funnel-header/funnel-header.vue +++ b/src/fmg-components/funnel-header/funnel-header.vue @@ -19,7 +19,7 @@ import alert from "@/ux-components/alert/alert"; import eventBus from "@/helpers/event-bus/event-bus"; import { globalEvents } from "@/constants/events"; -import menuModal from "@/common-components/funnel-header/menu-modal/menu-modal"; +import menuModal from "@/fmg-components/funnel-header/menu-modal/menu-modal"; export default { name: "funnel-header", diff --git a/src/common-components/funnel-header/menu-modal/menu-modal.spec.js b/src/fmg-components/funnel-header/menu-modal/menu-modal.spec.js similarity index 100% rename from src/common-components/funnel-header/menu-modal/menu-modal.spec.js rename to src/fmg-components/funnel-header/menu-modal/menu-modal.spec.js diff --git a/src/common-components/funnel-header/menu-modal/menu-modal.vue b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue similarity index 90% rename from src/common-components/funnel-header/menu-modal/menu-modal.vue rename to src/fmg-components/funnel-header/menu-modal/menu-modal.vue index fd0c96cb8..ccf2c38e0 100644 --- a/src/common-components/funnel-header/menu-modal/menu-modal.vue +++ b/src/fmg-components/funnel-header/menu-modal/menu-modal.vue @@ -4,8 +4,7 @@ class="menu-button" type="button" :class="[isActive ? 'active' : '']" - data-bs-toggle="modal" - data-bs-target="#footerModal" + @click="toggleModal" aria-label="Hamburger Menu (modal window)">
@@ -22,19 +21,6 @@ aria-hidden="true" v-on="{ 'show.bs.modal': show, 'hide.bs.modal': hide }" :style="`height: calc(100% - ${currentFooterAndHeaderHeight}px);`"> -