diff --git a/src/layouts/mobile-details/mobile-details.spec.js b/src/layouts/mobile-details/mobile-details.spec.js index a88dcab3d..a0c548a54 100644 --- a/src/layouts/mobile-details/mobile-details.spec.js +++ b/src/layouts/mobile-details/mobile-details.spec.js @@ -89,18 +89,53 @@ describe("mobile-details.vue", () => { // Assert expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled(); }); - test("arePagePrerequisitesValid should be true ", async () => { - //Arrange - const { wrapper } = setupMocks({ - mixins: [mockMixin], - attachTo: document.body, + describe("arePagePrerequisitesValid", () => { + test("returns true when all prerequisites are valid", () => { + const { wrapper } = setupMocks({ + mixins: [mockMixin], + attachTo: document.body, + }); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(true); }); - //Act - let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid(); + test("returns falsy when service zip info is missing", () => { + store.getters.order.serviceLocation.zipCode = null; + const { wrapper } = setupMocks({ + mixins: [mockMixin], + attachTo: document.body, + }); - //Assert - expect(arePagePrerequisitesValid).toBe(true); + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBeFalsy(); + }); + + test("returns false when appointment type is not mobile", () => { + store.getters.order.serviceLocation.appointmentType = "Inshop"; + const { wrapper } = setupMocks({ + mixins: [mockMixin], + attachTo: document.body, + }); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when scheduling info is missing", () => { + store.getters.order.schedule.date = null; + const { wrapper } = setupMocks({ + mixins: [mockMixin], + attachTo: document.body, + }); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); }); test("if the back button is clicked, navigate back", async () => { diff --git a/src/layouts/payment-adyen/payment-adyen.spec.js b/src/layouts/payment-adyen/payment-adyen.spec.js new file mode 100644 index 000000000..e13b468c7 --- /dev/null +++ b/src/layouts/payment-adyen/payment-adyen.spec.js @@ -0,0 +1,201 @@ +import paymentAdyen from "@/layouts/payment-adyen/payment-adyen.vue"; +import { shallowMount } from "@vue/test-utils"; +import { getMountOptions } from "@/helpers/unit-test-helper"; +import store from "@/store"; +import { AppointmentTypeStrings } from "@/constants/schedule-constants"; + +jest.mock("@/helpers/pricing-helper.js", () => ({ + getAmountDue: jest.fn().mockReturnValue(100), +})); + +jest.mock("@/helpers/cms-content-helper", () => ({ + fetchCmsContentForPage: () => Promise.resolve("content"), +})); + +jest.mock("@/helpers/layout-helper", () => ({ + settleAllPromises: jest.fn().mockResolvedValue({ cmsContent: "content" }), +})); + +jest.mock("@/helpers/loading-modal-helper", () => ({ + showFmgLoadingModal: jest.fn(), +})); + +jest.mock("@/helpers/heritage-integration/order-helper.js", () => ({ + submitWorkOrder: jest.fn(), +})); + +jest.mock("@/helpers/debug-log-helper.js", () => ({ + debugLog: jest.fn(), +})); + +// Component that skips Adyen initialization in mounted (only needed for arePagePrerequisitesValid tests) +const PaymentAdyenTestComponent = { + ...paymentAdyen, + mounted() { + // Stub - skip initializeAdyen to avoid Adyen/API setup + }, +}; + +const createValidOrder = () => ({ + vehicle: { + year: "2020", + make: "acura", + model: "mdx", + carId: "dummyCarId", + }, + serviceLocation: { + address: "123 Main St", + address2: "", + city: "Columbus", + state: "OH", + zipCode: "43235", + zipCodeCtu: "43235", + appointmentType: AppointmentTypeStrings.IN_SHOP, + provider: { + address: { + streetAddress: "456 Provider St", + city: "Columbus", + state: "OH", + zipCode: "43235", + zipCodeCtu: "43235", + }, + }, + }, + customer: { + firstName: "John", + lastName: "Doe", + emailAddress: "john.doe@example.com", + phoneNumber: "555-555-5555", + }, + payment: { + isInsurance: false, + isPia: true, + piaType: "CREDIT_CARD", + insuranceCoverage: {}, + }, + policy: { + currentDeductible: 0, + policyNumber: null, + }, + schedule: { + date: "2024-01-15", + startTime: "09:00", + endTime: "10:00", + jobMinMinutes: "30", + jobMaxMinutes: "45", + }, + workOrderNumber: "WO-123456", + referralCorrelationId: "ref-123", + referralSequenceNumber: 1, +}); + +describe("payment-adyen.vue", () => { + beforeEach(() => { + store.getters = { + order: createValidOrder(), + damage: {}, + lineItems: { glassParts: [] }, + payment: {}, + policy: {}, + }; + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + describe("arePagePrerequisitesValid", () => { + test("returns true when all prerequisites are valid", () => { + const wrapper = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(true); + }); + + test("returns false when service location info is missing", () => { + store.getters.order.serviceLocation.address = null; + store.getters.order.serviceLocation.provider.address.streetAddress = null; + const wrapper = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when insurance info is invalid", () => { + store.getters.order.payment.isInsurance = null; + const wrapper = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when scheduling info is missing", () => { + store.getters.order.schedule.date = null; + const wrapper = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when customer info is missing", () => { + store.getters.order.customer.firstName = null; + const wrapper = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when payment method info is invalid", () => { + store.getters.order.payment.isPia = null; + store.getters.order.payment.piaType = null; + const wrapper = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns true for mobile appointment type when address fields are present", () => { + store.getters.order.serviceLocation.appointmentType = + AppointmentTypeStrings.MOBILE; + store.getters.order.serviceLocation.address = "123 Mobile St"; + store.getters.order.serviceLocation.city = "Columbus"; + store.getters.order.serviceLocation.state = "OH"; + store.getters.order.serviceLocation.zipCode = "43235"; + const wrapper = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(true); + }); + }); +}); + +function setupMocks({ customMountOptions } = {}) { + const mountOptions = getMountOptions({ + ...customMountOptions, + store, + route: { name: "payment-adyen" }, + router: { + navigateWithSaving: jest.fn(), + navigateWithoutSaving: jest.fn(), + navigateWithPageData: jest.fn(), + }, + }); + mountOptions.global.mocks["navigationScenarios"] = {}; + mountOptions.mixins = [ + { + methods: { + getCmsContent: jest.fn(), + setCmsContent: jest.fn(), + }, + }, + ]; + + return shallowMount(PaymentAdyenTestComponent, mountOptions); +} diff --git a/src/layouts/payment-method/payment-method.spec.js b/src/layouts/payment-method/payment-method.spec.js index 1bc123d3f..353316427 100644 --- a/src/layouts/payment-method/payment-method.spec.js +++ b/src/layouts/payment-method/payment-method.spec.js @@ -8,6 +8,7 @@ import store from "@/store"; import { experimentSettings } from "@/constants/experiments"; import { storeMutations } from "@/constants/store-mutations"; import globalMethods from "@/global-methods"; +import { AppointmentTypeStrings } from "@/constants/schedule-constants"; globalMethods.callHttpClient = jest.fn(); @@ -29,8 +30,64 @@ jest.mock("@/helpers/pricing-helper.js", () => ({ getAmountDue: jest.fn(), })); +jest.mock("@/helpers/debug-log-helper.js", () => ({ + debugLog: jest.fn(), +})); + let piaDisabledFlag = false; +const createValidOrderForPaymentMethod = () => ({ + payment: { + isPia: false, + isInsurance: false, + insuranceCoverage: { isVerified: true }, + }, + lineItems: { + glassParts: [], + supportingItems: [], + vaps: [], + promos: [], + }, + policy: { + currentDeductible: 123, + isNoComp: false, + isItac: false, + }, + serviceLocation: { + appointmentType: AppointmentTypeStrings.MOBILE, + address: "123 Test Ave", + address2: "", + city: "Anytown", + state: "OH", + zipCode: "00000", + zipCodeCtu: "00000", + provider: { + address: { + streetAddress: "456 Provider St", + city: "Anytown", + state: "OH", + zipCode: "00000", + zipCodeCtu: "00000", + }, + }, + }, + customer: { + firstName: "John", + lastName: "Doe", + emailAddress: "john@example.com", + phoneNumber: "555-555-5555", + }, + schedule: { + date: "2024-01-15", + startTime: "09:00", + endTime: "10:00", + jobMinMinutes: "30", + jobMaxMinutes: "45", + }, + vehicle: { year: 2020, make: "Toyota", model: "Camry", carId: "12345" }, + damage: { isRepair: false }, +}); + describe("payment-method.vue", () => { describe("navigation", () => { test("if the back button is clicked, navigate back", async () => { @@ -54,6 +111,53 @@ describe("payment-method.vue", () => { expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled(); }); }); + + describe("arePagePrerequisitesValid", () => { + test("returns true when all prerequisites are valid", () => { + const { wrapper } = setupMocks(); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(true); + }); + + test("returns false when service location info is missing", () => { + const { wrapper } = setupMocks(); + store.getters.order.serviceLocation.address = null; + store.getters.order.serviceLocation.provider.address.streetAddress = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when insurance info is invalid", () => { + const { wrapper } = setupMocks(); + store.getters.order.payment.isInsurance = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when scheduling info is missing", () => { + const { wrapper } = setupMocks(); + store.getters.order.schedule.date = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when customer info is missing", () => { + const { wrapper } = setupMocks(); + store.getters.order.customer.firstName = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + }); }); function setupMocks() { @@ -65,35 +169,7 @@ function setupMocks() { vaps: [], promos: [], }, - order: { - payment: { - isPia: false, - insuranceCoverage: { - isVerified: true, - }, - }, - lineItems: { - glassParts: [], - supportingItems: [], - vaps: [], - promos: [], - }, - policy: { - currentDeductible: 123, - isNoComp: false, - isItac: false, - }, - serviceLocation: { - appointmentType: "Mobile", - address: "123 Test Ave", - city: "Anytown", - state: "OH", - zipCode: "00000", - provider: { providerNumber: "0000567" }, - }, - vehicle: { year: 2020, make: "Toyota", model: "Camry", carId: "12345" }, - damage: { isRepair: false }, - }, + order: createValidOrderForPaymentMethod(), applicationUser: { experiments: [], }, diff --git a/src/layouts/payment/payment.spec.js b/src/layouts/payment/payment.spec.js index 1b36d0644..ea5341eb0 100644 --- a/src/layouts/payment/payment.spec.js +++ b/src/layouts/payment/payment.spec.js @@ -258,6 +258,42 @@ describe("payment.vue", () => { expect(result).toBe(true); }); + test("Returns false when service location info is missing", () => { + const wrapper = setupMocks({}); + store.getters.order.serviceLocation.provider.address.streetAddress = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("Returns false when insurance info is invalid", () => { + const wrapper = setupMocks({}); + store.getters.order.payment.isInsurance = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("Returns false when scheduling info is missing", () => { + const wrapper = setupMocks({}); + store.getters.order.schedule.date = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("Returns false when customer info is missing", () => { + const wrapper = setupMocks({}); + store.getters.order.customer.firstName = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + describe("Payment method cases", () => { test("Returns false if pia options are not valid", () => { // Arrange diff --git a/src/layouts/quote/quote.spec.js b/src/layouts/quote/quote.spec.js index 60dd548ad..d9a36f11d 100644 --- a/src/layouts/quote/quote.spec.js +++ b/src/layouts/quote/quote.spec.js @@ -295,6 +295,47 @@ describe("quote.vue", () => { expect(arePagePrerequisitesValid).toBe(false); }); + + test("should fail arePagePrerequisitesValid when service zip info is missing", () => { + store.getters = { + order: { + lineItems: { glassParts: ["item"] }, + serviceLocation: { + zipCode: null, + zipCodeCtu: "value", + }, + damage: { isRepair: false }, + payment: { insuranceCoverage: { isVerified: false } }, + referralNumber: "1234567", + }, + }; + const { wrapper } = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("should fail arePagePrerequisitesValid when insurance coverage is verified", () => { + store.getters = { + order: { + lineItems: { glassParts: ["item"] }, + serviceLocation: { + zipCode: "12345", + zipCodeCtu: "value", + }, + damage: { isRepair: false }, + payment: { insuranceCoverage: { isVerified: true } }, + referralNumber: "1234567", + }, + }; + const { wrapper } = setupMocks({}); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + test("should have non-null values for necessary data members after 'beforeRouteEnter'", async () => { //Arrange store.getters = { diff --git a/src/layouts/schedule/schedule.spec.js b/src/layouts/schedule/schedule.spec.js index 7d5cdcec1..9e7952fd0 100644 --- a/src/layouts/schedule/schedule.spec.js +++ b/src/layouts/schedule/schedule.spec.js @@ -57,6 +57,40 @@ jest.mock("@/helpers/heritage-integration/navigation-helper", () => ({ navigateToHeritageFunnel: jest.fn(), })); +jest.mock("@/helpers/debug-log-helper.js", () => ({ + debugLog: jest.fn(), +})); + +const createValidOrderForSchedule = () => ({ + payment: { + isInsurance: false, + insuranceCoverage: { isVerified: false }, + }, + referralNumber: "", + serviceLocation: { + address: "", + address2: "", + city: "", + state: "", + zipCode: "00000", + zipCodeCtu: "000", + appointmentType: null, + provider: {}, + isVehicleProtected: false, + }, + schedule: { + date: "", + routeCode: "", + startTime: "", + endTime: "", + jobMinMinutes: null, + jobMaxMinutes: null, + }, + policy: { isItac: false, isNoComp: false }, + damage: { isRepair: true }, + lineItems: { glassParts: [] }, +}); + describe("schedule.vue", () => { describe("navigation", () => { test("backButtonAction => non-insurance: navigateWithoutSaving called", () => { @@ -149,8 +183,67 @@ describe("schedule.vue", () => { expect(wrapper.vm.$router.navigateWithSaving).not.toHaveBeenCalled(); }); }); + + describe("arePagePrerequisitesValid", () => { + test("returns true when all prerequisites are valid", () => { + const { wrapper } = setupMocksForArePagePrerequisitesValid(); + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(true); + }); + + test("returns false when service zip info is missing", () => { + const { wrapper } = setupMocksForArePagePrerequisitesValid(); + store.getters.order.serviceLocation.zipCode = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when glass parts or repair info is missing", () => { + const { wrapper } = setupMocksForArePagePrerequisitesValid(); + store.getters.order.damage.isRepair = false; + store.getters.order.lineItems.glassParts = []; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when insurance info is invalid", () => { + const { wrapper } = setupMocksForArePagePrerequisitesValid(); + store.getters.order.payment.isInsurance = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + + test("returns false when supporting items missing for cash order", () => { + const { wrapper } = setupMocksForArePagePrerequisitesValid(); + store.getters.order.payment.isInsurance = false; + store.getters.lineItems.supportingItems = null; + + const result = wrapper.vm.arePagePrerequisitesValid(); + + expect(result).toBe(false); + }); + }); }); +function setupMocksForArePagePrerequisitesValid() { + store.getters = { + ...storeMocked.getters, + order: createValidOrderForSchedule(), + lineItems: { + supportingItems: [], + }, + }; + return setupMocks({ store }); +} + function setupMocks(mountOptionsMockData = {}) { const route = { name: "schedule" }; const defaultMountOptions = {