diff --git a/package-lock.json b/package-lock.json
index 8d4b6e08d..91e44113b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,6 +14,7 @@
"canvas-confetti": "^1.4.0",
"core-js": "^3.6.5",
"http-status-codes": "^2.1.4",
+ "iframe-resizer": "^4.3.7",
"jest-junit": "^13.0.0",
"maska": "^1.5.0",
"vee-validate": "^4.5.7",
@@ -11813,6 +11814,18 @@
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
"dev": true
},
+ "node_modules/iframe-resizer": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/iframe-resizer/-/iframe-resizer-4.3.7.tgz",
+ "integrity": "sha512-a3EGVScU9NtUpj6lWvGhVw3EfOw5AopRs5xGsQU385kWdgQt++OsD6PCnTV+8YkgBu/g28rLIh0EztFg9UQr1Q==",
+ "engines": {
+ "node": ">=0.8.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://github.com/davidjbradshaw/iframe-resizer/blob/master/FUNDING.md"
+ }
+ },
"node_modules/ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -33845,6 +33858,11 @@
"integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
"dev": true
},
+ "iframe-resizer": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/iframe-resizer/-/iframe-resizer-4.3.7.tgz",
+ "integrity": "sha512-a3EGVScU9NtUpj6lWvGhVw3EfOw5AopRs5xGsQU385kWdgQt++OsD6PCnTV+8YkgBu/g28rLIh0EztFg9UQr1Q=="
+ },
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
diff --git a/package.json b/package.json
index a910ad0af..d99b971c2 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"canvas-confetti": "^1.4.0",
"core-js": "^3.6.5",
"http-status-codes": "^2.1.4",
+ "iframe-resizer": "^4.3.7",
"jest-junit": "^13.0.0",
"maska": "^1.5.0",
"vee-validate": "^4.5.7",
diff --git a/public/css/hop-styling.css b/public/css/hop-styling.css
index 1f0b0ddc2..1c0b155a0 100644
--- a/public/css/hop-styling.css
+++ b/public/css/hop-styling.css
@@ -75,14 +75,11 @@ body .creditCardSpecific div {
padding: 8px 0;
}
body .creditCardSpecific div .headerlinecontainer {
- padding: 0;
+ display: none;
}
body .creditCardSpecific div label {
font-weight: 500;
}
-body .creditCardSpecific div:first-child {
- display: none;
-}
body .creditCardSpecific #infoRow2 {
margin-bottom: 0;
}
diff --git a/public/scss/hop-styling.scss b/public/scss/hop-styling.scss
index 0e646a591..badab0912 100644
--- a/public/scss/hop-styling.scss
+++ b/public/scss/hop-styling.scss
@@ -88,14 +88,11 @@ body {
div {
padding: 8px 0;
.headerlinecontainer {
- padding: 0;
+ display: none;
}
label {
font-weight: 500;
}
- &:first-child {
- display: none;
- }
}
#infoRow2 {
margin-bottom: 0;
diff --git a/src/App.vue b/src/App.vue
index aef77fcb0..31fb663c3 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -5,15 +5,33 @@
+
diff --git a/src/constants/store-actions.js b/src/constants/store-actions.js
index 847b14477..2cfd08a8e 100644
--- a/src/constants/store-actions.js
+++ b/src/constants/store-actions.js
@@ -91,6 +91,9 @@ const storeActions = {
SAVE_SERVICE_LOCATION_TECH_NOTES: "saveServiceLocationTechNotes",
SAVE_CCTOKEN: "saveCCToken",
SAVE_PAYPAL_TOKEN: "savePaypalToken",
+
+ CREATE_SUBMITTED_ORDER: "createSubmittedOrder",
+ RESET_SUBMITTED_ORDER: "resetSubmittedOrder",
};
export { storeActions };
diff --git a/src/fmg-components/cart/cart.spec.js b/src/fmg-components/cart/cart.spec.js
new file mode 100644
index 000000000..bfe1dbb55
--- /dev/null
+++ b/src/fmg-components/cart/cart.spec.js
@@ -0,0 +1,369 @@
+// Components
+import cart from "@/fmg-components/cart/cart.vue";
+
+// Supporting Files
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+
+describe("cart.vue", () => {
+ describe("cartItem computeds", () => {
+ test("if there are one or more front wipers on the order, a front wiper cart item should be added to the cart", () => {
+ // Arrange
+ const lineItems = {
+ glassParts: [],
+ supportingItems: [],
+ vaps: [
+ {
+ cartItemType: "FRONT WIPERS",
+ description: 'WIPER BLADE STANDARD 18"',
+ kitPrice: 0,
+ laborAmount: 0,
+ partNumber: "WB18",
+ partType: "FRONT WIPER",
+ salesTax: 2.44,
+ sellingPrice: 32.49,
+ },
+ {
+ cartItemType: "FRONT WIPERS",
+ description: 'WIPER BLADE STANDARD 26"',
+ kitPrice: 0,
+ laborAmount: 0,
+ partNumber: "WB26",
+ partType: "FRONT WIPER",
+ salesTax: 2.44,
+ sellingPrice: 32.49,
+ },
+ ],
+ promos: [],
+ };
+
+ const availableLineItems = [];
+
+ // Act
+ const { wrapper } = setupMocks({
+ props: {
+ modelValue: lineItems,
+ availableLineItems: availableLineItems,
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.frontWipersCartItem).not.toBeNull();
+ expect(wrapper.vm.frontWipersCartItem.subTotal).toEqual(64.98);
+ expect(wrapper.vm.frontWipersCartItem.salesTax).toEqual(4.88);
+
+ const found =
+ wrapper.vm.cartItems.findIndex(
+ (cartItem) => cartItem == wrapper.vm.frontWipersCartItem
+ ) >= 0;
+ expect(found).toBe(true);
+ });
+
+ test("if there are one or more rear wipers on the order, a rear wiper cart item should be added to the cart", () => {
+ // Arrange
+ const lineItems = {
+ glassParts: [],
+ supportingItems: [],
+ vaps: [
+ {
+ cartItemType: "REAR WIPERS",
+ description: 'REAR WIPER BLADE STANDARD 18"',
+ kitPrice: 0,
+ laborAmount: 0,
+ partNumber: "EWB18",
+ partType: "REAR WIPER",
+ salesTax: 2.44,
+ sellingPrice: 32.49,
+ },
+ {
+ cartItemType: "REAR WIPERS",
+ description: 'REAR WIPER BLADE STANDARD 26"',
+ kitPrice: 0,
+ laborAmount: 0,
+ partNumber: "RWB26",
+ partType: "REAR WIPER",
+ salesTax: 2.44,
+ sellingPrice: 32.49,
+ },
+ ],
+ promos: [],
+ };
+
+ const availableLineItems = [];
+
+ // Act
+ const { wrapper } = setupMocks({
+ props: {
+ modelValue: lineItems,
+ availableLineItems: availableLineItems,
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.rearWipersCartItem).not.toBeNull();
+ expect(wrapper.vm.rearWipersCartItem.subTotal).toEqual(64.98);
+ expect(wrapper.vm.rearWipersCartItem.salesTax).toEqual(4.88);
+
+ const found =
+ wrapper.vm.cartItems.findIndex(
+ (cartItem) => cartItem == wrapper.vm.rearWipersCartItem
+ ) >= 0;
+ expect(found).toBe(true);
+ });
+
+ test("if there is Rain Defense on the order, a rain defense cart item should be added to the cart", () => {
+ // Arrange
+ const lineItems = {
+ glassParts: [],
+ supportingItems: [],
+ vaps: [
+ {
+ cartItemType: "RAIN DEFENSE",
+ description: null,
+ kitPrice: 0,
+ laborAmount: 0,
+ listPrice: "44.99",
+ partNumber: "RAIN DEFENSE",
+ partType: "RAIN DEFENSE",
+ salesTax: 3.37,
+ sellingPrice: 44.99,
+ },
+ ],
+ promos: [],
+ };
+
+ const availableLineItems = [];
+
+ // Act
+ const { wrapper } = setupMocks({
+ props: {
+ modelValue: lineItems,
+ availableLineItems: availableLineItems,
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.rainDefenseCartItem).not.toBeNull();
+ expect(wrapper.vm.rainDefenseCartItem.subTotal).toEqual(44.99);
+ expect(wrapper.vm.rainDefenseCartItem.salesTax).toEqual(3.37);
+
+ const found =
+ wrapper.vm.cartItems.findIndex(
+ (cartItem) => cartItem == wrapper.vm.rainDefenseCartItem
+ ) >= 0;
+ expect(found).toBe(true);
+ });
+
+ // test("if there are glass parts on the order, a glass part cart item should be added to the cart but should not be displayed", () => {
+ // // Arrange
+ // const windshieldWithChildParts = {
+ // canSafeliteRecalibrate: true,
+ // childParts: [
+ // {
+ // kitPrice: 0,
+ // laborAmount: 23.55,
+ // partNumber: "GGG FW4896",
+ // salesTax: 1.77,
+ // sellingPrice: 0,
+ // },
+ // ],
+ // color: "Green Tint",
+ // description:
+ // "solar, soundproofing, lane keep assist, lane departure warning system, w/adaptive cruise control",
+ // id: "db22fd44-10dd-456f-979b-ff88cf68cca6",
+ // kitPrice: 0,
+ // laborAmount: 60,
+ // partNumber: "FW04896GTYN",
+ // partType: "WINDSHIELD",
+ // recalibrationType: "STATIC",
+ // requiresCapabilityQuestions: false,
+ // requiresRecalibration: true,
+ // salesTax: 63.86,
+ // sellingPrice: 791.46,
+ // };
+
+ // const lineItems = {
+ // glassParts: [windshieldWithChildParts],
+ // supportingItems: [],
+ // vaps: [],
+ // promos: [],
+ // };
+
+ // const availableLineItems = [];
+
+ // // Act
+ // const { wrapper } = setupMocks({
+ // props: {
+ // modelValue: lineItems,
+ // availableLineItems: availableLineItems,
+ // },
+ // });
+
+ // // Assert
+ // expect(wrapper.vm.glassPartCartItems[0]).not.toBeNull();
+ // expect(wrapper.vm.glassPartCartItems[0].subTotal).toEqual(875.01);
+ // expect(wrapper.vm.glassPartCartItems[0].salesTax).toEqual(65.63);
+ // expect(wrapper.vm.glassPartCartItems[0].isDisplayed).toEqual(false);
+
+ // const found =
+ // wrapper.vm.cartItems.findIndex(
+ // (cartItem) => cartItem == wrapper.vm.glassPartsCartItem
+ // ) >= 0;
+
+ // expect(found).toBe(true);
+ // });
+
+ // Recycle Fee Cart Item
+ test("if there is recycling fee on the order, a recycle fee cart item should be added to the cart", () => {
+ // Arrange
+ const lineItems = {
+ glassParts: [],
+ supportingItems: [
+ {
+ description: null,
+ id: "9ff98501-03a4-432b-884e-e4e28f884a2f",
+ kitPrice: 0,
+ laborAmount: 34.98,
+ partNumber: "RECYCLE FEE",
+ partType: "REPLACE FEE",
+ salesTax: 2.62,
+ sellingPrice: 0,
+ },
+ ],
+ vaps: [],
+ promos: [],
+ };
+
+ const availableLineItems = [];
+
+ // Act
+ const { wrapper } = setupMocks({
+ props: {
+ modelValue: lineItems,
+ availableLineItems: availableLineItems,
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.recycleFeeCartItem).not.toBeNull();
+ expect(wrapper.vm.recycleFeeCartItem.subTotal).toEqual(34.98);
+ expect(wrapper.vm.recycleFeeCartItem.salesTax).toEqual(2.62);
+
+ const found =
+ wrapper.vm.cartItems.findIndex(
+ (cartItem) => cartItem == wrapper.vm.recycleFeeCartItem
+ ) >= 0;
+ expect(found).toBe(true);
+ });
+
+ // Mobile Fee Cart Item
+ test("if there is mobile fee on the order, a mobile fee cart item should be added to the cart", () => {
+ // Arrange
+ const lineItems = {
+ glassParts: [],
+ supportingItems: [
+ {
+ description: null,
+ id: "9ff98501-03a4-432b-884e-e4e28f884a2f",
+ kitPrice: 0,
+ laborAmount: 34.98,
+ partNumber: "MOBILE FEE",
+ partType: "REPLACE FEE",
+ salesTax: 2.62,
+ sellingPrice: 0,
+ },
+ ],
+ vaps: [],
+ promos: [],
+ };
+
+ const availableLineItems = [];
+
+ // Act
+ const { wrapper } = setupMocks({
+ props: {
+ modelValue: lineItems,
+ availableLineItems: availableLineItems,
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.mobileFeeCartItem).not.toBeNull();
+ expect(wrapper.vm.mobileFeeCartItem.subTotal).toEqual(34.98);
+ expect(wrapper.vm.mobileFeeCartItem.salesTax).toEqual(2.62);
+
+ const found =
+ wrapper.vm.cartItems.findIndex(
+ (cartItem) => cartItem == wrapper.vm.mobileFeeCartItem
+ ) >= 0;
+ expect(found).toBe(true);
+ });
+
+ // Other Supporting Items Cart Item
+ test("if there are other supporting items on the order, an other supporting items cart item should be added to the cart but should not be displayed", () => {
+ // Arrange
+ const recalibrationLineItem = {
+ cartItemType: "SUPPORTING ITEMS",
+ description: null,
+ id: "8ab6ef9b-8620-430a-8a92-29f7d4bb8b00",
+ kitPrice: 0,
+ laborAmount: 450,
+ partNumber: "RECAL STATIC",
+ partType: "RECALIBRATION",
+ salesTax: 33.75,
+ sellingPrice: 0,
+ };
+
+ const lineItems = {
+ glassParts: [],
+ supportingItems: [recalibrationLineItem],
+ vaps: [],
+ promos: [],
+ };
+
+ const availableLineItems = [];
+
+ // Act
+ const { wrapper } = setupMocks({
+ props: {
+ modelValue: lineItems,
+ availableLineItems: availableLineItems,
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.otherSupportingItemsCartItem).not.toBeNull();
+ expect(wrapper.vm.otherSupportingItemsCartItem.subTotal).toEqual(450);
+ expect(wrapper.vm.otherSupportingItemsCartItem.salesTax).toEqual(33.75);
+ expect(wrapper.vm.otherSupportingItemsCartItem.isDisplayed).toEqual(false);
+
+ const found =
+ wrapper.vm.cartItems.findIndex(
+ (cartItem) => cartItem == wrapper.vm.otherSupportingItemsCartItem
+ ) >= 0;
+ expect(found).toBe(true);
+ });
+ });
+});
+
+function setupMocks({ options, props }) {
+ const mountOptions = getMountOptions({
+ ...options,
+ });
+
+ const mockBaseMixin = {
+ methods: {
+ getTierOnePackagePrice: jest.fn(),
+ filterOutFees: jest.fn(),
+ getCmsContent: jest.fn(),
+ },
+ };
+
+ if (props) mountOptions.propsData = props;
+
+ mountOptions.global.mixins = [mockBaseMixin];
+
+ const wrapper = shallowMount(cart, mountOptions);
+
+ return { wrapper };
+}
diff --git a/src/fmg-components/cart/cart.vue b/src/fmg-components/cart/cart.vue
index 440823f67..ce43971d8 100644
--- a/src/fmg-components/cart/cart.vue
+++ b/src/fmg-components/cart/cart.vue
@@ -73,13 +73,18 @@
+
+
diff --git a/src/layouts/payment/payment-switch/payment-switch.vue b/src/layouts/payment/payment-switch/payment-switch.vue
new file mode 100644
index 000000000..5b72ffc39
--- /dev/null
+++ b/src/layouts/payment/payment-switch/payment-switch.vue
@@ -0,0 +1,99 @@
+
+
+
+ or
+
+ or
+
+
+
+
+
+
diff --git a/src/layouts/payment/payment.vue b/src/layouts/payment/payment.vue
index 2b4121c98..a8780cbc5 100644
--- a/src/layouts/payment/payment.vue
+++ b/src/layouts/payment/payment.vue
@@ -12,6 +12,7 @@
-
{{ switchPaymentText }}
-
-
-
-
or
-
-
-
-
or
-
-
-
+
{
+ iframeResize({ checkOrigin: false }, el);
+ });
+ },
+ unmounted: function (el) {
+ el.iFrameResizer.removeListeners();
+ },
+ },
+ },
async beforeRouteEnter(to, from, next) {
// Call APIs
const cmsContentPromise = fetchCmsContentForPage(to.query.fmgPage);
@@ -480,6 +466,7 @@ export default {
funnelHeader,
navbar,
loadingModal,
+ paymentSwitch,
},
};
@@ -487,7 +474,7 @@ export default {