Merge pull request #1259 from Safelite/feature/CSR-1370
Feature/csr 1370
This commit is contained in:
commit
efc21e118f
11 changed files with 2506 additions and 188 deletions
5
src/constants/package-names.js
Normal file
5
src/constants/package-names.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
export const packageNames = {
|
||||||
|
TIER_ONE: "TierOne",
|
||||||
|
TIER_TWO: "TierTwo",
|
||||||
|
TIER_THREE: "TierThree",
|
||||||
|
};
|
||||||
239
src/helpers/service-package-helper.js
Normal file
239
src/helpers/service-package-helper.js
Normal file
|
|
@ -0,0 +1,239 @@
|
||||||
|
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||||
|
import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";
|
||||||
|
import { packageNames } from "@/constants/package-names";
|
||||||
|
|
||||||
|
export function containsLineItemWithPartType(typeToFind, itemsToSearch) {
|
||||||
|
const partTypeMatches = findLineItemsWithPartType(typeToFind, itemsToSearch);
|
||||||
|
return !!partTypeMatches?.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function findLineItemsWithPartType(typeToFind, itemsToSearch) {
|
||||||
|
const partTypeMatches = itemsToSearch?.filter(
|
||||||
|
(lineItem) => lineItem.partType.toUpperCase() === typeToFind.toUpperCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
return partTypeMatches;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getVapsLineItems(availableLineItems, vapTypes) {
|
||||||
|
let lineItems = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < vapTypes.length; i++) {
|
||||||
|
lineItems.push(...findLineItemsWithPartType(vapTypes[i], availableLineItems));
|
||||||
|
}
|
||||||
|
|
||||||
|
return lineItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function containsGlassPieceWithLocation(locationToFind, glassPiecesToSearch) {
|
||||||
|
const glassLocationMatches = glassPiecesToSearch?.filter(
|
||||||
|
(glassPiece) => glassPiece.glassLocation.toUpperCase() === locationToFind.toUpperCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
return !!glassLocationMatches?.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getAvailablePackages(glassToReplace, availableLineItems, isRepair) {
|
||||||
|
let tierOneVaps = getPackageContents(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
packageNames.TIER_ONE
|
||||||
|
);
|
||||||
|
let tierTwoVaps = getPackageContents(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
packageNames.TIER_TWO
|
||||||
|
);
|
||||||
|
let tierThreeVaps = getPackageContents(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
packageNames.TIER_THREE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (tierTwoVaps.length === 0) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
packageName: packageNames.TIER_ONE,
|
||||||
|
vapTypes: tierOneVaps,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
packageName: packageNames.TIER_THREE,
|
||||||
|
vapTypes: tierThreeVaps,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
packageName: packageNames.TIER_ONE,
|
||||||
|
vapTypes: tierOneVaps,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
packageName: packageNames.TIER_TWO,
|
||||||
|
vapTypes: tierTwoVaps,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
packageName: packageNames.TIER_THREE,
|
||||||
|
vapTypes: tierThreeVaps,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPackageContents(glassToReplace, availableLineItems, isRepair, targetTier) {
|
||||||
|
let vaps = [];
|
||||||
|
|
||||||
|
if (shouldFrontWipersBeAvailable(glassToReplace, availableLineItems, isRepair, targetTier)) {
|
||||||
|
vaps.push(partTypeStrings.FRONT_WIPER);
|
||||||
|
}
|
||||||
|
if (shouldRearWipersBeAvailable(glassToReplace, availableLineItems, isRepair, targetTier)) {
|
||||||
|
vaps.push(partTypeStrings.REAR_WIPER);
|
||||||
|
}
|
||||||
|
if (shouldRainDefenseBeAvailable(glassToReplace, availableLineItems, isRepair, targetTier)) {
|
||||||
|
vaps.push(partTypeStrings.RAIN_DEFENSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function shouldFrontWipersBeAvailable(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
targetTier
|
||||||
|
) {
|
||||||
|
const frontWiperIsAvailable = containsLineItemWithPartType(
|
||||||
|
partTypeStrings.FRONT_WIPER,
|
||||||
|
availableLineItems
|
||||||
|
);
|
||||||
|
const isFrontWindshieldTask =
|
||||||
|
isRepair || containsGlassPieceWithLocation(glassLocations.WINDSHIELD, glassToReplace);
|
||||||
|
|
||||||
|
switch (targetTier) {
|
||||||
|
case packageNames.TIER_TWO:
|
||||||
|
return frontWiperIsAvailable && isFrontWindshieldTask;
|
||||||
|
case packageNames.TIER_THREE:
|
||||||
|
return frontWiperIsAvailable;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function shouldRearWipersBeAvailable(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
targetTier
|
||||||
|
) {
|
||||||
|
const rearWiperIsAvailable = containsLineItemWithPartType(
|
||||||
|
partTypeStrings.REAR_WIPER,
|
||||||
|
availableLineItems
|
||||||
|
);
|
||||||
|
const frontWiperIsAvailable = containsLineItemWithPartType(
|
||||||
|
partTypeStrings.FRONT_WIPER,
|
||||||
|
availableLineItems
|
||||||
|
);
|
||||||
|
const isRearWindshieldTask = containsGlassPieceWithLocation(
|
||||||
|
glassLocations.REAR,
|
||||||
|
glassToReplace
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (targetTier) {
|
||||||
|
case packageNames.TIER_TWO:
|
||||||
|
return rearWiperIsAvailable && isRearWindshieldTask;
|
||||||
|
case packageNames.TIER_THREE:
|
||||||
|
return rearWiperIsAvailable && (isRearWindshieldTask || !frontWiperIsAvailable);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function shouldRainDefenseBeAvailable(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
targetTier
|
||||||
|
) {
|
||||||
|
const isTierThree = targetTier === packageNames.TIER_THREE;
|
||||||
|
const frontWipersInTierTwo = shouldFrontWipersBeAvailable(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
packageNames.TIER_TWO
|
||||||
|
);
|
||||||
|
const frontWipersInTierThree = shouldFrontWipersBeAvailable(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
packageNames.TIER_THREE
|
||||||
|
);
|
||||||
|
const rearWipersInTierTwo = shouldRearWipersBeAvailable(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
packageNames.TIER_TWO
|
||||||
|
);
|
||||||
|
|
||||||
|
return isTierThree && !(rearWipersInTierTwo && !frontWipersInTierTwo && frontWipersInTierThree);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLowestTierForType(glassToReplace, availableLineItems, isRepair, partType) {
|
||||||
|
const packages = getAvailablePackages(glassToReplace, availableLineItems, isRepair);
|
||||||
|
for (let i = 0; i < packages.length; i++) {
|
||||||
|
for (let j = 0; j < packages[i].vapTypes.length; j++) {
|
||||||
|
if (packages[i].vapTypes[j].toUpperCase() === partType.toUpperCase()) {
|
||||||
|
return packages[i].packageName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return packageNames.TIER_ONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getHighestRequiredTier(glassToReplace, availableLineItems, isRepair, vaps) {
|
||||||
|
let currentHighestTier = packageNames.TIER_ONE;
|
||||||
|
for (let i = 0; i < vaps.length; i++) {
|
||||||
|
const lowestTierForItem = getLowestTierForType(
|
||||||
|
glassToReplace,
|
||||||
|
availableLineItems,
|
||||||
|
isRepair,
|
||||||
|
vaps[i].partType
|
||||||
|
);
|
||||||
|
|
||||||
|
currentHighestTier = maxTier(currentHighestTier, lowestTierForItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentHighestTier;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getHighestFullySatisfiedTier(glassToReplace, availableLineItems, isRepair, vaps) {
|
||||||
|
const packages = getAvailablePackages(glassToReplace, availableLineItems, isRepair);
|
||||||
|
let highestSatisfiedPackage = packageNames.TIER_ONE;
|
||||||
|
|
||||||
|
for (let i = 0; i < packages.length; i++) {
|
||||||
|
let isPackageSatisfied = true;
|
||||||
|
for (let j = 0; j < packages[i].vapTypes.length; j++) {
|
||||||
|
isPackageSatisfied =
|
||||||
|
isPackageSatisfied && containsLineItemWithPartType(packages[i].vapTypes[j], vaps);
|
||||||
|
}
|
||||||
|
if (isPackageSatisfied) {
|
||||||
|
highestSatisfiedPackage = packages[i].packageName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return highestSatisfiedPackage;
|
||||||
|
}
|
||||||
|
|
||||||
|
function maxTier(tierA, tierB) {
|
||||||
|
if (tierA === packageNames.TIER_THREE || tierB === packageNames.TIER_THREE) {
|
||||||
|
return packageNames.TIER_THREE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tierA === packageNames.TIER_TWO || tierB === packageNames.TIER_TWO) {
|
||||||
|
return packageNames.TIER_TWO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return packageNames.TIER_ONE;
|
||||||
|
}
|
||||||
1023
src/helpers/service-package-helper.spec.js
Normal file
1023
src/helpers/service-package-helper.spec.js
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -18,12 +18,17 @@ import { processIfStatements } from "@/helpers/cms-content-helper";
|
||||||
import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";
|
import { damageLocationsSelected as glassLocations } from "@/constants/damage-locations-selected";
|
||||||
import servicePackageRadio from "./service-package-radio/service-package-radio";
|
import servicePackageRadio from "./service-package-radio/service-package-radio";
|
||||||
import { partTypeStrings } from "@/constants/part-type-strings";
|
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||||
|
import { packageNames } from "@/constants/package-names";
|
||||||
const packageNames = {
|
import {
|
||||||
TIER_ONE: "TierOne",
|
shouldFrontWipersBeAvailable,
|
||||||
TIER_TWO: "TierTwo",
|
shouldRearWipersBeAvailable,
|
||||||
TIER_THREE: "TierThree",
|
shouldRainDefenseBeAvailable,
|
||||||
};
|
getAvailablePackages,
|
||||||
|
getHighestRequiredTier,
|
||||||
|
getPackageContents,
|
||||||
|
containsLineItemWithPartType,
|
||||||
|
findLineItemsWithPartType,
|
||||||
|
} from "@/helpers/service-package-helper";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "servicePackageQuestion",
|
name: "servicePackageQuestion",
|
||||||
|
|
@ -65,11 +70,17 @@ export default {
|
||||||
if (!cmsAnswersContent) {
|
if (!cmsAnswersContent) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!this.shouldDisplayTierTwoPackage) {
|
|
||||||
cmsAnswersContent = cmsAnswersContent.filter(
|
const availablePackages = getAvailablePackages(
|
||||||
(answer) => answer.Name != packageNames.TIER_TWO
|
this.glassToReplace,
|
||||||
);
|
this.nullSafeAvailableLineItems,
|
||||||
}
|
this.isRepair
|
||||||
|
);
|
||||||
|
|
||||||
|
cmsAnswersContent = cmsAnswersContent.filter((answer) =>
|
||||||
|
availablePackages.some((tier) => answer.Name === tier.packageName)
|
||||||
|
);
|
||||||
|
|
||||||
const modifiedAnswers = cmsAnswersContent.map((answer) => ({
|
const modifiedAnswers = cmsAnswersContent.map((answer) => ({
|
||||||
value: answer.Name,
|
value: answer.Name,
|
||||||
buttonLabel: this.getHeaderTextFromCms(answer.SubWidgetName),
|
buttonLabel: this.getHeaderTextFromCms(answer.SubWidgetName),
|
||||||
|
|
@ -81,67 +92,56 @@ export default {
|
||||||
return modifiedAnswers;
|
return modifiedAnswers;
|
||||||
},
|
},
|
||||||
isRecalibrationOnOrder() {
|
isRecalibrationOnOrder() {
|
||||||
return this.lineItemsContainsPartType(partTypeStrings.RECALIBRATION);
|
return containsLineItemWithPartType(
|
||||||
|
partTypeStrings.RECALIBRATION,
|
||||||
|
this.nullSafeAvailableLineItems
|
||||||
|
);
|
||||||
},
|
},
|
||||||
frontWipersApplicableForTierTwo() {
|
frontWipersApplicableForTierTwo() {
|
||||||
const frontWipersAreAvailable = this.lineItemsContainsPartType(
|
return shouldFrontWipersBeAvailable(
|
||||||
partTypeStrings.FRONT_WIPER
|
this.glassToReplace,
|
||||||
|
this.nullSafeAvailableLineItems,
|
||||||
|
this.isRepair,
|
||||||
|
packageNames.TIER_TWO
|
||||||
);
|
);
|
||||||
const isRepair = this.$store.getters.order.damage.isRepair;
|
|
||||||
const glassToReplaceContainsWindshield = this.glassToReplaceContainsGlassLocation(
|
|
||||||
glassLocations.WINDSHIELD
|
|
||||||
);
|
|
||||||
if (frontWipersAreAvailable) {
|
|
||||||
if (isRepair) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if (glassToReplaceContainsWindshield) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
rearWiperApplicableForTierTwo() {
|
rearWiperApplicableForTierTwo() {
|
||||||
const rearWiperIsAvailable = this.lineItemsContainsPartType(partTypeStrings.REAR_WIPER);
|
return shouldRearWipersBeAvailable(
|
||||||
return (
|
this.glassToReplace,
|
||||||
this.glassToReplaceContainsGlassLocation(glassLocations.REAR) &&
|
this.nullSafeAvailableLineItems,
|
||||||
rearWiperIsAvailable
|
this.isRepair,
|
||||||
|
packageNames.TIER_TWO
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
frontWipersApplicableForTierThree() {
|
frontWipersApplicableForTierThree() {
|
||||||
const frontWipersAreAvailable = this.lineItemsContainsPartType(
|
return shouldFrontWipersBeAvailable(
|
||||||
partTypeStrings.FRONT_WIPER
|
this.glassToReplace,
|
||||||
|
this.nullSafeAvailableLineItems,
|
||||||
|
this.isRepair,
|
||||||
|
packageNames.TIER_THREE
|
||||||
);
|
);
|
||||||
return frontWipersAreAvailable;
|
|
||||||
},
|
},
|
||||||
rearWiperApplicableForTierThree() {
|
rearWiperApplicableForTierThree() {
|
||||||
const rearWiperIsAvailable = this.lineItemsContainsPartType(partTypeStrings.REAR_WIPER);
|
return shouldRearWipersBeAvailable(
|
||||||
const frontWipersAreAvailable = this.lineItemsContainsPartType(
|
this.glassToReplace,
|
||||||
partTypeStrings.FRONT_WIPER
|
this.nullSafeAvailableLineItems,
|
||||||
);
|
this.isRepair,
|
||||||
return (
|
packageNames.TIER_THREE
|
||||||
rearWiperIsAvailable &&
|
|
||||||
(this.glassToReplaceContainsGlassLocation(glassLocations.REAR) ||
|
|
||||||
!frontWipersAreAvailable)
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
rainDefenseApplicableForTierThree() {
|
rainDefenseApplicableForTierThree() {
|
||||||
if (
|
return shouldRainDefenseBeAvailable(
|
||||||
this.rearWiperApplicableForTierTwo &&
|
this.glassToReplace,
|
||||||
!this.frontWipersApplicableForTierTwo &&
|
this.nullSafeAvailableLineItems,
|
||||||
this.frontWipersApplicableForTierThree
|
this.isRepair,
|
||||||
) {
|
packageNames.TIER_THREE
|
||||||
return false;
|
);
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
shouldDisplayTierTwoPackage() {
|
glassToReplace() {
|
||||||
return this.frontWipersApplicableForTierTwo || this.rearWiperApplicableForTierTwo;
|
return this.$store.getters.order.damage.glassToReplace;
|
||||||
|
},
|
||||||
|
isRepair() {
|
||||||
|
return this.$store.getters.order.damage.isRepair;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -170,65 +170,31 @@ export default {
|
||||||
: baseMixin.methods.getTierOnePackagePrice(
|
: baseMixin.methods.getTierOnePackagePrice(
|
||||||
baseMixin.methods.filterOutFees(this.nullSafeAvailableLineItems)
|
baseMixin.methods.filterOutFees(this.nullSafeAvailableLineItems)
|
||||||
);
|
);
|
||||||
if (packageName === packageNames.TIER_TWO) {
|
|
||||||
priceFloat += this.getTierTwoPackageVapsPrice();
|
priceFloat += this.getVapsPrice(packageName);
|
||||||
} else if (packageName === packageNames.TIER_THREE) {
|
|
||||||
priceFloat += this.getTierThreePackageVapsPrice();
|
|
||||||
}
|
|
||||||
return priceFloat;
|
return priceFloat;
|
||||||
},
|
},
|
||||||
getTierTwoPackageVapsPrice() {
|
getVapsPrice(packageName) {
|
||||||
let vapsPrice = 0;
|
const vapsItems = this.getVapsLineItemsForSelectedPackage(packageName);
|
||||||
const priceFrontWipers = this.frontWipersApplicableForTierTwo;
|
|
||||||
const priceRearWipers = this.rearWiperApplicableForTierTwo;
|
let price = 0;
|
||||||
this.nullSafeAvailableLineItems.forEach((item) => {
|
|
||||||
if (
|
vapsItems.forEach((item) => {
|
||||||
(priceFrontWipers &&
|
price += baseMixin.methods.getTotalLineItemPrice(item);
|
||||||
item.partType.toUpperCase() === partTypeStrings.FRONT_WIPER) ||
|
|
||||||
(priceRearWipers && item.partType.toUpperCase() === partTypeStrings.REAR_WIPER)
|
|
||||||
) {
|
|
||||||
vapsPrice += baseMixin.methods.getTotalLineItemPrice(item);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return vapsPrice;
|
|
||||||
},
|
return price;
|
||||||
getTierThreePackageVapsPrice() {
|
|
||||||
let vapsPrice = 0;
|
|
||||||
const priceFrontWipers = this.frontWipersApplicableForTierThree;
|
|
||||||
const priceRearWipers = this.rearWiperApplicableForTierThree;
|
|
||||||
const priceRainDefense = this.rainDefenseApplicableForTierThree;
|
|
||||||
this.nullSafeAvailableLineItems.forEach((item) => {
|
|
||||||
if (
|
|
||||||
(priceFrontWipers &&
|
|
||||||
item.partType.toUpperCase() === partTypeStrings.FRONT_WIPER) ||
|
|
||||||
(priceRearWipers &&
|
|
||||||
item.partType.toUpperCase() === partTypeStrings.REAR_WIPER) ||
|
|
||||||
(priceRainDefense &&
|
|
||||||
item.partType.toUpperCase() === partTypeStrings.RAIN_DEFENSE)
|
|
||||||
) {
|
|
||||||
vapsPrice += baseMixin.methods.getTotalLineItemPrice(item);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return vapsPrice;
|
|
||||||
},
|
},
|
||||||
selectDefaultPackage() {
|
selectDefaultPackage() {
|
||||||
const vapsFromStore = this.$store.getters.lineItems.vaps;
|
const vapsFromStore = this.$store.getters.lineItems.vaps ?? [];
|
||||||
let lowestTierForPackage = packageNames.TIER_ONE;
|
|
||||||
if (vapsFromStore?.length > 0) {
|
this.selectedPackageName = getHighestRequiredTier(
|
||||||
vapsFromStore.every((vapsItem) => {
|
this.glassToReplace,
|
||||||
let lowestTierForThisItem = this.getLowestTierForThisItem(vapsItem);
|
this.nullSafeAvailableLineItems,
|
||||||
if (lowestTierForThisItem === packageNames.TIER_THREE) {
|
this.isRepair,
|
||||||
lowestTierForPackage = packageNames.TIER_THREE;
|
vapsFromStore
|
||||||
return false;
|
);
|
||||||
} else if (lowestTierForThisItem === packageNames.TIER_TWO) {
|
|
||||||
lowestTierForPackage = packageNames.TIER_TWO;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.selectedPackageName = lowestTierForPackage;
|
|
||||||
},
|
},
|
||||||
allGlassPartsAndSupportingItemsHavePrices(lineItems) {
|
allGlassPartsAndSupportingItemsHavePrices(lineItems) {
|
||||||
if (lineItems?.glassParts) {
|
if (lineItems?.glassParts) {
|
||||||
|
|
@ -254,63 +220,22 @@ export default {
|
||||||
(lineItem.sellingPrice == null || lineItem.sellingPrice == 0)
|
(lineItem.sellingPrice == null || lineItem.sellingPrice == 0)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
getLowestTierForThisItem(vapsItem) {
|
|
||||||
let lowestTierForThisItem = null;
|
|
||||||
switch (vapsItem.partType) {
|
|
||||||
case partTypeStrings.FRONT_WIPER:
|
|
||||||
if (this.frontWipersApplicableForTierThree) {
|
|
||||||
lowestTierForThisItem = packageNames.TIER_THREE;
|
|
||||||
}
|
|
||||||
if (this.frontWipersApplicableForTierTwo) {
|
|
||||||
lowestTierForThisItem = packageNames.TIER_TWO;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case partTypeStrings.REAR_WIPER:
|
|
||||||
if (this.rearWiperApplicableForTierThree) {
|
|
||||||
lowestTierForThisItem = packageNames.TIER_THREE;
|
|
||||||
}
|
|
||||||
if (this.rearWiperApplicableForTierTwo) {
|
|
||||||
lowestTierForThisItem = packageNames.TIER_TWO;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case partTypeStrings.RAIN_DEFENSE:
|
|
||||||
if (this.rainDefenseApplicableForTierThree) {
|
|
||||||
lowestTierForThisItem = packageNames.TIER_THREE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return lowestTierForThisItem;
|
|
||||||
},
|
|
||||||
getVapsLineItemsForSelectedPackage(packageName) {
|
getVapsLineItemsForSelectedPackage(packageName) {
|
||||||
const vapsLineItemsForSelectedPackage = [];
|
const packageContentTypes = getPackageContents(
|
||||||
if (packageName === packageNames.TIER_TWO) {
|
this.glassToReplace,
|
||||||
if (this.frontWipersApplicableForTierTwo) {
|
this.nullSafeAvailableLineItems,
|
||||||
vapsLineItemsForSelectedPackage.push(
|
this.isRepair,
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.FRONT_WIPER)
|
packageName
|
||||||
);
|
);
|
||||||
}
|
|
||||||
if (this.rearWiperApplicableForTierTwo) {
|
let vapsLineItemsForSelectedPackage = [];
|
||||||
vapsLineItemsForSelectedPackage.push(
|
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.REAR_WIPER)
|
packageContentTypes.forEach((vapType) => {
|
||||||
);
|
vapsLineItemsForSelectedPackage.push(
|
||||||
}
|
...findLineItemsWithPartType(vapType, this.nullSafeAvailableLineItems)
|
||||||
} else if (packageName === packageNames.TIER_THREE) {
|
);
|
||||||
if (this.frontWipersApplicableForTierThree) {
|
});
|
||||||
vapsLineItemsForSelectedPackage.push(
|
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.FRONT_WIPER)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (this.rearWiperApplicableForTierThree) {
|
|
||||||
vapsLineItemsForSelectedPackage.push(
|
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.REAR_WIPER)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (this.rainDefenseApplicableForTierThree) {
|
|
||||||
vapsLineItemsForSelectedPackage.push(
|
|
||||||
...this.getLineItemsContainingPartType(partTypeStrings.RAIN_DEFENSE)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vapsLineItemsForSelectedPackage;
|
return vapsLineItemsForSelectedPackage;
|
||||||
},
|
},
|
||||||
getCustomValueFromString(str) {
|
getCustomValueFromString(str) {
|
||||||
|
|
@ -331,23 +256,6 @@ export default {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getLineItemsContainingPartType(partType) {
|
|
||||||
const partTypeMatches = this.nullSafeAvailableLineItems.filter(
|
|
||||||
(lineItem) => lineItem.partType.toUpperCase() === partType
|
|
||||||
);
|
|
||||||
return partTypeMatches;
|
|
||||||
},
|
|
||||||
lineItemsContainsPartType(partType) {
|
|
||||||
const partTypeMatches = this.getLineItemsContainingPartType(partType);
|
|
||||||
return !!partTypeMatches.length;
|
|
||||||
},
|
|
||||||
glassToReplaceContainsGlassLocation(glassLocation) {
|
|
||||||
const glassLocationMatches =
|
|
||||||
this.$store.getters.order.damage.glassToReplace?.filter(
|
|
||||||
(glassToReplace) => glassToReplace.glassLocation === glassLocation
|
|
||||||
) ?? [];
|
|
||||||
return !!glassLocationMatches.length;
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
buttonQuestion,
|
buttonQuestion,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,12 @@
|
||||||
:cmsWidgetName="headerCmsWidgetName"
|
:cmsWidgetName="headerCmsWidgetName"
|
||||||
typeStyle="body small bold dark"
|
typeStyle="body small bold dark"
|
||||||
margin="mt-0" />
|
margin="mt-0" />
|
||||||
<textLink linkType="textSmall" text="Edit" class="ml-auto" @click-event="linkClicked" />
|
<textLink
|
||||||
|
linkType="textSmall"
|
||||||
|
text="Edit"
|
||||||
|
class="ml-auto"
|
||||||
|
@click-event="linkClicked"
|
||||||
|
href="javascript:void(0)" />
|
||||||
</div>
|
</div>
|
||||||
<div class="small" v-for="item in content" :key="item" data-test="contentLine">
|
<div class="small" v-for="item in content" :key="item" data-test="contentLine">
|
||||||
{{ item }}
|
{{ item }}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,969 @@
|
||||||
|
import { shallowMount } from "@vue/test-utils";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import servicePackageReview from "@/layouts/review/review-sections/service-package-review/service-package-review";
|
||||||
|
|
||||||
|
import { packageNames } from "@/constants/package-names";
|
||||||
|
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||||
|
import { damageLocationsSelected as glassConstants } from "@/constants/damage-locations-selected";
|
||||||
|
|
||||||
|
const testConstants = {
|
||||||
|
cmsPropValues: {
|
||||||
|
servicePackageOptionsCmsName: "ServicePackageTitle",
|
||||||
|
defaultPackageItemsCmsName: "DefaultPackageItemDescriptions",
|
||||||
|
vapsItemsCmsName: "VapsItemDescriptions",
|
||||||
|
},
|
||||||
|
widgetNames: {
|
||||||
|
tierOneTitle: "EconomyServiceTitle",
|
||||||
|
tierTwoTitle: "StandardServiceTitle",
|
||||||
|
tierThreeTitle: "PremiumServiceTitle",
|
||||||
|
},
|
||||||
|
defaultItemCopy: {
|
||||||
|
itemOne: "Item Description 1",
|
||||||
|
itemTwo: "Item Description 2",
|
||||||
|
itemThree: "Item Description 3",
|
||||||
|
itemFour: "Item Description 4",
|
||||||
|
defaultItemCopyArray: ["Item Description 1", "Item Description 2", "Item Description 3"],
|
||||||
|
},
|
||||||
|
vapsCopy: {
|
||||||
|
frontWiperCopy: "Front Wiper copy",
|
||||||
|
rearWiperCopy: "Rear Wiper copy",
|
||||||
|
rainDefenseCopy: "Rain defense copy",
|
||||||
|
},
|
||||||
|
parts: {
|
||||||
|
frontWiperPart: {
|
||||||
|
partNumber: "SBB16",
|
||||||
|
description: "SAFELITE BEAM BLADE 16",
|
||||||
|
partType: "FRONT WIPER",
|
||||||
|
price: 32.64,
|
||||||
|
},
|
||||||
|
rearWiperPart: {
|
||||||
|
partNumber: "SBBR12A",
|
||||||
|
description: "SAFELITE REAR BLADE 12A",
|
||||||
|
partType: "REAR WIPER",
|
||||||
|
price: 24.48,
|
||||||
|
},
|
||||||
|
rainDefensePart: {
|
||||||
|
partNumber: "RAIN DEFENSE",
|
||||||
|
description: null,
|
||||||
|
partType: "RAIN DEFENSE",
|
||||||
|
price: 35.5,
|
||||||
|
},
|
||||||
|
recalPart: {
|
||||||
|
partNumber: "RECAL STATIC",
|
||||||
|
Description: "Recalibration",
|
||||||
|
partType: "recalibration",
|
||||||
|
Quantity: "1",
|
||||||
|
price: 150.0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
damages: {
|
||||||
|
frontWindshield: {
|
||||||
|
glassLocation: glassConstants.WINDSHIELD,
|
||||||
|
glassName: glassConstants.SINGLE,
|
||||||
|
},
|
||||||
|
rearWindshield: {
|
||||||
|
glassLocation: glassConstants.REAR,
|
||||||
|
glassName: glassConstants.STATIONARY,
|
||||||
|
},
|
||||||
|
sideGlass: {
|
||||||
|
glassLocation: glassConstants.PASSENGER,
|
||||||
|
glassName: glassConstants.QUARTER,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
imageId: "00000000-0000-0000-0000-000000000000",
|
||||||
|
};
|
||||||
|
|
||||||
|
const figmaScenarios = [
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_Cash",
|
||||||
|
params: {
|
||||||
|
availableVaps: [
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [testConstants.damages.frontWindshield],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard+RearWiper",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// 05_01_CSR_Quote_Standard_Repair & 05_01_CSR_Quote_Recal have identical outcomes to above, but included in case that changes in the future.
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_Standard_Repair",
|
||||||
|
params: {
|
||||||
|
availableVaps: [
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
damage: {
|
||||||
|
isRepair: true,
|
||||||
|
glassToReplace: [],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard+RearWiper",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_Recal",
|
||||||
|
params: {
|
||||||
|
availableVaps: [
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [testConstants.damages.frontWindshield],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [testConstants.parts.recalPart],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard+RearWiper",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// 05_01_CSR_Quote_RearGlass omitted as a duplicate of below.
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_RearGlass+NonWindshield",
|
||||||
|
params: {
|
||||||
|
availableVaps: [
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [testConstants.damages.rearWindshield],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+Frontwiper",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard",
|
||||||
|
vapsCombo: [testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard+RainDefense",
|
||||||
|
vapsCombo: [testConstants.parts.rearWiperPart, testConstants.parts.rainDefensePart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [testConstants.parts.rearWiperPart, testConstants.parts.frontWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_RearGlass+Windshield",
|
||||||
|
params: {
|
||||||
|
availableVaps: [
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [
|
||||||
|
testConstants.damages.frontWindshield,
|
||||||
|
testConstants.damages.rearWindshield,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+Frontwiper",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+Rearwiper",
|
||||||
|
vapsCombo: [testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+RainDefense",
|
||||||
|
vapsCombo: [testConstants.parts.rainDefensePart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+Frontwiper+RainDefense",
|
||||||
|
vapsCombo: [
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+Rearwiper+RainDefense",
|
||||||
|
vapsCombo: [testConstants.parts.rearWiperPart, testConstants.parts.rainDefensePart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_RearGlassNoFrontFit",
|
||||||
|
params: {
|
||||||
|
availableVaps: [testConstants.parts.rearWiperPart, testConstants.parts.rainDefensePart],
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [testConstants.damages.rearWindshield],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+Raindefense",
|
||||||
|
vapsCombo: [testConstants.parts.rainDefensePart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard",
|
||||||
|
vapsCombo: [testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [testConstants.parts.rearWiperPart, testConstants.parts.rainDefensePart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// 05_01_CSR_Quote_Windshield+SideGlass has identical outcomes to 05_01_CSR_Quote_Cash, but included in case that changes in the future.
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_Windshield+SideGlass",
|
||||||
|
params: {
|
||||||
|
availableVaps: [
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [
|
||||||
|
testConstants.damages.frontWindshield,
|
||||||
|
testConstants.damages.sideGlass,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Standard+RearWiper",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart, testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Has no standard package
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_SideGlass",
|
||||||
|
params: {
|
||||||
|
availableVaps: [
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
],
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [testConstants.damages.sideGlass],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+Frontwiper",
|
||||||
|
vapsCombo: [testConstants.parts.frontWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+RainDefense",
|
||||||
|
vapsCombo: [testConstants.parts.rainDefensePart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Economy+Rearwiper",
|
||||||
|
vapsCombo: [testConstants.parts.rearWiperPart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium+Rearwiper",
|
||||||
|
vapsCombo: [
|
||||||
|
testConstants.parts.rainDefensePart,
|
||||||
|
testConstants.parts.frontWiperPart,
|
||||||
|
testConstants.parts.rearWiperPart,
|
||||||
|
],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Has no standard package
|
||||||
|
{
|
||||||
|
name: "05_01_CSR_Quote_NoWiperFit",
|
||||||
|
params: {
|
||||||
|
availableVaps: [testConstants.parts.rainDefensePart],
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [testConstants.damages.frontWindshield],
|
||||||
|
},
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
},
|
||||||
|
iterations: [
|
||||||
|
{
|
||||||
|
name: "Economy",
|
||||||
|
vapsCombo: [],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierOneTitle,
|
||||||
|
displayContent: testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Premium",
|
||||||
|
vapsCombo: [testConstants.parts.rainDefensePart],
|
||||||
|
expected: {
|
||||||
|
packageNameWidget: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
displayContent: [
|
||||||
|
...testConstants.defaultItemCopy.defaultItemCopyArray,
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let cmsContent;
|
||||||
|
|
||||||
|
describe("Service Package Review Block", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cmsContent = {
|
||||||
|
ServicePackageTitle: {
|
||||||
|
Answers: [
|
||||||
|
{
|
||||||
|
Name: packageNames.TIER_ONE,
|
||||||
|
Text: "",
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: testConstants.widgetNames.tierOneTitle,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: packageNames.TIER_TWO,
|
||||||
|
Text: "",
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: testConstants.widgetNames.tierTwoTitle,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: packageNames.TIER_THREE,
|
||||||
|
Text: "",
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: testConstants.widgetNames.tierThreeTitle,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
DefaultPackageItemDescriptions: {
|
||||||
|
Answers: [
|
||||||
|
{
|
||||||
|
Name: "Item1",
|
||||||
|
Text: testConstants.defaultItemCopy.itemOne,
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Item2",
|
||||||
|
Text: testConstants.defaultItemCopy.itemTwo,
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Item3",
|
||||||
|
Text: testConstants.defaultItemCopy.itemThree,
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: "",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
VapsItemDescriptions: {
|
||||||
|
Answers: [
|
||||||
|
{
|
||||||
|
Name: partTypeStrings.FRONT_WIPER,
|
||||||
|
Text: testConstants.vapsCopy.frontWiperCopy,
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: partTypeStrings.REAR_WIPER,
|
||||||
|
Text: testConstants.vapsCopy.rearWiperCopy,
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: partTypeStrings.RAIN_DEFENSE,
|
||||||
|
Text: testConstants.vapsCopy.rainDefenseCopy,
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: "",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
describe("General functionality", () => {
|
||||||
|
it('Should properly "Round Down" package tier', async () => {
|
||||||
|
// Slightly longer explanation:
|
||||||
|
// Should only return the highest tier where *every* offered VAP is part of the order.
|
||||||
|
// However, there may be vaps not offered in the qualifying tier. Hence rounding *down*.
|
||||||
|
//
|
||||||
|
// I.e. Economy=[], Standard=[front wipers], Premium=[front wipers, rain defense].
|
||||||
|
// Current vaps=[rain defense]. Though rain defense is in Premium, we don't satisfy it or standard.
|
||||||
|
// So our tier should still be Economy.
|
||||||
|
// Should still display extra vaps.
|
||||||
|
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
|
||||||
|
props.lineItems.vaps = [testConstants.parts.rainDefensePart];
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.packageNameWidget).toEqual(testConstants.widgetNames.tierOneTitle);
|
||||||
|
|
||||||
|
let containsRainDefenseCopy = wrapper.vm.displayContent.includes(
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy
|
||||||
|
);
|
||||||
|
expect(containsRainDefenseCopy).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should display all default items from cms", async () => {
|
||||||
|
// Arrange
|
||||||
|
cmsContent.DefaultPackageItemDescriptions.Answers.push({
|
||||||
|
Name: "Item4",
|
||||||
|
Text: testConstants.defaultItemCopy.itemFour,
|
||||||
|
SubText: "",
|
||||||
|
ImageId: testConstants.imageId,
|
||||||
|
Image: "",
|
||||||
|
SubWidgetName: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
props.lineItems.vaps = [];
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
let expectedResult = [
|
||||||
|
testConstants.defaultItemCopy.itemOne,
|
||||||
|
testConstants.defaultItemCopy.itemTwo,
|
||||||
|
testConstants.defaultItemCopy.itemThree,
|
||||||
|
testConstants.defaultItemCopy.itemFour,
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(wrapper.vm.displayContent).toEqual(expectedResult);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should display vaps if and only if they are added", async () => {
|
||||||
|
// Arrange
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: generateDefaultProps(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
const includesFrontWiperCopy = wrapper.vm.displayContent.includes(
|
||||||
|
testConstants.vapsCopy.frontWiperCopy
|
||||||
|
);
|
||||||
|
const includesRainDefenseCopy = wrapper.vm.displayContent.includes(
|
||||||
|
testConstants.vapsCopy.rainDefenseCopy
|
||||||
|
);
|
||||||
|
expect(includesFrontWiperCopy).toBe(true);
|
||||||
|
expect(includesRainDefenseCopy).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should not error if cms content is missing (though may display poorly).", async () => {
|
||||||
|
// Arrange
|
||||||
|
cmsContent = {};
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: generateDefaultProps(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.packageNameWidget).toEqual("");
|
||||||
|
expect(wrapper.vm.displayContent).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Match Figma Scenarios", () => {
|
||||||
|
figmaScenarios.forEach((scenario) => {
|
||||||
|
scenario.iterations.forEach((iteration) => {
|
||||||
|
it(`Should match figma scenario "${scenario.name}", iteration "${iteration.name}"`, async () => {
|
||||||
|
// Arrange
|
||||||
|
let props = generateDefaultProps();
|
||||||
|
props.availableVaps = scenario.params.availableVaps;
|
||||||
|
props.damage = scenario.params.damage;
|
||||||
|
props.glassParts = scenario.params.glassParts;
|
||||||
|
props.lineItems.supportingItems = scenario.params.supportingItems;
|
||||||
|
props.lineItems.vaps = iteration.vapsCombo;
|
||||||
|
|
||||||
|
const { wrapper } = setupMocks({
|
||||||
|
propsData: props,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await wrapper.vm.$nextTick();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.packageNameWidget).toEqual(
|
||||||
|
iteration.expected.packageNameWidget
|
||||||
|
);
|
||||||
|
expect(wrapper.vm.displayContent).toEqual(iteration.expected.displayContent);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function generateDefaultProps() {
|
||||||
|
return {
|
||||||
|
servicePackageOptionsCmsName: testConstants.cmsPropValues.servicePackageOptionsCmsName,
|
||||||
|
defaultPackageItemsCmsName: testConstants.cmsPropValues.defaultPackageItemsCmsName,
|
||||||
|
vapsItemsCmsName: testConstants.cmsPropValues.vapsItemsCmsName,
|
||||||
|
availableVaps: [testConstants.parts.frontWiperPart, testConstants.parts.rainDefensePart],
|
||||||
|
lineItems: {
|
||||||
|
glassParts: [],
|
||||||
|
supportingItems: [],
|
||||||
|
vaps: [testConstants.parts.frontWiperPart],
|
||||||
|
},
|
||||||
|
damage: {
|
||||||
|
isRepair: false,
|
||||||
|
glassToReplace: [testConstants.damages.frontWindshield],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupMocks(customMountOptions) {
|
||||||
|
const mountOptions = getMountOptions(customMountOptions);
|
||||||
|
|
||||||
|
const mockMixin = {
|
||||||
|
methods: {
|
||||||
|
getCmsContent: jest.fn((widgetName, cmsFieldName) => {
|
||||||
|
return cmsContent?.[widgetName]?.[cmsFieldName] ?? "";
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
mountOptions.global.mixins = [mockMixin];
|
||||||
|
|
||||||
|
const wrapper = shallowMount(servicePackageReview, mountOptions);
|
||||||
|
wrapper.vm.setCmsContent = jest.fn();
|
||||||
|
return { wrapper };
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
<template>
|
||||||
|
<reviewBlock
|
||||||
|
:headerCmsWidgetName="packageNameWidget"
|
||||||
|
:content="displayContent"
|
||||||
|
@edit-clicked="editClicked" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import reviewBlock from "@/layouts/review/review-block/review-block";
|
||||||
|
import {
|
||||||
|
getHighestFullySatisfiedTier,
|
||||||
|
containsLineItemWithPartType,
|
||||||
|
} from "@/helpers/service-package-helper";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "service-package-review",
|
||||||
|
props: {
|
||||||
|
servicePackageOptionsCmsName: String,
|
||||||
|
defaultPackageItemsCmsName: String,
|
||||||
|
vapsItemsCmsName: String,
|
||||||
|
availableVaps: Array,
|
||||||
|
lineItems: Object,
|
||||||
|
damage: Object,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editClicked() {
|
||||||
|
this.$emit("edit-clicked");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
displayContent() {
|
||||||
|
return [...this.defaultPackageText, ...this.vapsItemText];
|
||||||
|
},
|
||||||
|
packageNameWidget() {
|
||||||
|
const servicePackageNames = this.getCmsContent(
|
||||||
|
this.servicePackageOptionsCmsName,
|
||||||
|
"Answers"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!servicePackageNames) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentPackage = servicePackageNames.find(
|
||||||
|
(entry) => entry.Name === this.packageLevel
|
||||||
|
);
|
||||||
|
|
||||||
|
return currentPackage.SubWidgetName;
|
||||||
|
},
|
||||||
|
defaultPackageText() {
|
||||||
|
const defaultItems = this.getCmsContent(this.defaultPackageItemsCmsName, "Answers");
|
||||||
|
|
||||||
|
if (!defaultItems) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultItems.map((answer) => answer.Text);
|
||||||
|
},
|
||||||
|
vapsItemText() {
|
||||||
|
const vapsDescriptions = this.getCmsContent(this.vapsItemsCmsName, "Answers");
|
||||||
|
|
||||||
|
if (!vapsDescriptions) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const vapsDescriptionsOnOrder = vapsDescriptions.filter((answer) =>
|
||||||
|
containsLineItemWithPartType(answer.Name, this.vaps)
|
||||||
|
);
|
||||||
|
|
||||||
|
return vapsDescriptionsOnOrder.map((answer) => answer.Text);
|
||||||
|
},
|
||||||
|
packageLevel() {
|
||||||
|
return getHighestFullySatisfiedTier(
|
||||||
|
this.glassToReplace,
|
||||||
|
this.availableLineItems,
|
||||||
|
this.isRepair,
|
||||||
|
this.vaps
|
||||||
|
);
|
||||||
|
},
|
||||||
|
glassToReplace() {
|
||||||
|
return this.damage.glassToReplace;
|
||||||
|
},
|
||||||
|
isRepair() {
|
||||||
|
return this.damage.isRepair;
|
||||||
|
},
|
||||||
|
vaps() {
|
||||||
|
return this.lineItems?.vaps;
|
||||||
|
},
|
||||||
|
availableLineItems() {
|
||||||
|
return [
|
||||||
|
...(this.lineItems?.glassParts ?? []),
|
||||||
|
...(this.lineItems?.supportingItems ?? []),
|
||||||
|
...this.availableVaps,
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
reviewBlock,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -27,7 +27,9 @@
|
||||||
class="mb-2"
|
class="mb-2"
|
||||||
@click-event="forwardButtonAction" />
|
@click-event="forwardButtonAction" />
|
||||||
|
|
||||||
<hr />
|
<div>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
|
||||||
<textBlock
|
<textBlock
|
||||||
customText="Appointment Details"
|
customText="Appointment Details"
|
||||||
|
|
@ -48,9 +50,22 @@
|
||||||
cmsWidgetName="DamageReviewWidget"
|
cmsWidgetName="DamageReviewWidget"
|
||||||
:damage="damageInfo"
|
:damage="damageInfo"
|
||||||
@edit-clicked="editDamage" />
|
@edit-clicked="editDamage" />
|
||||||
|
|
||||||
|
<hr class="my-0" />
|
||||||
|
|
||||||
|
<servicePackageReview
|
||||||
|
servicePackageOptionsCmsName="ServicePackageTitle"
|
||||||
|
defaultPackageItemsCmsName="DefaultPackageItemDescriptions"
|
||||||
|
vapsItemsCmsName="VapsItemDescriptions"
|
||||||
|
:damage="damageInfo"
|
||||||
|
:availableVaps="availableVaps"
|
||||||
|
:lineItems="lineItems"
|
||||||
|
@edit-clicked="editServicePackage" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr class="my-0" />
|
<div>
|
||||||
|
<hr class="my-0" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<funnelFooter
|
<funnelFooter
|
||||||
cmsWidgetName="FunnelFooterWidget"
|
cmsWidgetName="FunnelFooterWidget"
|
||||||
|
|
@ -66,17 +81,26 @@ import funnelFooter from "@/fmg-components/funnel-footer/funnel-footer";
|
||||||
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
|
import vehicleBanner from "@/fmg-components/vehicle-banner/vehicle-banner";
|
||||||
import buttonMain from "@/ux-components/button-main/button-main";
|
import buttonMain from "@/ux-components/button-main/button-main";
|
||||||
import textBlock from "@/digital-components/text-block/text-block";
|
import textBlock from "@/digital-components/text-block/text-block";
|
||||||
|
|
||||||
import vehicleReview from "@/layouts/review/review-sections/vehicle-review/vehicle-review";
|
import vehicleReview from "@/layouts/review/review-sections/vehicle-review/vehicle-review";
|
||||||
import damageReview from "@/layouts/review/review-sections/damage-review/damage-review";
|
import damageReview from "@/layouts/review/review-sections/damage-review/damage-review";
|
||||||
|
import servicePackageReview from "@/layouts/review/review-sections/service-package-review/service-package-review";
|
||||||
|
|
||||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||||
import { settleAllPromises } from "@/helpers/layout-helper";
|
import { settleAllPromises } from "@/helpers/layout-helper";
|
||||||
|
import baseMixin from "@/mixins/base-mixin.js";
|
||||||
|
import { storeActions } from "@/constants/store-actions";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "review",
|
name: "review",
|
||||||
async beforeRouteEnter(to, from, next) {
|
async beforeRouteEnter(to, from, next) {
|
||||||
// Call APIs
|
// Call APIs
|
||||||
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
|
||||||
|
// Get rain defense and wiper availability for package review section.
|
||||||
|
const wipersPromise = baseMixin.methods.dispatchStoreAction(storeActions.GET_WIPERS);
|
||||||
|
const rainDefensePromise = baseMixin.methods.dispatchStoreAction(
|
||||||
|
storeActions.GET_RAIN_DEFENSE
|
||||||
|
);
|
||||||
|
|
||||||
// Settle promises and get results
|
// Settle promises and get results
|
||||||
const promiseResultMap = [
|
const promiseResultMap = [
|
||||||
|
|
@ -84,16 +108,30 @@ export default {
|
||||||
resultKey: "cmsContent",
|
resultKey: "cmsContent",
|
||||||
promise: cmsContentPromise,
|
promise: cmsContentPromise,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
resultKey: "wipers",
|
||||||
|
promise: wipersPromise,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resultKey: "rainDefense",
|
||||||
|
promise: rainDefensePromise,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const resultMap = await settleAllPromises(promiseResultMap);
|
const resultMap = await settleAllPromises(promiseResultMap);
|
||||||
|
|
||||||
next((vm) => {
|
next((vm) => {
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
|
|
||||||
|
vm.availableWipers = resultMap.wipers;
|
||||||
|
vm.availableRainDefense = [resultMap.rainDefense];
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {
|
||||||
|
availableWipers: null,
|
||||||
|
availableRainDefense: null,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
|
|
@ -113,6 +151,12 @@ export default {
|
||||||
this.$route
|
this.$route
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
editServicePackage() {
|
||||||
|
this.$router.navigateWithoutSaving(
|
||||||
|
this.navigationScenarios.CLICKED_SERVICE_PACKAGE_EDIT,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
subHeaderTitle() {
|
subHeaderTitle() {
|
||||||
|
|
@ -130,6 +174,12 @@ export default {
|
||||||
damageInfo() {
|
damageInfo() {
|
||||||
return this.$store.getters.damage;
|
return this.$store.getters.damage;
|
||||||
},
|
},
|
||||||
|
availableVaps() {
|
||||||
|
return [...(this.availableWipers ?? []), ...(this.availableRainDefense ?? [])];
|
||||||
|
},
|
||||||
|
lineItems() {
|
||||||
|
return this.$store.getters.lineItems;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
funnelHeader,
|
funnelHeader,
|
||||||
|
|
@ -139,6 +189,7 @@ export default {
|
||||||
textBlock,
|
textBlock,
|
||||||
vehicleReview,
|
vehicleReview,
|
||||||
damageReview,
|
damageReview,
|
||||||
|
servicePackageReview,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ const navigationScenarios = {
|
||||||
// Review
|
// Review
|
||||||
CLICKED_VEHICLE_EDIT: "CLICKED_VEHICLE_EDIT",
|
CLICKED_VEHICLE_EDIT: "CLICKED_VEHICLE_EDIT",
|
||||||
CLICKED_DAMAGE_EDIT: "CLICKED_DAMAGE_EDIT",
|
CLICKED_DAMAGE_EDIT: "CLICKED_DAMAGE_EDIT",
|
||||||
|
CLICKED_SERVICE_PACKAGE_EDIT: "CLICKED_SERVICE_PACKAGE_EDIT",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { navigationScenarios };
|
export { navigationScenarios };
|
||||||
|
|
|
||||||
|
|
@ -472,6 +472,10 @@ const routingTable = function (store) {
|
||||||
scenario: navigationScenarios.CLICKED_DAMAGE_EDIT,
|
scenario: navigationScenarios.CLICKED_DAMAGE_EDIT,
|
||||||
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
|
destinationFmgPageValue: fmgPageValues.VEHICLE_DAMAGE,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
scenario: navigationScenarios.CLICKED_SERVICE_PACKAGE_EDIT,
|
||||||
|
destinationFmgPageValue: fmgPageValues.QUOTE,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
scenario: navigationScenarios.CLICKED_BACK,
|
scenario: navigationScenarios.CLICKED_BACK,
|
||||||
destinationFmgPageValue: fmgPageValues.CUSTOMER_DETAILS,
|
destinationFmgPageValue: fmgPageValues.CUSTOMER_DETAILS,
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { fmgPageValues } from "@/router/router-constants/fmgPage-values";
|
||||||
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js";
|
import { deleteFunnelCookie } from "@/helpers/heritage-integration/cookie-helper.js";
|
||||||
import { deepEqual } from "@/helpers/object-helper";
|
import { deepEqual } from "@/helpers/object-helper";
|
||||||
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from "@/constants/schedule-constants";
|
import { AppointmentTypeStrings, PREMIUM_FEE_PART_TYPE } from "@/constants/schedule-constants";
|
||||||
|
import { partTypeStrings } from "@/constants/part-type-strings";
|
||||||
|
|
||||||
// Export State
|
// Export State
|
||||||
const getDefaultState = () => {
|
const getDefaultState = () => {
|
||||||
|
|
@ -536,6 +537,14 @@ export const getters = {
|
||||||
isMobileAppointment: (state) => {
|
isMobileAppointment: (state) => {
|
||||||
return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
|
return state.order.serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
|
||||||
},
|
},
|
||||||
|
isRecalibrationOnOrder: (state) => {
|
||||||
|
return getHasRecalibrationPart(state);
|
||||||
|
},
|
||||||
|
areRearWipersOnOrder: (state) => {
|
||||||
|
return !!state.order.lineItems.vaps?.some(
|
||||||
|
(vap) => vap.partType.toUpperCase() === partTypeStrings.REAR_WIPER.toUpperCase()
|
||||||
|
);
|
||||||
|
},
|
||||||
lineItems: (state) => state.order.lineItems,
|
lineItems: (state) => state.order.lineItems,
|
||||||
pageData: (state) => (page) => {
|
pageData: (state) => (page) => {
|
||||||
return state.applicationUser.pageData[page];
|
return state.applicationUser.pageData[page];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue