Started working on Unit tests
This commit is contained in:
parent
cfc5cbd467
commit
ee60b23598
5 changed files with 358 additions and 113 deletions
|
|
@ -21,7 +21,7 @@ module.exports = {
|
|||
"!src/layouts/part-questions/**/*.vue",
|
||||
"!src/layouts/reveal/**/*.vue",
|
||||
// REMOVE THESE AFTER WRITING UNIT TESTS
|
||||
"!src/layouts/address-lookup/address-lookup.vue",
|
||||
|
||||
"!src/layouts/address-lookup/customer-questions/customer-questions.vue",
|
||||
"!src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue",
|
||||
// END
|
||||
|
|
|
|||
244
src/layouts/address-lookup/address-lookup.spec.js
Normal file
244
src/layouts/address-lookup/address-lookup.spec.js
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
// Components
|
||||
import addressLookup from "@/layouts/address-lookup/address-lookup.vue";
|
||||
import funnelHeader from "@/common-components/funnel-header/funnel-header";
|
||||
import funnelFooter from "@/common-components/funnel-footer/funnel-footer";
|
||||
import vehicleBanner from "@/common-components/vehicle-banner/vehicle-banner";
|
||||
import funnelSubHeader from "@/common-components/funnel-sub-header/funnel-sub-header";
|
||||
import customerQuestions from "@/layouts/address-lookup/customer-questions/customer-questions";
|
||||
import addressQuestions from "@/layouts/address-lookup/customer-questions/address-questions/address-questions";
|
||||
|
||||
// Supporting Files
|
||||
import { settleAllPromises } from "@/helpers/layout-helper.js";
|
||||
import baseMixin from "@/mixins/base-mixin";
|
||||
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
|
||||
import { mount, flushPromises } from "@vue/test-utils";
|
||||
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||
import { maska } from 'maska';
|
||||
import { nextTick } from "vue";
|
||||
import { storeActions } from "@/constants/store-actions";
|
||||
import { storeMutations } from "@/constants/store-mutations";
|
||||
import store from "@/store";
|
||||
import { validate } from "vee-validate";
|
||||
|
||||
// Mock our module for promises.
|
||||
jest.mock("@/helpers/layout-helper.js", () => ({
|
||||
settleAllPromises: jest.fn(),
|
||||
}));
|
||||
|
||||
// Mock fetchCmsContentForPage
|
||||
jest.mock("@/helpers/cms-content-helper", () => ({
|
||||
fetchCmsContentForPage: jest.fn(),
|
||||
}));
|
||||
|
||||
describe("address-lookup.vue", () => {
|
||||
test("Page header is initialized with api data", async (done) => {
|
||||
//Arrange
|
||||
const pageHeaderWidgetHeaderText = "Select Damage";
|
||||
const { wrapper, apiPromise } = setupMocks({
|
||||
pageHeaderWidgetHeaderText: pageHeaderWidgetHeaderText,
|
||||
});
|
||||
|
||||
//Act
|
||||
addressLookup.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "address-lookup" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
apiPromise.finally(() => {
|
||||
expect(funnelSubHeader.methods.initializeComponent).toHaveBeenCalledWith(
|
||||
pageHeaderWidgetHeaderText
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("Customer Questions component is initialized with api data", async (done) => {
|
||||
//Arrange
|
||||
const StreetAddressQuestionWidget = { QuestionText: "test" };
|
||||
const CityQuestionWidget = { QuestionText: "test" };
|
||||
const StateQuestionWidget = { QuestionText: "test" };
|
||||
const ZipQuestionWidget = { QuestionText: "test" };
|
||||
const FirstNameQuestionWidget = { QuestionText: "test" };
|
||||
const LastNameQuestionWidget = { QuestionText: "test" };
|
||||
const EmailAddressQuestionWidget = { QuestionText: "test" };
|
||||
const AlertVerificationWarningWidget = { HeaderText: "test", BodyText: "test" };
|
||||
const AlertNoMatchWarningWidget = { HeaderText: "test", BodyText: "test" };
|
||||
|
||||
const widgets = [
|
||||
StreetAddressQuestionWidget,
|
||||
CityQuestionWidget,
|
||||
StateQuestionWidget,
|
||||
ZipQuestionWidget,
|
||||
AlertVerificationWarningWidget,
|
||||
AlertNoMatchWarningWidget,
|
||||
FirstNameQuestionWidget,
|
||||
LastNameQuestionWidget,
|
||||
EmailAddressQuestionWidget,
|
||||
];
|
||||
|
||||
const { wrapper, apiPromise } = setupMocks({
|
||||
cmsContent: widgets,
|
||||
});
|
||||
|
||||
//Act
|
||||
addressLookup.beforeRouteEnter.call(
|
||||
wrapper.vm,
|
||||
{ query: { fmgPage: "address-lookup" } },
|
||||
undefined,
|
||||
(c) => c(wrapper.vm)
|
||||
);
|
||||
|
||||
//Assert
|
||||
apiPromise.finally(() => {
|
||||
expect(customerQuestions.methods.initializeComponent).toHaveBeenCalledWith(
|
||||
widgets
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
function setupMocks({
|
||||
pageHeaderWidgetHeaderText = {},
|
||||
mountOptionsMockData = {
|
||||
router: {
|
||||
navigate: jest.fn(),
|
||||
},
|
||||
store: {
|
||||
getters: {
|
||||
vehicle: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}) {
|
||||
//Mock api responses
|
||||
baseMixin.methods.dispatchNonBlockingStoreAction = jest.fn();
|
||||
const apiResponses = {
|
||||
cmsContent: {
|
||||
FunnelSubHeaderWidget: pageHeaderWidgetHeaderText,
|
||||
VehicleBannerWidget: {
|
||||
GenericVehicleImage:
|
||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/blurred-image.jpg?sfvrsn=a6ce3034_3",
|
||||
},
|
||||
FunnelHeaderWidget: {
|
||||
LogoImage:
|
||||
"https://digitalconsumercms-dev.safelite.com/images/default-source/default-album/safelite-logo.svg?sfvrsn=45e7ed06_3",
|
||||
},
|
||||
StreetAddressQuestionWidget: {
|
||||
QuestionText:
|
||||
"test"
|
||||
},
|
||||
CityQuestionWidget: {
|
||||
QuestionText:
|
||||
"test"
|
||||
},
|
||||
StateQuestionWidget: {
|
||||
QuestionText:
|
||||
"test"
|
||||
},
|
||||
ZipQuestionWidget: {
|
||||
QuestionText:
|
||||
"test"
|
||||
},
|
||||
FirstNameQuestionWidget: {
|
||||
QuestionText:
|
||||
"test"
|
||||
},
|
||||
LastNameQuestionWidget: {
|
||||
QuestionText:
|
||||
"test"
|
||||
},
|
||||
EmailAddressQuestionWidget: {
|
||||
QuestionText:
|
||||
"test"
|
||||
},
|
||||
AlertVerificationWarningWidget: {
|
||||
HeaderText:
|
||||
"test",
|
||||
BodyText:
|
||||
"test",
|
||||
},
|
||||
AlertNoMatchWarningWidget: {
|
||||
HeaderText:
|
||||
"test",
|
||||
BodyText:
|
||||
"test",
|
||||
},
|
||||
|
||||
},
|
||||
};
|
||||
|
||||
const apiPromise = Promise.resolve(apiResponses);
|
||||
|
||||
settleAllPromises.mockImplementation(() => apiPromise);
|
||||
fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
|
||||
|
||||
//Mock damage initialize methods
|
||||
funnelHeader.methods = {
|
||||
initializeComponent: jest.fn(),
|
||||
};
|
||||
|
||||
vehicleBanner.methods = {
|
||||
initializeComponent: jest.fn(),
|
||||
};
|
||||
|
||||
funnelSubHeader.methods = {
|
||||
initializeComponent: jest.fn(),
|
||||
};
|
||||
|
||||
funnelFooter.methods = {
|
||||
initializeComponent: jest.fn(),
|
||||
};
|
||||
|
||||
customerQuestions.methods = {
|
||||
initializeComponent: jest.fn(),
|
||||
};
|
||||
|
||||
addressQuestions.methods = {
|
||||
initializeComponent: jest.fn(),
|
||||
setupAddressLookup: jest.fn(),
|
||||
};
|
||||
|
||||
const mountOptions = getMountOptions(mountOptionsMockData);
|
||||
mountOptions['attachTo'] = document.body; // append wrapper to document.body to test DOM methods
|
||||
|
||||
mountOptions.global.directives = {
|
||||
maska: maska
|
||||
};
|
||||
|
||||
const wrapper = mount(addressLookup, mountOptions);
|
||||
|
||||
const funnelHeaderWrapper = wrapper.findComponent({ name: "funnelHeader" });
|
||||
funnelHeaderWrapper.vm.initializeComponent =
|
||||
funnelHeader.methods.initializeComponent;
|
||||
|
||||
const vehicleBannerWrapper = wrapper.findComponent({ name: "vehicleBanner" });
|
||||
vehicleBannerWrapper.vm.initializeComponent =
|
||||
vehicleBanner.methods.initializeComponent;
|
||||
|
||||
const funnelSubHeaderWrapper = wrapper.findComponent({ name: "funnelSubHeader" });
|
||||
funnelSubHeaderWrapper.vm.initializeComponent =
|
||||
funnelSubHeader.methods.initializeComponent;
|
||||
|
||||
const funnelFooterWrapper = wrapper.findComponent({ name: "funnelFooter" });
|
||||
funnelFooterWrapper.vm.initializeComponent =
|
||||
funnelFooter.methods.initializeComponent;
|
||||
|
||||
const customerQuestionsWrapper = wrapper.findComponent({ name: "customerQuestions" });
|
||||
customerQuestionsWrapper.vm.initializeComponent =
|
||||
customerQuestions.methods.initializeComponent;
|
||||
|
||||
const addressQuestionsWrapper = wrapper.findComponent({ name: "addressQuestions" });
|
||||
addressQuestionsWrapper.vm.initializeComponent =
|
||||
addressQuestions.methods.initializeComponent;
|
||||
addressQuestionsWrapper.vm.setupAddressLookup =
|
||||
addressQuestions.methods.setupAddressLookup;
|
||||
|
||||
return { wrapper, apiPromise };
|
||||
}
|
||||
|
|
@ -66,15 +66,15 @@ export default {
|
|||
resultMap.cmsContent.FunnelFooterWidget
|
||||
);
|
||||
vm.$refs.customerQuestions.initializeComponent([
|
||||
resultMap.cmsContent.StreetAddressQuestionWidget,
|
||||
resultMap.cmsContent.CityQuestionWidget,
|
||||
resultMap.cmsContent.StateQuestionWidget,
|
||||
resultMap.cmsContent.ZipQuestionWidget,
|
||||
resultMap.cmsContent.AlertVerificationWarningWidget,
|
||||
resultMap.cmsContent.AlertNoMatchWarningWidget,
|
||||
resultMap.cmsContent.FirstNameQuestionWidget,
|
||||
resultMap.cmsContent.LastNameQuestionWidget,
|
||||
resultMap.cmsContent.EmailAddressQuestionWidget,
|
||||
resultMap.cmsContent.StreetAddressQuestionWidget,
|
||||
resultMap.cmsContent.CityQuestionWidget,
|
||||
resultMap.cmsContent.StateQuestionWidget,
|
||||
resultMap.cmsContent.ZipQuestionWidget,
|
||||
resultMap.cmsContent.AlertVerificationWarningWidget,
|
||||
resultMap.cmsContent.AlertNoMatchWarningWidget,
|
||||
resultMap.cmsContent.FirstNameQuestionWidget,
|
||||
resultMap.cmsContent.LastNameQuestionWidget,
|
||||
resultMap.cmsContent.EmailAddressQuestionWidget,
|
||||
|
||||
]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -165,112 +165,113 @@ export default ({
|
|||
|
||||
this.alertHeadlineNoMatchWarning = cmsContent[5].HeadlineText;
|
||||
this.alertCopyNoMatchWarning = cmsContent[5].BodyText;
|
||||
},
|
||||
|
||||
setupAddressLookup() {
|
||||
const addressField1 = document.getElementById("autocomplete");
|
||||
const self = this;
|
||||
|
||||
const apiKey = applicationConfig.GOOGLE_PLACES_API_KEY;
|
||||
|
||||
this.$loadScript(`https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`)
|
||||
.then(() => {
|
||||
// Script is loaded, initialize the autocomplete textbox
|
||||
const autocomplete = new window.google.maps.places.Autocomplete(
|
||||
addressField1,
|
||||
{
|
||||
componentRestrictions: { country: ["us"] },
|
||||
fields: ["address_components"],
|
||||
types: ["address"],
|
||||
}
|
||||
);
|
||||
|
||||
// Standard place_changed event handling
|
||||
autocomplete.addListener('place_changed', fillInAddress);
|
||||
|
||||
addressField1.onblur = function() {
|
||||
const hover = document.querySelector(".pac-container .pac-item:hover");
|
||||
|
||||
// if an item has been clicked, do nothing, otherwise get first solution and use Geocoder to get the place
|
||||
if (hover === null) {
|
||||
const item = document.querySelector(".pac-container .pac-item");
|
||||
if (item != null) {
|
||||
const firstResult = item.textContent;
|
||||
const geocoder = new window.google.maps.Geocoder();
|
||||
geocoder.geocode({
|
||||
address: firstResult
|
||||
}, function (results, status) {
|
||||
if (status === window.google.maps.GeocoderStatus.OK) {
|
||||
fillInAddress(results[0]);
|
||||
self.displayVerificationWarning = true;
|
||||
self.displayNoMatchWarning = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
self.addressModel.city = "";
|
||||
self.addressModel.state = "";
|
||||
self.addressModel.zip = "";
|
||||
self.showAddressFields = true;
|
||||
self.displayVerificationWarning = false;
|
||||
self.displayNoMatchWarning = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function fillInAddress(place) {
|
||||
if (!place) {
|
||||
place = autocomplete.getPlace();
|
||||
}
|
||||
|
||||
if (place && place.address_components) {
|
||||
self.addressModel.streetAddress= "";
|
||||
self.showAddressFields = true;
|
||||
|
||||
for (const component of place.address_components) {
|
||||
const componentType = component.types[0];
|
||||
|
||||
switch (componentType) {
|
||||
case "street_number": {
|
||||
self.addressModel.streetAddress = component.long_name;
|
||||
break;
|
||||
}
|
||||
case "route": {
|
||||
self.addressModel.streetAddress += ' ' + component.short_name;
|
||||
break;
|
||||
}
|
||||
case "locality": {
|
||||
self.addressModel.city = component.long_name;
|
||||
break;
|
||||
}
|
||||
case "administrative_area_level_1": {
|
||||
self.addressModel.state = component.short_name;
|
||||
break;
|
||||
}
|
||||
case "postal_code": {
|
||||
self.addressModel.zip = component.long_name;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
self.displayVerificationWarning = false;
|
||||
self.displayNoMatchWarning = false;
|
||||
}
|
||||
else {
|
||||
self.displayVerificationWarning = true;
|
||||
self.displayNoMatchWarning = false;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Failed to fetch script
|
||||
console.log("Unable to load Google Places API script");
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
const addressField1 = document.getElementById("autocomplete");
|
||||
const self = this;
|
||||
|
||||
const apiKey = applicationConfig.GOOGLE_PLACES_API_KEY;
|
||||
|
||||
this.$loadScript(`https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`)
|
||||
.then(() => {
|
||||
// Script is loaded, initialize the autocomplete textbox
|
||||
const autocomplete = new window.google.maps.places.Autocomplete(
|
||||
addressField1,
|
||||
{
|
||||
componentRestrictions: { country: ["us"] },
|
||||
fields: ["address_components"],
|
||||
types: ["address"],
|
||||
}
|
||||
);
|
||||
|
||||
// Standard place_changed event handling
|
||||
autocomplete.addListener('place_changed', fillInAddress);
|
||||
|
||||
addressField1.onblur = function() {
|
||||
const hover = document.querySelector(".pac-container .pac-item:hover");
|
||||
|
||||
// if an item has been clicked, do nothing, otherwise get first solution and use Geocoder to get the place
|
||||
if (hover === null) {
|
||||
const item = document.querySelector(".pac-container .pac-item");
|
||||
if (item != null) {
|
||||
const firstResult = item.textContent;
|
||||
const geocoder = new window.google.maps.Geocoder();
|
||||
geocoder.geocode({
|
||||
address: firstResult
|
||||
}, function (results, status) {
|
||||
if (status === window.google.maps.GeocoderStatus.OK) {
|
||||
fillInAddress(results[0]);
|
||||
self.displayVerificationWarning = true;
|
||||
self.displayNoMatchWarning = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
self.addressModel.city = "";
|
||||
self.addressModel.state = "";
|
||||
self.addressModel.zip = "";
|
||||
self.showAddressFields = true;
|
||||
self.displayVerificationWarning = false;
|
||||
self.displayNoMatchWarning = true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
function fillInAddress(place) {
|
||||
if (!place) {
|
||||
place = autocomplete.getPlace();
|
||||
}
|
||||
|
||||
if (place && place.address_components) {
|
||||
self.addressModel.streetAddress= "";
|
||||
self.showAddressFields = true;
|
||||
|
||||
for (const component of place.address_components) {
|
||||
const componentType = component.types[0];
|
||||
|
||||
switch (componentType) {
|
||||
case "street_number": {
|
||||
self.addressModel.streetAddress = component.long_name;
|
||||
break;
|
||||
}
|
||||
case "route": {
|
||||
self.addressModel.streetAddress += ' ' + component.short_name;
|
||||
break;
|
||||
}
|
||||
case "locality": {
|
||||
self.addressModel.city = component.long_name;
|
||||
break;
|
||||
}
|
||||
case "administrative_area_level_1": {
|
||||
self.addressModel.state = component.short_name;
|
||||
break;
|
||||
}
|
||||
case "postal_code": {
|
||||
self.addressModel.zip = component.long_name;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
self.displayVerificationWarning = false;
|
||||
self.displayNoMatchWarning = false;
|
||||
}
|
||||
else {
|
||||
self.displayVerificationWarning = true;
|
||||
self.displayNoMatchWarning = false;
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Failed to fetch script
|
||||
console.log("Unable to load Google Places API script");
|
||||
});
|
||||
this.setupAddressLookup();
|
||||
},
|
||||
components: {
|
||||
textboxQuestion,
|
||||
|
|
|
|||
Loading…
Reference in a new issue