Merge branch 'develop' into feature/SSR-1464

This commit is contained in:
Katie Kroell 2024-09-23 14:16:32 -04:00
commit 61af19ed6e
16 changed files with 414 additions and 215 deletions

252
package-lock.json generated
View file

@ -52,7 +52,7 @@
"sass-loader": "^12.0.0",
"vite": "^4.4.6",
"vitest": "^0.33.0",
"volar-service-vetur": "latest"
"volar-service-vetur": "*"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@ -5867,9 +5867,9 @@
"dev": true
},
"node_modules/body-parser": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
"integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"dev": true,
"dependencies": {
"bytes": "3.1.2",
@ -5880,7 +5880,7 @@
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
"qs": "6.13.0",
"raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
@ -6077,13 +6077,19 @@
}
},
"node_modules/call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -7365,6 +7371,23 @@
"clone": "^1.0.2"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-lazy-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
@ -7720,9 +7743,9 @@
}
},
"node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"dev": true,
"engines": {
"node": ">= 0.8"
@ -7816,6 +7839,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dev": true,
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-get-iterator": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.2.tgz",
@ -8723,37 +8767,37 @@
}
},
"node_modules/express": {
"version": "4.19.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
"integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
"integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==",
"dev": true,
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.2",
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~1.0.2",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.2.0",
"finalhandler": "1.3.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"merge-descriptors": "1.0.1",
"merge-descriptors": "1.0.3",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"path-to-regexp": "0.1.10",
"proxy-addr": "~2.0.7",
"qs": "6.11.0",
"qs": "6.13.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.18.0",
"serve-static": "1.15.0",
"send": "0.19.0",
"serve-static": "1.16.2",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
@ -8930,13 +8974,13 @@
}
},
"node_modules/finalhandler": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
"integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
"dev": true,
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
@ -9125,10 +9169,13 @@
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/function.prototype.name": {
"version": "1.1.5",
@ -9185,14 +9232,19 @@
}
},
"node_modules/get-intrinsic": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
"integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.3"
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -9378,12 +9430,24 @@
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
"integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dev": true,
"dependencies": {
"get-intrinsic": "^1.1.1"
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -9422,6 +9486,18 @@
"integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
"dev": true
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
@ -13973,10 +14049,13 @@
}
},
"node_modules/merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==",
"dev": true
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/merge-source-map": {
"version": "1.1.0",
@ -14473,10 +14552,13 @@
}
},
"node_modules/object-inspect": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@ -14897,9 +14979,9 @@
"dev": true
},
"node_modules/path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==",
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz",
"integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==",
"dev": true
},
"node_modules/path-type": {
@ -15788,12 +15870,12 @@
}
},
"node_modules/qs": {
"version": "6.11.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"dev": true,
"dependencies": {
"side-channel": "^1.0.4"
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
@ -16391,9 +16473,9 @@
}
},
"node_modules/send": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
"integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"dev": true,
"dependencies": {
"debug": "2.6.9",
@ -16429,6 +16511,15 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
"node_modules/send/node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"dev": true,
"engines": {
"node": ">= 0.8"
}
},
"node_modules/send/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@ -16523,20 +16614,37 @@
}
},
"node_modules/serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
"integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
"dev": true,
"dependencies": {
"encodeurl": "~1.0.2",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.18.0"
"send": "0.19.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"dependencies": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@ -16592,14 +16700,18 @@
"dev": true
},
"node_modules/side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
"call-bind": "^1.0.7",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.4",
"object-inspect": "^1.13.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"

View file

@ -80,6 +80,10 @@ const endpoints = Object.freeze({
url: `${PRICE_BASE_URL}/order-items-with-itac-pricing`,
method: 'POST'
},
GetCombinedQuote: {
url: `${PRICE_BASE_URL}/combined-quote`,
method: 'POST'
},
GetProviders: {
url: `${LOCATION_BASE_URL}/providers`,
method: 'GET'

View file

@ -28,7 +28,7 @@ export async function getPricedMobileFeePart(serviceZipCode) {
// Get the Mobile Fee Part Price
const pricingResults = await useMainStore()
.getInsurancePriceOrderItems([mobileFeePart.data]);
.getCombinedQuote([mobileFeePart.data]);
return Promise.resolve(pricingResults[0]);
}

View file

@ -10,6 +10,17 @@ export function stripRteStyle(stringWithStyleTag) {
return stringWithStyleTag.replace(regexExp, '');
}
/**
* @function createOrderedListFromStringOfParagraphs
* @summary
* Returns string with <p> tags changed to <li> and wrapped in an <ol>
* @param {string} stringOfParagraphs single string with 1 to N <p> tags
* @returns {string} converted string wrapped in an <ol>
*/
export function createOrderedListFromStringOfParagraphs(stringOfParagraphs) {
return `<ol>${stringOfParagraphs.replaceAll('<p></p>', '').replaceAll('<p>', '<li>').replaceAll('</p>', '</li>')}</ol>`;
}
/**
* @function toTitleCase
* @summary Returns title cased string version of 'text'

View file

@ -1,4 +1,10 @@
import { toTitleCase, toDisplayPhoneNumber, formatAddress, formatAmountInDollars } from '@/helpers/text-helper.js';
import {
toTitleCase,
toDisplayPhoneNumber,
formatAddress,
formatAmountInDollars,
createOrderedListFromStringOfParagraphs
} from '@/helpers/text-helper.js';
describe('text-helper', () => {
test.each([
@ -68,4 +74,23 @@ describe('text-helper', () => {
])('formatAmountInDollars(%s) should return %s', (amount, expected) => {
expect(formatAmountInDollars(amount)).toBe(expected);
});
describe('createOrderedListFromStringOfParagraphs', () => {
test('returns orderedlist from paragraph string', () => {
// Arrange
const testData = '<p>String one</p><p>String two</p>';
const expected = '<ol><li>String one</li><li>String two</li></ol>';
// Assert
expect(createOrderedListFromStringOfParagraphs(testData)).toBe(expected);
});
test('returns orderedlist from paragraph string with empty <p> tag', () => {
// Arrange
const testData = '<p>String one</p><p>String two</p><p></p>';
const expected = '<ol><li>String one</li><li>String two</li></ol>';
// Assert
expect(createOrderedListFromStringOfParagraphs(testData)).toBe(expected);
});
});
});

View file

@ -12,7 +12,8 @@
hasIcon
disableAutoFill
validationRules="street-address-required"
@keydown.enter.prevent />
@keydown.enter.prevent
@focusout="fillInAddress()" />
</div>
</div>
<transition

View file

@ -27,6 +27,11 @@ jest.mock('@/helpers/cms-content-helper', () => ({
processIfStatements: jest.fn()
}));
jest.mock('@/helpers/text-helper', () => ({
createOrderedListFromStringOfParagraphs: jest.fn(),
formatAmountInDollars: jest.fn()
}));
const SAFELITE_PROVIDER = 'Safelite';
const CANCEL_CLAIM_REF_NAME = 'CancelClaimModal';

View file

@ -127,7 +127,7 @@ import baseFormMixin from '@/mixins/base-form-mixin.js';
import navigationScenarios from '@/router/router-constants/navigation-scenarios.js';
import bailoutMessage from '@/constants/bailoutMessage';
import widgetFields from '@/constants/cms-widget-fields.js';
import { formatAmountInDollars } from '@/helpers/text-helper.js';
import { formatAmountInDollars, createOrderedListFromStringOfParagraphs } from '@/helpers/text-helper.js';
import showIssLoadingModal from '@/helpers/loading-modal-helper';
import { getPriceOfLineItems } from '@/helpers/price-calculator';
import coverageStatuses from '@/constants/coverage-statuses';
@ -275,10 +275,12 @@ export default {
);
},
nextStepsBody() {
return this.getTextFromCmsWithCustomIfStatements(
const cmsText = this.getTextFromCmsWithCustomIfStatements(
this.widget.nextStep,
widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT
)?.replaceAll('{custom:damage}', this.damageText);
return createOrderedListFromStringOfParagraphs(cmsText);
},
damageText() {
const damageString = getDamageString();
@ -394,12 +396,10 @@ export default {
showIssLoadingModal(false);
},
async getPricedParts() {
const clonedGlassParts = useMainStore().lineItems.glassParts
? JSON.parse(JSON.stringify(useMainStore().lineItems.glassParts))
: [];
const { glassParts, supportingItems } = this.mainStore.order.lineItems;
const availableLineItems = [
...(this.mainStore.lineItems.supportingItems ?? []),
...(clonedGlassParts ?? [])
...(glassParts ?? []),
...(supportingItems ?? [])
];
// We only call the ITAC pricing endpoint if we are not repair or we are NoComp
@ -506,6 +506,17 @@ export default {
.deductible-text {
line-height: 1.5rem;
}
:deep ol {
padding: 0;
padding-left: 1.125rem;
padding-right: 1.125rem;
line-height: 1.5rem;
font-size: .875rem;
li {
margin-bottom: .5rem;
}
}
:deep p {
line-height: 1.5rem;
font-size: 0.875rem;

View file

@ -93,7 +93,12 @@ describe('payment-method.vue', () => {
payment: {
isPayInAdvance: true,
payInAdvanceType: payInAdvanceMethod
}
},
insuranceCoverage: {
coverageStatus: coverageStatuses.VERIFIED,
coverageType: coverageType.Deductible
},
currentDeductible: 1000
}
};
const wrapper = setupMocks({}, store);
@ -101,6 +106,88 @@ describe('payment-method.vue', () => {
// Act
const paymethod = wrapper.vm.getPaymentMethodFromStore();
// Assert
expect(paymethod).toBe(payInAdvanceMethod);
});
test('getting PAY_AT_TIME_OF_SERVICE when deductible is 0', async () => {
// Arrange
const payInAdvanceMethod = paymentMethods.PAY_AT_TIME_OF_SERVICE;
const store = {
order: {
payment: {
isPayInAdvance: true,
payInAdvanceType: payInAdvanceMethod
},
insuranceCoverage: {
coverageStatus: coverageStatuses.VERIFIED,
coverageType: coverageType.Deductible
},
currentDeductible: 0
}
};
const wrapper = setupMocks({}, store);
// Act
const paymethod = wrapper.vm.getPaymentMethodFromStore();
// Assert
expect(paymethod).toBe(payInAdvanceMethod);
});
test('getting PAY_AT_TIME_OF_SERVICE when Unverified', async () => {
// Arrange
const payInAdvanceMethod = paymentMethods.PAY_AT_TIME_OF_SERVICE;
const store = {
order: {
payment: {
isPayInAdvance: true,
payInAdvanceType: payInAdvanceMethod
},
insuranceCoverage: {
coverageStatus: coverageStatuses.PENDING,
coverageType: coverageType.Deductible
},
currentDeductible: 1000
}
};
const wrapper = setupMocks({}, store);
// Act
const paymethod = wrapper.vm.getPaymentMethodFromStore();
// Assert
expect(paymethod).toBe(payInAdvanceMethod);
});
test('getting PAY_AT_TIME_OF_SERVICE when PIA Experiment disabled', async () => {
// Arrange
const payInAdvanceMethod = paymentMethods.PAY_AT_TIME_OF_SERVICE;
const mixin = {
methods: {
getSettingValue: jest.fn((settingName) => {
if (settingName === experimentSettings.ISS_DISPLAY_PAY_IN_ADVANCE) {
return 'false';
}
return 'false';
})
}
};
const store = {
order: {
payment: {
isPayInAdvance: true,
payInAdvanceType: payInAdvanceMethod
},
insuranceCoverage: {
coverageStatus: coverageStatuses.VERIFIED,
coverageType: coverageType.Deductible
},
currentDeductible: 1000
}
};
const wrapper = setupMocks({}, store, mixin);
// Act
const paymethod = wrapper.vm.getPaymentMethodFromStore();
// Assert
expect(paymethod).toBe(payInAdvanceMethod);
});

View file

@ -111,26 +111,11 @@ export default {
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.issPage);
const reviewDropdownPromise = reviewDropdown.methods.loadInitialData();
const wipersPromise = useMainStore().getWipers();
const rainDefensePromise = useMainStore().getRainDefense();
const promiseResultMap = [
{
resultKey: 'cmsContent',
promise: cmsContentPromise
},
{
resultKey: 'reviewDropdownData',
promise: reviewDropdownPromise
},
{
resultKey: 'wipers',
promise: wipersPromise
},
{
resultKey: 'rainDefense',
promise: rainDefensePromise
}
];
@ -138,28 +123,10 @@ export default {
await useMainStore().setPriceAndSalesTaxForOrderLineItems();
const unpricedVaps = [...resultMap.wipers, resultMap.rainDefense];
let hasBailedOut = false;
const pricedVaps = await useMainStore()
.getInsurancePriceOrderItems(unpricedVaps)
.catch((err) => {
useMainStore().setBailout(bailoutMessage.pricingResponseError(
unpricedVaps.map((li) => li.partNumber),
{ code: err.code, message: err.message, data: err.data }
));
hasBailedOut = true;
next(`/?issPage=${issPageValues.BAILOUT_PAGE}`);
});
if (!hasBailedOut) {
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
vm.$refs.reviewDropdown.initializeComponent(resultMap.reviewDropdownData);
vm.storeAvailableVaps(pricedVaps ?? []);
});
}
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.updateFooterButtonText(vm.customCallToActionButtonCopy);
});
},
data() {
return {
@ -287,7 +254,8 @@ export default {
const { payInAdvanceType } = useMainStore().order.payment;
const isPayInAdvance =
useMainStore().order.payment.isPayInAdvance
&& !!payInAdvanceType;
&& !!payInAdvanceType
&& !this.isPayInAdvanceDisabled;
return isPayInAdvance
? payInAdvanceType
@ -321,9 +289,6 @@ export default {
this.$route
);
}
},
storeAvailableVaps(vaps) {
useMainStore().order.availableVaps = vaps;
}
}
};

View file

@ -96,21 +96,6 @@ export default {
}
},
methods: {
async loadInitialData() {
const servicePackageInitialDataPromise = servicePackageReview.methods.loadInitialData();
const promiseResultMap = [
{
resultKey: 'servicePackageData',
promise: servicePackageInitialDataPromise
}
];
return settleAllPromises(promiseResultMap);
},
initializeComponent(apiResponses) {
this.$refs.servicePackageReview.initializeComponent(apiResponses.servicePackageData);
},
toggleIsExpanded() {
this.isExpanded = !this.isExpanded;
}

View file

@ -8,6 +8,7 @@ import { getMountOptions } from '@/helpers/unit-test-helper.js';
import packageNames from '@/constants/package-names';
import partTypeStrings from '@/constants/part-type-strings';
import damageLocationsSelected from '@/constants/damage-locations-selected';
import { useMainStore } from '@/store';
const testConstants = {
cmsPropValues: {
@ -717,11 +718,8 @@ const mockMixin = {
}
};
function initializeWithDefault(wrapper) {
wrapper.vm.initializeComponent({
wipers: [testConstants.parts.frontWiperPart],
rainDefense: testConstants.parts.rainDefensePart
});
function initializeWithDefault() {
useMainStore().order.availableVaps = [testConstants.parts.frontWiperPart, testConstants.parts.rainDefensePart];
}
function getShallowMountedComponent(initialData = {}, methodToRun = () => {}) {
@ -853,7 +851,7 @@ describe('Service Package Review Block', () => {
...props
});
initializeWithDefault(wrapper);
initializeWithDefault();
// Act
await wrapper.vm.$nextTick();
@ -883,7 +881,7 @@ describe('Service Package Review Block', () => {
...props
});
initializeWithDefault(wrapper);
initializeWithDefault();
// Act
await wrapper.vm.$nextTick();
@ -909,7 +907,7 @@ describe('Service Package Review Block', () => {
// Act
await wrapper.vm.$nextTick();
initializeWithDefault(wrapper);
initializeWithDefault();
// Assert
const includesFrontWiperCopy = wrapper.vm.displayContent.includes(testConstants.vapsCopy.frontWiperCopy);
@ -926,7 +924,7 @@ describe('Service Package Review Block', () => {
...props
});
initializeWithDefault(wrapper);
initializeWithDefault();
// Act
await wrapper.vm.$nextTick();
@ -952,10 +950,7 @@ describe('Service Package Review Block', () => {
...props
});
wrapper.vm.initializeComponent({
wipers: scenario.params.wiperResponse,
rainDefense: scenario.params.rainDefenseResponse
});
useMainStore().order.availableVaps = [scenario.params.rainDefenseResponse, ...scenario.params.wiperResponse];
// Act
await wrapper.vm.$nextTick();

View file

@ -92,34 +92,9 @@ export default {
return [
...(this.lineItems?.glassParts ?? []),
...(this.lineItems?.supportingItems ?? []),
...this.availableVaps
...(useMainStore().order.availableVaps ?? [])
];
}
},
methods: {
// TODO maybe move to shared location "loadAvailableVaps"
loadInitialData() {
const wipersPromise = useMainStore().getWipers();
const rainDefensePromise = useMainStore().getRainDefense();
const promiseResultMap = [
{
resultKey: 'wipers',
promise: wipersPromise
},
{
resultKey: 'rainDefense',
promise: rainDefensePromise
}
];
return settleAllPromises(promiseResultMap);
},
initializeComponent(apiResponses) {
const vapsFromApi = [...apiResponses.wipers, apiResponses.rainDefense];
this.availableVaps = vapsFromApi;
}
}
};
</script>

View file

@ -262,7 +262,7 @@ export default {
const premiumFeeWithPricePromise = premiumFeePromise.then((result) => {
if (result.data) {
return useMainStore().getInsurancePriceOrderItems(result.data);
return useMainStore().getCombinedQuote(result.data);
}
return result.data;
});

View file

@ -96,7 +96,6 @@ export default {
const wipersPromise = await store.getWipers();
const rainDefensePromise = await store.getRainDefense();
const supportingItemsPromise = await store.getSupportingItems();
const promiseResultMap = [
{
resultKey: 'cmsContent',
@ -109,27 +108,20 @@ export default {
{
resultKey: 'rainDefense',
promise: rainDefensePromise
},
{
resultKey: 'supportingItems',
promise: supportingItemsPromise
}
];
const resultMap = await settleAllPromises(promiseResultMap);
const clonedGlassParts = store.order.lineItems.glassParts
? JSON.parse(JSON.stringify(store.order.lineItems.glassParts))
: [];
const { feeItems } = store.order.lineItems;
const availableLineItems = [
resultMap.rainDefense,
...resultMap.supportingItems,
...resultMap.wipers,
...clonedGlassParts
...feeItems
];
let hasBailedOut = false;
const pricingResults = await store
.getInsurancePriceOrderItems(availableLineItems)
await store.getCombinedQuote(availableLineItems)
.catch((err) => {
useMainStore().setBailout(bailoutMessage.pricingResponseError(
availableLineItems.map((li) => li.partNumber),
@ -143,7 +135,7 @@ export default {
if (!hasBailedOut) {
next((vm) => {
vm.setCmsContent(resultMap.cmsContent);
vm.setData(clonedGlassParts, resultMap.supportingItems, pricingResults);
vm.setData([resultMap.rainDefense, ...resultMap.wipers]);
});
}
},
@ -151,8 +143,6 @@ export default {
return {
selectedVaps: [],
availableLineItems: [],
supportingItems: [],
pricedGlassParts: [],
loadingText: [
'Finding shops near you',
'Looking for dates',
@ -183,27 +173,20 @@ export default {
&& store.order.lineItems.glassParts.length > 0))
);
},
setData(clonedGlassParts, supportingItems, pricingResults) {
this.pricedGlassParts = clonedGlassParts;
this.supportingItems = supportingItems;
this.availableLineItems = pricingResults;
setData(pricedVaps) {
this.availableLineItems = pricedVaps;
useMainStore().order.availableVaps = pricedVaps;
},
vapsItemsSelectedAction(vapsItemsSelected) {
this.selectedVaps = vapsItemsSelected;
},
forwardButtonAction() {
const parts = {
glassParts: this.pricedGlassParts,
supportingItems: this.supportingItems,
vaps: this.selectedVaps
};
if (!allGlassPartsAndItemsHavePrices(parts)) {
window.console.error('One or more items have no price assigned!');
}
if (this.pricedGlassParts.length > 0) {
store.updateGlassParts(this.pricedGlassParts);
}
store.updateSupportingItems(this.supportingItems);
store.updateVaps(this.selectedVaps);
this.$router.navigate(

View file

@ -1158,6 +1158,52 @@ export const useMainStore = defineStore({
return availableLineItems;
},
async getCombinedQuote(availableLineItems) {
const { vehicle, serviceLocation, policy, eon, referralNumber, referralDate, referralSequenceNumber, lineItems } = this.order;
const payload = {
ParentAccountNumber: this.order.parentAccountNumber,
BillToAccountNumber: this.billToAccountNumber,
ProviderNumber: this.providerNumber,
CarId: vehicle.carId,
Make: vehicle.make,
Model: vehicle.model,
Year: vehicle.year,
EON: eon,
ZipCode: policy.policyZipCode,
State: policy.damageState,
ReferralNumber: referralNumber,
ReferralDate: referralDate,
ReferralSequenceNumber: referralSequenceNumber,
ServiceZipCode: serviceLocation.zipCode,
IsReplacement: !this.isRepair,
ServerData: lineItems.serverData,
LineItems: getLineItemsFlattened(availableLineItems)
};
const response = await globalMethods
.callHttpClient({
method: endpoints.GetCombinedQuote.method,
endpoint: endpoints.GetCombinedQuote.url,
payload
})
.catch((error) => {
console.error(error);
return [];
});
const { lineItems: pricedLinedItems, serverData } = response.data;
if (serverData) {
this.order.lineItems.serverData = serverData;
}
if (pricedLinedItems) {
return addPricesToLineItems(availableLineItems, pricedLinedItems);
}
return availableLineItems;
},
getMobileFeePart() {
const damageType = this.damage.isRepair ? 'Repair' : 'Replace';
@ -1775,18 +1821,14 @@ export const useMainStore = defineStore({
},
async setPriceAndSalesTaxForOrderLineItems() {
const lineItemsToPrice = [
...(this.order.lineItems.supportingItems ?? []),
...(this.order.lineItems.glassParts ?? []),
...(this.order.lineItems.otherParts ?? []),
...(this.order.lineItems.vaps ?? []),
...(this.order.lineItems.feeItems ?? [])
];
let lineItemsToTax = [];
if (!this.isVerified || !this.isDeductible) {
let lineItemsToTax;
if (this.isVerified && !this.isDeductible) {
lineItemsToTax = [
...lineItemsToPrice
...(this.order.lineItems.supportingItems ?? []),
...(this.order.lineItems.glassParts ?? []),
...(this.order.lineItems.otherParts ?? []),
...(this.order.lineItems.vaps ?? []),
...(this.order.lineItems.feeItems ?? [])
];
} else {
lineItemsToTax = [
@ -1795,8 +1837,6 @@ export const useMainStore = defineStore({
];
}
await this.getInsurancePriceOrderItems(lineItemsToPrice);
if (lineItemsToTax && lineItemsToTax.length > 0) {
await this.getTaxOrderItems(lineItemsToTax);
}