Merge branch 'develop' into feature/CSR-2182-ajc
This commit is contained in:
commit
737ef41ad1
47 changed files with 11119 additions and 36820 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"tabWidth": 4,
|
"tabWidth": 4,
|
||||||
"bracketSameLine": true,
|
"bracketSameLine": true,
|
||||||
"printWidth": 100
|
"printWidth": 100,
|
||||||
|
"trailingComma" : "es5"
|
||||||
}
|
}
|
||||||
|
|
@ -18,7 +18,7 @@ pr:
|
||||||
resources:
|
resources:
|
||||||
containers:
|
containers:
|
||||||
- container: node
|
- container: node
|
||||||
image: packagerepository.sagaws.net:8082/safelite/node-build:15
|
image: packagerepository.sagaws.net:8082/safelite/node-build:18
|
||||||
- container: awscli
|
- container: awscli
|
||||||
image: packagerepository.sagaws.net:8082/safelite/awscli2-build:3.9
|
image: packagerepository.sagaws.net:8082/safelite/awscli2-build:3.9
|
||||||
- container: prettier-node
|
- container: prettier-node
|
||||||
|
|
@ -28,7 +28,7 @@ resources:
|
||||||
type: github
|
type: github
|
||||||
name: Safelite/AzureDevOps
|
name: Safelite/AzureDevOps
|
||||||
endpoint: Safelite
|
endpoint: Safelite
|
||||||
ref: refs/tags/t5.5.40
|
ref: refs/tags/t5.6.41
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
- group: Digital-Infrastructure
|
- group: Digital-Infrastructure
|
||||||
|
|
@ -37,15 +37,15 @@ variables:
|
||||||
stages:
|
stages:
|
||||||
# PR's
|
# PR's
|
||||||
- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
|
- ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
|
||||||
- stage: TestFormat
|
# - stage: TestFormat
|
||||||
displayName: Test Code Format
|
# displayName: Test Code Format
|
||||||
jobs:
|
# jobs:
|
||||||
- job: checkFormatting
|
# - job: checkFormatting
|
||||||
displayName: Check formatting
|
# displayName: Check formatting
|
||||||
container: prettier-node
|
# container: prettier-node
|
||||||
steps:
|
# steps:
|
||||||
- bash: prettier --check "$(Build.SourcesDirectory)/src/**/*.(js|vue)"
|
# - bash: prettier --check "$(Build.SourcesDirectory)/src/**/*.(js|vue)"
|
||||||
displayName: Run Prettier check
|
# displayName: Run Prettier check
|
||||||
|
|
||||||
- stage: TestPr
|
- stage: TestPr
|
||||||
displayName: Run Unit Tests For PullRequest
|
displayName: Run Unit Tests For PullRequest
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ module.exports = {
|
||||||
coverageReporters: ["html", "text", "jest-junit", "cobertura"],
|
coverageReporters: ["html", "text", "jest-junit", "cobertura"],
|
||||||
testResultsProcessor: "jest-junit",
|
testResultsProcessor: "jest-junit",
|
||||||
preset: "@vue/cli-plugin-unit-jest",
|
preset: "@vue/cli-plugin-unit-jest",
|
||||||
transform: { "^.+\\.vue$": "vue-jest" },
|
transform: { "^.+\\.vue$": "@vue/vue3-jest" },
|
||||||
moduleFileExtensions: ["js", "vue"],
|
moduleFileExtensions: ["js", "vue"],
|
||||||
modulePathIgnorePatterns: ["vin-lookup"],
|
modulePathIgnorePatterns: ["vin-lookup"],
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
|
|
|
||||||
47337
package-lock.json
generated
47337
package-lock.json
generated
File diff suppressed because it is too large
Load diff
61
package.json
61
package.json
|
|
@ -11,42 +11,39 @@
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@popperjs/core": "^2.10.2",
|
|
||||||
"axios": "^0.23.0",
|
"axios": "^0.23.0",
|
||||||
"bootstrap": "^5.1.1",
|
"bootstrap": "^5.3.3",
|
||||||
"canvas-confetti": "^1.4.0",
|
"core-js": "^3.38.1",
|
||||||
"core-js": "^3.6.5",
|
"http-status-codes": "^2.3.0",
|
||||||
"http-status-codes": "^2.1.4",
|
"iframe-resizer": "^4.4.5",
|
||||||
"iframe-resizer": "^4.3.7",
|
"jest-junit": "^13.2.0",
|
||||||
"jest-junit": "^13.0.0",
|
|
||||||
"jquery": "^3.7.1",
|
"jquery": "^3.7.1",
|
||||||
"jquery-ui": "^1.13.2",
|
"jquery-ui": "^1.14.0",
|
||||||
"maska": "^1.5.0",
|
"maska": "^1.5.2",
|
||||||
"vee-validate": "^4.5.7",
|
"vee-validate": "^4.13.2",
|
||||||
"vue": "^3.0.0",
|
"vue": "^3.4.38",
|
||||||
"vue-plugin-load-script": "^2.1.0",
|
"vue-plugin-load-script": "^2.1.1",
|
||||||
"vue-router": "^4.0.11",
|
"vue-router": "^4.4.3",
|
||||||
"vuex": "^4.0.2",
|
"vuex": "^4.1.0",
|
||||||
"vuex-persistedstate": "^4.1.0",
|
"vuex-persistedstate": "^4.1.0"
|
||||||
"yup": "^0.32.11"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vue/cli-plugin-babel": "~4.5.0",
|
"@babel/eslint-parser": "^7.25.1",
|
||||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
"@vue/cli-plugin-babel": "~5.0.8",
|
||||||
"@vue/cli-plugin-unit-jest": "~4.5.0",
|
"@vue/cli-plugin-eslint": "~5.0.8",
|
||||||
"@vue/cli-service": "~4.5.0",
|
"@vue/cli-plugin-unit-jest": "~5.0.8",
|
||||||
"@vue/compiler-sfc": "^3.0.0",
|
"@vue/cli-service": "~5.0.8",
|
||||||
"@vue/eslint-config-prettier": "^6.0.0",
|
"@vue/compiler-sfc": "^3.4.38",
|
||||||
"@vue/test-utils": "^2.0.0-0",
|
"@vue/eslint-config-prettier": "^9.0.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"@vue/test-utils": "^2.4.6",
|
||||||
"eslint": "^6.7.2",
|
"@vue/vue3-jest": "^27.0.0",
|
||||||
"eslint-plugin-prettier": "^3.3.1",
|
"eslint": "8.57",
|
||||||
"eslint-plugin-vue": "^7.0.0",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"prettier": "^2.2.1",
|
"eslint-plugin-vue": "^9.27.0",
|
||||||
"sass": "^1.26.5",
|
"prettier": "^3.3.3",
|
||||||
|
"sass": "^1.77.8",
|
||||||
"sass-loader": "^8.0.2",
|
"sass-loader": "^8.0.2",
|
||||||
"typescript": "~3.9.3",
|
"typescript": "^4.9.5"
|
||||||
"vue-jest": "^5.0.0-0"
|
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"root": true,
|
"root": true,
|
||||||
|
|
@ -58,7 +55,7 @@
|
||||||
"eslint:recommended"
|
"eslint:recommended"
|
||||||
],
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"parser": "babel-eslint"
|
"parser": "@babel/eslint-parser"
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-unused-vars": "off"
|
"no-unused-vars": "off"
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,12 @@ module.exports = {
|
||||||
env: {
|
env: {
|
||||||
jest: true,
|
jest: true,
|
||||||
},
|
},
|
||||||
|
rules: {
|
||||||
|
"vue/multi-word-component-names": "off",
|
||||||
|
"vue/valid-next-tick": "off",
|
||||||
|
"vue/no-v-text-v-html-on-component": "off",
|
||||||
|
"vue/no-reserved-component-names": "off",
|
||||||
|
"vue/require-toggle-inside-transition": "off",
|
||||||
|
},
|
||||||
//...
|
//...
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ const applicationConfig = {
|
||||||
"https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent",
|
"https://outlook.office.com/calendar/deeplink/compose?path=/calendar/action/compose&rru=addevent",
|
||||||
FRONTEND_LOGGER_PATH: "/analytics/api/v1/logging",
|
FRONTEND_LOGGER_PATH: "/analytics/api/v1/logging",
|
||||||
AFFILIATE_COOKIE_CONTAINING_NAME: "_Track",
|
AFFILIATE_COOKIE_CONTAINING_NAME: "_Track",
|
||||||
|
COOKIE_NAME_LENGTH_MAX_LIMIT: 44,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { applicationConfig };
|
export { applicationConfig };
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ const cookieNames = {
|
||||||
DXDEV: "dxdev",
|
DXDEV: "dxdev",
|
||||||
SESSION_ID: "sid",
|
SESSION_ID: "sid",
|
||||||
SESSION_KEY: "skey",
|
SESSION_KEY: "skey",
|
||||||
|
|
||||||
|
//Commission Junction Cookie
|
||||||
|
CJE: "cje",
|
||||||
};
|
};
|
||||||
|
|
||||||
const cookieExpirations = {
|
const cookieExpirations = {
|
||||||
|
|
@ -17,6 +20,8 @@ const cookieExpirations = {
|
||||||
DXDEV: convertToSeconds({ years: 1 }),
|
DXDEV: convertToSeconds({ years: 1 }),
|
||||||
FUNNEL_USER_ID: convertToSeconds({ weeks: 1 }),
|
FUNNEL_USER_ID: convertToSeconds({ weeks: 1 }),
|
||||||
FUNNEL_SESSION_KEY: convertToSeconds({ minutes: 30 }),
|
FUNNEL_SESSION_KEY: convertToSeconds({ minutes: 30 }),
|
||||||
|
CJE: convertToSeconds({ days: 395 }),
|
||||||
|
NON_CJ: convertToSeconds({ days: 100000 }),
|
||||||
};
|
};
|
||||||
|
|
||||||
export { cookieNames, cookieExpirations };
|
export { cookieNames, cookieExpirations };
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,13 @@ const queryStrings = {
|
||||||
VIN_SELECTION: "vinselection",
|
VIN_SELECTION: "vinselection",
|
||||||
SERVICE_PACKAGE: "servicepackage",
|
SERVICE_PACKAGE: "servicepackage",
|
||||||
NUMBER_OF_CHIPS: "numberofchips",
|
NUMBER_OF_CHIPS: "numberofchips",
|
||||||
|
UTM_SOURCE: "_source",
|
||||||
|
UTM_MEDIUM: "_medium",
|
||||||
|
UTM_CAMPAIGN: "_campaign",
|
||||||
|
CJ_EVENT: "cjevent",
|
||||||
|
CJUNCTION: "cjunction",
|
||||||
|
ORGANIC: "organic",
|
||||||
|
ORGANIC_SOCIAL: "organic_social",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { queryStrings };
|
export { queryStrings };
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ describe("baseInputButton.vue", () => {
|
||||||
describe("mouse clicks", () => {
|
describe("mouse clicks", () => {
|
||||||
describe("checkbox", () => {
|
describe("checkbox", () => {
|
||||||
describe("clicked once", () => {
|
describe("clicked once", () => {
|
||||||
test("correct event and value are emitted", async () => {
|
test("correct event and value are emitted and input is checked", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mockData: {
|
mockData: {
|
||||||
|
|
@ -71,31 +71,12 @@ describe("baseInputButton.vue", () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.trigger("click");
|
await wrapper.find("input").setChecked();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.emitted()["update:modelValue"][0][0]).toEqual(["X"]);
|
expect(wrapper.emitted()["update:modelValue"][0][0]).toEqual(["X"]);
|
||||||
});
|
expect(wrapper.find("input").element.checked).toBe(true);
|
||||||
|
|
||||||
test("input is checked", async () => {
|
|
||||||
// Arrange
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
mockData: {
|
|
||||||
propsData: {
|
|
||||||
isMultiSelect: true,
|
|
||||||
value: "X",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const input = wrapper.find("input");
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await wrapper.trigger("click");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(input.element.checked).toBe(true);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -135,25 +116,7 @@ describe("baseInputButton.vue", () => {
|
||||||
});
|
});
|
||||||
const input = wrapper.find("input");
|
const input = wrapper.find("input");
|
||||||
|
|
||||||
// Act
|
expect(input.element.checked).toBe(true);
|
||||||
await wrapper.trigger("click");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
expect(input.element.checked).toBe(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("input is unchecked", async () => {
|
|
||||||
// Arrange
|
|
||||||
const { wrapper } = setupMocks({
|
|
||||||
mockData: {
|
|
||||||
propsData: {
|
|
||||||
isMultiSelect: true,
|
|
||||||
value: "X",
|
|
||||||
modelValue: ["X"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const input = wrapper.find("input");
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await wrapper.trigger("click");
|
await wrapper.trigger("click");
|
||||||
|
|
|
||||||
|
|
@ -1147,7 +1147,12 @@ function setupMocks(mountOptionsMockData = {}) {
|
||||||
const baseMountOptions = getMountOptions(
|
const baseMountOptions = getMountOptions(
|
||||||
Object.assign(defaultMountOptions, mountOptionsMockData)
|
Object.assign(defaultMountOptions, mountOptionsMockData)
|
||||||
);
|
);
|
||||||
|
|
||||||
const allMountOptions = Object.assign(defaultMountOptions, baseMountOptions);
|
const allMountOptions = Object.assign(defaultMountOptions, baseMountOptions);
|
||||||
|
// Add in group name to avoid vee-validate failures
|
||||||
|
if (!allMountOptions.propsData.groupName) {
|
||||||
|
allMountOptions.propsData.groupName = "group-name";
|
||||||
|
}
|
||||||
|
|
||||||
return allMountOptions;
|
return allMountOptions;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -177,8 +177,8 @@ export default {
|
||||||
const baseClasses = this.isOverflowScrollable
|
const baseClasses = this.isOverflowScrollable
|
||||||
? "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"
|
? "container-fluid overflow-scroll position-absolute px-5 pt-1 py-0"
|
||||||
: this.buttonTypeString == "listCard"
|
: this.buttonTypeString == "listCard"
|
||||||
? "w-100"
|
? "w-100"
|
||||||
: "";
|
: "";
|
||||||
const withSmallQuestionClass = this.isSmallQuestionText
|
const withSmallQuestionClass = this.isSmallQuestionText
|
||||||
? baseClasses + " small-question-text"
|
? baseClasses + " small-question-text"
|
||||||
: baseClasses;
|
: baseClasses;
|
||||||
|
|
|
||||||
|
|
@ -732,7 +732,9 @@ export default {
|
||||||
margin: 0 auto 2rem auto;
|
margin: 0 auto 2rem auto;
|
||||||
max-width: 414px;
|
max-width: 414px;
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: height ease 2s, opacity ease 2s;
|
transition:
|
||||||
|
height ease 2s,
|
||||||
|
opacity ease 2s;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(7, 1fr);
|
grid-template-columns: repeat(7, 1fr);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -805,7 +807,9 @@ export default {
|
||||||
outline: none;
|
outline: none;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: height ease 250ms, opacity ease 250ms;
|
transition:
|
||||||
|
height ease 250ms,
|
||||||
|
opacity ease 250ms;
|
||||||
|
|
||||||
input[type="radio"] {
|
input[type="radio"] {
|
||||||
position: absolute; //override bootstrap
|
position: absolute; //override bootstrap
|
||||||
|
|
@ -818,7 +822,9 @@ export default {
|
||||||
|
|
||||||
&:focus + label,
|
&:focus + label,
|
||||||
&:checked:focus + label {
|
&:checked:focus + label {
|
||||||
box-shadow: 0 0 0 3px #fff, 0 0 0 5.5px #1574a1;
|
box-shadow:
|
||||||
|
0 0 0 3px #fff,
|
||||||
|
0 0 0 5.5px #1574a1;
|
||||||
background-color: $blue;
|
background-color: $blue;
|
||||||
color: $white;
|
color: $white;
|
||||||
&.current-day {
|
&.current-day {
|
||||||
|
|
|
||||||
|
|
@ -76,13 +76,17 @@ export default {
|
||||||
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
}
|
}
|
||||||
&:focus, // Mouse, touch, stylus focus
|
&:focus, // Mouse, touch, stylus focus
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
// Keyboard focus for accessibility
|
// Keyboard focus for accessibility
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
color: $white;
|
color: $white;
|
||||||
background: linear-gradient(270deg, rgba(6, 87, 124, 1) 0%, rgba(6, 87, 124, 1) 100%);
|
background: linear-gradient(270deg, rgba(6, 87, 124, 1) 0%, rgba(6, 87, 124, 1) 100%);
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +104,9 @@ export default {
|
||||||
&.has-loader {
|
&.has-loader {
|
||||||
color: $white;
|
color: $white;
|
||||||
background: $blue-700;
|
background: $blue-700;
|
||||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
&.delay {
|
&.delay {
|
||||||
|
|
@ -125,7 +131,9 @@ export default {
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
// Keyboard focus for accessibility
|
// Keyboard focus for accessibility
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px $white,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
color: $white;
|
color: $white;
|
||||||
@include blue-gradient;
|
@include blue-gradient;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import { cookieNames, cookieExpirations } from "@/constants/cookie-names";
|
import { cookieNames, cookieExpirations } from "@/constants/cookie-names";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import { applicationConfig } from "@/constants/application-config";
|
import { applicationConfig } from "@/constants/application-config";
|
||||||
|
import { getQuerystringParameter } from "@/helpers/querystring-helper";
|
||||||
|
import { queryStrings } from "@/constants/query-strings";
|
||||||
|
//import { cookieParameters } from "@/constants/cookie-parameters";
|
||||||
/*
|
/*
|
||||||
Will update the cookie if present, or create a new one if not.
|
Will update the cookie if present, or create a new one if not.
|
||||||
*/
|
*/
|
||||||
|
|
@ -221,6 +223,79 @@ export function getAffiliateCookies() {
|
||||||
return affiliateCookies;
|
return affiliateCookies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setupAdvertiserTracking() {
|
||||||
|
var utmSource = getQuerystringParameter(queryStrings.UTM_SOURCE);
|
||||||
|
var utmMedium = getQuerystringParameter(queryStrings.UTM_MEDIUM);
|
||||||
|
var utmCampaign = getQuerystringParameter(queryStrings.UTM_CAMPAIGN);
|
||||||
|
const cjEvent = getQuerystringParameter(queryStrings.CJ_EVENT);
|
||||||
|
// helper check for if an object is defined (but maybe falsey)
|
||||||
|
const isDefined = (x) => x !== null && x !== undefined;
|
||||||
|
if (isDefined(cjEvent) != "") {
|
||||||
|
const cjeCookieName = cookieNames.CJE;
|
||||||
|
if (!isCookieSet(cjeCookieName)) {
|
||||||
|
createCJEventCookie(cjEvent, cjeCookieName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Firstly, Can't continue without utm-source or utm-medium.
|
||||||
|
//Secondly, Ignore the advertiser for CJ-affiliate-click and Email-click.
|
||||||
|
if (
|
||||||
|
!isDefined(utmSource) ||
|
||||||
|
isDefined(utmSource) == "" ||
|
||||||
|
!isDefined(utmMedium) ||
|
||||||
|
isDefined(utmMedium) == "" ||
|
||||||
|
utmSource?.toLowerCase() == queryStrings.CJUNCTION ||
|
||||||
|
utmMedium?.toLowerCase() == queryStrings.EMAIL ||
|
||||||
|
utmMedium?.toLowerCase() == queryStrings.ORGANIC ||
|
||||||
|
utmMedium?.toLowerCase() == queryStrings.ORGANIC_SOCIAL
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//UTC date time format yyyy-MM-dd/HH:mm:ss
|
||||||
|
const currentDateTime = new Date().toISOString().replace(/T/, "/").replace(/\..+/, "");
|
||||||
|
|
||||||
|
//Format cookie, by removing spaces and special characters.
|
||||||
|
utmSource = FormatCookieElementName(utmSource);
|
||||||
|
utmMedium = FormatCookieElementName(utmMedium);
|
||||||
|
utmCampaign = FormatCookieElementName(utmCampaign);
|
||||||
|
|
||||||
|
var cookieNameBuilder = utmSource + "_" + utmMedium;
|
||||||
|
//Since utmCampaign is optional, ignore the rest.
|
||||||
|
if (isDefined(utmCampaign) && utmCampaign != "") {
|
||||||
|
cookieNameBuilder = cookieNameBuilder + "_" + utmCampaign;
|
||||||
|
}
|
||||||
|
const cookieName =
|
||||||
|
(cookieNameBuilder.length > applicationConfig.COOKIE_NAME_LENGTH_MAX_LIMIT
|
||||||
|
? cookieNameBuilder.substring(0, applicationConfig.COOKIE_NAME_LENGTH_MAX_LIMIT)
|
||||||
|
: cookieNameBuilder) + applicationConfig.AFFILIATE_COOKIE_CONTAINING_NAME;
|
||||||
|
|
||||||
|
if (!isCookieSet(cookieName)) {
|
||||||
|
const values = [
|
||||||
|
`utm_source= ${utmSource}`,
|
||||||
|
`utm_medium= ${utmMedium}`,
|
||||||
|
`utm_campaign= ${utmCampaign}`,
|
||||||
|
`timestamp= ${currentDateTime}`,
|
||||||
|
`tagEvent= ${cjEvent}`,
|
||||||
|
];
|
||||||
|
let valueString = values.join("&");
|
||||||
|
createOrUpdateCookie(cookieName, valueString, {
|
||||||
|
useDefaultFunnelCookieAttributes: true,
|
||||||
|
maxAge: cookieExpirations.NON_CJ,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const cookieValue = getCookieValueByName(cookieName);
|
||||||
|
if (cookieValue) {
|
||||||
|
let cookieValueObj = convertStringToObject(cookieValue);
|
||||||
|
cookieValueObj.timestamp = currentDateTime; // Update the property
|
||||||
|
// Set the updated cookie
|
||||||
|
const cookieValueString = objectToString(cookieValueObj);
|
||||||
|
createOrUpdateCookie(cookieName, cookieValueString, {
|
||||||
|
useDefaultFunnelCookieAttributes: true,
|
||||||
|
maxAge: cookieExpirations.NON_CJ,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===========================
|
===========================
|
||||||
= PRIVATE FUNCTIONS =
|
= PRIVATE FUNCTIONS =
|
||||||
|
|
@ -253,7 +328,7 @@ function setFunnelCookieProperties(properties) {
|
||||||
function createOrUpdateCookie(
|
function createOrUpdateCookie(
|
||||||
key,
|
key,
|
||||||
value = "",
|
value = "",
|
||||||
{ useDefaultFunnelCookieAttributes = true, maxAge, isSecure = true }
|
{ useDefaultFunnelCookieAttributes = true, maxAge, isSecure = true, crossSiteAccess = false }
|
||||||
) {
|
) {
|
||||||
let cookieToAdd = `${key}=${value}; `;
|
let cookieToAdd = `${key}=${value}; `;
|
||||||
|
|
||||||
|
|
@ -266,6 +341,9 @@ function createOrUpdateCookie(
|
||||||
if (!isNaN(maxAge)) {
|
if (!isNaN(maxAge)) {
|
||||||
cookieToAdd += `max-age=${maxAge};`;
|
cookieToAdd += `max-age=${maxAge};`;
|
||||||
}
|
}
|
||||||
|
if (crossSiteAccess && isSecure) {
|
||||||
|
cookieToAdd += `sameSite=None;`;
|
||||||
|
}
|
||||||
|
|
||||||
document.cookie = cookieToAdd;
|
document.cookie = cookieToAdd;
|
||||||
}
|
}
|
||||||
|
|
@ -315,3 +393,42 @@ function getCookiesContainingName(name) {
|
||||||
}
|
}
|
||||||
return matchingCookies;
|
return matchingCookies;
|
||||||
}
|
}
|
||||||
|
function createCJEventCookie(cjEvent, cookieName) {
|
||||||
|
createOrUpdateCookie(cookieName, cjEvent, {
|
||||||
|
useDefaultFunnelCookieAttributes: true,
|
||||||
|
maxAge: cookieExpirations.CJE,
|
||||||
|
isSecure: true,
|
||||||
|
crossSiteAccess: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function FormatCookieElementName(cookie) {
|
||||||
|
// Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
|
||||||
|
const problemSymbols = '\\s\\(\\)<>@,;:\\\\/\\[\\]\\?=\\{}"';
|
||||||
|
const otherSymbols = "!#$%^&+\\-*|~`";
|
||||||
|
const symbolsToIgnore = new RegExp("[" + problemSymbols + otherSymbols + "]+", "g");
|
||||||
|
|
||||||
|
return (cookie || "").replace(symbolsToIgnore, ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertStringToObject(str) {
|
||||||
|
let obj = {};
|
||||||
|
let pairs = str.split("&");
|
||||||
|
|
||||||
|
pairs.forEach((pair) => {
|
||||||
|
let [key, value] = pair.split("=");
|
||||||
|
obj[key] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
function objectToString(obj) {
|
||||||
|
let str = "";
|
||||||
|
for (let key in obj) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
||||||
|
str += key + "=" + obj[key] + "&";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Remove the trailing '&'
|
||||||
|
return str.slice(0, -1);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
import experimentMixin from "@/mixins/experiment-mixin";
|
import experimentMixin from "@/mixins/experiment-mixin";
|
||||||
import { experimentSettings } from "@/constants/experiments";
|
import { experimentSettings } from "@/constants/experiments";
|
||||||
import { includesWindshieldReplacement } from "@/helpers/damage-helper";
|
import { includesWindshieldReplacement } from "@/helpers/damage-helper";
|
||||||
|
import { applicationConfig } from "@/constants/application-config.js";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
|
|
||||||
|
|
@ -33,7 +34,7 @@ export async function getDirectNavigation(toRoute) {
|
||||||
// vehicle -> vehicle-damage
|
// vehicle -> vehicle-damage
|
||||||
// quote -> vin-lookup/estimate
|
// quote -> vin-lookup/estimate
|
||||||
// insurance-company -> vin-lookup/estimate
|
// insurance-company -> vin-lookup/estimate
|
||||||
if (store.getters.requiresVerifiedRedirecting) {
|
if (store.getters.payment?.insuranceCoverage?.isVerified) {
|
||||||
if (fmgPageValue === fmgPageValues.VEHICLE) {
|
if (fmgPageValue === fmgPageValues.VEHICLE) {
|
||||||
return fmgPageValues.VEHICLE_DAMAGE;
|
return fmgPageValues.VEHICLE_DAMAGE;
|
||||||
}
|
}
|
||||||
|
|
@ -106,6 +107,8 @@ export async function getImplicitNavigation(toRoute) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLog }) {
|
export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLog }) {
|
||||||
|
console.log(new Date() + " navigateToHeritageFunnel: " + JSON.stringify(applicationConfig));
|
||||||
|
console.log(new Date() + " navigateToHeritageFunnel: " + applicationConfig.HERITAGE_FUNNEL);
|
||||||
// Create the order (or save existing order) when navigating to Heritage Funnel.
|
// Create the order (or save existing order) when navigating to Heritage Funnel.
|
||||||
if (shouldSaveSession) {
|
if (shouldSaveSession) {
|
||||||
await saveSession({ pageNameToLog: pageNameToLog, shouldAwaitSaveSessionQueue: true });
|
await saveSession({ pageNameToLog: pageNameToLog, shouldAwaitSaveSessionQueue: true });
|
||||||
|
|
@ -133,7 +136,7 @@ export async function navigateToHeritageFunnel({ shouldSaveSession, pageNameToLo
|
||||||
heritageParms["forceEndToEndInsurance"] = true;
|
heritageParms["forceEndToEndInsurance"] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
router.navigateToExternalUrl(externalUrls.HERITAGE_FUNNEL, heritageParms);
|
router.navigateToExternalUrl(applicationConfig.HERITAGE_FUNNEL, heritageParms);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function skipVinLookup() {
|
export async function skipVinLookup() {
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,7 @@ describe("capabilityQuestions.vue", () => {
|
||||||
test("Should trigger handleCompletedQuestionChainAnswers if watched data changes", async () => {
|
test("Should trigger handleCompletedQuestionChainAnswers if watched data changes", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
wrapper.vm.handleCompletedQuestionChainAnswers = jest.fn();
|
||||||
const spy = jest.spyOn(wrapper.vm, "handleCompletedQuestionChainAnswers");
|
const spy = jest.spyOn(wrapper.vm, "handleCompletedQuestionChainAnswers");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
|
|
@ -215,9 +215,10 @@ describe("estimate.vue", () => {
|
||||||
|
|
||||||
describe("estimate.vue", () => {
|
describe("estimate.vue", () => {
|
||||||
test("should call forwardButtonAction if isExternalParameter is true and form is valid", async () => {
|
test("should call forwardButtonAction if isExternalParameter is true and form is valid", async () => {
|
||||||
store.commit(storeMutations.UPDATE_IS_EXTERNAL_PARAMETER, true);
|
store.getters = {
|
||||||
store.commit(storeMutations.UPDATE_EXTERNAL_PARAMETER_VIN_SELECTION, "decline");
|
isExternalParameter: true,
|
||||||
|
externalParameterEstimate: { vinSelection: "decline" },
|
||||||
|
};
|
||||||
// Set up the component
|
// Set up the component
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@ describe("moldingQuestions.vue", () => {
|
||||||
test("Should trigger handleCompletedQuestionChainAnswers if watched data changes", async () => {
|
test("Should trigger handleCompletedQuestionChainAnswers if watched data changes", async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
wrapper.vm.handleCompletedQuestionChainAnswers = jest.fn();
|
||||||
const spy = jest.spyOn(wrapper.vm, "handleCompletedQuestionChainAnswers");
|
const spy = jest.spyOn(wrapper.vm, "handleCompletedQuestionChainAnswers");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -268,6 +269,7 @@ describe("moldingQuestions.vue", () => {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const spy = jest.spyOn(wrapper.vm, "dispatchStoreAction");
|
const spy = jest.spyOn(wrapper.vm, "dispatchStoreAction");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,7 @@ describe("partQuestions.vue...", () => {
|
||||||
order: {},
|
order: {},
|
||||||
};
|
};
|
||||||
const { wrapper } = setupMocks({});
|
const { wrapper } = setupMocks({});
|
||||||
|
wrapper.vm.handleCompletedQuestionChainAnswers = jest.fn();
|
||||||
const spy = jest.spyOn(wrapper.vm, "handleCompletedQuestionChainAnswers");
|
const spy = jest.spyOn(wrapper.vm, "handleCompletedQuestionChainAnswers");
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
|
|
@ -225,12 +225,12 @@ export default {
|
||||||
// instead of what comes from the backend. This is to prevent issues with part interchange.
|
// instead of what comes from the backend. This is to prevent issues with part interchange.
|
||||||
const availableFrontWipers = orderHasFrontWipers
|
const availableFrontWipers = orderHasFrontWipers
|
||||||
? frontWipersOnOrder
|
? frontWipersOnOrder
|
||||||
: resultMap.wipers.filter((wiper) => wiper.partType == partTypeStrings.FRONT_WIPER) ??
|
: (resultMap.wipers.filter((wiper) => wiper.partType == partTypeStrings.FRONT_WIPER) ??
|
||||||
[];
|
[]);
|
||||||
const availableRearWipers = orderHasRearWipers
|
const availableRearWipers = orderHasRearWipers
|
||||||
? rearWipersOnOrder
|
? rearWipersOnOrder
|
||||||
: resultMap.wipers.filter((wiper) => wiper.partType == partTypeStrings.REAR_WIPER) ??
|
: (resultMap.wipers.filter((wiper) => wiper.partType == partTypeStrings.REAR_WIPER) ??
|
||||||
[];
|
[]);
|
||||||
|
|
||||||
const lineItemsToTax = [
|
const lineItemsToTax = [
|
||||||
resultMap.rainDefense,
|
resultMap.rainDefense,
|
||||||
|
|
@ -526,14 +526,18 @@ export default {
|
||||||
await submitWorkOrder({ pageNameToLog: "payment-method", submitAfterSave: true });
|
await submitWorkOrder({ pageNameToLog: "payment-method", submitAfterSave: true });
|
||||||
this.$router.navigateWithoutSaving(
|
this.$router.navigateWithoutSaving(
|
||||||
this.navigationScenarios.CLICKED_FORWARD,
|
this.navigationScenarios.CLICKED_FORWARD,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_PIA_ALERT]: false }
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (this.paymentMethod == paymentMethods.INSURANCE) {
|
if (this.paymentMethod == paymentMethods.INSURANCE) {
|
||||||
this.dispatchStoreAction(this.storeActions.SAVE_PAYMENT_TYPE, true, false);
|
this.dispatchStoreAction(this.storeActions.SAVE_PAYMENT_TYPE, true, false);
|
||||||
this.$router.navigateWithoutSaving(
|
this.$router.navigateWithoutSaving(
|
||||||
this.navigationScenarios.CLICKED_INSURANCE,
|
this.navigationScenarios.CLICKED_INSURANCE,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_PIA_ALERT]: false }
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.setupPia();
|
this.setupPia();
|
||||||
|
|
@ -555,14 +559,16 @@ export default {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error: response from pia submit work order:" + error.message);
|
console.log("error: response from pia submit work order:" + error.message);
|
||||||
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
||||||
this.$route.params[routerParams.DISPLAY_PIA_ALERT] = true;
|
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
this.dispatchStoreAction(storeActions.RESET_SAVE_SESSION_PROMISE);
|
||||||
this.$router.navigateWithoutSaving(
|
this.$router.navigateWithoutSaving(
|
||||||
this.navigationScenarios.CLICKED_PAY_NOW,
|
this.navigationScenarios.CLICKED_PAY_NOW,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_PIA_ALERT]: false }
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
hasSubmittedOrder() {
|
hasSubmittedOrder() {
|
||||||
|
|
@ -683,7 +689,7 @@ export default {
|
||||||
shouldDisplayPiaAlert() {
|
shouldDisplayPiaAlert() {
|
||||||
return (
|
return (
|
||||||
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] ||
|
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] ||
|
||||||
this.$route.params[routerParams.DISPLAY_PIA_ALERT]
|
eval(window.history.state.displayPiaAlert)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
// Necessary to make the watcher of lineItems work
|
// Necessary to make the watcher of lineItems work
|
||||||
|
|
|
||||||
|
|
@ -747,7 +747,7 @@ export default {
|
||||||
shouldDisplayPiaAlert(payMethod) {
|
shouldDisplayPiaAlert(payMethod) {
|
||||||
return (
|
return (
|
||||||
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] === payMethod ||
|
this.$route.query[queryStrings.DISPLAY_PIA_ALERT] === payMethod ||
|
||||||
this.$route.params[routerParams.DISPLAY_PIA_ALERT] === payMethod
|
eval(window.history.state.displayPiaAlert)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -125,6 +125,7 @@ import { partTypeStrings } from "@/constants/part-type-strings";
|
||||||
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
|
import { containsLineItemWithPartType } from "@/helpers/service-package-helper";
|
||||||
import { nextTick } from "vue";
|
import { nextTick } from "vue";
|
||||||
import { packageNames } from "@/constants/package-names";
|
import { packageNames } from "@/constants/package-names";
|
||||||
|
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
||||||
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
defineRule("option-required", required(errorMessages.OPTION_REQUIRED));
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -271,6 +272,20 @@ export default {
|
||||||
validateAlerts[0].shouldAutoFade
|
validateAlerts[0].shouldAutoFade
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const payment = store.getters.payment;
|
||||||
|
const policy = store.getters.policy;
|
||||||
|
if (payment?.isInsurance) {
|
||||||
|
const vehicleChangedDuringPolicyLookupInHeritage =
|
||||||
|
payment.insuranceCoverage?.coverageStatus && policy?.policyNumber !== "";
|
||||||
|
|
||||||
|
// This is a safeguard to prevent insurance from seeing quote page again.
|
||||||
|
// Usually this is caught in vehicle-questions-mixin with a referral length 6 check
|
||||||
|
if (vehicleChangedDuringPolicyLookupInHeritage) {
|
||||||
|
navigateToHeritageFunnel({ shouldSaveSession: true, pageNameToLog: "quote" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (store.getters.isExternalParameter) {
|
if (store.getters.isExternalParameter) {
|
||||||
if (store.getters.externalParameterQuote.isInsurance == true) {
|
if (store.getters.externalParameterQuote.isInsurance == true) {
|
||||||
vm.isInsuranceSelected = true;
|
vm.isInsuranceSelected = true;
|
||||||
|
|
|
||||||
|
|
@ -384,6 +384,7 @@ describe("service-package-question.vue", () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
wrapper.vm.selectDefaultPackage = jest.fn();
|
||||||
const selectDefaultPackageMock = jest.spyOn(wrapper.vm, "selectDefaultPackage");
|
const selectDefaultPackageMock = jest.spyOn(wrapper.vm, "selectDefaultPackage");
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,10 @@ export default {
|
||||||
},
|
},
|
||||||
getDiscountedPackagePriceString(packageName, servicePackageDiscount) {
|
getDiscountedPackagePriceString(packageName, servicePackageDiscount) {
|
||||||
const formattedPriceFloat = parseFloat(
|
const formattedPriceFloat = parseFloat(
|
||||||
this.getPackagePrice(packageName, { discountedPrice: true, servicePackageDiscount })
|
this.getPackagePrice(packageName, {
|
||||||
|
discountedPrice: true,
|
||||||
|
servicePackageDiscount,
|
||||||
|
})
|
||||||
).toFixed(2);
|
).toFixed(2);
|
||||||
return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat;
|
return (this.isInsuranceSelected ? "As little as $" : "$") + formattedPriceFloat;
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ describe("service-package-radio.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const mockProps = {
|
const mockProps = {
|
||||||
|
groupName: "group-name",
|
||||||
buttonLabel: "buttonLabel test copy",
|
buttonLabel: "buttonLabel test copy",
|
||||||
buttonLabelAuxillaryCopy: "buttonLabelAuxillaryCopy test copy",
|
buttonLabelAuxillaryCopy: "buttonLabelAuxillaryCopy test copy",
|
||||||
buttonLabelSubCopy: "buttonLabelSubCopy test copy",
|
buttonLabelSubCopy: "buttonLabelSubCopy test copy",
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,8 @@ export default {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border: 1px solid $gray-300;
|
border: 1px solid $gray-300;
|
||||||
box-shadow: 0px 4px 8px -4px rgba(0, 0, 0, 0.15),
|
box-shadow:
|
||||||
|
0px 4px 8px -4px rgba(0, 0, 0, 0.15),
|
||||||
0px 4px 24px -8px rgba(0, 0, 0, 0.2);
|
0px 4px 24px -8px rgba(0, 0, 0, 0.2);
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
@ -220,7 +221,9 @@ export default {
|
||||||
+ .package-label {
|
+ .package-label {
|
||||||
&:before {
|
&:before {
|
||||||
border: 1px solid #8e9292;
|
border: 1px solid #8e9292;
|
||||||
box-shadow: 0px 0px 0px 4px #9fcee6, 0px 1px 4px rgba(0, 0, 0, 0.2);
|
box-shadow:
|
||||||
|
0px 0px 0px 4px #9fcee6,
|
||||||
|
0px 1px 4px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -309,7 +309,7 @@ describe("service-zip.vue", () => {
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const wrapper = setupMocks({});
|
const wrapper = setupMocks({});
|
||||||
|
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
|
||||||
jest.spyOn(wrapper.vm, "navigateForwardWithSingleCarMatch").mockImplementation();
|
jest.spyOn(wrapper.vm, "navigateForwardWithSingleCarMatch").mockImplementation();
|
||||||
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -329,7 +329,7 @@ describe("service-zip.vue", () => {
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
const wrapper = setupMocks({});
|
const wrapper = setupMocks({});
|
||||||
|
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
|
||||||
jest.spyOn(wrapper.vm, "navigateForwardWithSingleCarMatch").mockImplementation();
|
jest.spyOn(wrapper.vm, "navigateForwardWithSingleCarMatch").mockImplementation();
|
||||||
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
@ -397,6 +397,7 @@ describe("service-zip.vue", () => {
|
||||||
wrapper.vm.displayInvalidZipAlert = true;
|
wrapper.vm.displayInvalidZipAlert = true;
|
||||||
wrapper.vm.displayNonServiceableZipAlert = true;
|
wrapper.vm.displayNonServiceableZipAlert = true;
|
||||||
|
|
||||||
|
wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
|
||||||
jest.spyOn(wrapper.vm, "navigateForwardWithSingleCarMatch").mockImplementation();
|
jest.spyOn(wrapper.vm, "navigateForwardWithSingleCarMatch").mockImplementation();
|
||||||
|
|
||||||
await wrapper.vm.forwardButtonAction();
|
await wrapper.vm.forwardButtonAction();
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,6 @@ import {
|
||||||
skipVinLookupNotRepair,
|
skipVinLookupNotRepair,
|
||||||
} from "@/helpers/heritage-integration/navigation-helper";
|
} from "@/helpers/heritage-integration/navigation-helper";
|
||||||
import vinPagesMixin from "@/mixins/vin-pages-mixin";
|
import vinPagesMixin from "@/mixins/vin-pages-mixin";
|
||||||
import { navigateToHeritageFunnel } from "@/helpers/heritage-integration/navigation-helper";
|
|
||||||
import { saveSession } from "@/helpers/heritage-integration/order-helper.js";
|
import { saveSession } from "@/helpers/heritage-integration/order-helper.js";
|
||||||
import baseMixin from "@/mixins/base-mixin.js";
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
import { queryStrings } from "@/constants/query-strings";
|
import { queryStrings } from "@/constants/query-strings";
|
||||||
|
|
@ -208,17 +207,7 @@ export default {
|
||||||
const payment = this.$store.getters.payment;
|
const payment = this.$store.getters.payment;
|
||||||
const policy = this.$store.getters.policy;
|
const policy = this.$store.getters.policy;
|
||||||
|
|
||||||
const vehicleChangedDuringPolicyLookupInHeritage =
|
if (this.$store.getters.order.referralNumber?.length === 6) {
|
||||||
payment.isInsurance &&
|
|
||||||
payment.insuranceCoverage.coverageStatus &&
|
|
||||||
policy.policyNumber !== "";
|
|
||||||
|
|
||||||
if (vehicleChangedDuringPolicyLookupInHeritage) {
|
|
||||||
navigateToHeritageFunnel({
|
|
||||||
shouldSaveSession: true,
|
|
||||||
pageNameToLog: "estimate",
|
|
||||||
});
|
|
||||||
} else if (this.$store.getters.order.referralNumber?.length === 6) {
|
|
||||||
await this.navigateForwardWithSingleCarMatch();
|
await this.navigateForwardWithSingleCarMatch();
|
||||||
} else if (this.isRepair) {
|
} else if (this.isRepair) {
|
||||||
const supportingItemsPromise = await this.dispatchStoreActionWithLogging(
|
const supportingItemsPromise = await this.dispatchStoreActionWithLogging(
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,13 @@ export default {
|
||||||
: [];
|
: [];
|
||||||
return filteredAnswers.map((ans) => {
|
return filteredAnswers.map((ans) => {
|
||||||
const newName = ans.Name.includes("-") ? ans.Name.split("-")[1] : ans.Name;
|
const newName = ans.Name.includes("-") ? ans.Name.split("-")[1] : ans.Name;
|
||||||
ans.Name = newName;
|
return {
|
||||||
return ans;
|
Name: newName,
|
||||||
|
AnswerImageUrl: ans.AnswerImageUrl,
|
||||||
|
ImageId: ans.ImageId,
|
||||||
|
SubText: ans.SubText,
|
||||||
|
Text: ans.Text,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -83,8 +83,13 @@ export default {
|
||||||
|
|
||||||
return filteredAnswers.map((ans) => {
|
return filteredAnswers.map((ans) => {
|
||||||
const newName = ans.Name.includes("-") ? ans.Name.split("-")[1] : ans.Name;
|
const newName = ans.Name.includes("-") ? ans.Name.split("-")[1] : ans.Name;
|
||||||
ans.Name = newName;
|
return {
|
||||||
return ans;
|
Name: newName,
|
||||||
|
AnswerImageUrl: ans.AnswerImageUrl,
|
||||||
|
ImageId: ans.ImageId,
|
||||||
|
SubText: ans.SubText,
|
||||||
|
Text: ans.Text,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
shouldDisplayReplaceOptionsQuestion() {
|
shouldDisplayReplaceOptionsQuestion() {
|
||||||
|
|
|
||||||
|
|
@ -142,8 +142,13 @@ export default {
|
||||||
|
|
||||||
return filteredAnswers.map((ans) => {
|
return filteredAnswers.map((ans) => {
|
||||||
const newName = ans.Name.includes("-") ? ans.Name.split("-")[1] : ans.Name;
|
const newName = ans.Name.includes("-") ? ans.Name.split("-")[1] : ans.Name;
|
||||||
ans.Name = newName;
|
return {
|
||||||
return ans;
|
Name: newName,
|
||||||
|
AnswerImageUrl: ans.AnswerImageUrl,
|
||||||
|
ImageId: ans.ImageId,
|
||||||
|
SubText: ans.SubText,
|
||||||
|
Text: ans.Text,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
isDriverSideReplaceOptionsQuestionAvailable() {
|
isDriverSideReplaceOptionsQuestionAvailable() {
|
||||||
|
|
|
||||||
|
|
@ -310,12 +310,11 @@ describe("vehicle-damage.vue", () => {
|
||||||
describe("alert", () => {
|
describe("alert", () => {
|
||||||
test("when displayVehicleChangeAlert router params is true, the alert: 'vehicleChangeAlert' should be rendered", () => {
|
test("when displayVehicleChangeAlert router params is true, the alert: 'vehicleChangeAlert' should be rendered", () => {
|
||||||
// Arrange & Act
|
// Arrange & Act
|
||||||
|
window.history.pushState({ displayVehicleChangeAlert: "true" }, "", "");
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
route: {
|
route: {
|
||||||
params: {
|
state: { displayVehicleChangeAlert: true },
|
||||||
[routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
@ -325,21 +324,24 @@ describe("vehicle-damage.vue", () => {
|
||||||
|
|
||||||
test("when displayVehicleChangeAlert router params is false, the alert: 'vehicleChangeAlert' should not be rendered", () => {
|
test("when displayVehicleChangeAlert router params is false, the alert: 'vehicleChangeAlert' should not be rendered", () => {
|
||||||
// Arrange & Act
|
// Arrange & Act
|
||||||
|
window.history.pushState({ displayVehicleChangeAlert: "false" }, "", "");
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
route: {
|
route: {
|
||||||
params: {
|
state: {
|
||||||
[routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false,
|
[routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.findComponent({ ref: "vehicleChangeAlert" }).exists()).toBe(false);
|
expect(wrapper.findComponent({ ref: "vehicleChangeAlert" }).exists()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("when displayVehicleChangeAlert router params is undefined, the alert: 'vehicleChangeAlert' should not be rendered", () => {
|
test("when displayVehicleChangeAlert router params is undefined, the alert: 'vehicleChangeAlert' should not be rendered", () => {
|
||||||
// Arrange & Act
|
// Arrange & Act
|
||||||
|
window.history.pushState({ displayVehicleChangeAlert: "false" }, "", "");
|
||||||
const { wrapper } = setupMocks({
|
const { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
route: {
|
route: {
|
||||||
|
|
@ -850,7 +852,7 @@ function setupMocks({ pageHeaderWidgetHeaderText, mountOptionsMockData, funnelCo
|
||||||
navigateWithSaving: jest.fn(),
|
navigateWithSaving: jest.fn(),
|
||||||
},
|
},
|
||||||
route: {
|
route: {
|
||||||
params: {
|
state: {
|
||||||
[routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false,
|
[routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ import { errorMessages } from "@/constants/error-messages";
|
||||||
import { damageLocationsCms } from "@/constants/damage-locations-cms.js";
|
import { damageLocationsCms } from "@/constants/damage-locations-cms.js";
|
||||||
import { damageLocationsSelected } from "@/constants/damage-locations-selected.js";
|
import { damageLocationsSelected } from "@/constants/damage-locations-selected.js";
|
||||||
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
import { getFunnelCookie } from "@/helpers/heritage-integration/cookie-helper";
|
||||||
|
import { routerParams } from "@/router/router-constants/router-params";
|
||||||
|
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import baseMixin from "@/mixins/base-mixin";
|
import baseMixin from "@/mixins/base-mixin";
|
||||||
|
|
@ -405,20 +406,26 @@ export default {
|
||||||
if (skipVin) {
|
if (skipVin) {
|
||||||
this.$router.navigateWithSaving(
|
this.$router.navigateWithSaving(
|
||||||
this.navigationScenarios.CLICKED_FORWARD_WITH_SKIP_VIN,
|
this.navigationScenarios.CLICKED_FORWARD_WITH_SKIP_VIN,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false }
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (store.getters.damage.isRepair) {
|
if (store.getters.damage.isRepair) {
|
||||||
this.$router.navigateWithSaving(
|
this.$router.navigateWithSaving(
|
||||||
this.navigationScenarios
|
this.navigationScenarios
|
||||||
.CLICKED_FORWARD_WITH_REPAIR_AND_VERIFIED_INSURANCE,
|
.CLICKED_FORWARD_WITH_REPAIR_AND_VERIFIED_INSURANCE,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false }
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.$router.navigateWithSaving(
|
this.$router.navigateWithSaving(
|
||||||
this.navigationScenarios
|
this.navigationScenarios
|
||||||
.CLICKED_FORWARD_WITH_REPLACE_AND_VERIFIED_INSURANCE,
|
.CLICKED_FORWARD_WITH_REPLACE_AND_VERIFIED_INSURANCE,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -427,17 +434,23 @@ export default {
|
||||||
else if (store.getters.vehicle.vin) {
|
else if (store.getters.vehicle.vin) {
|
||||||
this.$router.navigateWithSaving(
|
this.$router.navigateWithSaving(
|
||||||
this.navigationScenarios.CLICKED_FORWARD_WITH_VIN,
|
this.navigationScenarios.CLICKED_FORWARD_WITH_VIN,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false }
|
||||||
);
|
);
|
||||||
} else if (skipVin) {
|
} else if (skipVin) {
|
||||||
this.$router.navigateWithSaving(
|
this.$router.navigateWithSaving(
|
||||||
this.navigationScenarios.CLICKED_FORWARD_WITH_SKIP_VIN,
|
this.navigationScenarios.CLICKED_FORWARD_WITH_SKIP_VIN,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false }
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.$router.navigateWithSaving(
|
this.$router.navigateWithSaving(
|
||||||
this.navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN,
|
this.navigationScenarios.CLICKED_FORWARD_WITHOUT_VIN,
|
||||||
this.$route
|
this.$route,
|
||||||
|
{},
|
||||||
|
{ [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -566,7 +579,7 @@ export default {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
shouldDisplayVehicleChangeAlert() {
|
shouldDisplayVehicleChangeAlert() {
|
||||||
return this.$route.params[this.routerParams.DISPLAY_VEHICLE_CHANGE_ALERT];
|
return eval(window.history.state.displayVehicleChangeAlert);
|
||||||
},
|
},
|
||||||
shouldHideBackButton() {
|
shouldHideBackButton() {
|
||||||
return this.$store.getters.requiresVerifiedRedirecting;
|
return this.$store.getters.requiresVerifiedRedirecting;
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,11 @@ defineRule(
|
||||||
defineRule(
|
defineRule(
|
||||||
"check-for-repair-and-replace",
|
"check-for-repair-and-replace",
|
||||||
(selectedWindshieldDamageType, selectedDamageLocations) => {
|
(selectedWindshieldDamageType, selectedDamageLocations) => {
|
||||||
|
// vee-validate adds an extra arrray on initial selection
|
||||||
|
// remove here
|
||||||
|
selectedDamageLocations[0] = selectedDamageLocations[0].filter((location) => {
|
||||||
|
return !Array.isArray(location);
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
selectedWindshieldDamageType.toString() != damageLocationsSelected.REPAIR ||
|
selectedWindshieldDamageType.toString() != damageLocationsSelected.REPAIR ||
|
||||||
(!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD) &&
|
(!selectedDamageLocations.includes(damageLocationsSelected.WINDSHIELD) &&
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ const basePartResponse = {
|
||||||
};
|
};
|
||||||
|
|
||||||
describe("vehicle-parts.vue", () => {
|
describe("vehicle-parts.vue", () => {
|
||||||
test("Set cms content called on load", async (done) => {
|
test("Set cms content called on load", (done) => {
|
||||||
//Arrange
|
//Arrange
|
||||||
store.getters.pageData.mockReturnValue(basePartResponse);
|
store.getters.pageData.mockReturnValue(basePartResponse);
|
||||||
store.getters.lineItems = { glassParts: null };
|
store.getters.lineItems = { glassParts: null };
|
||||||
|
|
|
||||||
|
|
@ -398,11 +398,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
isDisabled(options) {
|
isDisabled(options) {
|
||||||
if (
|
if (!options.length || store.getters.payment?.insuranceCoverage?.isVerified) {
|
||||||
!options.length ||
|
|
||||||
store.getters.requiresVerifiedRedirecting ||
|
|
||||||
getFunnelCookie()?.HasDelayedClaimRegistration
|
|
||||||
) {
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -222,12 +222,7 @@ export default {
|
||||||
|
|
||||||
// Provider Ctu
|
// Provider Ctu
|
||||||
if (isDefined(order.serviceLocation.zipCodeCtu)) {
|
if (isDefined(order.serviceLocation.zipCodeCtu)) {
|
||||||
const parsedCtu = parseInt(order.serviceLocation.zipCodeCtu);
|
payload.providerCtu = order.serviceLocation.zipCodeCtu;
|
||||||
if (!isNaN(parsedCtu)) {
|
|
||||||
payload.providerCtu = parseInt(order.serviceLocation.zipCodeCtu);
|
|
||||||
} else {
|
|
||||||
payload.providerCtu = "";
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
payload.providerCtu = "";
|
payload.providerCtu = "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ describe("input-button-wrapper-mixin", () => {
|
||||||
expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
|
expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
|
||||||
expect(wrapper.vm.value).toEqual([]);
|
expect(wrapper.vm.value).toEqual([]);
|
||||||
|
|
||||||
await inputButtonOne.find("input").trigger("click");
|
await inputButtonOne.find("input").setChecked();
|
||||||
await inputButtonTwo.find("input").trigger("click");
|
await inputButtonTwo.find("input").setChecked();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.value).toEqual(["value1", "value2"]);
|
expect(wrapper.vm.value).toEqual(["value1", "value2"]);
|
||||||
|
|
@ -52,9 +52,9 @@ describe("input-button-wrapper-mixin", () => {
|
||||||
expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
|
expect(inputButtonTwo.vm.isMultiSelect).toBe(true);
|
||||||
expect(wrapper.vm.value).toEqual([]);
|
expect(wrapper.vm.value).toEqual([]);
|
||||||
|
|
||||||
await inputButtonOne.find("input").trigger("click");
|
await inputButtonOne.find("input").setChecked();
|
||||||
await inputButtonTwo.find("input").trigger("click");
|
await inputButtonTwo.find("input").setChecked();
|
||||||
await inputButtonOne.find("input").trigger("click");
|
await inputButtonOne.find("input").setChecked(false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.value).toEqual(["value2"]);
|
expect(wrapper.vm.value).toEqual(["value2"]);
|
||||||
|
|
@ -80,8 +80,8 @@ describe("input-button-wrapper-mixin", () => {
|
||||||
expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
|
expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
|
||||||
expect(wrapper.vm.value).toEqual("");
|
expect(wrapper.vm.value).toEqual("");
|
||||||
|
|
||||||
await inputButtonOne.find("input").trigger("click");
|
await inputButtonOne.find("input").setChecked();
|
||||||
await inputButtonTwo.find("input").trigger("click");
|
await inputButtonTwo.find("input").setChecked();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.value).toEqual("value2");
|
expect(wrapper.vm.value).toEqual("value2");
|
||||||
|
|
@ -105,9 +105,9 @@ describe("input-button-wrapper-mixin", () => {
|
||||||
expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
|
expect(inputButtonTwo.vm.isMultiSelect).toBe(false);
|
||||||
expect(wrapper.vm.value).toEqual("");
|
expect(wrapper.vm.value).toEqual("");
|
||||||
|
|
||||||
await inputButtonOne.find("input").trigger("click");
|
await inputButtonOne.find("input").setChecked();
|
||||||
await inputButtonTwo.find("input").trigger("click");
|
await inputButtonTwo.find("input").setChecked();
|
||||||
await inputButtonOne.find("input").trigger("click");
|
await inputButtonOne.find("input").setChecked();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.vm.value).toEqual("value1");
|
expect(wrapper.vm.value).toEqual("value1");
|
||||||
|
|
@ -295,23 +295,20 @@ function setupBaseInputButtonWrapper({ mockData = {} }) {
|
||||||
parentComponentTemplate += `<baseInputButtonWrapper v-model="value" groupName="myGroupName" :isMultiSelect="${mockData.isMultiSelect}" value="value1" />`;
|
parentComponentTemplate += `<baseInputButtonWrapper v-model="value" groupName="myGroupName" :isMultiSelect="${mockData.isMultiSelect}" value="value1" />`;
|
||||||
parentComponentTemplate += `<baseInputButtonWrapper v-model="value" groupName="myGroupName" :isMultiSelect="${mockData.isMultiSelect}" value="value2" />`;
|
parentComponentTemplate += `<baseInputButtonWrapper v-model="value" groupName="myGroupName" :isMultiSelect="${mockData.isMultiSelect}" value="value2" />`;
|
||||||
parentComponentTemplate += `</div>`;
|
parentComponentTemplate += `</div>`;
|
||||||
const wrapper = mount(
|
const wrapper = mount({
|
||||||
{
|
data() {
|
||||||
data() {
|
return {
|
||||||
return {
|
value: mockData.initialValue ?? (mockData.isMultiSelect ? [] : ""),
|
||||||
value: mockData.initialValue ?? (mockData.isMultiSelect ? [] : ""),
|
$route: {
|
||||||
$route: {
|
query: {
|
||||||
query: {
|
fmgPage: "myPage",
|
||||||
fmgPage: "myPage",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
},
|
||||||
},
|
};
|
||||||
template: parentComponentTemplate,
|
|
||||||
components: { baseInputButtonWrapper },
|
|
||||||
},
|
},
|
||||||
{}
|
template: parentComponentTemplate,
|
||||||
);
|
components: { baseInputButtonWrapper },
|
||||||
|
});
|
||||||
|
|
||||||
return { wrapper };
|
return { wrapper };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -123,9 +123,8 @@ export default {
|
||||||
answerString;
|
answerString;
|
||||||
// mark this question as suppressed if needed (question-chain uses this)
|
// mark this question as suppressed if needed (question-chain uses this)
|
||||||
if (answeredQuestion.suppressThisQuestion) {
|
if (answeredQuestion.suppressThisQuestion) {
|
||||||
glass.questions[
|
glass.questions[answeredQuestion.questionNum - 1].suppressThisQuestion =
|
||||||
answeredQuestion.questionNum - 1
|
true;
|
||||||
].suppressThisQuestion = true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import {
|
||||||
updateSessionIdCookie,
|
updateSessionIdCookie,
|
||||||
deleteFunnelCookie,
|
deleteFunnelCookie,
|
||||||
getAffiliateCookies,
|
getAffiliateCookies,
|
||||||
|
setupAdvertiserTracking,
|
||||||
} from "@/helpers/heritage-integration/cookie-helper";
|
} from "@/helpers/heritage-integration/cookie-helper";
|
||||||
import { loadSessionIfPresent, saveSession } from "@/helpers/heritage-integration/order-helper";
|
import { loadSessionIfPresent, saveSession } from "@/helpers/heritage-integration/order-helper";
|
||||||
import {
|
import {
|
||||||
|
|
@ -103,7 +104,7 @@ const routes = [
|
||||||
if (affiliateCookies != null && affiliateCookies.length > 0) {
|
if (affiliateCookies != null && affiliateCookies.length > 0) {
|
||||||
store.commit(storeMutations.UPDATE_AFFILIATE_COOKIES, affiliateCookies);
|
store.commit(storeMutations.UPDATE_AFFILIATE_COOKIES, affiliateCookies);
|
||||||
}
|
}
|
||||||
|
setupAdvertiserTracking();
|
||||||
const loadSessionResponse = await loadSessionIfPresent(
|
const loadSessionResponse = await loadSessionIfPresent(
|
||||||
to.query.isInsurance != null
|
to.query.isInsurance != null
|
||||||
? to.query.isInsurance == "true"
|
? to.query.isInsurance == "true"
|
||||||
|
|
@ -129,7 +130,7 @@ const routes = [
|
||||||
// Reroute around pages that should not be available.
|
// Reroute around pages that should not be available.
|
||||||
|
|
||||||
// Exception 1: Integrated Users should not see vehicle or quote pages.
|
// Exception 1: Integrated Users should not see vehicle or quote pages.
|
||||||
if (store.getters.requiresVerifiedRedirecting) {
|
if (store.getters.payment?.insuranceCoverage?.isVerified) {
|
||||||
if (to.query.fmgPage === fmgPageValues.VEHICLE) {
|
if (to.query.fmgPage === fmgPageValues.VEHICLE) {
|
||||||
to.query.fmgPage = fmgPageValues.VEHICLE_DAMAGE;
|
to.query.fmgPage = fmgPageValues.VEHICLE_DAMAGE;
|
||||||
} else if (
|
} else if (
|
||||||
|
|
@ -286,7 +287,7 @@ router.afterEach(async (to, from) => {
|
||||||
store.commit(storeMutations.UPDATE_LAST_PAGE_VISITED, to.name);
|
store.commit(storeMutations.UPDATE_LAST_PAGE_VISITED, to.name);
|
||||||
|
|
||||||
// If saving on navigation is requested, check for saved SessionId or EmailAddress to determine if saving is appropriate
|
// If saving on navigation is requested, check for saved SessionId or EmailAddress to determine if saving is appropriate
|
||||||
if (eval(to.params.isSavingNavigation)) {
|
if (eval(window.history.state.isSavingNavigation)) {
|
||||||
if (
|
if (
|
||||||
store.getters.applicationUser.savedSessionId ||
|
store.getters.applicationUser.savedSessionId ||
|
||||||
store.getters.order.customer?.emailAddress
|
store.getters.order.customer?.emailAddress
|
||||||
|
|
@ -394,7 +395,7 @@ async function navigate(
|
||||||
destinationFmgPageValue,
|
destinationFmgPageValue,
|
||||||
Object.keys(optionalPageData).length > 0
|
Object.keys(optionalPageData).length > 0
|
||||||
? optionalPageData
|
? optionalPageData
|
||||||
: existingPageDataForPage ?? {}
|
: (existingPageDataForPage ?? {})
|
||||||
);
|
);
|
||||||
|
|
||||||
optionalParams.isSavingNavigation = isSavingNavigation;
|
optionalParams.isSavingNavigation = isSavingNavigation;
|
||||||
|
|
@ -430,7 +431,7 @@ async function navigate(
|
||||||
router.push({
|
router.push({
|
||||||
name: "root",
|
name: "root",
|
||||||
query: Object.assign(optionalQuery, queryStringsObject),
|
query: Object.assign(optionalQuery, queryStringsObject),
|
||||||
params: optionalParams,
|
state: optionalParams,
|
||||||
});
|
});
|
||||||
} else if (matchingScenarioMap.destinationUrl !== undefined) {
|
} else if (matchingScenarioMap.destinationUrl !== undefined) {
|
||||||
navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery);
|
navigateToUrl(matchingScenarioMap.destinationUrl, optionalQuery);
|
||||||
|
|
@ -524,7 +525,7 @@ async function DisplayPageError() {
|
||||||
// we use the pageError querystring as a counter to how many times a user has experienced an error and been routed here.
|
// we use the pageError querystring as a counter to how many times a user has experienced an error and been routed here.
|
||||||
// once they receive more than 1 pageerrors, we'll reset their state to hopefully correct any issues they may be having.
|
// once they receive more than 1 pageerrors, we'll reset their state to hopefully correct any issues they may be having.
|
||||||
var navPage = fmgPageValues.VEHICLE;
|
var navPage = fmgPageValues.VEHICLE;
|
||||||
if (store.getters.requiresVerifiedRedirecting) {
|
if (store.getters.payment?.insuranceCoverage?.isVerified) {
|
||||||
navPage = fmgPageValues.VEHICLE_DAMAGE;
|
navPage = fmgPageValues.VEHICLE_DAMAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -590,7 +591,7 @@ async function runExperiments(nextPage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRedirectedStartPage() {
|
function getRedirectedStartPage() {
|
||||||
if (store.getters.requiresVerifiedRedirecting) {
|
if (store.getters.payment?.insuranceCoverage?.isVerified) {
|
||||||
return fmgPageValues.VEHICLE_DAMAGE;
|
return fmgPageValues.VEHICLE_DAMAGE;
|
||||||
} else {
|
} else {
|
||||||
return funnelStartPageName;
|
return funnelStartPageName;
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,9 @@ html {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
&.btn.btn-primary:focus-visible {
|
&.btn.btn-primary:focus-visible {
|
||||||
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $gray-700;
|
box-shadow:
|
||||||
|
0 0 0 3px $white,
|
||||||
|
0 0 0 5.5px $gray-700;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,13 +75,17 @@ export default {
|
||||||
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
background: linear-gradient(270deg, $blue 0%, $blue-800 100%);
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
}
|
}
|
||||||
&:focus, // Mouse, touch, stylus focus
|
&:focus, // Mouse, touch, stylus focus
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
// Keyboard focus for accessibility
|
// Keyboard focus for accessibility
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
color: $white;
|
color: $white;
|
||||||
background: linear-gradient(270deg, rgba(6, 87, 124, 1) 0%, rgba(6, 87, 124, 1) 100%);
|
background: linear-gradient(270deg, rgba(6, 87, 124, 1) 0%, rgba(6, 87, 124, 1) 100%);
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +103,9 @@ export default {
|
||||||
&.has-loader {
|
&.has-loader {
|
||||||
color: $white;
|
color: $white;
|
||||||
background: $blue-700;
|
background: $blue-700;
|
||||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
&.delay {
|
&.delay {
|
||||||
|
|
@ -124,7 +130,9 @@ export default {
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
// Keyboard focus for accessibility
|
// Keyboard focus for accessibility
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: 0 0 0 3px $white, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px $white,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
color: $white;
|
color: $white;
|
||||||
@include blue-gradient;
|
@include blue-gradient;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ describe("checkbox.vue", () => {
|
||||||
let { wrapper } = setupMocks({
|
let { wrapper } = setupMocks({
|
||||||
mountOptionsMockData: {
|
mountOptionsMockData: {
|
||||||
propsData: {
|
propsData: {
|
||||||
|
groupName: "checkbox-button-test",
|
||||||
buttonLabel: "label text",
|
buttonLabel: "label text",
|
||||||
value: "test value",
|
value: "test value",
|
||||||
},
|
},
|
||||||
|
|
@ -42,7 +43,15 @@ describe("checkbox.vue", () => {
|
||||||
|
|
||||||
it("Should have correct screenreader-only text", async () => {
|
it("Should have correct screenreader-only text", async () => {
|
||||||
// Act
|
// Act
|
||||||
let { wrapper } = setupMocks({});
|
let { wrapper } = setupMocks({
|
||||||
|
mountOptionsMockData: {
|
||||||
|
propsData: {
|
||||||
|
groupName: "checkbox-button-test",
|
||||||
|
buttonLabel: "label text",
|
||||||
|
value: "test value",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// Arrange
|
// Arrange
|
||||||
await wrapper.setProps({
|
await wrapper.setProps({
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
&:checked:focus + .list-button-horizontal-content {
|
&:checked:focus + .list-button-horizontal-content {
|
||||||
box-shadow: 0 0 0 3px, 0 0 0 5.5px $blue-700;
|
box-shadow:
|
||||||
|
0 0 0 3px,
|
||||||
|
0 0 0 5.5px $blue-700;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:checked + .list-button-horizontal-content p:first-child {
|
&:checked + .list-button-horizontal-content p:first-child {
|
||||||
|
|
|
||||||
|
|
@ -295,6 +295,12 @@ describe("list-button.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({ mockData }) {
|
function setupMocks({ mockData }) {
|
||||||
|
// Add in group name to avoid vee-validate failures
|
||||||
|
if (!mockData.propsData) {
|
||||||
|
mockData.propsData = { groupName: "group-name" };
|
||||||
|
} else if (!mockData.propsData.groupName) {
|
||||||
|
mockData.propsData.groupName = "group-name";
|
||||||
|
}
|
||||||
const wrapper = mount(listButton, {
|
const wrapper = mount(listButton, {
|
||||||
...mockData,
|
...mockData,
|
||||||
mixins: [inputButtonWrapperMixin],
|
mixins: [inputButtonWrapperMixin],
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,12 @@ describe("radio.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function setupMocks({ mountOptionsMockData = {} }) {
|
function setupMocks({ mountOptionsMockData = {} }) {
|
||||||
|
// Add in group name to avoid vee-validate failures
|
||||||
|
if (!mountOptionsMockData.propsData) {
|
||||||
|
mountOptionsMockData.propsData = { groupName: "group-name" };
|
||||||
|
} else if (!mountOptionsMockData.propsData.groupName) {
|
||||||
|
mountOptionsMockData.propsData.groupName = "group-name";
|
||||||
|
}
|
||||||
const wrapper = mount(radio, {
|
const wrapper = mount(radio, {
|
||||||
...mountOptionsMockData,
|
...mountOptionsMockData,
|
||||||
mixins: [inputButtonWrapperMixin],
|
mixins: [inputButtonWrapperMixin],
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue