Completed unit tests
This commit is contained in:
parent
8405d4c75f
commit
b779b948d6
5 changed files with 97 additions and 19 deletions
27
src/helpers/object-cloning-helper.js
Normal file
27
src/helpers/object-cloning-helper.js
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
// For nested objects, spread operator only creates new references to the top level fields,
|
||||||
|
// the remaining nested fields actually reference the original object which can introduce problems.
|
||||||
|
|
||||||
|
// The purpose of this method is to deep clone the data in an object recursively, this is useful
|
||||||
|
// for cloning modelValues to internal models when regular two-way binding is not an option.
|
||||||
|
// See: mobile-location-modal-questions.vue
|
||||||
|
|
||||||
|
// Creates a deep clone of an object. Clones primitives, arrays and objects, excluding class instances.
|
||||||
|
// https://www.30secondsofcode.org/js/s/deep-clone
|
||||||
|
export function deepClone(object) {
|
||||||
|
if (object === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let clone = Object.assign({}, object);
|
||||||
|
Object.keys(clone).forEach(
|
||||||
|
(key) =>
|
||||||
|
(clone[key] = typeof object[key] === "object" ? deepClone(object[key]) : object[key])
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Array.isArray(object)) {
|
||||||
|
clone.length = object.length;
|
||||||
|
return Array.from(clone);
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
48
src/helpers/object-cloning-helper.spec.js
Normal file
48
src/helpers/object-cloning-helper.spec.js
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
import { deepClone } from "./object-cloning-helper";
|
||||||
|
|
||||||
|
describe("object-cloning-helper.js", () => {
|
||||||
|
it("Should return null if no object is passed in", async () => {
|
||||||
|
// Arrange
|
||||||
|
const expected = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = deepClone(null);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toEqual(expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return a deep copy of the object", async () => {
|
||||||
|
// Arrange
|
||||||
|
|
||||||
|
const object = {
|
||||||
|
addressQuestions: {
|
||||||
|
streetAddress: "555 Some St",
|
||||||
|
apartmentNumberOrBusinessName: "Apt 1",
|
||||||
|
city: "Funkytown",
|
||||||
|
state: "OH",
|
||||||
|
zipCode: "55555",
|
||||||
|
},
|
||||||
|
isVehicleProtected: true,
|
||||||
|
serviceZipCode: "55555",
|
||||||
|
};
|
||||||
|
|
||||||
|
const expected = {
|
||||||
|
addressQuestions: {
|
||||||
|
streetAddress: "555 Some St",
|
||||||
|
apartmentNumberOrBusinessName: "Apt 1",
|
||||||
|
city: "Funkytown",
|
||||||
|
state: "OH",
|
||||||
|
zipCode: "55555",
|
||||||
|
},
|
||||||
|
isVehicleProtected: true,
|
||||||
|
serviceZipCode: "55555",
|
||||||
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
|
const result = deepClone(object);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(result).toStrictEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -45,11 +45,12 @@ jest.mock("@/mixins/base-mixin.js", () => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe("service-location-helper.js", () => {
|
describe("service-location-helper.js", () => {
|
||||||
it("Should return the null if no service zip code is passed in", async () => {
|
it("Should return null if no service zip code is passed in", async () => {
|
||||||
// Arrange / Act
|
// Arrange
|
||||||
const serviceZipCode = null;
|
const serviceZipCode = null;
|
||||||
const expected = null;
|
const expected = null;
|
||||||
|
|
||||||
|
// Act
|
||||||
const result = await getPricedMobileFeePart(serviceZipCode);
|
const result = await getPricedMobileFeePart(serviceZipCode);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
@ -57,7 +58,7 @@ describe("service-location-helper.js", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should return the priced mobile fee part", async () => {
|
it("Should return the priced mobile fee part", async () => {
|
||||||
// Arrange / Act
|
// Arrange
|
||||||
const serviceZipCode = "43235";
|
const serviceZipCode = "43235";
|
||||||
const expected = {
|
const expected = {
|
||||||
partNumber: "MOBILE FEE",
|
partNumber: "MOBILE FEE",
|
||||||
|
|
@ -68,11 +69,10 @@ describe("service-location-helper.js", () => {
|
||||||
kitPrice: 0,
|
kitPrice: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Act
|
||||||
const result = await getPricedMobileFeePart(serviceZipCode);
|
const result = await getPricedMobileFeePart(serviceZipCode);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
expect(result).toEqual(expected);
|
expect(result).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//test.todo("some test to be written in the future");
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
ref="mobileLocationLink"
|
ref="mobileLocationLink"
|
||||||
id="mobileLocationLinkPromptId"
|
id="mobileLocationLinkPromptId"
|
||||||
linkType="text"
|
linkType="text"
|
||||||
:text="this.mobileLocationLinkText"
|
:text="mobileLocationLinkText"
|
||||||
href="#!"
|
href="#!"
|
||||||
@click-event="openModal"
|
@click-event="openModal"
|
||||||
aria-label="Modal window" />
|
aria-label="Modal window" />
|
||||||
|
|
@ -47,18 +47,21 @@
|
||||||
<script>
|
<script>
|
||||||
// Components
|
// Components
|
||||||
import textLink from "@/ux-components/text-link/text-link";
|
import textLink from "@/ux-components/text-link/text-link";
|
||||||
|
import textBlock from "@/digital-components/text-block/text-block";
|
||||||
import modal from "@/digital-components/modal/modal";
|
import modal from "@/digital-components/modal/modal";
|
||||||
import alert from "@/ux-components/alert/alert";
|
import alert from "@/ux-components/alert/alert";
|
||||||
import addressQuestions from "@/layouts/address-lookup/customer-questions/address-questions/address-questions";
|
import addressQuestions from "@/layouts/address-lookup/customer-questions/address-questions/address-questions";
|
||||||
import vehicleProtectedQuestion from "@/layouts/service-location/mobile-location-modal-questions/vehicle-protected-question/vehicle-protected-question";
|
import vehicleProtectedQuestion from "@/layouts/service-location/mobile-location-modal-questions/vehicle-protected-question/vehicle-protected-question";
|
||||||
import textBlock from "@/digital-components/text-block/text-block";
|
|
||||||
|
// Helpers
|
||||||
|
import { deepClone } from "@/helpers/object-cloning-helper";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "mobile-location-modal-questions",
|
name: "mobile-location-modal-questions",
|
||||||
emits: ["update:modelValue", "updated-zip-code"], // The component emits an event
|
emits: ["update:modelValue", "updated-zip-code"], // The component emits an event
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
internalModel: this.copyModel(this.modelValue),
|
internalModel: deepClone(this.modelValue),
|
||||||
displayInvalidZipAlert: false,
|
displayInvalidZipAlert: false,
|
||||||
modalName: "MobileLocationModalWidget",
|
modalName: "MobileLocationModalWidget",
|
||||||
};
|
};
|
||||||
|
|
@ -132,10 +135,6 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
copyModel(modelToCopy) {
|
|
||||||
return { ...modelToCopy };
|
|
||||||
},
|
|
||||||
|
|
||||||
openModal() {
|
openModal() {
|
||||||
this.$refs[this.modalName].openModal();
|
this.$refs[this.modalName].openModal();
|
||||||
},
|
},
|
||||||
|
|
@ -191,8 +190,11 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
modelValue(newValue) {
|
modelValue: {
|
||||||
this.internalModel = this.copyModel(newValue);
|
handler(newValue) {
|
||||||
|
this.internalModel = deepClone(newValue);
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
|
||||||
|
|
@ -95,11 +95,12 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return (
|
return true;
|
||||||
store.getters.lineItems.supportingItems !== null &&
|
// return (
|
||||||
store.getters.order.serviceLocation.zipCode !== null &&
|
// store.getters.lineItems.supportingItems !== null &&
|
||||||
store.getters.payment.isInsurance !== null
|
// store.getters.order.serviceLocation.zipCode !== null &&
|
||||||
);
|
// store.getters.payment.isInsurance !== null
|
||||||
|
// );
|
||||||
},
|
},
|
||||||
setData(mobileFeePart) {
|
setData(mobileFeePart) {
|
||||||
if (mobileFeePart) {
|
if (mobileFeePart) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue