Merge branch 'develop' into feature/CSR-1093

This commit is contained in:
Leah Schumann 2023-03-30 10:38:20 -04:00
commit 4a105a0ec9
4 changed files with 428 additions and 59 deletions

View file

@ -49,10 +49,8 @@ describe("appointment-type-question.vue", () => {
mixins: [mockMixin], mixins: [mockMixin],
props: { props: {
cmsWidgetName: cmsWidgetName, cmsWidgetName: cmsWidgetName,
isGlassServiceableInshop: true, isServiceableInshop: true,
isRecalibrationServiceableInshop: true, isServiceableMobile: true,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true,
}, },
mountOptions: { mountOptions: {
attachTo: document.body, attachTo: document.body,
@ -91,10 +89,8 @@ describe("appointment-type-question.vue", () => {
mixins: [mockMixin], mixins: [mockMixin],
props: { props: {
cmsWidgetName: cmsWidgetName, cmsWidgetName: cmsWidgetName,
isGlassServiceableInshop: true, isServiceableInshop: true,
isRecalibrationServiceableInshop: true, isServiceableMobile: false,
isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: false,
}, },
mountOptions: { mountOptions: {
attachTo: document.body, attachTo: document.body,
@ -126,10 +122,8 @@ describe("appointment-type-question.vue", () => {
mixins: [mockMixin], mixins: [mockMixin],
props: { props: {
cmsWidgetName: cmsWidgetName, cmsWidgetName: cmsWidgetName,
isGlassServiceableInshop: false, isServiceableInshop: false,
isRecalibrationServiceableInshop: false, isServiceableMobile: true,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true,
}, },
mountOptions: { mountOptions: {
attachTo: document.body, attachTo: document.body,
@ -154,10 +148,8 @@ describe("appointment-type-question.vue", () => {
mixins: [mockMixin], mixins: [mockMixin],
props: { props: {
cmsWidgetName: cmsWidgetName, cmsWidgetName: cmsWidgetName,
isGlassServiceableInshop: false, isServiceableInshop: false,
isRecalibrationServiceableInshop: false, isServiceableMobile: false,
isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: false,
}, },
mountOptions: { mountOptions: {
attachTo: document.body, attachTo: document.body,

View file

@ -26,10 +26,8 @@ export default {
suppressError: Boolean, suppressError: Boolean,
validationRules: String, validationRules: String,
cmsWidgetName: String, cmsWidgetName: String,
isGlassServiceableMobile: Boolean, isServiceableMobile: Boolean,
isGlassServiceableInshop: Boolean, isServiceableInshop: Boolean,
isRecalibrationServiceableInshop: Boolean,
isRecalibrationServiceableMobile: Boolean,
}, },
computed: { computed: {
questionText() { questionText() {
@ -40,45 +38,20 @@ export default {
}, },
answersToDisplay() { answersToDisplay() {
let filteredAnswers; let filteredAnswers;
if (this.serviceability == "All") { if (this.isServiceableMobile && this.isServiceableInshop) {
filteredAnswers = this.answersFromCms; filteredAnswers = this.answersFromCms;
} else if (this.serviceability == "MobileOnly") { } else if (this.isServiceableMobile) {
filteredAnswers = this.answersFromCms.filter((answer) => answer.Name == "Mobile"); filteredAnswers = this.answersFromCms.filter((answer) => answer.Name == "Mobile");
} else if (this.serviceability == "InshopOnly") { } else if (this.isServiceableInshop) {
filteredAnswers = this.answersFromCms.filter( filteredAnswers = this.answersFromCms.filter(
(answer) => answer.Name == "Inshop" || answer.Name == "DropOff" (answer) => answer.Name == "Inshop" || answer.Name == "DropOff"
); );
} else if (this.serviceability == "None") { } else {
filteredAnswers = []; filteredAnswers = [];
} }
return filteredAnswers; return filteredAnswers;
}, },
serviceability() {
let mobileAvailable;
if (this.IsRecalibrationServiceableMobile == null) {
mobileAvailable = this.isGlassServiceableMobile;
} else {
mobileAvailable =
this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile;
}
const inshopAvailable =
this.isGlassServiceableInshop && this.isRecalibrationServiceableInshop;
let result;
if (inshopAvailable && mobileAvailable) {
result = "All";
} else if (inshopAvailable && !mobileAvailable) {
result = "InshopOnly";
} else if (!inshopAvailable && mobileAvailable) {
result = "MobileOnly";
} else if (!inshopAvailable && !mobileAvailable) {
result = "None";
}
return result;
},
selectedValues: { selectedValues: {
get: function () { get: function () {
return this.modelValue; return this.modelValue;
@ -87,11 +60,14 @@ export default {
this.$emit("update:modelValue", newValue); this.$emit("update:modelValue", newValue);
}, },
}, },
isMobileOnly() {
return this.isServiceableMobile && !this.isServiceableInshop;
},
}, },
watch: { watch: {
serviceability: { isMobileOnly: {
handler(newValue) { handler(newValue) {
if (newValue == "MobileOnly") { if (newValue) {
this.selectedValues = "Mobile"; this.selectedValues = "Mobile";
} else { } else {
this.selectedValues = null; this.selectedValues = null;

View file

@ -7,6 +7,7 @@ import { getMountOptions } from "@/helpers/unit-test-helper";
import store from "@/store"; import store from "@/store";
import baseMixin from "@/mixins/base-mixin"; import baseMixin from "@/mixins/base-mixin";
import { getServiceabilityDetails } from "@/layouts/service-location/helpers/service-location-helper/service-location-helper";
// Define Mocks // Define Mocks
jest.mock("@/helpers/cms-content-helper", () => ({ jest.mock("@/helpers/cms-content-helper", () => ({
@ -437,6 +438,386 @@ describe("service-location.vue", () => {
expect(wrapper.vm.serviceZipCodeQuestion).toStrictEqual(newServiceZipCodeInfo); expect(wrapper.vm.serviceZipCodeQuestion).toStrictEqual(newServiceZipCodeInfo);
}); });
}); });
describe("serviceability logic", () => {
describe("should be logical AND when recalibration is defined.", () => {
test("T & T => T", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(true);
expect(wrapper.vm.isServiceableInshop).toEqual(true);
});
test("T & F => F", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: false,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: false,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(false);
expect(wrapper.vm.isServiceableInshop).toEqual(false);
});
test("F & T => F", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: true,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(false);
expect(wrapper.vm.isServiceableInshop).toEqual(false);
});
test("F & F => F", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: false,
isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: false,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(false);
expect(wrapper.vm.isServiceableInshop).toEqual(false);
});
test("displayServiceableMobileOnly should be true if mobile is true and inshop is false.", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: false,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(true);
expect(wrapper.vm.isServiceableInshop).toEqual(false);
expect(wrapper.vm.displayServiceableMobileOnly).toEqual(true);
});
test("displayServiceableMobileOnly should be false if mobile is false.", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: false,
isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: false,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(false);
expect(wrapper.vm.isServiceableInshop).toEqual(false);
expect(wrapper.vm.displayServiceableMobileOnly).toEqual(false);
});
test("displayServiceableMobileOnly should be false if inShop is true", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(true);
expect(wrapper.vm.isServiceableInshop).toEqual(true);
expect(wrapper.vm.displayServiceableMobileOnly).toEqual(false);
});
});
describe("should be based only on glass serviceability if recalibration is not defined.", () => {
test("Should return true", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: null,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(true);
expect(wrapper.vm.isServiceableInshop).toEqual(true);
});
test("Should return false", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: null,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(false);
expect(wrapper.vm.isServiceableInshop).toEqual(false);
});
test("displayServiceableMobileOnly should be true if mobile is true and inshop is false.", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: null,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(true);
expect(wrapper.vm.isServiceableInshop).toEqual(false);
expect(wrapper.vm.displayServiceableMobileOnly).toEqual(true);
});
test("displayServiceableMobileOnly should be false if mobile is false", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: false,
isRecalibrationServiceableMobile: null,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(false);
expect(wrapper.vm.isServiceableInshop).toEqual(false);
expect(wrapper.vm.displayServiceableMobileOnly).toEqual(false);
});
test("displayServiceableMobileOnly should be false if inShop is true", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: null,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: null,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
// Assert
expect(wrapper.vm.isServiceableMobile).toEqual(true);
expect(wrapper.vm.isServiceableInshop).toEqual(true);
expect(wrapper.vm.displayServiceableMobileOnly).toEqual(false);
});
});
describe("should properly display alerts.", () => {
test("Should show mobile-only error if only mobile is available.", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: false,
isRecalibrationServiceableInshop: false,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
const alertComponent = wrapper.findComponent({ ref: "alertMobileOnly" });
// Assert
expect(alertComponent.exists()).toBe(true);
});
test("Should not show mobile-only error if not mobile-only.", async () => {
// Arrange
getServiceabilityDetails.mockImplementation(() =>
Promise.resolve({
isGlassServiceableInshop: true,
isRecalibrationServiceableInshop: true,
isGlassServiceableMobile: true,
isRecalibrationServiceableMobile: true,
})
);
const { wrapper } = setupMocks({});
// Act
await serviceLocation.beforeRouteEnter.call(
wrapper.vm,
{ query: { fmgPage: "serviceLocation" } },
undefined,
(c) => c(wrapper.vm)
);
const alertComponent = wrapper.findComponent({ ref: "alertMobileOnly" });
// Assert
expect(alertComponent.exists()).toBe(false);
});
});
});
}); });
function setupMocks({ mountOptionsMockData = {} }) { function setupMocks({ mountOptionsMockData = {} }) {

View file

@ -14,21 +14,27 @@
linkWidgetName="ServiceZipLinkWidget" linkWidgetName="ServiceZipLinkWidget"
modalWidgetName="ServiceZipModalWidget" /> modalWidgetName="ServiceZipModalWidget" />
<alert <alert
ref="alertMilitaryBaseZip"
class="my-4" class="my-4"
cmsWidgetName="AlertMilitaryBaseZipWidget" cmsWidgetName="AlertMilitaryBaseZipWidget"
v-if="displayMilitaryZipAlert" v-if="displayMilitaryZipAlert"
alertClass="alert-warning" /> alertClass="alert-warning" />
<alert <alert
ref="alertMobileOnly"
class="my-4"
cmsWidgetName="AlertMobileOnlyWidget"
v-if="displayServiceableMobileOnly"
alertClass="alert-warning" />
<alert
ref="alertNoShops"
class="my-4" class="my-4"
cmsWidgetName="AlertNoShopsWidget" cmsWidgetName="AlertNoShopsWidget"
v-if="displayNoShopsAlert" v-if="displayNoShopsAlert"
alertClass="alert-warning" /> alertClass="alert-warning" />
<appointmentTypeQuestion <appointmentTypeQuestion
v-model="selectedAppointmentType" v-model="selectedAppointmentType"
:isGlassServiceableInshop="isGlassServiceableInshop" :isServiceableMobile="isServiceableMobile"
:isRecalibrationServiceableInshop="isRecalibrationServiceableInshop" :isServiceableInshop="isServiceableInshop"
:isGlassServiceableMobile="isGlassServiceableMobile"
:isRecalibrationServiceableMobile="isRecalibrationServiceableMobile"
ref="appointmentTypeQuestion" ref="appointmentTypeQuestion"
groupName="appointmentTypeQuestion" groupName="appointmentTypeQuestion"
cmsWidgetName="AppointmentTypeQuestionWidget" cmsWidgetName="AppointmentTypeQuestionWidget"
@ -195,10 +201,24 @@ export default {
}, },
}, },
displayMilitaryZipAlert() { displayMilitaryZipAlert() {
const isZipServiceableMobile = return this.zipContainsMilitaryBase && this.isServiceableMobile;
this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile; },
isServiceableMobile() {
return this.zipContainsMilitaryBase && isZipServiceableMobile; if (this.isRecalibrationServiceableMobile !== null) {
return this.isGlassServiceableMobile && this.isRecalibrationServiceableMobile;
} else {
return this.isGlassServiceableMobile;
}
},
isServiceableInshop() {
if (this.isRecalibrationServiceableInshop !== null) {
return this.isGlassServiceableInshop && this.isRecalibrationServiceableInshop;
} else {
return this.isGlassServiceableInshop;
}
},
displayServiceableMobileOnly() {
return this.isServiceableMobile && !this.isServiceableInshop;
}, },
displayNoShopsAlert() { displayNoShopsAlert() {
let mobileAvailable; let mobileAvailable;