CSR-98 Test call order/save endpoint on vehicle-damage page

This commit is contained in:
Katie 2022-03-01 17:03:14 -05:00
commit edda638d4f
88 changed files with 2661 additions and 211 deletions

View file

@ -17,6 +17,9 @@ module.exports = {
"!src/layouts/vehicle-damage/windshield-options/windshield-options.vue",
"!src/layouts/address-poc/address-poc.vue",
"!src/layouts/nested-radio-poc/nested-radio.vue",
"!src/layouts/button-question-examples/**/*.vue",
"!src/layouts/part-questions/**/*.vue",
"!src/layouts/reveal/**/*.vue",
], //! means exclude from coverage.
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
coverageThreshold: {

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8976)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8976" x1="51.9586" y1="33.0102" x2="51.9586" y2="6.98049" gradientUnits="userSpaceOnUse">
<stop stop-color="#CADCDD"/>
<stop offset="0.2653" stop-color="#C8DBDC"/>
<stop offset="0.3972" stop-color="#C0D6D7"/>
<stop offset="0.4996" stop-color="#B3CDD0"/>
<stop offset="0.5869" stop-color="#A0C1C5"/>
<stop offset="0.6645" stop-color="#88B1B8"/>
<stop offset="0.7353" stop-color="#6A9EA7"/>
<stop offset="0.8009" stop-color="#468793"/>
<stop offset="0.8607" stop-color="#1E6D7C"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_9006)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_9006" x1="51.9586" y1="33.0065" x2="51.9586" y2="6.97682" gradientUnits="userSpaceOnUse">
<stop stop-color="#D0CDC2"/>
<stop offset="0.2632" stop-color="#CECCC1"/>
<stop offset="0.394" stop-color="#C6C8BE"/>
<stop offset="0.4956" stop-color="#B9C0B8"/>
<stop offset="0.5823" stop-color="#A6B6B1"/>
<stop offset="0.6593" stop-color="#8EA8A6"/>
<stop offset="0.7295" stop-color="#70989A"/>
<stop offset="0.7947" stop-color="#4C848B"/>
<stop offset="0.854" stop-color="#246E7A"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,19 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8763)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8763" x1="51.9586" y1="33.0065" x2="51.9586" y2="6.97682" gradientUnits="userSpaceOnUse">
<stop stop-color="#E7E7E8"/>
<stop offset="0.2559" stop-color="#E5E6E7"/>
<stop offset="0.383" stop-color="#DDE1E3"/>
<stop offset="0.4818" stop-color="#D0D9DC"/>
<stop offset="0.5659" stop-color="#BDCDD1"/>
<stop offset="0.6409" stop-color="#A5BFC4"/>
<stop offset="0.7091" stop-color="#87ACB4"/>
<stop offset="0.7724" stop-color="#6397A1"/>
<stop offset="0.8318" stop-color="#3A7D8A"/>
<stop offset="0.8859" stop-color="#0C6272"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8750)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8750" x1="51.9586" y1="33.0219" x2="51.9586" y2="6.99218" gradientUnits="userSpaceOnUse">
<stop stop-color="#CBE9DD"/>
<stop offset="0.265" stop-color="#C9E7DC"/>
<stop offset="0.3966" stop-color="#C1E2D7"/>
<stop offset="0.4989" stop-color="#B4D9D0"/>
<stop offset="0.5861" stop-color="#A1CCC6"/>
<stop offset="0.6636" stop-color="#89BAB8"/>
<stop offset="0.7343" stop-color="#6BA5A7"/>
<stop offset="0.7998" stop-color="#478C93"/>
<stop offset="0.8595" stop-color="#1F707D"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,19 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8908)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8908" x1="51.9812" y1="33.0046" x2="51.9812" y2="6.97492" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="0.2491" stop-color="#FDFEFE"/>
<stop offset="0.3729" stop-color="#F5F9F9"/>
<stop offset="0.4691" stop-color="#E8F0F2"/>
<stop offset="0.551" stop-color="#D5E4E7"/>
<stop offset="0.6239" stop-color="#BDD4D9"/>
<stop offset="0.6904" stop-color="#9FC1C7"/>
<stop offset="0.752" stop-color="#7BAAB3"/>
<stop offset="0.8099" stop-color="#528F9A"/>
<stop offset="0.8626" stop-color="#247280"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8984)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8984" x1="51.9519" y1="33.0065" x2="51.9519" y2="6.97682" gradientUnits="userSpaceOnUse">
<stop stop-color="#D0CDC2"/>
<stop offset="0.2738" stop-color="#CECBC0"/>
<stop offset="0.4097" stop-color="#C9C6B8"/>
<stop offset="0.5154" stop-color="#C0BCAB"/>
<stop offset="0.6055" stop-color="#B3AD98"/>
<stop offset="0.6856" stop-color="#A39B80"/>
<stop offset="0.7586" stop-color="#8E8462"/>
<stop offset="0.8262" stop-color="#766A3E"/>
<stop offset="0.8879" stop-color="#5B4B16"/>
<stop offset="0.8993" stop-color="#55450E"/>
<stop offset="1" stop-color="#55450E"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8980)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8980" x1="51.9552" y1="33.0102" x2="51.9552" y2="6.98049" gradientUnits="userSpaceOnUse">
<stop stop-color="#CADCDD"/>
<stop offset="0.2908" stop-color="#C8DADB"/>
<stop offset="0.4353" stop-color="#C1D2D3"/>
<stop offset="0.5475" stop-color="#B6C5C6"/>
<stop offset="0.6432" stop-color="#A5B2B3"/>
<stop offset="0.7282" stop-color="#909A9B"/>
<stop offset="0.8057" stop-color="#767C7D"/>
<stop offset="0.8761" stop-color="#58595A"/>
<stop offset="0.8993" stop-color="#4C4C4D"/>
<stop offset="1" stop-color="#4C4C4D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 981 B

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_9018)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_9018" x1="51.9552" y1="33.0065" x2="51.9552" y2="6.97682" gradientUnits="userSpaceOnUse">
<stop stop-color="#D0CDC2"/>
<stop offset="0.2978" stop-color="#CECBC0"/>
<stop offset="0.4457" stop-color="#C6C3B9"/>
<stop offset="0.5606" stop-color="#B9B6AE"/>
<stop offset="0.6585" stop-color="#A6A49D"/>
<stop offset="0.7456" stop-color="#8E8C87"/>
<stop offset="0.8237" stop-color="#71706D"/>
<stop offset="0.8959" stop-color="#4E4E4F"/>
<stop offset="0.8993" stop-color="#4C4C4D"/>
<stop offset="1" stop-color="#4C4C4D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 981 B

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8978)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8978" x1="51.9552" y1="33.0065" x2="51.9552" y2="6.97682" gradientUnits="userSpaceOnUse">
<stop stop-color="#E7E7E8"/>
<stop offset="0.2851" stop-color="#E5E5E6"/>
<stop offset="0.4267" stop-color="#DDDDDE"/>
<stop offset="0.5368" stop-color="#D0D0D1"/>
<stop offset="0.6305" stop-color="#BDBDBE"/>
<stop offset="0.7139" stop-color="#A5A5A6"/>
<stop offset="0.7899" stop-color="#878788"/>
<stop offset="0.8589" stop-color="#646465"/>
<stop offset="0.8993" stop-color="#4C4C4D"/>
<stop offset="1" stop-color="#4C4C4D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 981 B

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8932)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8932" x1="51.9552" y1="33.0219" x2="51.9552" y2="6.99218" gradientUnits="userSpaceOnUse">
<stop stop-color="#CBE9DD"/>
<stop offset="0.2841" stop-color="#C9E7DB"/>
<stop offset="0.4252" stop-color="#C3DFD4"/>
<stop offset="0.5349" stop-color="#B8D2C8"/>
<stop offset="0.6283" stop-color="#A9BFB7"/>
<stop offset="0.7114" stop-color="#96A7A0"/>
<stop offset="0.7871" stop-color="#7D8985"/>
<stop offset="0.8559" stop-color="#616665"/>
<stop offset="0.8993" stop-color="#4C4C4D"/>
<stop offset="1" stop-color="#4C4C4D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 981 B

View file

@ -0,0 +1,20 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="#CEE7DB"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8920)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8920" x1="51.9618" y1="33.0102" x2="51.9618" y2="6.98049" gradientUnits="userSpaceOnUse">
<stop stop-color="#CADCDD"/>
<stop offset="0.2653" stop-color="#C8DBDB"/>
<stop offset="0.3972" stop-color="#C0D6D5"/>
<stop offset="0.4996" stop-color="#B3CFCB"/>
<stop offset="0.5869" stop-color="#A0C4BD"/>
<stop offset="0.6645" stop-color="#88B6AA"/>
<stop offset="0.7353" stop-color="#6AA593"/>
<stop offset="0.8009" stop-color="#469177"/>
<stop offset="0.8607" stop-color="#1E7A58"/>
<stop offset="0.8993" stop-color="#006941"/>
<stop offset="1" stop-color="#006941"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8982)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8982" x1="51.9814" y1="33.0065" x2="51.9814" y2="6.97682" gradientUnits="userSpaceOnUse">
<stop stop-color="#D0CDC2"/>
<stop offset="0.2632" stop-color="#CECCC1"/>
<stop offset="0.394" stop-color="#C6C8BC"/>
<stop offset="0.4956" stop-color="#B9C2B4"/>
<stop offset="0.5823" stop-color="#A6B9A8"/>
<stop offset="0.6593" stop-color="#8EAD99"/>
<stop offset="0.7295" stop-color="#709F86"/>
<stop offset="0.7947" stop-color="#4C8E70"/>
<stop offset="0.854" stop-color="#247A57"/>
<stop offset="0.8993" stop-color="#006941"/>
<stop offset="1" stop-color="#006941"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="url(#paint0_linear_841_8896)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8896" x1="51.9618" y1="33.0219" x2="51.9618" y2="6.99218" gradientUnits="userSpaceOnUse">
<stop stop-color="#CBE9DD"/>
<stop offset="0.265" stop-color="#C9E8DB"/>
<stop offset="0.3966" stop-color="#C1E3D5"/>
<stop offset="0.4989" stop-color="#B4DACB"/>
<stop offset="0.5861" stop-color="#A1CFBD"/>
<stop offset="0.6636" stop-color="#89BFAA"/>
<stop offset="0.7343" stop-color="#6BAC93"/>
<stop offset="0.7998" stop-color="#479678"/>
<stop offset="0.8595" stop-color="#1F7D59"/>
<stop offset="0.8993" stop-color="#006941"/>
<stop offset="1" stop-color="#006941"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="#CBDDDE" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="#D1CEC3" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="#5D564C" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="#D3D3D3" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="#E9E9EB" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="#CBE9DD" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="white" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 368 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M78.25 33H25.7083C24.2188 33 23 31.7812 23 30.2917V9.70833C23 8.21874 24.2188 7 25.7083 7H78.25C79.7396 7 80.9583 8.21874 80.9583 9.70833V30.2917C80.9583 31.7812 79.7396 33 78.25 33Z" fill="#626167" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 370 B

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8966)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8966" x1="51.9716" y1="34.0522" x2="51.9716" y2="5.97896" gradientUnits="userSpaceOnUse">
<stop stop-color="#CADCDD"/>
<stop offset="0.2653" stop-color="#C8DBDC"/>
<stop offset="0.3972" stop-color="#C0D6D7"/>
<stop offset="0.4996" stop-color="#B3CDD0"/>
<stop offset="0.5869" stop-color="#A0C1C5"/>
<stop offset="0.6645" stop-color="#88B1B8"/>
<stop offset="0.7353" stop-color="#6A9EA7"/>
<stop offset="0.8009" stop-color="#468793"/>
<stop offset="0.8607" stop-color="#1E6D7C"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_9004)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_9004" x1="51.9716" y1="34.0483" x2="51.9716" y2="5.975" gradientUnits="userSpaceOnUse">
<stop stop-color="#D0CDC2"/>
<stop offset="0.2632" stop-color="#CECCC1"/>
<stop offset="0.394" stop-color="#C6C8BE"/>
<stop offset="0.4956" stop-color="#B9C0B8"/>
<stop offset="0.5823" stop-color="#A6B6B1"/>
<stop offset="0.6593" stop-color="#8EA8A6"/>
<stop offset="0.7295" stop-color="#70989A"/>
<stop offset="0.7947" stop-color="#4C848B"/>
<stop offset="0.854" stop-color="#246E7A"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,19 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_825_8758)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_825_8758" x1="51.9716" y1="34.0483" x2="51.9716" y2="5.975" gradientUnits="userSpaceOnUse">
<stop stop-color="#E7E7E8"/>
<stop offset="0.2559" stop-color="#E5E6E7"/>
<stop offset="0.383" stop-color="#DDE1E3"/>
<stop offset="0.4818" stop-color="#D0D9DC"/>
<stop offset="0.5659" stop-color="#BDCDD1"/>
<stop offset="0.6409" stop-color="#A5BFC4"/>
<stop offset="0.7091" stop-color="#87ACB4"/>
<stop offset="0.7724" stop-color="#6397A1"/>
<stop offset="0.8318" stop-color="#3A7D8A"/>
<stop offset="0.8859" stop-color="#0C6272"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.99" fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_206_8118)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_206_8118" x1="51.9712" y1="34.0648" x2="51.9712" y2="5.99159" gradientUnits="userSpaceOnUse">
<stop stop-color="#CEDEE7"/>
<stop offset="0.265" stop-color="#C9E7DC"/>
<stop offset="0.3966" stop-color="#C1E2D7"/>
<stop offset="0.4989" stop-color="#B4D9D0"/>
<stop offset="0.5861" stop-color="#A1CCC6"/>
<stop offset="0.6636" stop-color="#89BAB8"/>
<stop offset="0.7343" stop-color="#6BA5A7"/>
<stop offset="0.7998" stop-color="#478C93"/>
<stop offset="0.8993" stop-color="#125B7E"/>
<stop offset="1" stop-color="#125B7E"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,19 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8906)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8906" x1="52.0028" y1="34.0462" x2="52.0028" y2="5.97295" gradientUnits="userSpaceOnUse">
<stop stop-color="white"/>
<stop offset="0.2491" stop-color="#FDFEFE"/>
<stop offset="0.3729" stop-color="#F5F9F9"/>
<stop offset="0.4691" stop-color="#E8F0F2"/>
<stop offset="0.551" stop-color="#D5E4E7"/>
<stop offset="0.6239" stop-color="#BDD4D9"/>
<stop offset="0.6904" stop-color="#9FC1C7"/>
<stop offset="0.752" stop-color="#7BAAB3"/>
<stop offset="0.8099" stop-color="#528F9A"/>
<stop offset="0.8626" stop-color="#247280"/>
<stop offset="0.8993" stop-color="#005A6B"/>
<stop offset="1" stop-color="#005A6B"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8974)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8974" x1="51.9623" y1="34.0483" x2="51.9623" y2="5.975" gradientUnits="userSpaceOnUse">
<stop stop-color="#D0CDC2"/>
<stop offset="0.2738" stop-color="#CECBC0"/>
<stop offset="0.4097" stop-color="#C9C6B8"/>
<stop offset="0.5154" stop-color="#C0BCAB"/>
<stop offset="0.6055" stop-color="#B3AD98"/>
<stop offset="0.6856" stop-color="#A39B80"/>
<stop offset="0.7586" stop-color="#8E8462"/>
<stop offset="0.8262" stop-color="#766A3E"/>
<stop offset="0.8879" stop-color="#5B4B16"/>
<stop offset="0.8993" stop-color="#55450E"/>
<stop offset="1" stop-color="#55450E"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8970)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8970" x1="51.9669" y1="34.0522" x2="51.9669" y2="5.97896" gradientUnits="userSpaceOnUse">
<stop stop-color="#CADCDD"/>
<stop offset="0.2908" stop-color="#C8DADB"/>
<stop offset="0.4353" stop-color="#C1D2D3"/>
<stop offset="0.5475" stop-color="#B6C5C6"/>
<stop offset="0.6432" stop-color="#A5B2B3"/>
<stop offset="0.7282" stop-color="#909A9B"/>
<stop offset="0.8057" stop-color="#767C7D"/>
<stop offset="0.8761" stop-color="#58595A"/>
<stop offset="0.8993" stop-color="#4C4C4D"/>
<stop offset="1" stop-color="#4C4C4D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_9016)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_9016" x1="51.9669" y1="34.0483" x2="51.9669" y2="5.975" gradientUnits="userSpaceOnUse">
<stop stop-color="#D0CDC2"/>
<stop offset="0.2978" stop-color="#CECBC0"/>
<stop offset="0.4457" stop-color="#C6C3B9"/>
<stop offset="0.5606" stop-color="#B9B6AE"/>
<stop offset="0.6585" stop-color="#A6A49D"/>
<stop offset="0.7456" stop-color="#8E8C87"/>
<stop offset="0.8237" stop-color="#71706D"/>
<stop offset="0.8959" stop-color="#4E4E4F"/>
<stop offset="0.8993" stop-color="#4C4C4D"/>
<stop offset="1" stop-color="#4C4C4D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8968)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8968" x1="51.9669" y1="34.0483" x2="51.9669" y2="5.975" gradientUnits="userSpaceOnUse">
<stop stop-color="#E7E7E8"/>
<stop offset="0.2851" stop-color="#E5E5E6"/>
<stop offset="0.4267" stop-color="#DDDDDE"/>
<stop offset="0.5368" stop-color="#D0D0D1"/>
<stop offset="0.6305" stop-color="#BDBDBE"/>
<stop offset="0.7139" stop-color="#A5A5A6"/>
<stop offset="0.7899" stop-color="#878788"/>
<stop offset="0.8589" stop-color="#646465"/>
<stop offset="0.8993" stop-color="#4C4C4D"/>
<stop offset="1" stop-color="#4C4C4D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,17 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8930)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8930" x1="51.9669" y1="34.0648" x2="51.9669" y2="5.99157" gradientUnits="userSpaceOnUse">
<stop stop-color="#CBE9DD"/>
<stop offset="0.2841" stop-color="#C9E7DB"/>
<stop offset="0.4252" stop-color="#C3DFD4"/>
<stop offset="0.5349" stop-color="#B8D2C8"/>
<stop offset="0.6283" stop-color="#A9BFB7"/>
<stop offset="0.7114" stop-color="#96A7A0"/>
<stop offset="0.7871" stop-color="#7D8985"/>
<stop offset="0.8559" stop-color="#616665"/>
<stop offset="0.8993" stop-color="#4C4C4D"/>
<stop offset="1" stop-color="#4C4C4D"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8918)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8918" x1="51.976" y1="34.0522" x2="51.976" y2="5.97896" gradientUnits="userSpaceOnUse">
<stop stop-color="#CADCDD"/>
<stop offset="0.2653" stop-color="#C8DBDB"/>
<stop offset="0.3972" stop-color="#C0D6D5"/>
<stop offset="0.4996" stop-color="#B3CFCB"/>
<stop offset="0.5869" stop-color="#A0C4BD"/>
<stop offset="0.6645" stop-color="#88B6AA"/>
<stop offset="0.7353" stop-color="#6AA593"/>
<stop offset="0.8009" stop-color="#469177"/>
<stop offset="0.8607" stop-color="#1E7A58"/>
<stop offset="0.8993" stop-color="#006941"/>
<stop offset="1" stop-color="#006941"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8972)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8972" x1="52.0031" y1="34.0483" x2="52.0031" y2="5.975" gradientUnits="userSpaceOnUse">
<stop stop-color="#D0CDC2"/>
<stop offset="0.2632" stop-color="#CECCC1"/>
<stop offset="0.394" stop-color="#C6C8BC"/>
<stop offset="0.4956" stop-color="#B9C2B4"/>
<stop offset="0.5823" stop-color="#A6B9A8"/>
<stop offset="0.6593" stop-color="#8EAD99"/>
<stop offset="0.7295" stop-color="#709F86"/>
<stop offset="0.7947" stop-color="#4C8E70"/>
<stop offset="0.854" stop-color="#247A57"/>
<stop offset="0.8993" stop-color="#006941"/>
<stop offset="1" stop-color="#006941"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,18 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="url(#paint0_linear_841_8894)" stroke="black"/>
<defs>
<linearGradient id="paint0_linear_841_8894" x1="51.976" y1="34.0648" x2="51.976" y2="5.99157" gradientUnits="userSpaceOnUse">
<stop stop-color="#CBE9DD"/>
<stop offset="0.265" stop-color="#C9E8DB"/>
<stop offset="0.3966" stop-color="#C1E3D5"/>
<stop offset="0.4989" stop-color="#B4DACB"/>
<stop offset="0.5861" stop-color="#A1CFBD"/>
<stop offset="0.6636" stop-color="#89BFAA"/>
<stop offset="0.7343" stop-color="#6BAC93"/>
<stop offset="0.7998" stop-color="#479678"/>
<stop offset="0.8595" stop-color="#1F7D59"/>
<stop offset="0.8993" stop-color="#006941"/>
<stop offset="1" stop-color="#006941"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="#CBDDDE" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 662 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="#D1CEC3" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 662 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="#5D564C" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 662 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="#D3D3D3" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 662 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="#E9E9EB" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 662 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="#CBE9DD" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 662 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="white" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 660 B

View file

@ -0,0 +1,3 @@
<svg width="104" height="40" viewBox="0 0 104 40" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.9768 32.4623C54.8365 32.4623 73.392 32.1997 87.6574 34.0091C90.1732 34.3302 91.889 32.1711 91.9744 30.7698C92.5182 22.8924 84.227 12.0979 84.227 12.0979C84.227 12.0979 81.7113 8.18778 75.6493 7.42988C75.6493 7.42988 61.3546 6 52.0061 6C43.2576 6 28.3617 7.42988 28.3617 7.42988C22.3009 8.18778 19.7851 12.0967 19.7851 12.0967C19.7851 12.0967 11.3793 22.9222 12.0366 30.7698C12.1232 31.9371 13.8378 34.3302 16.3536 34.0091C30.5641 32.1997 49.1184 32.4623 51.9768 32.4623Z" fill="#626167" stroke="black"/>
</svg>

After

Width:  |  Height:  |  Size: 662 B

View file

@ -14,7 +14,7 @@
:key="answer.Name ? answer.Name : answer"
@isCheckedChanged="handleCheckedChanged"
:buttonID="answer.Name ? groupName + '-' + answer.Name : groupName + '-' + answer"
:value="answer.Name ? answer.Name : answer"
:value="getValues(answer)"
:buttonLabel="answer.Text ? answer.Text : answer"
:buttonLabelSubCopy="answer.SubText"
:textPosition="textPosition"
@ -23,8 +23,8 @@
:selectingInitiatesLoad="selectingInitiatesLoad"
:loaderColor="loaderColor"
:loaderPosition="loaderPosition"
:isWide="isWide"
:isRequired="isRequired"
:isWide=isWide
:isRequired=isRequired
:buttonImage="answer.AnswerImageUrl"
:buttonImageId="answer.ImageId"
:altText="answer.Name ? answer.Name : answer"
@ -80,6 +80,7 @@ export default {
modelValue: Array,
validationRules: String,
suppressError: Boolean,
useTextForValue: Boolean,
},
computed: {
getFieldSetClasses() {
@ -122,6 +123,12 @@ export default {
},
},
methods: {
getValues(answer){
if (this.useTextForValue){
return answer.Text
}
return answer.Name ? answer.Name : answer;
},
handleCheckedChanged(val) {
if(this.isMultiSelect && this.selectedValues) {
// Add or remove item to array of data to emit

View file

@ -0,0 +1,9 @@
const damageLocationsCms = {
WINDSHIELD: "WINDSHIELD",
SIDEDOOR: "SIDEDOOR",
REARWINDOW: "REARWINDOW",
DRIVERSIDE: "DRIVERSIDE",
PASSENGERSIDE: "PASSENGERSIDE",
};
export { damageLocationsCms };

View file

@ -0,0 +1,8 @@
const damageLocationsParts = {
WINDSHIELD: "Windshield",
DRIVER: "Driver",
PASSENGER: "Passenger",
REAR: "Rear",
};
export { damageLocationsParts };

View file

@ -0,0 +1,57 @@
// Used to support custom (non-state) related dynamic text.
// Example: {custom:glassName}, each key in the array is the value after custom:, like 'glassname'
// Please use lowercase only so that we don't have to worry about case sensitivity.
const customMappings = {
formattedglassname: [
{ key: 'Windshield Single', transformedValue: 'windshield' },
{ key: 'Windshield Driver', transformedValue: 'driver side split windshield' },
{ key: 'Windshield Passenger', transformedValue: 'passenger side split windshield' },
{ key: 'Rear Stationary', transformedValue: 'rear window' },
{ key: 'Rear Slider', transformedValue: 'rear window' },
{ key: 'Driver Front', transformedValue: 'driver side front door' },
{ key: 'Driver Back ', transformedValue: 'driver side back door' },
{ key: 'Driver Vent', transformedValue: 'driver side vent glass' },
{ key: 'Driver Quarter', transformedValue: 'driver side quarter panel' },
{ key: 'Driver SideDoor', transformedValue: 'driver side sliding door' },
{ key: 'Passenger Front', transformedValue: 'passenger side front door' },
{ key: 'Passenger Back', transformedValue: 'passenger side back door' },
{ key: 'Passenger Vent', transformedValue: 'passenger side vent glass' },
{ key: 'Passenger Quarter', transformedValue: 'passenger side quarter panel' },
{ key: 'Passenger SlideDoor', transformedValue: 'passenger side sliding door' },
]
}
// Gets an instance of a string where the dynamic portion of the text {custom:KeyName}
// is replaced by a value from the above map.
// If the value isn't found, return the original dynamic string without replacement
export function getCustomTransformValue(dynamicString, key) {
// Get array key from the dynamic string
const regexExp = new RegExp("{(.*?):(.*?)}", "g");
const matches = [...dynamicString.matchAll(regexExp)];
if (matches.length === 0) {
return dynamicString;
}
const arrayKey = matches[0][2];
// Get the array of possible values based on the key name.
const transformArray = customMappings[arrayKey.toLowerCase()];
if(transformArray === undefined) {
return dynamicString;
}
// Get the value where the name matches the key name, there should only be one so find() is used.
const mapObject = transformArray.find(map => map.key.toLowerCase() === key.toLowerCase());
if(mapObject === undefined){
return dynamicString;
}
const finalString = dynamicString.replace(`{custom:${arrayKey}}`, mapObject.transformedValue);
return finalString
}

View file

@ -43,6 +43,14 @@ const endpoints = {
url: "/vehicle/api/v1/vehicle/Lookup",
method: "POST",
},
GetPartsOrQuestions: {
url: "/parts/api/v1/parts/parts-or-questions",
method: "POST",
},
SaveOrder: {
url: "/order/api/v1/order/save",
method: "POST",
}
};
export { endpoints };

View file

@ -11,12 +11,14 @@ const storeActions = {
GET_EVOX_IMAGE: "getEvoxImage",
LOOKUP_VEHICLE_BY_YMMS: "lookupVehicleByYmms",
LOOKUP_VEHICLE_BY_VIN: "lookupVehicleByVin",
GET_PARTS_OR_QUESTIONS: "getPartsOrQuestions",
SAVE_ORDER: "saveOrder",
// DEPENDENCY MUTATIONS
RESET_VEHICLE_AND_DEPS: "resetVehicleAndDependencies",
RESET_DAMAGE_AND_DEPS: "resetDamageAndDependencies",
RESET_REGISTRATION_AND_DEPS: "resetRegistrationAndDependencies",
RESET_PARTS_AND_DEPS: "resetPartsAndDependencies",
RESET_VEHICLE_STATE: "resetVehicleAndDependencies",
RESET_DAMAGE_STATE: "resetDamageAndDependencies",
RESET_REGISTRATION_STATE: "resetRegistrationAndDependencies",
RESET_PARTS_STATE: "resetPartsAndDependencies",
};
export { storeActions };

View file

@ -10,16 +10,23 @@ const storeMutations = {
UPDATE_VEHICLE_IMAGE_URL: "updateVehicleImageUrl",
UPDATE_VEHICLE_IMAGE_VIF_NUMBER: "updateVehicleImageVifNumber",
UPDATE_VEHICLE_IMAGE_COLOR: "updateVehicleImageColor",
UPDATE_IS_REPAIR: "updateIsRepair",
UPDATE_NUMBER_OF_CHIPS: "updateNumberOfChips",
UPDATE_GLASS_TO_REPLACE: "updateGlassToReplace",
UPDATE_PARTS: "updateParts",
// EVENT BUS MUTATIONS
ADD_EVENT_TO_BUS: "addEventToBus",
REMOVE_EVENT_FROM_BUS: "removeEventFromBus",
// DEPENDENCY MUTATIONS
RESET_VEHICLE_AND_DEPS: "resetVehicleAndDependencies",
RESET_DAMAGE_AND_DEPS: "resetDamageAndDependencies",
RESET_REGISTRATION_AND_DEPS: "resetRegistrationAndDependencies",
RESET_PARTS_AND_DEPS: "resetPartsAndDependencies",
RESET_VEHICLE_STATE: "resetVehicleState",
RESET_DAMAGE_STATE: "resetDamageState",
RESET_REGISTRATION_STATE: "resetRegistrationState",
RESET_PARTS_STATE: "resetPartsState",
// OTHER MUTATIONS
UPDATE_PAGE_DATA: "updatePageData",
};

View file

@ -0,0 +1,95 @@
// TintMap with array keys by location, lowercase to avoid as much string mismatching as possible.
// Src assumes you have a @/assets/img/tints/, making the final value @/assets/img/tints/{Src} in the markup.
// See vehicle-parts for implementation example.
const tintMap = {
other: [
// Blue Shade
{ name: "blue tint, blue shade", src: "Glass-BlueShade-BlueTint.svg" },
{ name: "brown tint, blue shade", src: "Glass-BlueShade-BrownTint.svg" },
{ name: "gray tint, blue shade", src: "Glass-BlueShade-GrayTint.svg" },
{ name: "green tint, blue shade", src: "Glass-BlueShade-GreenTint.svg" },
{ name: "blue shade", src: "Glass-BlueShade-NoTint.svg" },
// Brown Shade
{ name: "brown tint, brown shade", src: "Glass-BrownShade-BrownTint.svg" },
// Gray Shade
{ name: "blue tint, gray shade", src: "Glass-GrayShade-BlueTint.svg" },
{ name: "brown tint, gray shade", src: "Glass-GrayShade-BrownTint.svg" },
{ name: "gray tint, gray shade", src: "Glass-GrayShade-GrayTint.svg" },
{ name: "green tint, gray shade", src: "Glass-GrayShade-GreenTint.svg" },
// Green Shade
{ name: "blue tint, green shade", src: "Glass-GreenShade-BlueTint.svg" },
{ name: "brown tint, green shade", src: "Glass-GreenShade-BrownTint.svg" },
{ name: "green tint, green shade", src: "Glass-GreenShade-GreenTint.svg" },
// Tints Only
{ name: "blue tint", src: "Glass-NoShade-BlueTint.svg" },
{ name: "brown tint", src: "Glass-NoShade-BrownTint.svg" },
{ name: "dark brown tint", src: "Glass-NoShade-DarkBrownTint.svg" },
{ name: "dark gray tint", src: "Glass-NoShade-DarkGrayTint.svg" },
{ name: "gray tint", src: "Glass-NoShade-GrayTint.svg" },
{ name: "green tint", src: "Glass-NoShade-GreenTint.svg" },
{ name: "gray tint privacy", src: "Glass-NoShade-Privacy.svg" },
// No shade or tint
{ name: "no shade, no tint", src: "Glass-NoShade-NoTint.svg" }, // ???
],
windshield: [
// Blue Shade
{ name: "blue tint, blue shade", src: "Windshield-BlueShade-BlueTint.svg" },
{ name: "brown tint, blue shade", src: "Windshield-BlueShade-BrownTint.svg" },
{ name: "gray tint, blue shade", src: "Windshield-BlueShade-GrayTint.svg" },
{ name: "green tint, blue shade", src: "Windshield-BlueShade-GreenTint.svg" },
{ name: "blue shade", src: "Windshield-BlueShade-NoTint.svg" },
// Brown Shade
{ name: "brown tint, brown shade", src: "Windshield-BrownShade-BrownTint.svg" },
// Gray Shade
{ name: "blue tint, gray shade", src: "Windshield-GrayShade-BlueTint.svg" },
{ name: "brown tint, gray shade", src: "Windshield-GrayShade-BrownTint.svg" },
{ name: "gray tint, gray shade", src: "Windshield-GrayShade-GrayTint.svg" },
{ name: "green tint, gray shade", src: "Windshield-GrayShade-GreenTint.svg" },
// Green Shade
{ name: "blue tint, green shade", src: "Windshield-GreenShade-BlueTint.svg" },
{ name: "brown tint, green shade", src: "Windshield-GreenShade-BrownTint.svg" },
{ name: "green tint, green shade", src: "Windshield-GreenShade-GreenTint.svg" },
// Tints Only
{ name: "blue tint", src: "Windshield-NoShade-BlueTint.svg" },
{ name: "brown tint", src: "Windshield-NoShade-BrownTint.svg" },
{ name: "dark brown tint", src: "Windshield-NoShade-DarkBrownTint.svg" },
{ name: "dark gray tint", src: "Windshield-NoShade-DarkGrayTint.svg" },
{ name: "gray tint", src: "Windshield-NoShade-GrayTint.svg" },
{ name: "green tint", src: "Windshield-NoShade-GreenTint.svg" },
{ name: "gray tint privacy", src: "Windshield-NoShade-Privacy.svg" },
// No shade or tint
{ name: "no shade, no tint", src: "Windshield-NoShade-NoTint.svg" }, // ???
]
}
// Gets the tint image source string given the glass location, and the tint description (like 'Green Tint')
// Use lowered strings here to try to avoid mismatch. Returns an empty string if array key doesn't exist.
// Returns undefined if no items are found.
export function getTintImage(glassLocation, colorString) {
// Windshield glass has special images, all other glass uses the same though.
if(glassLocation.toLowerCase() !== 'windshield'){
glassLocation = 'other';
}
if (tintMap[glassLocation.toLowerCase()] === undefined) {
return '';
}
const tintImageSource = tintMap[glassLocation.toLowerCase()].find(item => item.name.toLowerCase() == colorString.toLowerCase())
return tintImageSource;
}

View file

@ -19,7 +19,11 @@ export default {
}).then(
(response) => {
if (response.status == httpStatusCodes.OK) {
resolve(response);
if(response.data == undefined) {
reject(response);
}else{
resolve(response);
}
} else {
reject(response);
}

View file

@ -2,11 +2,28 @@ import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations.js";
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios.js";
import { vehicleCategories } from "@/constants/vehicle-categories.js";
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import baseMixin from "@/mixins/base-mixin";
export function getMountOptions(mockData) {
// Define our mocks to attached to the 'global' object for Vue/Jest.
const mocks = {};
//this is mocking if you use the mixin directly(baseMixin.methods.dispatchNonBlockingStoreAction) vs this.dispatchNonBlockingStoreAction
if (mockData.actionList !== undefined) {
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
baseMixin.methods.dispatchNonBlockingStoreAction.mockImplementation((actionName) => {
let actionFilterResult = mockData.actionList.filter(
(x) => x.actionName == actionName
);
if (actionFilterResult.length > 0 && actionFilterResult.length === 1) {
return Promise.resolve({
data: actionFilterResult[0].data,
});
}
});
}
mocks.dispatchNonBlockingStoreAction = jest.fn();
mocks.dispatchNonBlockingStoreAction.mockImplementation((actionName) => {
let actionFilterResult = mockData.actionList.filter(
@ -25,10 +42,13 @@ export function getMountOptions(mockData) {
mocks.storeMutations = storeMutations;
mocks.navigationScenarios = navigationScenarios;
mocks.vehicleCategories = vehicleCategories;
mocks.fmgPageValues = fmgPageValues;
// Mock $store and $router when accessing this.$store/$router
mocks.$store = mockData.store;
mocks.$router = mockData.router;
mocks.$route = mockData.route;
const global = {
mocks: mocks,

View file

@ -144,7 +144,7 @@ export default {
},
resetDependentState() {
// Invokes
store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
store.dispatch(storeActions.RESET_PARTS_STATE);
},
onSubmit(values) {
window.alert('Success! Submitted values: ' + JSON.stringify(values, null ,2))

View file

@ -1,20 +1,18 @@
<template>
<div class="container-fluid nested-radio">
<div class="row mb-1">
<div class="col">
<listCard
groupName="listcard1"
isWide="true"
buttonImage="https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3"
buttonLabel="Green Tint, Blue Shade"
buttonID="radio1"
groupName="listcard1"
isWide="true"
buttonImage="https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3"
buttonLabel="Green Tint, Blue Shade"
buttonID="radio1"
/>
</div>
</div>
<div class="row mb-1">
<div class="col">
<p class="mb-0 fw-bold">Ok, select the features</p>
<buttonQuestion
buttonType="radio"
groupName="Demo Group"
@ -23,22 +21,22 @@
value="test button"
screenReaderOnlyText="rain sensor, solar, 3rd visor band"
:answers="demoArray"
questionText="ok now select your features"
/>
</div>
</div>
<div class="row mb-2">
<div class="col">
<listCard
groupName="listcard1"
isWide="true"
buttonImage="https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3"
buttonLabel="Green Tint"
buttonID="radio2"
groupName="listcard1"
isWide="true"
buttonImage="https://digitalconsumercms-dev.safelite.com/images/default-source/damage-options/car.svg?sfvrsn=1468d7f1_3"
buttonLabel="Green Tint"
buttonID="radio2"
/>
</div>
</div>
</div>
</template>
<script>
@ -56,9 +54,9 @@ export default {
demoArray: [
"rain sensor, solar, 3rd visor band",
"rain sensor, heated glass, solar, 3rd visor band",
]
}
}
],
};
},
};
</script>
@ -66,10 +64,11 @@ export default {
.nested-radio {
.ui-radio {
flex-direction: column;
margin: .25rem 0;
margin: 0.25rem 0;
}
p {
font-size: .875rem;
font-size: 0.875rem;
}
}
</style>

View file

@ -0,0 +1,83 @@
<template>
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall">
<funnelHeader ref="funnelHeader" />
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage="false" />
<funnelSubHeader ref="funnelSubHeader" />
<h1>Part Questions Page Placeholder</h1>
<funnelFooter ref="funnelFooter" @back-clicked="backButtonAction" />
</div>
</template>
<script>
// Components
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
// Supporting Files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import {storeMutations} from "@/constants/store-mutations";
import {storeActions} from "@/constants/store-actions";
import store from "@/store";
export default {
name: "part-questions",
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
// Settle promises and get results
const promiseResultMap = [{
resultKey: "cmsContent",
promise: cmsContentPromise,
}, ];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.$refs.funnelHeader.initializeComponent(
resultMap.cmsContent.FunnelHeaderWidget
);
vm.$refs.vehicleBanner.initializeComponent(
resultMap.cmsContent.VehicleBannerWidget
);
vm.$refs.funnelSubHeader.initializeComponent(
resultMap.cmsContent.FunnelSubHeaderWidget
);
vm.$refs.funnelFooter.initializeComponent(
resultMap.cmsContent.FunnelFooterWidget
);
});
},
methods: {
backButtonAction() {
// route to move backwards
this.$router.navigate(
this.navigationScenarios.CLICKED_BACK,
this.$route
);
},
arePagePrerequisitesValid() {
return store.getters.lineItems.glassParts !== null;
},
resetDependentState() {
// Set
store.commit(storeMutations.UPDATE_PARTS, null);
// Invokes
store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
},
},
data() {
},
components: {
funnelHeader,
vehicleBanner,
funnelSubHeader,
funnelFooter,
},
};
</script>

View file

@ -0,0 +1,71 @@
<template>
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall">
<funnelHeader ref="funnelHeader" />
<h1>Reveal Confetti Page Placeholder</h1>
<funnelFooter ref="funnelFooter" @back-clicked="backButtonAction" />
</div>
</template>
<script>
// Components
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
// Supporting Files
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { settleAllPromises } from "@/helpers/layout-helper";
import {storeMutations} from "@/constants/store-mutations";
import {storeActions} from "@/constants/store-actions";
import store from "@/store";
export default {
name: "quote",
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
// Settle promises and get results
const promiseResultMap = [{
resultKey: "cmsContent",
promise: cmsContentPromise,
}, ];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.$refs.funnelHeader.initializeComponent(
resultMap.cmsContent.FunnelHeaderWidget
);
vm.$refs.funnelFooter.initializeComponent(
resultMap.cmsContent.FunnelFooterWidget
);
});
},
methods: {
backButtonAction() {
// route to move backwards
this.$router.navigate(
this.navigationScenarios.CLICKED_BACK,
this.$route
);
},
arePagePrerequisitesValid() {
return store.getters.lineItems.glassParts !== null;
},
resetDependentState() {
// Set
store.commit(storeMutations.UPDATE_PARTS, null);
// Invokes
store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
},
},
data() {
},
components: {
funnelHeader,
funnelFooter,
},
};
</script>

View file

@ -2,82 +2,81 @@ import { shallowMount } from "@vue/test-utils";
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import store from "@/store";
jest.mock("@/store", () => { return {}; }, {virtual: true});
jest.mock("@/store", () => { return {}; }, { virtual: true });
describe("damage-location-question.vue", () => {
test("Selected location option is emitted upon selection.", async () => {
//Arrange
const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
const locationToSelect = ["Backseat"];
//Act
wrapper.setValue({ modelValue: locationToSelect });
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{modelValue: ["Backseat"]}]);
});
test("Selected location option is emitted upon selection.", async () => {
//Arrange
const { wrapper } = setupMocks({ modelValueProp: ["Windshield"] });
const locationToSelect = ["Backseat"];
//Act
wrapper.setValue({ modelValue: locationToSelect });
await wrapper.vm.$nextTick();
//Assert
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ modelValue: ["Backseat"] }]);
});
describe("damage-location-question.vue", () => {
test("Answers to display filtered by data from api.", async () => {
//Arrange
const { wrapper, cmsContent, damageOptions } = setupMocks({ dataFromStoreApi: {
driverSideOptions: {
availableReplacementOptions: ['Quarter', 'Front']
},
windshieldOptions: {
availableReplacementOptions: ['Single']
},
backGlassOptions: {
availableReplacementOptions: []
}
}
});
//Act
damageLocationQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, damageOptions, "car-group");
//Assert
expect(wrapper.vm.answersToDisplay).toStrictEqual([ { Name: 'Windshield' }, { Name: 'SideDoor' } ])
test("Answers to display filtered by data from api.", async () => {
//Arrange
const { wrapper, cmsContent, damageOptions } = setupMocks({
dataFromStoreApi: {
driverSideOptions: {
availableReplacementOptions: ['Quarter', 'Front']
},
windshieldOptions: {
availableReplacementOptions: ['Single']
},
backGlassOptions: {
availableReplacementOptions: []
}
}
});
//Act
damageLocationQuestion.methods.initializeComponent.call(wrapper.vm, cmsContent, damageOptions, "car-group");
//Assert
expect(wrapper.vm.answersToDisplay).toStrictEqual([{ Name: 'Windshield' }, { Name: 'SideDoor' }])
});
});
function setupMocks({
modelValueProp = ["Windshield", "SideDoor"],
isMultiSelect = false,
groupName = "damageQuestion",
cmsQuestionText = "CMS text goes here",
cmsAnswers = [{ Name: "car-Windshield" }, { Name: "car-SideDoor" }, { Name: "car-RearWindow" }],
dataFromStoreApi = [],
}) {
//Mock store
store.dispatch = jest.fn(() => dataFromStoreApi);
store.getters = { vehicle: { year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR' } };
const mountOptions = getMountOptions({
store: {
dispatch: store.dispatch,
getters: store.getters,
},
});
function setupMocks({
modelValueProp = ["Windshield", "SideDoor"],
isMultiSelect = false,
groupName = "damageQuestion",
cmsQuestionText = "CMS text goes here",
cmsAnswers = [{Name: "car-Windshield"}, {Name: "car-SideDoor"}, {Name: "car-RearWindow"}],
dataFromStoreApi = [],
}) {
//Mock store
store.dispatch = jest.fn(() => dataFromStoreApi);
store.getters = { vehicle: {year: 2019, make: 'honda', model: 'civc', style: '2 Door', category: 'CAR'} };
const mountOptions = getMountOptions({
store: {
dispatch: store.dispatch,
getters: store.getters,
},
});
//Mock props
mountOptions.propsData = {
modelValue: modelValueProp,
isMultiSelect: isMultiSelect,
};
const wrapper = shallowMount(damageLocationQuestion, mountOptions);
//Mock CMS content
const cmsContent = {
groupName: groupName,
QuestionText: cmsQuestionText,
Answers: cmsAnswers,
};
const damageOptions = dataFromStoreApi;
return { wrapper, cmsContent, damageOptions };
}
//Mock props
mountOptions.propsData = {
modelValue: modelValueProp,
isMultiSelect: isMultiSelect,
};
const wrapper = shallowMount(damageLocationQuestion, mountOptions);
//Mock CMS content
const cmsContent = {
groupName: groupName,
QuestionText: cmsQuestionText,
Answers: cmsAnswers,
};
const damageOptions = dataFromStoreApi;
return { wrapper, cmsContent, damageOptions };
}

View file

@ -52,7 +52,7 @@ export default ({
},
updateSelectedValues() {
// UPDATE SELECTEDVALUES IF ONLY ONE ANSWER
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1 && this.selectedValues) {
if(Array.isArray(this.answersToDisplay) && this.answersToDisplay.length === 1) {
this.selectedValues = [this.answersToDisplay[0].Name];
}
},

View file

@ -17,6 +17,7 @@ import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import store from "@/store";
// Mock our module for promises.
@ -145,28 +146,6 @@ describe("vehicle-damage.vue", () => {
});
});
describe("vehicle-damage.vue", () => {
test("Call invalidation, ResetPartsAndDeps should be called", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.resetDependentState();
//Assert
expect(store.dispatch).toBeCalledWith(storeActions.RESET_PARTS_AND_DEPS)
});
});
describe("vehicle-damage.vue", () => {
test("BackButtonAction triggers a router.navigate change", async () => {
@ -189,6 +168,303 @@ describe("vehicle-damage.vue", () => {
});
});
describe("vehicle-damage.vue", () => {
test("Replace several pieces of glass on ForwardButtonAction triggers a router.navigateAfterSave and saves selections to store", async () => {
//Arrange
const partsData = {
partsOrQuestions: [{
glassName: "Single",
glassLocation: "Windshield",
parts: null,
partQuestions: [{
questionSequence: 1,
questionText: "Is your vehicle equipped with a heated steering wheel?",
answers: [{
answerText: "Yes",
nextQuestionSequence: null,
answerResult: "FW04957"
},
{
answerText: "No",
nextQuestionSequence: 2,
answerResult: ""
}]
},
{
questionSequence: 2,
questionText: "Is your vehicle equipped with a remote start?",
answers: [{
answerText: "Yes",
nextQuestionSequence: null,
answerResult: "FW04181"
},
{
answerText: "No",
nextQuestionSequence: null,
answerResult: "FW04179"
}]
}]
}]
};
const { wrapper } = setupMocks({
pageHeaderWidgetHeaderText: "",
mountOptionsMockData: {
router: { navigateAfterSave: jest.fn(), },
actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],
},
});
wrapper.vm.selectedDamageLocations = ["Windshield", "SideDoor", "RearWindow"];
wrapper.vm.selectedWindshieldOptions = {
selectedWindshieldChipCount : null,
selectedWindshieldReplaceOptions : ["Single"],
selectedWindshieldDamageType: ["Replace"]
};
wrapper.vm.sideDoorOptionsData = {
selectedDoorSides: ["DriverSide", "PassengerSide"],
selectedDriverSideReplaceOptions: ["Back"],
selectedPassengerSideReplaceOptions: ["Quarter"]
};
wrapper.vm.selectedRearReplaceOptions = ["Stationary"];
const expectedGlassToReplace = [{location: "Windshield", name: "Single"}, {location: "Driver", name: "Back"},
{location: "Passenger", name: "Quarter"}, {location: "Rear", name: "Stationary"}];
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false);
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace);
});
});
describe("vehicle-damage.vue", () => {
test("Windshield replace with single part on ForwardButtonAction triggers a router.navigateAfterSave and saves selections to store", async () => {
//Arrange
const partsData = { partsOrQuestions: [
{
glassLocation: "Windshield",
glassName: "Single",
partQuestions: null,
parts: [
{
color: "Green Tint, Green Shade",
description: "rain sensor, solar",
partNumber: "FW02728GGYN",
requiresCapabilityQuestions: false,
requiresRecalibration: false
}
]}]};
const { wrapper } = setupMocks({
pageHeaderWidgetHeaderText: "",
mountOptionsMockData: {
router: { navigateAfterSave: jest.fn(), },
actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],},
});
wrapper.vm.selectedDamageLocations = ["Windshield"];
wrapper.vm.selectedWindshieldOptions = {
selectedWindshieldChipCount : null,
selectedWindshieldReplaceOptions : ["Single"],
selectedWindshieldDamageType: ["Replace"]
};
const expectedGlassToReplace = [{location: "Windshield", name: "Single"},];
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false);
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace);
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_PARTS, partsData.partsOrQuestions[0].parts);
});
});
describe("vehicle-damage.vue", () => {
test("Windshield replace with multiple parts on ForwardButtonAction triggers a router.navigateAfterSave and saves selections to store", async () => {
//Arrange
const partsData = { partsOrQuestions: [
{
glassLocation: "Windshield",
glassName: "Single",
partQuestions: null,
parts: [
{
color: "Green Tint, Green Shade",
description: "rain sensor, solar",
partNumber: "FW02728GGYN",
requiresCapabilityQuestions: false,
requiresRecalibration: false
},
{
color: "Green Tint, Green Shade",
description: "rain sensor, solar, hydrophobic coating",
partNumber: "FW02760GGYN",
requiresCapabilityQuestions: false,
requiresRecalibration: false
}
]},
{
glassName: "Stationary",
glassLocation: "Rear",
parts: [
{
partNumber: "DB09626GTYN",
description: "heated glass, solar, antenna",
color: "Green Tint",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null
},
{
partNumber: "DB09821GTYN",
description: "heated glass, solar, antenna, onstar",
color: "Green Tint",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null
}
],
"partQuestions": null
}
]};
const { wrapper } = setupMocks({
pageHeaderWidgetHeaderText: "",
mountOptionsMockData: {
router: { navigateAfterSave: jest.fn(), },
actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],},
});
wrapper.vm.selectedDamageLocations = ["Windshield"];
wrapper.vm.selectedWindshieldOptions = {
selectedWindshieldChipCount : null,
selectedWindshieldReplaceOptions : ["Single"],
selectedWindshieldDamageType: ["Replace"]
};
const expectedGlassToReplace = [{location: "Windshield", name: "Single"},];
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false);
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace);
});
});
describe("vehicle-damage.vue", () => {
test("Windshield repair on ForwardButtonAction triggers a router.navigateAfterSave and saves selection to store", async () => {
//Arrange
const partsData = { partsOrQuestions: []};
const { wrapper } = setupMocks({
pageHeaderWidgetHeaderText: "",
mountOptionsMockData: {
router: { navigateAfterSave: jest.fn(), },
actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData, },],},
});
wrapper.vm.selectedDamageLocations = ["Windshield"];
wrapper.vm.selectedWindshieldOptions = {
selectedWindshieldChipCount : [2],
selectedWindshieldDamageType: ["Repair"]
};
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, true);
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_NUMBER_OF_CHIPS, 2);
});
});
describe("vehicle-damage.vue", () => {
test("isWindshieldDamageLocation is true when windshield is selected", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.selectedDamageLocations = ["Windshield"];
//Assert
expect(wrapper.vm.isWindshieldDamageLocation).toEqual(true);
});
});
describe("vehicle-damage.vue", () => {
test("isSideDoorDamageLocation is true Side door is selected", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.selectedDamageLocations = ["Sidedoor"];
//Assert
expect(wrapper.vm.isSideDoorDamageLocation).toEqual(true);
});
});
describe("vehicle-damage.vue", () => {
test("isRearWindowDamageLocation is true if Rear Window damage is selected", async () => {
@ -207,6 +483,115 @@ describe("vehicle-damage.vue", () => {
//Assert
expect(wrapper.vm.isRearWindowDamageLocation).toEqual(true);
});
});
describe("vehicle-damage.vue", () => {
test("isWindshieldRepair is true if windshield repair is selected", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.selectedDamageLocations = ["Windshield"];
wrapper.vm.selectedWindshieldOptions = { selectedWindshieldDamageType: ["Repair"]};
//Assert
expect(wrapper.vm.isWindshieldRepair).toEqual(true);
});
});
describe("vehicle-damage.vue", () => {
test("isWindshieldRepair is false if windshield damage is not selected", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.selectedDamageLocations = ["SideDoor"];
wrapper.vm.selectedWindshieldOptions = { selectedWindshieldDamageType: ["Repair"]};
//Assert
expect(wrapper.vm.isWindshieldRepair).toEqual(false);
});
});
describe("vehicle-damage.vue", () => {
test("isDriverSideReplace is true if side door driver is selected", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.selectedDamageLocations = ["Sidedoor"];
wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["DriverSide"]};
//Assert
expect(wrapper.vm.isDriverSideReplace).toEqual(true);
});
});
describe("vehicle-damage.vue", () => {
test("isPassengerSideReplace is true if side door passenger selected", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.selectedDamageLocations = ["Sidedoor"];
wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["PassengerSide"]};
//Assert
expect(wrapper.vm.isPassengerSideReplace).toEqual(true);
});
});
describe("vehicle-damage.vue", () => {
test("Call invalidation, ResetPartsAndState should be called", async () => {
//Arrange
const { wrapper } = setupMocks({});
//Act
vehicleDamage.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-damage" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.resetDependentState();
//Assert
expect(store.dispatch).toBeCalledWith(storeActions.RESET_PARTS_STATE)
});
});
@ -300,14 +685,14 @@ function setupMocks({
const sideDoorOptionsWrapper = wrapper.findComponent({ name: "sideDoorOptions" });
sideDoorOptionsWrapper.vm.initializeComponent =
sideDoorOptions.methods.initializeComponent;
sideDoorOptions.methods.initializeComponent;
const windshieldOptionsWrapper = wrapper.findComponent({
name: "windshieldOptions",
});
windshieldOptionsWrapper.vm.initializeComponent =
windshieldOptions.methods.initializeComponent;
windshieldOptions.methods.initializeComponent;
const funnelSubHeaderWrapper = wrapper.findComponent({
name: "funnelSubHeader",
@ -319,13 +704,13 @@ function setupMocks({
name: "replaceOptionsQuestion",
});
backGlassOptionsWrapper.vm.initializeComponent =
replaceOptionsQuestion.methods.initializeComponent;
replaceOptionsQuestion.methods.initializeComponent;
const damageLocationQuestionWrapper = wrapper.findComponent({
name: "damageLocationQuestion",
});
damageLocationQuestionWrapper.vm.initializeComponent =
damageLocationQuestion.methods.initializeComponent;
damageLocationQuestion.methods.initializeComponent;
const funnelFooterWrapper = wrapper.findComponent({
name: "funnelFooter",

View file

@ -46,7 +46,8 @@ import { settleAllPromises } from "@/helpers/layout-helper";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import baseMixin from "@/mixins/base-mixin";
import { damageLocationsParts } from "@/constants/damage-locations-parts.js";
import { damageLocationsCms } from "@/constants/damage-locations-cms.js";
export default {
name: "vehicle-damage",
@ -102,14 +103,6 @@ export default {
);
});
},
computed: {
isRearWindowDamageLocation() {
return this.selectedDamageLocations.some(selectedDamages =>
{
return selectedDamages.toUpperCase() === "REARWINDOW";
});
},
},
data(){
return {
selectedDamageLocations: [],
@ -127,8 +120,7 @@ export default {
return store.getters.vehicle.carId !== null;
},
resetDependentState() {
// Invokes
store.dispatch(storeActions.RESET_PARTS_AND_DEPS);
store.dispatch(storeActions.RESET_PARTS_STATE);
},
backButtonAction() {
// route to move backwards
@ -137,14 +129,140 @@ export default {
this.$route
);
},
forwardButtonAction() {
async forwardButtonAction() {
var windshieldChipCount = this.selectedWindshieldOptions.selectedWindshieldChipCount && this.isWindshieldDamageLocation ?
this.selectedWindshieldOptions.selectedWindshieldChipCount[0] : null;
store.commit(this.storeMutations.UPDATE_IS_REPAIR, this.isWindshieldRepair);
if (windshieldChipCount){
store.commit(this.storeMutations.UPDATE_NUMBER_OF_CHIPS, parseInt(windshieldChipCount));
}
store.commit(this.storeMutations.UPDATE_GLASS_TO_REPLACE, this.selectedGlassToReplace());
var partsData = await baseMixin.methods.dispatchNonBlockingStoreAction(this.storeActions.GET_PARTS_OR_QUESTIONS,
{ carId: store.getters.vehicle.carId, glassArray: this.selectedGlassToReplace()}, false);
/******** START CSR-98 ********/
var savedOrderInfo = await baseMixin.methods.dispatchNonBlockingStoreAction(this.storeActions.SAVE_ORDER);
console.log(savedOrderInfo)
/******** END CSR-98 ********/
this.navigateForward(partsData);
},
navigateForward(partsData){
/******** START CSR-98 ********/
console.log("Get estimate!")
this.$router.navigate(
this.navigationScenarios.CLICKED_FORWARD,
this.$route
);
// this.$router.navigate(
// this.navigationScenarios.CLICKED_FORWARD,
// this.$route
// );
/******** END CSR-98 ********/
//found problem questions
if (partsData.data.partsOrQuestions.some(pq => pq.partQuestions != null && pq.partQuestions.length > 0)){
this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS, this.$route, {}, {}, partsData.data);
return;
}
//found multiple parts for a single glass location (Windshield, Driver, Passenger, Rear)
if (partsData.data.partsOrQuestions){
var multiParts = false;
partsData.data.partsOrQuestions.forEach(pq => {
if (pq.parts != null && pq.parts.length > 1){
this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS, this.$route, {}, {}, partsData.data);
multiParts = true;
}
});
if (multiParts) return;
}
//if not a repair then there should only be 1 part and no problem questions at this point so save the part to the store.
if (!this.isWindshieldRepair){
store.commit(this.storeMutations.UPDATE_PARTS, partsData.data.partsOrQuestions[0].parts);
}
this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART, this.$route);
},
selectedGlassToReplace() {
var selectedGlassToReplace = [];
if (this.isWindshieldDamageLocation && !this.isWindshieldRepair){
this.selectedWindshieldOptions.selectedWindshieldReplaceOptions.forEach(wsItem => {
selectedGlassToReplace.push({ location: damageLocationsParts.WINDSHIELD, name: wsItem});
})
}
if (this.isDriverSideReplace){
this.sideDoorOptionsData.selectedDriverSideReplaceOptions.forEach(driverItem => {
selectedGlassToReplace.push({ location: damageLocationsParts.DRIVER, name: driverItem});
})
}
if (this.isPassengerSideReplace){
this.sideDoorOptionsData.selectedPassengerSideReplaceOptions.forEach(passengerItem => {
selectedGlassToReplace.push({ location: damageLocationsParts.PASSENGER, name: passengerItem});
})
}
if (this.isRearWindowDamageLocation) {
this.selectedRearReplaceOptions.forEach(rearItem => {
selectedGlassToReplace.push({ location: damageLocationsParts.REAR, name: rearItem});
})
}
return selectedGlassToReplace;
},
},
computed:{
isWindshieldDamageLocation() {
return this.selectedDamageLocations.some(selectedDamages =>
{
return selectedDamages.toUpperCase() === damageLocationsCms.WINDSHIELD;
});
},
isSideDoorDamageLocation() {
return this.selectedDamageLocations.some(selectedDamages =>
{
return selectedDamages.toUpperCase() === damageLocationsCms.SIDEDOOR;
});
},
isRearWindowDamageLocation() {
return this.selectedDamageLocations.some(selectedDamages =>
{
return selectedDamages.toUpperCase() === damageLocationsCms.REARWINDOW;
});
},
isWindshieldRepair() {
if (!this.isWindshieldDamageLocation) return false;
return this.selectedWindshieldOptions.selectedWindshieldDamageType.some(selectedDamageType =>
{
return selectedDamageType.toUpperCase() === "REPAIR";
});
},
isDriverSideReplace() {
if (!this.isSideDoorDamageLocation) return false;
return this.sideDoorOptionsData.selectedDoorSides.some(selectedDriverSide =>
{
return selectedDriverSide.toUpperCase() === damageLocationsCms.DRIVERSIDE;
});
},
isPassengerSideReplace() {
if (!this.isSideDoorDamageLocation) return false;
return this.sideDoorOptionsData.selectedDoorSides.some(selectedPassengerSide =>
{
return selectedPassengerSide.toUpperCase() === damageLocationsCms.PASSENGERSIDE;
});
}
},
components: {
funnelHeader,
funnelFooter,

View file

@ -6,6 +6,7 @@
:answers="answersFromCms"
:groupName="groupName"
buttonType="listButtonHorizontal"
useTextForValue
v-model="selectedChipCountValues"
/>
</div>

View file

@ -223,8 +223,8 @@ describe("vehicle-make.vue", () => {
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_STATE)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_STATE)
});
});

View file

@ -94,8 +94,8 @@ export default {
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
// Invokes
store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
store.dispatch(storeActions.RESET_DAMAGE_STATE);
store.dispatch(storeActions.RESET_REGISTRATION_STATE);
},
},

View file

@ -208,8 +208,8 @@ describe("vehicle-model.vue", () => {
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_STATE)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_STATE)
});
});

View file

@ -94,8 +94,8 @@ export default {
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
// Invokes
store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
store.dispatch(storeActions.RESET_DAMAGE_STATE);
store.dispatch(storeActions.RESET_REGISTRATION_STATE);
},
},

View file

@ -0,0 +1,122 @@
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass-part-question.vue";
import store from "@/store";
jest.mock("@/store", () => { return {}; }, { virtual: true });
const featureListData = {
colorAnswersProp: [
{ ColorAnswerText: 'Green Tint', FeatureAnswers: [{ FeatureAnswerText: "heated glass, solar, 1 hole", PartNumber: "DB12209GTYN" }] },
{ ColorAnswerText: 'Gray Tint Privacy', FeatureAnswers: [{ FeatureAnswerText: "heated glass, solar, 1 hole", PartNumber: "DB12209YPYN" }] }
],
glassLocationProp: "Rear",
glassNameProp: "Stationary",
modelValueProp: {}
}
describe("glass-part-question.vue", () => {
test("Part data passed in, should map data for ButtonQuestion (radio type)", async () => {
//Arrange
const { wrapper } = setupMocks(featureListData);
//Act
await wrapper.vm.$nextTick();
//Assert
expect(Object.keys(wrapper.vm.featureListData).length).toBe(2);
expect(wrapper.vm.featureListData['Green Tint'][0].Text).toBe("heated glass, solar, 1 hole");
expect(wrapper.vm.featureListData['Green Tint'][0].Name).toBe("DB12209GTYN");
expect(wrapper.vm.featureListData['Gray Tint Privacy'][0].Text).toBe("heated glass, solar, 1 hole");
expect(wrapper.vm.featureListData['Gray Tint Privacy'][0].Name).toBe("DB12209YPYN");
});
test("Tint mapper, should get tint image by glassLocation and tintColor", async () => {
//Arrange
const { wrapper } = setupMocks(featureListData);
//Act
await wrapper.vm.$nextTick();
const tintSourceImage = wrapper.vm.getTintSourceImage("Rear", "Green Tint");
//Assert
expect(tintSourceImage).toBe("Glass-NoShade-GreenTint.svg");
});
test("Tint mapper, should return empty string if no tint map found", async () => {
//Arrange
const { wrapper } = setupMocks(featureListData);
//Act
await wrapper.vm.$nextTick();
const tintSourceImage = wrapper.vm.getTintSourceImage("Rear", "Crazy Rainbow Tint");
//Assert
expect(tintSourceImage).toBe("");
});
test("Should emit updateModelValue, and have correct attributes", async () => {
//Arrange
const { wrapper } = setupMocks(featureListData);
//Act
await wrapper.vm.$nextTick();
const listCard = await wrapper.findComponent({
name: "listCard",
});
wrapper.setValue({ selectedTint: 'Green Tint' });
//Assert
expect(wrapper.emitted()["update:modelValue"][0]).toEqual([{ selectedTint: 'Green Tint' }]);
expect(listCard.attributes("buttonid")).toBe("Rear-Stationary-Green Tint");
expect(listCard.attributes("groupname")).toBe("Rear-Stationary");
expect(listCard.attributes("isradio")).toBe("true");
});
test("ResetTintAndPartSelections, should reset data elements ", async () => {
//Arrange
const { wrapper } = setupMocks(featureListData);
//Act
await wrapper.vm.$nextTick();
wrapper.setData({selectedTint: {"Rear-Stationary" : 'Green Tint' } });
expect(wrapper.vm.selectedTint).toStrictEqual({"Rear-Stationary": 'Green Tint'});
await wrapper.vm.ResetTintAndPartSelections();
expect(wrapper.vm.selectedTint).toStrictEqual({});
});
});
function setupMocks({ glassNameProp, glassLocationProp, colorAnswersProp, modelValueProp }) {
//Mock store
const mountOptions = getMountOptions({});
mountOptions.propsData = {
glassName: glassNameProp,
glassLocation: glassLocationProp,
colorAnswers: colorAnswersProp,
modelValue: modelValueProp
};
const wrapper = shallowMount(glassPartQuestion, mountOptions);
return { wrapper };
}

View file

@ -0,0 +1,143 @@
<template>
<div class="container">
<div class="row">
<p class="mb-0">{{ colorQuestionText }}</p>
</div>
</div>
<div class="container nested-radio" v-for="(value, name, index) in featureListData" :key="index">
<div class="row my-2">
<div class="col">
<listCard v-model="selectedTint[name]" :isRadio="true" :isWide="true" :buttonImage="
require(`@/assets/img/tints/${getTintSourceImage(
glassLocation,
name
)}`)
" :buttonLabel="name" altText="" :buttonID="`${glassLocation}-${glassName}-${name}`" :groupName="`${glassLocation}-${glassName}`" @isCheckedChanged="ResetTintAndPartSelections()" />
</div>
</div>
<transition name="fade" mode="out-in">
<div v-if="
selectedTint[name] != undefined &&
selectedTint[name].buttonId === `${glassLocation}-${glassName}-${name}`
" class="row my-2" aria-live="polite">
<div class="col">
<buttonQuestion v-model="selectedPart[glassLocation]" buttonType="radio" class="radioQuestion" :questionText="glassFeatureQuestion" :answers="value" textPosition="text-start" :loaderEnabled="false" :isRequired="true" :groupName="`${glassLocation}-${glassName}-${name}`" />
</div>
</div>
</transition>
</div>
</template>
<script>
// Components
import listCard from "@/ux-components/list-card/list-card";
import buttonQuestion from "@/common-components/button-question/button-question";
// Supporting files
import {
getTintImage
} from "@/constants/tint-mapper";
import {
getCustomTransformValue
} from "@/constants/dynamictext-mapper";
export default {
name: "glass-part-question",
inheritAttrs: false,
data() {
return {
glassColorQuestion: '',
glassFeatureQuestion: '',
selectedTint: {}, // v-model for the list card selections
};
},
props: {
glassName: String,
glassLocation: String,
colorAnswers: Array,
modelValue: Object
},
components: {
listCard,
buttonQuestion,
},
computed: {
colorQuestionText() {
return getCustomTransformValue(this.glassColorQuestion, `${this.glassLocation} ${this.glassName}`);
},
selectedPart: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
}
},
// Creates a map of the feature list data in the correct Name/Value
// format for the button-question component.
featureListData() {
const tintMapByColor = this.colorAnswers.reduce((arr, item) => {
// Create the key
const itemColor = item.ColorAnswerText;
arr[itemColor] = arr[itemColor] || [];
// Map the data to Name/Text object for ButtonQuestion
const mappedItem = item.FeatureAnswers.reduce((featureArr, item) => {
featureArr["Text"] = item.FeatureAnswerText; // Display to User
featureArr["Name"] = item.PartNumber; // Backing Value
return featureArr;
}, {});
// Add onto the final object
arr[itemColor].push(mappedItem);
return arr;
}, {});
return tintMapByColor;
}
},
methods: {
initializeComponent(cmsContent) {
this.glassColorQuestion = cmsContent.ColorQuestionWidget.QuestionText;
this.glassFeatureQuestion = cmsContent.FeatureQuestionWidget.QuestionText;
},
// Gets tint images based on the glass type, and tint name.
// Returns an empty string if the src or object is undefined.
getTintSourceImage(glassLocation, tintColor) {
const tintSourceObject = getTintImage(glassLocation, tintColor);
if (tintSourceObject === undefined || tintSourceObject.src == undefined) {
return "";
}
return tintSourceObject.src;
},
// Reset selections when tint changes for the same glass to ensure proper selection.
ResetTintAndPartSelections() {
this.selectedTint = {};
this.selectedPart = {};
}
},
};
</script>
<style lang="scss">
.nested-radio {
.ui-radio {
flex-direction: column;
margin: 0.25rem 0;
}
p {
font-size: 0.875rem;
}
}
</style>

View file

@ -0,0 +1,385 @@
// Components
import vehicleParts from "@/layouts/vehicle-parts/vehicle-parts.vue";
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass-part-question";
// Supporting Files
import { settleAllPromises } from "@/helpers/layout-helper.js";
import baseMixin from "@/mixins/base-mixin";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
import { storeActions } from "@/constants/store-actions";
import { storeMutations } from "@/constants/store-mutations";
import store from "@/store";
// Mock our module for promises.
jest.mock("@/helpers/layout-helper.js", () => ({
settleAllPromises: jest.fn(),
}));
// Mock fetchCmsContentForPage
jest.mock("@/helpers/cms-content-helper", () => ({
fetchCmsContentForPage: jest.fn(),
}));
// Mock store
jest.mock("@/store", () => { return {}; }, { virtual: true });
store.getters = {
pageData: jest.fn(),
damage: {
isRepair: false
}
};
const basePartResponse = {
partsOrQuestions: [
{
glassName: "Stationary",
glassLocation: "Rear",
parts: [
{
partNumber: "DB12209GTYN",
description: "heated glass, solar, 1 hole",
color: "Green Tint",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null
},
{
partNumber: "DB12209YPYNOEM",
description: "heated glass, solar, 1 hole",
color: "Gray Tint Privacy",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null
}
],
partQuestions: null
}
]
}
describe("vehicle-parts.vue", () => {
test("Page header is initialized with api data", async (done) => {
//Arrange
store.getters.pageData.mockReturnValueOnce({
partsOrQuestions: [
{
glassName: "Stationary",
glassLocation: "Rear",
parts: [
{
partNumber: "DB12209GTYN",
description: "heated glass, solar, 1 hole",
color: "Green Tint",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null
},
{
partNumber: "DB12209YPYNOEM",
description: "heated glass, solar, 1 hole",
color: "Gray Tint Privacy",
requiresRecalibration: false,
requiresCapabilityQuestions: false,
childParts: null
}
],
partQuestions: null
}
]
});
const pageHeaderWidgetHeaderText = "Select Parts";
const { wrapper, apiPromise } = setupMocks(
{
pageHeaderWidgetHeaderText: pageHeaderWidgetHeaderText,
mountOptionsMockData: {
router: {
navigateAfterSave: jest.fn()
},
route: {
query: {
fmgPage: 'vehicle-parts',
}
},
store: {
getters: store.getters
},
}
});
//Act
vehicleParts.beforeRouteEnter.call(wrapper.vm,
{ query: { fmgPage: "vehicle-parts" } },
undefined,
(c) => c(wrapper.vm)
);
//Assert
apiPromise.finally(() => {
expect(funnelSubHeader.methods.initializeComponent).toHaveBeenCalledWith(pageHeaderWidgetHeaderText);
done();
});
});
test("Page logo image is initialized with api data", async (done) => {
//Arrange
const SiteHeaderWidget = {
LogoImage:
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
};
store.getters.pageData.mockReturnValueOnce(basePartResponse);
const { wrapper, apiPromise } = setupMocks(
{
SiteHeaderWidget: SiteHeaderWidget,
mountOptionsMockData: {
router: {
navigateAfterSave: jest.fn()
},
route: {
query: {
fmgPage: 'vehicle-parts',
}
},
store: {
getters: store.getters
},
}
});
//Act
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-parts" } },
undefined,
(c) => c(wrapper.vm)
);
//Assert
apiPromise.finally(() => {
expect(funnelHeader.methods.initializeComponent).toHaveBeenCalledWith(SiteHeaderWidget);
done();
});
});
test("Vehicle image is initialized with api data", async (done) => {
//Arrange
const VehicleBannerWidget = {
GenericVehicleImage:
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
};
store.getters.pageData.mockReturnValue(basePartResponse);
const { wrapper, apiPromise } = setupMocks(
{
VehicleBannerWidget: VehicleBannerWidget,
mountOptionsMockData: {
router: {
navigateAfterSave: jest.fn()
},
route: {
query: {
fmgPage: 'vehicle-parts',
}
},
store: {
getters: store.getters
},
}
});
//Act
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-parts" } },
undefined,
(c) => c(wrapper.vm)
);
//Assert
apiPromise.finally(() => {
expect(vehicleBanner.methods.initializeComponent).toHaveBeenCalledWith(VehicleBannerWidget);
done();
});
});
test("PageData / isRepair populated in Vuex. arePagePrerequisitesValid should be true ", async () => {
//Arrange
store.getters.pageData.mockReturnValueOnce(basePartResponse);
const { wrapper } = setupMocks({
mountOptionsMockData: {
router: {
navigateAfterSave: jest.fn()
},
route: {
query: {
fmgPage: 'vehicle-parts',
}
},
store: {
getters: store.getters
},
}
});
//Act
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-parts" } },
undefined,
(c) => c(wrapper.vm)
);
let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
await nextTick();
//Assert
expect(arePagePrerequisitesValid).toBe(true);
});
test("BackButtonAction triggers a router.navigate change", async () => {
//Arrange
store.getters.pageData.mockReturnValueOnce(basePartResponse);
const { wrapper } = setupMocks({
mountOptionsMockData: {
router: {
navigateAfterSave: jest.fn(),
navigate: jest.fn()
},
route: {
query: {
fmgPage: 'vehicle-parts',
}
},
store: {
getters: store.getters
},
}
});
//Act
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-parts" } },
undefined,
(c) => c(wrapper.vm)
);
wrapper.vm.backButtonAction();
//Assert
expect(wrapper.vm.$router.navigate).toHaveBeenCalled();
});
test("ForwardButtonAction triggers a router.navigate change and saves selected parts to store", async () => {
//Arrange
store.getters.pageData.mockReturnValueOnce(basePartResponse);
store.commit = jest.fn();
const { wrapper } = setupMocks({
mountOptionsMockData: {
router: {
navigateAfterSave: jest.fn(),
navigate: jest.fn()
},
route: {
query: {
fmgPage: 'vehicle-parts',
}
},
store: {
getters: store.getters,
commit: store.commit
},
}
});
wrapper.setData({ glassParts: { "Rear-Stationary": { "Rear": ['DB12209YPYNOEM'] } } });
//Act
vehicleParts.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "vehicle-parts" } },
undefined,
(c) => c(wrapper.vm)
);
await wrapper.vm.forwardButtonAction();
//Assert
expect(wrapper.vm.$router.navigateAfterSave).toHaveBeenCalled();
// expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
// expect(store.commit).toBeCalledWith(storeMutations.UPDATE_IS_REPAIR, false);
// expect(store.commit).toBeCalledWith(storeMutations.UPDATE_GLASS_TO_REPLACE, expectedGlassToReplace);
});
});
function setupMocks({ pageHeaderWidgetHeaderText = {}, mountOptionsMockData = {} }) {
//Mock api responses
const apiResponses = {
cmsContent: {
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
VehicleBannerWidget: {
GenericVehicleImage:
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
},
FunnelHeaderWidget: {
LogoImage:
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
},
ColorQuestionWidget: 'Please choose your rear window tint color',
FeatureQuestionWidget: 'Ok no choose features',
AlertWidget: {
BodyText: 'Please choose your tint color',
HeadlineText: 'Just a few more steps to go',
}
}
};
const apiPromise = Promise.resolve(apiResponses);
settleAllPromises.mockImplementation(() => apiPromise);
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
//Mock damage initialize methods
funnelHeader.methods = { initializeComponent: jest.fn() };
vehicleBanner.methods = { initializeComponent: jest.fn() };
funnelSubHeader.methods = { initializeComponent: jest.fn() };
funnelFooter.methods = { initializeComponent: jest.fn() }
const mountOptions = getMountOptions(mountOptionsMockData,);
const wrapper = shallowMount(vehicleParts, mountOptions);
const funnelHeaderWrapper = wrapper.findComponent({ name: "funnelHeader" });
funnelHeaderWrapper.vm.initializeComponent = funnelHeader.methods.initializeComponent;
const vehicleBannerWrapper = wrapper.findComponent({ name: "vehicleBanner" });
vehicleBannerWrapper.vm.initializeComponent = vehicleBanner.methods.initializeComponent;
const funnelSubHeaderWrapper = wrapper.findComponent({ name: "funnelSubHeader", });
funnelSubHeaderWrapper.vm.initializeComponent = funnelSubHeader.methods.initializeComponent;
const funnelFooterWrapper = wrapper.findComponent({ name: "funnelFooter", });
funnelFooterWrapper.vm.initializeComponent = funnelFooter.methods.initializeComponent;
const partQuestionRearWrapper = wrapper.findComponent({ name: "glassPartQuestion", });
partQuestionRearWrapper.vm.initializeComponent = glassPartQuestion.methods.initializeComponent;
return { wrapper, apiPromise };
}

View file

@ -0,0 +1,192 @@
<template>
<div class="container-fluid shadow rounded-3 p-2 position-relative make-tall">
<funnelHeader ref="funnelHeader" />
<vehicleBanner ref="vehicleBanner" :displayGenericVehicleImage="false" />
<funnelSubHeader ref="funnelSubHeader" />
<div class="container-fluid prevent-squish my-5">
<div class="row">
<div class="col">
<alert class="rounded border-0 shadow-sm" alertClass="alert-warning" :alertHeadline="alertWidgetData.headline" :alertCopy="alertWidgetData.copy" :isDismissible="false" />
</div>
</div>
</div>
<div v-for="(item, i) in PartsForQuestions" :key="i">
<!-- Render horizontal lines if there is multi-glass (aka if i > 0) -->
<div class="container-fluid">
<hr v-if="i > 0" />
</div>
<glassPartQuestion :ref="`${refPrefix}-${item.glassLocation}`" v-model="glassParts[item.glassLocation + '-' + item.glassName]" :glassLocation="item.glassLocation" :glassName="item.glassName" :colorAnswers="item.colorAnswers" />
</div>
<funnelFooter ref="funnelFooter" @back-clicked="backButtonAction" @ForwardClicked="forwardButtonAction" />
</div>
</template>
<script>
// Components
import glassPartQuestion from "@/layouts/vehicle-parts/glass-part-question/glass-part-question";
import funnelHeader from "@/common-components/funnel-header/funnel-header";
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
import alert from "@/ux-components/alert/alert";
// Supporting Files
import {
fetchCmsContentForPage
} from "@/helpers/cms-content-helper";
import {
settleAllPromises
} from "@/helpers/layout-helper";
import {
fmgPageValues
} from "@/router/router-constants/fmgPage-values";
import {
storeMutations
} from "@/constants/store-mutations";
import store from "@/store";
export default {
name: "vehicle-parts",
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
// Settle promises and get results
const promiseResultMap = [{
resultKey: "cmsContent",
promise: cmsContentPromise,
}, ];
const resultMap = await settleAllPromises(promiseResultMap);
// Call the "next" function to complete the transition to this page.
next((vm) => {
vm.$refs.funnelHeader.initializeComponent(
resultMap.cmsContent.FunnelHeaderWidget
);
vm.$refs.vehicleBanner.initializeComponent(
resultMap.cmsContent.VehicleBannerWidget
);
vm.$refs.funnelSubHeader.initializeComponent(
resultMap.cmsContent.FunnelSubHeaderWidget
);
vm.$refs.funnelFooter.initializeComponent(
resultMap.cmsContent.FunnelFooterWidget
);
// Glass Part Question dynamic component
Object.keys(vm.$refs)
.filter((r) => r.includes(vm.refPrefix) && vm.$refs[r][0] !== undefined)
.forEach((c) =>
vm.$refs[c][0].initializeComponent({
ColorQuestionWidget: resultMap.cmsContent.ColorQuestionWidget,
FeatureQuestionWidget: resultMap.cmsContent.FeatureQuestionWidget,
})
);
// Set alertData for the page alert. These use props so we don't call
// initializeComponent here.
vm.alertWidgetData = {
copy: resultMap.cmsContent.AlertWidget.BodyText,
headline: resultMap.cmsContent.AlertWidget.HeadlineText
};
});
},
data() {
return {
glassParts: {},
refPrefix: "partQuestion",
alertWidgetData: Object,
};
},
components: {
glassPartQuestion,
funnelHeader,
vehicleBanner,
funnelSubHeader,
funnelFooter,
alert,
},
computed: {
PartsForQuestions() {
const partsData = this.$store.getters.pageData(this.$route.query.fmgPage);
// Map API result data, to vehicle-parts data structure
const mappedData = partsData.partsOrQuestions.map(g => {
return {
glassName: g.glassName,
glassLocation: g.glassLocation,
colorAnswers: g.parts.reduce((arr, p) => {
arr.push({
ColorAnswerText: p.color,
FeatureAnswers: [{
FeatureAnswerText: p.description === '' ? p.color : p.description,
PartNumber: p.partNumber
}]
});
return arr;
}, [])
}
});
return mappedData;
},
PartsFromApi() {
return store.getters.pageData(fmgPageValues.VEHICLE_PARTS);
}
},
methods: {
arePagePrerequisitesValid() {
// Check if isRepair is populated and if the pageData we need is here (Parts data)
if (store.getters.damage.isRepair !== null && Object.keys(store.getters.pageData(fmgPageValues.VEHICLE_PARTS)).length !== 0) {
return true;
}
return false
},
backButtonAction() {
this.$router.navigate(
this.navigationScenarios.CLICKED_BACK,
this.$route
);
},
forwardButtonAction() {
const selectedGlassPartNumbers = [];
const matchedParts = [];
// Compile all selected parts from the page.
for (let [key, value] of Object.entries(this.glassParts)) {
for (let [glassKey, glassValue] of Object.entries(value)) {
selectedGlassPartNumbers.push(glassValue[0]);
}
}
// Match them to the parts from the API.
for (let [key, value] of Object.entries(this.PartsFromApi.partsOrQuestions)) {
for (let [partKey, partValue] of Object.entries(value.parts)) {
const currentPart = this.PartsFromApi.partsOrQuestions[key].parts[partKey];
const isMatched = selectedGlassPartNumbers.some(p => p === currentPart.partNumber);
if (isMatched) {
matchedParts.push(currentPart);
}
}
}
// If no parts could be matched, throw an error.
if (matchedParts.length === 0) {
throw new Error("Could not match any parts to the selected parts");
}
// Save parts to the store.
store.commit(storeMutations.UPDATE_PARTS, matchedParts);
// Navigate to the next page.
this.$router.navigateAfterSave(this.navigationScenarios.SELECTED_PARTS, this.$route);
}
},
};
</script>

View file

@ -99,8 +99,8 @@ export default {
},
resetDependentState() {
// Invokes
store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
store.dispatch(storeActions.RESET_DAMAGE_STATE);
store.dispatch(storeActions.RESET_REGISTRATION_STATE);
},
},

View file

@ -163,8 +163,8 @@ describe("vehicle-year.vue", () => {
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_CAR_ID, null)
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_VEHICLE_CATEGORY, null)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_AND_DEPS)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_AND_DEPS)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_DAMAGE_STATE)
expect(store.dispatch).toBeCalledWith(storeActions.RESET_REGISTRATION_STATE)
});
});

View file

@ -95,8 +95,8 @@ export default {
store.commit(storeMutations.UPDATE_VEHICLE_CATEGORY, null);
// Invokes
store.dispatch(storeActions.RESET_DAMAGE_AND_DEPS);
store.dispatch(storeActions.RESET_REGISTRATION_AND_DEPS);
store.dispatch(storeActions.RESET_DAMAGE_STATE);
store.dispatch(storeActions.RESET_REGISTRATION_STATE);
}
},
components: {

View file

@ -18,6 +18,9 @@ export default {
return store.dispatch(type, payload);
},
savePageDataToStore(page, data){
store.commit(storeMutations.UPDATE_PAGE_DATA, { page: page, data: data });
}
},
computed: {
storeActions() {

View file

@ -26,6 +26,14 @@ describe("baseMixin.js", () => {
expect(store.dispatch).toBeCalledWith(type, payload);
});
test("savePageDataToStore, should call store commit", () => {
const mixIn = getMixInInstance({});
mixIn.methods.savePageDataToStore('vehicle-year', {});
expect(store.commit).toBeCalledWith(storeMutations.UPDATE_PAGE_DATA, { page: 'vehicle-year', data: {}});
});
test("computed: storeActions should be equal to import object", () => {
// Arrange
const mixIn = getMixInInstance({});
@ -91,9 +99,11 @@ function getMixInInstance({ isDispatchSuccess = true }) {
// Attach mocks to mixin
const baseMixIn = baseMixin;
baseMixIn.methods.$route = route;
store.dispatch = storeDispatch;
baseMixIn.methods.storeActions = storeActions;
baseMixIn.methods.widgetNames = widgetNames;
store.dispatch = storeDispatch;
store.commit = jest.fn();
return baseMixIn;
}

View file

@ -1,6 +1,7 @@
// Supporting files
import { createWebHistory, createRouter } from "vue-router";
import { storeActions } from "@/constants/store-actions";
import baseMixin from "@/mixins/base-mixin";
import { lazyLoadComponent } from "@/router/dynamic-routing/component-loader.js";
import { routingTable } from "@/router/router-constants/routing-table.js";
import { globalEvents, globalEventTypes } from "@/constants/events";
@ -114,18 +115,18 @@ const router = createRouter({
//---------------------------------------------------------- Router Functions ----------------------------------------------------------
router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => {
navigate(scenario, currentRoute, false, optionalQuery, optionalParams);
router.navigate = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => {
navigate(scenario, currentRoute, false, optionalQuery, optionalParams, optionalPageData);
}
router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}) => {
navigate(scenario, currentRoute, true, optionalQuery, optionalParams);
router.navigateAfterSave = (scenario, currentRoute, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) => {
navigate(scenario, currentRoute, true, optionalQuery, optionalParams, optionalPageData);
}
// PRIVATE FUNCTIONS
// Navigate to the next route, depending on the scenario.
function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}) {
function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {}, optionalParams = {}, optionalPageData = {}) {
if (!scenario) {
console.error("No scenario provided. Please review the routing table.");
return;
@ -144,6 +145,9 @@ function navigate(scenario, currentRoute, invalidateOnSave, optionalQuery = {},
resetDependentState(currentComponent);
}
// Append page data to the store for the NEXT page, if any. It will be an empty object if none is provided.
baseMixin.methods.savePageDataToStore(matchingScenarioMap.destinationFmgPageValue, optionalPageData);
router.push({
name: "root",
query: Object.assign(optionalQuery, {
@ -232,4 +236,4 @@ function resetDependentState(component) {
return component.default.methods.resetDependentState();
}
export default router;
export default router;

View file

@ -0,0 +1,5 @@
const externalUrls = {
HERITAGE_FUNNEL: process.env.VUE_APP_HERITAGE_FUNNEL,
};
export { externalUrls };

View file

@ -4,6 +4,9 @@ const fmgPageValues = {
VEHICLE_MODEL: "vehicle-model",
VEHICLE_STYLE: "vehicle-style",
VEHICLE_DAMAGE: "vehicle-damage",
VEHICLE_PARTS: "vehicle-parts",
PART_QUESTIONS: "part-questions",
REVEAL : "reveal",
};
export { fmgPageValues };
export { fmgPageValues };

View file

@ -4,7 +4,11 @@ const navigationScenarios = {
SELECTED_MAKE: "SELECTED_MAKE",
SELECTED_STYLE: "SELECTED_STYLE",
CLICKED_BACK: "CLICKED_BACK",
CLICKED_FORWARD: "CLICKED_FORWARD"
CLICKED_FORWARD: "CLICKED_FORWARD",
SELECTED_PARTS: "SELECTED_PARTS",
SELECTED_DAMAGE_WITH_SINGLE_PART: "SELECTED_DAMAGE_WITH_SINGLE_PART",
SELECTED_DAMAGE_WITH_MULTIPLE_PARTS: "SELECTED_DAMAGE_WITH_MULTIPLE_PARTS",
SELECTED_DAMAGE_WITH_PART_QUESTIONS: "SELECTED_DAMAGE_WITH_PART_QUESTIONS"
};
export { navigationScenarios };

View file

@ -0,0 +1,3 @@
const routerParameterKeys = { };
export { routerParameterKeys };

View file

@ -1,4 +1,5 @@
import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
import { externalUrls } from "@/router/router-constants/externalUrl-values";
import { navigationScenarios } from "@/router/router-constants/navigation-scenarios";
const routingTable = [
@ -59,7 +60,32 @@ const routingTable = [
},
{
scenario: navigationScenarios.CLICKED_FORWARD,
destinationUrl: "http://localhost:38000/default.aspx",
destinationUrl: externalUrls.HERITAGE_FUNNEL,
},
{
scenario: navigationScenarios.SELECTED_DAMAGE_WITH_SINGLE_PART,
destinationFmgPageValue: fmgPageValues.REVEAL
},
{
scenario: navigationScenarios.SELECTED_DAMAGE_WITH_MULTIPLE_PARTS,
destinationFmgPageValue: fmgPageValues.VEHICLE_PARTS,
},
{
scenario: navigationScenarios.SELECTED_DAMAGE_WITH_PART_QUESTIONS,
destinationFmgPageValue: fmgPageValues.PART_QUESTIONS,
},
],
},
{
fmgPageValue: fmgPageValues.VEHICLE_PARTS,
maps: [
{
scenario: navigationScenarios.CLICKED_BACK,
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
},
{
scenario: navigationScenarios.SELECTED_PARTS,
destinationFmgPageValue: fmgPageValues.QUOTE,
},
],
},

View file

@ -25,9 +25,16 @@ export const state = {
numberOfChips: null,
glassToReplace: null,
},
lineItems:{
glassParts: null,
otherParts: null
},
referralSeqNum: null,
correlationId: null,
},
applicationUser: {
eventBus: [],
pageData: {}
},
}
@ -61,6 +68,21 @@ export const mutations = {
updateVehicleImageColor(state, imageColor) {
state.order.vehicle.imageColor = imageColor;
},
updateIsRepair(state, isRepair){
state.order.damage.isRepair = isRepair;
},
updateNumberOfChips(state, numberOfChips){
state.order.damage.numberOfChips = numberOfChips;
},
updateGlassToReplace(state, glassToReplace){
state.order.damage.glassToReplace = glassToReplace;
},
updateParts(state, partsData){
state.order.lineItems.glassParts = partsData;
},
updatePageData(state, pageData){
state.applicationUser.pageData[pageData.page] = pageData.data;
},
// EVENT BUS MUTATIONS
addEventToBus(state, event) {
@ -81,7 +103,7 @@ export const mutations = {
},
// DEPENDENCY MUTATIONS
resetVehicleAndDependencies(state) {
resetVehicleState(state) {
state.order.vehicle.year = null;
state.order.vehicle.make = null;
state.order.vehicle.model = null;
@ -89,7 +111,7 @@ export const mutations = {
state.order.vehicle.carId = null;
state.order.vehicle.category = null;
},
resetDamageAndDependencies(state) {
resetDamageState(state) {
state.order.damage.isRepair = null;
state.order.damage.numberOfChips = null;
state.order.damage.windshieldGlassToReplace = null;
@ -98,11 +120,13 @@ export const mutations = {
state.order.damage.rearGlassToReplace = null;
},
resetRegistrationAndDependencies(state) {
resetRegistrationState(state) {
},
resetPartsAndDependencies(state) {
resetPartsState(state) {
state.glassParts = null;
state.childParts = null;
state.otherParts = null;
}
}
@ -118,6 +142,11 @@ export const getters = {
return matchedEvent !== undefined ? matchedEvent.eventValue : undefined;
},
eventBus: (state) => state.applicationUser.eventBus,
damage: (state) => state.order.damage,
lineItems: (state) => state.order.lineItems,
pageData: (state) => (page) => {
return state.applicationUser.pageData[page];
}
}
// Export Actions
@ -193,20 +222,20 @@ export const actions = {
// DEPENDENCY ACTIONS
resetVehicleAndDependencies(context) {
context.commit(storeMutations.RESET_VEHICLE_AND_DEPS);
context.commit(storeMutations.RESET_DAMAGE_AND_DEPS);
context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS);
context.commit(storeMutations.RESET_VEHICLE_STATE);
context.commit(storeMutations.RESET_DAMAGE_STATE);
context.commit(storeMutations.RESET_REGISTRATION_STATE);
},
resetDamageAndDependencies(context) {
context.commit(storeMutations.RESET_DAMAGE_AND_DEPS);
context.commit(storeMutations.RESET_PARTS_AND_DEPS);
context.commit(storeMutations.RESET_DAMAGE_STATE);
context.commit(storeMutations.RESET_PARTS_STATE);
},
resetRegistrationAndDependencies(context) {
context.commit(storeMutations.RESET_REGISTRATION_AND_DEPS);
context.commit(storeMutations.RESET_PARTS_AND_DEPS)
context.commit(storeMutations.RESET_REGISTRATION_STATE);
context.commit(storeMutations.RESET_PARTS_STATE)
},
resetPartsAndDependencies(context) {
context.commit(storeMutations.RESET_PARTS_AND_DEPS);
context.commit(storeMutations.RESET_PARTS_STATE);
},
// Content API Actions
@ -239,6 +268,41 @@ export const actions = {
payload: {},
});
},
// Parts API Actions
getPartsOrQuestions(context, { carId, glassArray, zipCode, vin = '' }) {
return globalMethods.callHttpClient({
method: endpoints.GetPartsOrQuestions.method,
endpoint: endpoints.GetPartsOrQuestions.url,
payload: {
carId: carId,
glass: glassArray,
zip: zipCode,
vin: vin
},
});
},
// Order API Actions
saveOrder(context) {
const vehicle = context.getters.vehicle;
const damage = context.getters.damage;
return globalMethods.callHttpClient({
method: endpoints.SaveOrder.method,
endpoint: endpoints.SaveOrder.url,
payload: {
vehicle: {
carId: vehicle.carId,
year: vehicle.year,
make: vehicle.make,
model: vehicle.model,
style: vehicle.style,
},
numberOfChips: damage.numberOfChips,
},
});
},
}
export default createStore({
@ -252,4 +316,4 @@ export default createStore({
mutations,
getters,
actions,
});
});

View file

@ -100,7 +100,7 @@ describe("Mutations", () => {
expect(storeState.applicationUser.eventBus).toEqual([{ EventOne: "ValueOne" }]);
});
it("resetVehicleAndDependencies, should set fields to null", () => {
it("resetVehicleState, should set fields to null", () => {
// Arrange
const storeState = state;
@ -120,7 +120,7 @@ describe("Mutations", () => {
expect(storeState.order.vehicle.category).toEqual("CAR");
// Act
mutations.resetVehicleAndDependencies(storeState);
mutations.resetVehicleState(storeState);
// Expect
expect(storeState.order.vehicle.year).toEqual(null);
@ -132,7 +132,7 @@ describe("Mutations", () => {
});
it("resetDamageAndDependencies, should set fields to null", () => {
it("resetDamageState, should set fields to null", () => {
// Arrange
const storeState = state;
@ -154,7 +154,7 @@ describe("Mutations", () => {
expect(storeState.order.damage.rearGlassToReplace).toEqual("Slider");
// Act
mutations.resetDamageAndDependencies(storeState);
mutations.resetDamageState(storeState);
// Expect
expect(storeState.order.damage.isRepair).toEqual(null);
@ -166,6 +166,50 @@ describe("Mutations", () => {
});
it("Updates number of chips in state", () => {
// Arrange
const storeState = state;
// Act
mutations.updateNumberOfChips(storeState, "1");
// Assert
expect(storeState.order.damage.numberOfChips).toEqual("1");
});
it("Updates glass to replace in state", () => {
// Arrange
const storeState = state;
// Act
mutations.updateGlassToReplace(storeState, ["Windshield"]);
// Assert
expect(storeState.order.damage.glassToReplace).toEqual(["Windshield"]);
});
it("Updates Parts in state", () => {
// Arrange
const storeState = state;
// Act
mutations.updateParts(storeState, { 'Windshield-Single': 'PARTNUM101'});
// Assert
expect(storeState.order.lineItems.glassParts).toEqual({ 'Windshield-Single': 'PARTNUM101'});
});
it("Updates page data in state", () => {
// Arrange
const storeState = state;
// Act
mutations.updatePageData(storeState, { page: 'vehicle-year', data: {} });
// Assert
expect(storeState.applicationUser.pageData['vehicle-year']).toEqual({});
});
});
describe("Actions", () => {
@ -313,9 +357,9 @@ describe("Actions", () => {
// Act
await actions.resetVehicleAndDependencies(context)
expect(commit).toBeCalledWith(storeMutations.RESET_VEHICLE_AND_DEPS);
expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS);
expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS);
expect(commit).toBeCalledWith(storeMutations.RESET_VEHICLE_STATE);
expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_STATE);
expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_STATE);
});
@ -330,8 +374,8 @@ describe("Actions", () => {
// Act
await actions.resetDamageAndDependencies(context)
expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_AND_DEPS);
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
expect(commit).toBeCalledWith(storeMutations.RESET_DAMAGE_STATE);
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_STATE);
});
@ -346,8 +390,8 @@ describe("Actions", () => {
// Act
await actions.resetRegistrationAndDependencies(context)
expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_AND_DEPS);
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
expect(commit).toBeCalledWith(storeMutations.RESET_REGISTRATION_STATE);
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_STATE);
});
@ -362,7 +406,7 @@ describe("Actions", () => {
// Act
await actions.resetPartsAndDependencies(context)
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_AND_DEPS);
expect(commit).toBeCalledWith(storeMutations.RESET_PARTS_STATE);
});
@ -480,4 +524,41 @@ describe("Getters", () => {
});
it("Damage getter, should return damage data", () => {
// Arrange
const storeState = state;
// Act
mutations.updateGlassToReplace(storeState, ["Rear"]);
// Assert
expect(getters.damage(storeState).glassToReplace).toEqual(["Rear"]);
});
it("lineItems getter, should return lineItem data", () => {
// Arrange
const storeState = state;
// Act
mutations.updateParts(storeState, {"Rear-Stationary": 'PART101'});
// Assert
expect(getters.lineItems(storeState).glassParts).toEqual({"Rear-Stationary": 'PART101'});
});
it("PageData getter, should return page data for specific page", () => {
// Arrange
const storeState = state;
// Act
mutations.updatePageData(storeState, { page: 'vehicle-year', data: {} });
// Assert
expect(getters.pageData(storeState)('vehicle-year')).toEqual({});
});
});

View file

@ -3,7 +3,6 @@
body {
font-size: 16px;
background-color: #fff;
.container-fluid {
max-width: 576px; //Remove once desktop app is complete
&.container-shadow {
@ -14,6 +13,9 @@ body {
display: flex;
flex-direction: column;
}
.prevent-squish{
overflow-x: unset;
}
}
.pointer {
cursor: pointer;

View file

@ -204,11 +204,12 @@ describe("list-card.vue", () => {
isRequired: true,
isWide: false,
modelValue: ["List Card Checkbox"],
buttonID: 'list-card-id'
},
});
wrapper.vm.handleCheckChange();
// Assert
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: Boolean}]);
expect(wrapper.emitted()["isCheckedChanged"][0]).toEqual([{value: "List Card Checkbox", checkValue: Boolean, buttonId: 'list-card-id'}]);
});
it("Should set checkValue data if selectedButtonIDs has value(s)", async () => {

View file

@ -49,7 +49,6 @@
<script>
import { useField } from "vee-validate";
export default {
name: "listCard",
props: {
@ -100,13 +99,14 @@ export default {
handleCheckChange(newValue, oldValue){
const isInitialization = typeof(oldValue) === 'function';
if (!isInitialization) {
this.$emit('isCheckedChanged', { checkValue: this.checkValue, value: this.value.toString() });
const emitEvent = { checkValue: this.checkValue, value: this.value.toString(), buttonId: this.buttonID.toString() };
this.$emit('isCheckedChanged', emitEvent);
this.$emit('update:modelValue', emitEvent);
}
}
},
setup(props) {
const inputType = props.isMultiSelect ? "checkbox" : "radio";
const {
value: inputValue,
handleChange,
@ -277,4 +277,4 @@ export default {
}
}
}
</style>
</style>

View file

@ -10,7 +10,7 @@
:aria-required="isRequired"
:value="value"
:v-model="checkValue"
@change="handleCheckChange()"
@change="handleCheckChanged()"
/>
<label class="d-flex align-items-start form-check-label" :for="buttonID">
<p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p>
@ -43,8 +43,8 @@ export default {
checkValue: Boolean,
};
},
created(){
if(this.selectedButtonIDs){
created() {
if (this.selectedButtonIDs) {
this.checkValue = this.selectedButtonIDs[0];
}
},
@ -52,12 +52,20 @@ export default {
handleClick(value) {
this.handleChange(value);
},
handleCheckChange(newValue, oldValue){
const isInitialization = typeof(oldValue) === 'function';
handleCheckChanged(newValue, oldValue) {
const isInitialization = typeof oldValue === "function";
if (!isInitialization) {
this.$emit('isCheckedChanged', { checkValue: this.checkValue, value: this.value.toString() });
const emitEvent = {
checkValue: this.checkValue,
value: this.value.toString(),
buttonID: this.buttonID.toString(),
};
this.$emit("isCheckedChanged", emitEvent);
this.$emit("update:modelValue", emitEvent);
}
}
},
},
setup(props) {
const { groupName, value } = toRefs(props);
@ -83,7 +91,7 @@ export default {
.form-check-input {
border: 1px solid $gray-500;
border-radius: 100%;
margin-right: .5rem;
margin-right: 0.5rem;
&:checked {
background-color: $white;
background-size: 71%;

View file

@ -1,5 +1,7 @@
process.env.VUE_APP_CONSUMER_API_GATEWAY =
"https://consumerapidev.safelite.com";
process.env.VUE_APP_HERITAGE_FUNNEL =
"http://localhost:38000/default.aspx";
module.exports = {
outputDir: "dist/fmg",
@ -19,4 +21,7 @@ module.exports = {
},
},
},
configureWebpack: {
devtool: 'source-map'
}
};