diff --git a/src/layouts/scheduling/scheduling-zip-search/scheduling-zip-search.spec.js b/src/layouts/scheduling/scheduling-zip-search/scheduling-zip-search.spec.js
index e75a76a17..a384b1603 100644
--- a/src/layouts/scheduling/scheduling-zip-search/scheduling-zip-search.spec.js
+++ b/src/layouts/scheduling/scheduling-zip-search/scheduling-zip-search.spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from "@vue/test-utils";
import schedulingZipSearch from "./scheduling-zip-search";
import store from "@/store";
+import { errorMessages } from "@/constants/error-messages";
import {
getBillToAccountNumber,
getZipCodeData,
@@ -21,77 +22,72 @@ jest.mock(
})
);
-function mountComponent(props = {}) {
+function createWrapper(props = {}) {
return shallowMount(schedulingZipSearch, {
props: {
- modelValue: "43235",
+ modelValue: "",
pageNameToLog: "scheduling",
...props,
},
+ global: {
+ mocks: {
+ $root: {
+ cmsContentByWidget: {
+ ServiceZipQuestionWidget: {
+ QuestionText: "Service ZIP code:",
+ },
+ },
+ },
+ },
+ },
});
}
describe("scheduling-zip-search.vue", () => {
- test("renders serviceZipQuestion with search icon", () => {
- const wrapper = mountComponent();
- const zipQuestion = wrapper.find("service-zip-question-stub");
- expect(zipQuestion.exists()).toBe(true);
- expect(zipQuestion.attributes("includesearchicon")).toBeDefined();
- wrapper.unmount();
+ beforeEach(() => {
+ jest.clearAllMocks();
});
- test("validates zip on search when field is blank", async () => {
- const validate = jest.fn().mockResolvedValue({ valid: false });
- const wrapper = mountComponent({ modelValue: "" });
- Object.defineProperty(wrapper.vm.$refs, "zipCodeSearch", {
- configurable: true,
- value: {
- $refs: {
- zipInputTextQuestion: { validate },
- },
- },
- });
+ test("prefills the zip input and CMS label from modelValue / ServiceZipQuestionWidget", () => {
+ const wrapper = createWrapper({ modelValue: "43235" });
+
+ expect(wrapper.find("#sz-service-zip").element.value).toBe("43235");
+ expect(wrapper.vm.zipLabelText).toBe("Service ZIP code:");
+ expect(wrapper.find("label").html()).toContain("Service ZIP code:");
+ });
+
+ test("shows required error when searching with a blank zip", async () => {
+ const wrapper = createWrapper({ modelValue: "" });
await wrapper.vm.onZipSearch({ preventDefault: jest.fn() });
- expect(validate).toHaveBeenCalled();
+ expect(wrapper.vm.errorMessage).toBe(errorMessages.SERVICE_ZIP_REQUIRED);
+ expect(wrapper.find(".scheduling-zip-search__error").classes()).toContain("active");
+ expect(getZipCodeData).not.toHaveBeenCalled();
+ expect(wrapper.emitted("zip-searched")).toBeUndefined();
+ });
+
+ test("shows format error when zip is invalid", async () => {
+ const wrapper = createWrapper({ modelValue: "123" });
+
+ await wrapper.vm.onZipSearch({ preventDefault: jest.fn() });
+
+ expect(wrapper.vm.errorMessage).toBe(errorMessages.SERVICE_ZIP_FORMAT);
expect(getZipCodeData).not.toHaveBeenCalled();
expect(wrapper.emitted("zip-searched")).toBeUndefined();
- wrapper.unmount();
});
test("does not search when disabled", async () => {
- const validate = jest.fn().mockResolvedValue({ valid: true });
- const wrapper = mountComponent({ disabled: true });
- Object.defineProperty(wrapper.vm.$refs, "zipCodeSearch", {
- configurable: true,
- value: {
- $refs: {
- zipInputTextQuestion: { validate },
- },
- },
- });
+ const wrapper = createWrapper({ modelValue: "44101", disabled: true });
await wrapper.vm.onZipSearch({ preventDefault: jest.fn() });
- expect(validate).toHaveBeenCalled();
expect(getZipCodeData).not.toHaveBeenCalled();
- wrapper.unmount();
+ expect(wrapper.emitted("zip-searched")).toBeUndefined();
});
test("saves zip info and emits billToAccountNumber when a valid zip is searched", async () => {
- store.dispatch.mockClear();
- const wrapper = mountComponent({ modelValue: "44101" });
- Object.defineProperty(wrapper.vm.$refs, "zipCodeSearch", {
- configurable: true,
- value: {
- $refs: {
- zipInputTextQuestion: {
- validate: jest.fn().mockResolvedValue({ valid: true }),
- },
- },
- },
- });
+ const wrapper = createWrapper({ modelValue: "44101" });
await wrapper.vm.onZipSearch({ preventDefault: jest.fn() });
@@ -105,6 +101,20 @@ describe("scheduling-zip-search.vue", () => {
expect(wrapper.emitted("zip-searched")).toEqual([
[{ zipCode: "44101", billToAccountNumber: "87291" }],
]);
- wrapper.unmount();
+ });
+
+ test("focusZipInput scrolls and focuses the zip input", () => {
+ const wrapper = createWrapper({ modelValue: "43235" });
+ const zipInput = wrapper.find("#sz-service-zip").element;
+ zipInput.scrollIntoView = jest.fn();
+ zipInput.focus = jest.fn();
+
+ wrapper.vm.focusZipInput();
+
+ expect(zipInput.scrollIntoView).toHaveBeenCalledWith({
+ behavior: "smooth",
+ block: "center",
+ });
+ expect(zipInput.focus).toHaveBeenCalledWith({ preventScroll: true });
});
});
diff --git a/src/layouts/scheduling/scheduling-zip-search/scheduling-zip-search.vue b/src/layouts/scheduling/scheduling-zip-search/scheduling-zip-search.vue
index 75aad0029..25203fd28 100644
--- a/src/layouts/scheduling/scheduling-zip-search/scheduling-zip-search.vue
+++ b/src/layouts/scheduling/scheduling-zip-search/scheduling-zip-search.vue
@@ -1,37 +1,47 @@
-
-
-
+
+
+
+
+
+
+
+ {{ errorMessage }}
+
+
diff --git a/src/layouts/scheduling/scheduling.spec.js b/src/layouts/scheduling/scheduling.spec.js
index aa5cc4a78..60347ace7 100644
--- a/src/layouts/scheduling/scheduling.spec.js
+++ b/src/layouts/scheduling/scheduling.spec.js
@@ -185,15 +185,11 @@ describe("scheduling.vue", () => {
});
describe("service zip", () => {
- test("prefills zipSearchCode and billToAccountNumber from store on mount", () => {
+ test("prefills zipSearchCode and billToAccountNumber from store and renders zip search", () => {
const { wrapper } = setupMocks();
+
expect(wrapper.vm.zipSearchCode).toBe("43235");
expect(wrapper.vm.billToAccountNumber).toBe("12345");
- wrapper.unmount();
- });
-
- test("renders schedulingZipSearch", () => {
- const { wrapper } = setupMocks();
expect(wrapper.find("scheduling-zip-search-stub").exists()).toBe(true);
wrapper.unmount();
});
@@ -228,16 +224,10 @@ describe("scheduling.vue", () => {
await wrapper.vm.onZipSearched({ zipCode: "44101", billToAccountNumber: "87291" });
- const getProvidersDispatch = store.dispatch.mock.calls.find(
- ([actionName]) => actionName === "getProviders"
- );
- expect(getProvidersDispatch).toEqual([
- "getProviders",
- {
- payload: { serviceZipCode: "44101" },
- pageNameToLog: undefined,
- },
- ]);
+ expect(store.dispatch).toHaveBeenCalledWith("getProviders", {
+ payload: { serviceZipCode: "44101" },
+ pageNameToLog: undefined,
+ });
expect(wrapper.vm.billToAccountNumber).toBe("87291");
expect(settleAllPromises).toHaveBeenCalled();
expect(wrapper.vm.datePickerKey).toBe(initialDatePickerKey + 1);
@@ -248,5 +238,16 @@ describe("scheduling.vue", () => {
expect(wrapper.vm.mobileProviderAndTimeSlot.providerNumber).toBe("12345");
wrapper.unmount();
});
+
+ test("anchors to zip search when mobile zip is clicked", () => {
+ const { wrapper } = setupMocks();
+ const focusZipInput = jest.fn();
+ wrapper.vm.$refs.schedulingZipSearch = { focusZipInput };
+
+ wrapper.vm.onMobileZipCodeClicked();
+
+ expect(focusZipInput).toHaveBeenCalled();
+ wrapper.unmount();
+ });
});
});
diff --git a/src/layouts/scheduling/scheduling.vue b/src/layouts/scheduling/scheduling.vue
index a0f67df4a..b9d11a8bc 100644
--- a/src/layouts/scheduling/scheduling.vue
+++ b/src/layouts/scheduling/scheduling.vue
@@ -12,6 +12,7 @@