// Components
import vehicleDamage from "@/layouts/vehicle-damage/vehicle-damage.vue";
import sideDoorOptions from "@/layouts/vehicle-damage/side-door-options/side-door-options";
import damageLocationQuestion from "@/layouts/vehicle-damage/damage-location-question/damage-location-question";
import windshieldOptions from "@/layouts/vehicle-damage/windshield-options/windshield-options";
import replaceOptionsQuestion from "@/layouts/vehicle-damage/replace-options-question/replace-options-question";

// Supporting Files
import { settleAllPromises } from "@/helpers/layout-helper.js";
import baseMixin from "@/mixins/base-mixin";
import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
import { shallowMount } from "@vue/test-utils";
import { getMountOptions } from "@/helpers/unit-test-helper.js";
import { nextTick } from "vue";
import { storeActions } from "@/constants/store-actions";
import store from "@/store";
import { validate } from "vee-validate";
import { damageLocationsSelected } from "@/constants/damage-locations-selected.js";
import { routerParams } from "@/router/router-constants/router-params";
import * as cookieHelper from "@/helpers/heritage-integration/cookie-helper";

// 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(),
}));

// Mock getFunnelCookie
jest.mock("@/helpers/heritage-integration/cookie-helper", () => ({
    getFunnelCookie: jest.fn(),
}));

// Mock Store
jest.mock("@/store", () => ({
    commit: jest.fn(),
    dispatch: jest.fn(),
    getters: {
        vehicle: {
            carId: "C00000000",
            image: "test.jpg",
            payment: {
                insuranceCoverage: {
                    isVerified: false,
                },
            },
        },
        eventBusItem: jest.fn(),
        damage: {
            glassToReplace: [],
        },
        order: {
            vehicle: {
                carId: "C00000000",
                image: "test.jpg",
                payment: {
                    insuranceCoverage: {
                        isVerified: false,
                    },
                },
            },
            damage: {
                glassToReplace: [],
            },
        },
        externalParameterState: { isExternalParameter: false },
        externalParameterDamage: {
            damageType: null,
            isRepair: null,
            numberOfChips: null,
        },
    },
}));

describe("vehicle-damage.vue", () => {
    describe("navigation", () => {
        test("BackButtonAction triggers a router.navigateWithoutSaving change", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.backButtonAction();

            //Assert
            expect(wrapper.vm.$router.navigateWithoutSaving).toHaveBeenCalled();
        });

        test("Replace several pieces of glass on first pass through concept on ForwardButtonAction triggers a router.navigate and saves selections to store", async () => {
            //Arrange
            const partsData = {
                partsOrQuestions: [
                    {
                        glassName: "Single",
                        glassLocation: "Windshield",
                        parts: null,
                        partQuestions: [
                            {
                                questionSequence: 1,
                                questionText:
                                    "Is your vehicle equipped with a heated steering wheel?",
                                answers: [
                                    {
                                        answerText: "Yes",
                                        nextQuestionSequence: null,
                                        answerResult: "FW04957",
                                    },
                                    {
                                        answerText: "No",
                                        nextQuestionSequence: 2,
                                        answerResult: "",
                                    },
                                ],
                            },
                            {
                                questionSequence: 2,
                                questionText: "Is your vehicle equipped with a remote start?",
                                answers: [
                                    {
                                        answerText: "Yes",
                                        nextQuestionSequence: null,
                                        answerResult: "FW04181",
                                    },
                                    {
                                        answerText: "No",
                                        nextQuestionSequence: null,
                                        answerResult: "FW04179",
                                    },
                                ],
                            },
                        ],
                    },
                ],
            };

            const { wrapper } = setupMocks({
                pageHeaderWidgetHeaderText: "",
                mountOptionsMockData: {
                    router: { navigate: jest.fn(), navigateWithSaving: jest.fn() },
                    actionList: [
                        { actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData },
                    ],
                    store: {
                        getters: {
                            vehicle: {},
                            payment: { insuranceCoverage: { isVerified: false } },
                            externalParameterDamage: {
                                damageType: null,
                                isRepair: null,
                                numberOfChips: null,
                            },
                        },
                    },
                },
            });

            wrapper.setData({
                selectedDamageLocations: ["Windshield", "SideDoor", "RearWindow"],
                selectedWindshieldOptions: {
                    selectedWindshieldChipCount: null,
                    selectedWindshieldReplaceOptions: ["Single"],
                    selectedWindshieldDamageType: "Replace",
                },
                sideDoorOptionsData: {
                    selectedDoorSides: ["DriverSide", "PassengerSide"],
                    selectedDriverSideReplaceOptions: ["Back"],
                    selectedPassengerSideReplaceOptions: ["Quarter"],
                },
                selectedRearReplaceOptions: "Stationary",
            });

            const expectedGlassToReplace = [
                { glassLocation: "Windshield", glassName: "Single" },
                { glassLocation: "Driver", glassName: "Back" },
                { glassLocation: "Passenger", glassName: "Quarter" },
                { glassLocation: "Rear", glassName: "Stationary" },
            ];

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.isFormValid = jest.fn();
            await wrapper.vm.forwardButtonAction();

            //Assert
            expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
            expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
            expect(baseMixin.methods.dispatchStoreActionWithLogging).toBeCalledWith(
                storeActions.GET_DAMAGE_OPTIONS,
                { carId: "C00000000" },
                "vehicle-damage"
            );
        });

        test("Windshield replace with multiple parts on ForwardButtonAction triggers a router.navigate and saves selections to store", async () => {
            //Arrange
            const partsData = {
                partsOrQuestions: [
                    {
                        glassLocation: "Windshield",
                        glassName: "Single",
                        partQuestions: null,
                        parts: [
                            {
                                color: "Green Tint, Green Shade",
                                description: "rain sensor, solar",
                                partNumber: "FW02728GGYN",
                                requiresCapabilityQuestions: false,
                                requiresRecalibration: false,
                            },
                            {
                                color: "Green Tint, Green Shade",
                                description: "rain sensor, solar, hydrophobic coating",
                                partNumber: "FW02760GGYN",
                                requiresCapabilityQuestions: false,
                                requiresRecalibration: false,
                            },
                        ],
                    },
                    {
                        glassName: "Stationary",
                        glassLocation: "Rear",
                        parts: [
                            {
                                partNumber: "DB09626GTYN",
                                description: "heated glass, solar, antenna",
                                color: "Green Tint",
                                requiresRecalibration: false,
                                requiresCapabilityQuestions: false,
                                childParts: null,
                            },
                            {
                                partNumber: "DB09821GTYN",
                                description: "heated glass, solar, antenna, onstar",
                                color: "Green Tint",
                                requiresRecalibration: false,
                                requiresCapabilityQuestions: false,
                                childParts: null,
                            },
                        ],
                        partQuestions: null,
                    },
                ],
            };

            const { wrapper } = setupMocks({
                pageHeaderWidgetHeaderText: "",
                mountOptionsMockData: {
                    router: { navigate: jest.fn(), navigateWithSaving: jest.fn() },
                    actionList: [
                        { actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: partsData },
                    ],
                    store: {
                        getters: {
                            vehicle: {},
                            payment: { insuranceCoverage: { isVerified: false } },
                            externalParameterDamage: {
                                damageType: null,
                                isRepair: null,
                                numberOfChips: null,
                            },
                        },
                    },
                },
            });

            wrapper.vm.selectedDamageLocations = ["Windshield"];
            wrapper.vm.selectedWindshieldOptions = {
                selectedWindshieldChipCount: null,
                selectedWindshieldReplaceOptions: ["Single"],
                selectedWindshieldDamageType: "Replace",
            };

            const expectedGlassToReplace = [{ glassLocation: "Windshield", glassName: "Single" }];

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );
            wrapper.vm.isFormValid = jest.fn();
            await wrapper.vm.forwardButtonAction();

            //Assert
            expect(wrapper.vm.$router.navigateWithSaving).toHaveBeenCalled();
            expect(wrapper.vm.selectedGlassToReplace()).toEqual(expectedGlassToReplace);
            expect(baseMixin.methods.dispatchStoreActionWithLogging).toBeCalledWith(
                storeActions.GET_DAMAGE_OPTIONS,
                { carId: "C00000000" },
                "vehicle-damage"
            );
        });
    });
    describe("alert", () => {
        test("when displayVehicleChangeAlert router params is true, the alert: 'vehicleChangeAlert' should be rendered", () => {
            // Arrange & Act
            window.history.pushState({ displayVehicleChangeAlert: "true" }, "", "");
            const { wrapper } = setupMocks({
                mountOptionsMockData: {
                    route: {
                        state: { displayVehicleChangeAlert: true },
                    },
                },
            });
            // Assert
            expect(wrapper.findComponent({ ref: "vehicleChangeAlert" }).exists()).toBe(true);
        });

        test("when displayVehicleChangeAlert router params is false, the alert: 'vehicleChangeAlert' should not be rendered", () => {
            // Arrange & Act
            window.history.pushState({ displayVehicleChangeAlert: "false" }, "", "");
            const { wrapper } = setupMocks({
                mountOptionsMockData: {
                    route: {
                        state: {
                            [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false,
                        },
                    },
                },
            });

            // Assert
            expect(wrapper.findComponent({ ref: "vehicleChangeAlert" }).exists()).toBe(false);
        });

        test("when displayVehicleChangeAlert router params is undefined, the alert: 'vehicleChangeAlert' should not be rendered", () => {
            // Arrange & Act
            window.history.pushState({ displayVehicleChangeAlert: "false" }, "", "");
            const { wrapper } = setupMocks({
                mountOptionsMockData: {
                    route: {
                        params: {
                            [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: undefined,
                        },
                    },
                },
            });
            // Assert
            expect(wrapper.findComponent({ ref: "vehicleChangeAlert" }).exists()).toBe(false);
        });
    });
    describe("glass selections and corresponding variables", () => {
        test("isWindshieldDamageLocation is true when windshield is selected", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.selectedDamageLocations = ["Windshield"];

            //Assert
            expect(wrapper.vm.isWindshieldDamageLocation).toEqual(true);
        });

        test("isSideDoorDamageLocation is true Side door is selected", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.selectedDamageLocations = ["Sidedoor"];

            //Assert
            expect(wrapper.vm.isSideDoorDamageLocation).toEqual(true);
        });

        test("isRearWindowDamageLocation is true if Rear Window damage is selected", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.selectedDamageLocations = ["RearWindow"];

            //Assert
            expect(wrapper.vm.isRearWindowDamageLocation).toEqual(true);
        });

        test("isWindshieldRepair is true if windshield repair is selected", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.selectedDamageLocations = ["Windshield"];
            wrapper.vm.selectedWindshieldOptions = { selectedWindshieldDamageType: "Repair" };

            //Assert
            expect(wrapper.vm.isWindshieldRepair).toEqual(true);
        });

        test("isWindshieldRepair is false if windshield damage is not selected", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.selectedDamageLocations = ["SideDoor"];
            wrapper.vm.selectedWindshieldOptions = { selectedWindshieldDamageType: "Repair" };

            //Assert
            expect(wrapper.vm.isWindshieldRepair).toEqual(false);
        });

        test("isDriverSideReplace is true if side door driver is selected", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.selectedDamageLocations = ["Sidedoor"];
            wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["DriverSide"] };

            //Assert
            expect(wrapper.vm.isDriverSideReplace).toEqual(true);
        });

        test("isPassengerSideReplace is true if side door passenger selected", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            wrapper.vm.selectedDamageLocations = ["Sidedoor"];
            wrapper.vm.sideDoorOptionsData = { selectedDoorSides: ["PassengerSide"] };

            //Assert
            expect(wrapper.vm.isPassengerSideReplace).toEqual(true);
        });
    });
    describe("state validations", () => {
        test("CarId set, arePagePrerequisitesValid should be true ", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );

            let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
            await nextTick();

            //Assert
            expect(arePagePrerequisitesValid).toBe(true);
        });
    });
    describe("input validations", () => {
        // THE FOLLOWING TEST IS NOT NECESSARILY REQUIRED FOR COVERAGE
        //    BUT KEEP FOR AN EXAMPLE OF A VALIDATION TEST
        test("when validation rules are set they should validate correctly", async () => {
            //Arrange
            const { wrapper } = setupMocks({});

            //Act
            vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                (c) => c(wrapper.vm)
            );
            const testNull = validate("", "replace-options-required");
            const testString = validate("sldfj", "replace-options-required");

            //Assert
            testNull.then(function (data) {
                expect(data.valid).toEqual(false);
            });
            testString.then(function (data) {
                expect(data.valid).toEqual(true);
            });
        });
    });
    describe("get glass options from store", () => {
        const damageLocations = [
            ["Windshield", [damageLocationsSelected.WINDSHIELD]],
            ["Driver", [damageLocationsSelected.SIDEDOOR]],
            ["Passenger", [damageLocationsSelected.SIDEDOOR]],
            ["Rear", [damageLocationsSelected.REARWINDOW]],
        ];
        test.each(damageLocations)(
            "getDamageLocationsFromStore for %s returns expected %s",
            async (damageLocation, expectedGlass) => {
                //Arrange
                const { wrapper } = setupMocks({});

                //Act
                vehicleDamage.beforeRouteEnter.call(
                    wrapper.vm,
                    { query: { fmgPage: "vehicle-damage" } },
                    undefined,
                    (c) => c(wrapper.vm)
                );

                store.getters = {
                    vehicle: { carId: "C0000000" },
                    eventBusItem: jest.fn(),
                    damage: { glassToReplace: [{ glassLocation: damageLocation }] },
                    isRepair: true,
                    externalParameterDamage: {
                        damageType: null,
                        isRepair: null,
                        numberOfChips: null,
                    },
                };

                var glassSelections = wrapper.vm.getDamageLocationsFromStore();

                //Assert
                expect(glassSelections).toEqual(expectedGlass);
            }
        );

        const storeWindshieldOptions = [
            [
                1,
                false,
                "Windshield",
                "Single",
                {
                    selectedWindshieldDamageType: damageLocationsSelected.REPLACE,
                    selectedWindshieldChipCount: null,
                    selectedWindshieldReplaceOptions: [damageLocationsSelected.SINGLE],
                },
            ],
            [
                2,
                false,
                "Windshield",
                "Driver",
                {
                    selectedWindshieldDamageType: damageLocationsSelected.REPLACE,
                    selectedWindshieldChipCount: null,
                    selectedWindshieldReplaceOptions: [damageLocationsSelected.DRIVER],
                },
            ],
            [
                3,
                false,
                "Windshield",
                "Passenger",
                {
                    selectedWindshieldDamageType: damageLocationsSelected.REPLACE,
                    selectedWindshieldChipCount: null,
                    selectedWindshieldReplaceOptions: [damageLocationsSelected.PASSENGER],
                },
            ],
            [
                4,
                true,
                "",
                "",
                {
                    selectedWindshieldDamageType: damageLocationsSelected.REPAIR,
                    selectedWindshieldChipCount: 2,
                    selectedWindshieldReplaceOptions: [],
                },
            ],
        ];
        test.each(storeWindshieldOptions)(
            "getWindshieldOptionsFromStore test #%s",
            async (testNum, isRepair, damageLocation, damageName, expectedWindshieldOptions) => {
                //Arrange
                const { wrapper } = setupMocks({});

                //Act
                vehicleDamage.beforeRouteEnter.call(
                    wrapper.vm,
                    { query: { fmgPage: "vehicle-damage" } },
                    undefined,
                    (c) => c(wrapper.vm)
                );

                store.getters = {
                    vehicle: { carId: "C0000000" },
                    eventBusItem: jest.fn(),
                    damage: {
                        glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }],
                        isRepair: isRepair,
                        numberOfChips: 2,
                    },
                    externalParameterDamage: {
                        damageType: null,
                        isRepair: null,
                        numberOfChips: null,
                    },
                };

                var windshieldSelections = wrapper.vm.getWindshieldOptionsFromStore();

                //Assert
                expect(windshieldSelections).toEqual(expectedWindshieldOptions);
            }
        );

        const driverDoorSides = [
            ["Driver", "Front", [damageLocationsSelected.FRONT]],
            ["Driver", "Back", [damageLocationsSelected.BACK]],
            ["Driver", "Vent", [damageLocationsSelected.VENT]],
            ["Driver", "Quarter", [damageLocationsSelected.QUARTER]],
        ];
        test.each(driverDoorSides)(
            "getDriverSideReplaceOptionsFromStore for %s-%s returns expected %s",
            async (damageLocation, damageName, expectedGlass) => {
                //Arrange
                const { wrapper } = setupMocks({});

                //Act
                vehicleDamage.beforeRouteEnter.call(
                    wrapper.vm,
                    { query: { fmgPage: "vehicle-damage" } },
                    undefined,
                    (c) => c(wrapper.vm)
                );

                store.getters = {
                    vehicle: { carId: "C0000000" },
                    eventBusItem: jest.fn(),
                    damage: {
                        glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }],
                    },
                    isRepair: true,
                    externalParameterDamage: {
                        damageType: null,
                        isRepair: null,
                        numberOfChips: null,
                    },
                };

                var glassSelections = wrapper.vm.getDriverSideReplaceOptionsFromStore();

                //Assert
                expect(glassSelections).toEqual(expectedGlass);
            }
        );

        const passengerDoorSides = [
            ["Passenger", "Front", [damageLocationsSelected.FRONT]],
            ["Passenger", "Back", [damageLocationsSelected.BACK]],
            ["Passenger", "Vent", [damageLocationsSelected.VENT]],
            ["Passenger", "Quarter", [damageLocationsSelected.QUARTER]],
        ];
        test.each(passengerDoorSides)(
            "getPassengerSideReplaceOptionsFromStore for %s-%s returns expected %s",
            async (damageLocation, damageName, expectedGlass) => {
                //Arrange
                const { wrapper } = setupMocks({});

                //Act
                vehicleDamage.beforeRouteEnter.call(
                    wrapper.vm,
                    { query: { fmgPage: "vehicle-damage" } },
                    undefined,
                    (c) => c(wrapper.vm)
                );

                store.getters = {
                    vehicle: { carId: "C0000000" },
                    eventBusItem: jest.fn(),
                    damage: {
                        glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }],
                    },
                    isRepair: true,
                    externalParameterDamage: {
                        damageType: null,
                        isRepair: null,
                        numberOfChips: null,
                    },
                };

                var glassSelections = wrapper.vm.getPassengerSideReplaceOptionsFromStore();

                //Assert
                expect(glassSelections).toEqual(expectedGlass);
            }
        );

        const rearReplaceOptions = [
            ["Rear", "Stationary", damageLocationsSelected.STATIONARY],
            ["Rear", "Slider", damageLocationsSelected.SLIDER],
        ];
        test.each(rearReplaceOptions)(
            "getRearReplaceOptionsFromStore for %s-%s returns expected %s",
            async (damageLocation, damageName, expectedGlass) => {
                //Arrange
                const { wrapper } = setupMocks({});

                //Act
                vehicleDamage.beforeRouteEnter.call(
                    wrapper.vm,
                    { query: { fmgPage: "vehicle-damage" } },
                    undefined,
                    (c) => c(wrapper.vm)
                );

                store.getters = {
                    vehicle: { carId: "C0000000" },
                    eventBusItem: jest.fn(),
                    damage: {
                        glassToReplace: [{ glassLocation: damageLocation, glassName: damageName }],
                    },
                    isRepair: true,
                    externalParameterDamage: {
                        damageType: null,
                        isRepair: null,
                        numberOfChips: null,
                    },
                };

                var glassSelections = wrapper.vm.getRearReplaceOptionsFromStore();

                //Assert
                expect(glassSelections).toEqual(expectedGlass);
            }
        );
    });
    describe("hide back button", () => {
        test("if claim is verified => should hide back button", () => {
            // Arrange
            const { wrapper } = setupMocks({
                mountOptionsMockData: {
                    router: { navigate: jest.fn() },
                    actionList: [{ actionName: storeActions.GET_PARTS_OR_QUESTIONS, data: {} }],
                    store: {
                        getters: {
                            vehicle: {},
                            payment: { insuranceCoverage: { isVerified: true } },
                            requiresVerifiedRedirecting: true,
                            externalParameterDamage: {
                                damageType: null,
                                isRepair: null,
                                numberOfChips: null,
                            },
                        },
                    },
                },
            });

            // Assert
            expect(wrapper.vm.shouldHideBackButton).toBe(true);
        });

        test("if claim isn't verified yet => allow user to go back", () => {
            // Arrange
            const { wrapper } = setupMocks({});

            // Assert
            expect(wrapper.vm.shouldHideBackButton).toBeFalsy();
        });
    });

    describe("vehicle-damage.vue", () => {
        test("should call forwardButtonAction if isExternalParameter is true and form is valid", async () => {
            // Set up the store with isExternalParameter as true
            store.getters.externalParameterState = { isExternalParameter: true };
            store.getters.externalParameterDamage = {
                damageType: "windshieldReplace",
                isRepair: false,
                numberOfChips: null,
            };

            // Set up the component
            const { wrapper } = setupMocks({});
            wrapper.vm.forwardButtonAction = jest.fn();

            baseMixin.methods.isFormValid = jest.fn().mockReturnValue(true);
            const nextFunction = jest.fn((c) => {
                c(wrapper.vm);
            });

            // Call the method that contains the if-else logic
            await vehicleDamage.beforeRouteEnter.call(
                wrapper.vm,
                { query: { fmgPage: "vehicle-damage" } },
                undefined,
                nextFunction
            );
            await nextTick();
            expect(nextFunction).toHaveBeenCalled();
            expect(wrapper.vm.forwardButtonAction).toHaveBeenCalled();
        });
    });
});

function setupMocks({ pageHeaderWidgetHeaderText, mountOptionsMockData, funnelCookie = {} }) {
    var pageHeaderWidgetHeaderTextDefault = {};
    var mountOptionsMockDataDefault = {
        router: {
            navigate: jest.fn(),
            navigateWithoutSaving: jest.fn(),
            navigateWithSaving: jest.fn(),
        },
        route: {
            state: {
                [routerParams.DISPLAY_VEHICLE_CHANGE_ALERT]: false,
            },
        },
        store: {
            getters: {
                vehicle: {},
                payment: {
                    insuranceCoverage: {
                        isVerified: false,
                    },
                },
            },
        },
    };
    // Combine parameters with default values
    pageHeaderWidgetHeaderText = Object.assign(
        pageHeaderWidgetHeaderTextDefault,
        pageHeaderWidgetHeaderText
    );
    mountOptionsMockData = Object.assign(mountOptionsMockDataDefault, mountOptionsMockData);
    //Mock api responses
    baseMixin.methods.dispatchStoreAction = jest.fn();
    baseMixin.methods.dispatchStoreActionWithLogging = jest.fn();
    baseMixin.methods.ResetExternalParamsAndHideModal = 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",
            },
        },
        damageOptions: {
            driverSideOptions: {
                availableReplacementOptions: ["Front", "Back", "Side"],
            },
            passengerSideOptions: {
                availableReplacementOptions: ["Front", "Back", "Side"],
            },
            windshieldOptions: {
                availableReplacementOptions: ["Single", "Driver", "Passenger"],
            },
            backGlassOptions: {
                availableReplacementOptions: ["Front", "Back", "Side"],
            },
        },
    };

    const apiPromise = Promise.resolve(apiResponses);

    settleAllPromises.mockImplementation(() => apiPromise);
    fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
    cookieHelper.getFunnelCookie = jest
        .spyOn(cookieHelper, "getFunnelCookie")
        .mockReturnValue(funnelCookie);

    //Mock damage initialize methods
    damageLocationQuestion.methods = {
        initializeComponent: jest.fn(),
    };

    sideDoorOptions.methods = {
        initializeComponent: jest.fn(),
    };

    windshieldOptions.methods = {
        initializeComponent: jest.fn(),
    };

    replaceOptionsQuestion.methods = {
        initializeComponent: jest.fn(),
        updateSelectedValues: jest.fn(),
    };

    const mountOptions = getMountOptions(mountOptionsMockData);
    mountOptions["attachTo"] = document.body; // append wrapper to document.body to test DOM methods

    const wrapper = shallowMount(vehicleDamage, mountOptions);

    const sideDoorOptionsWrapper = wrapper.findComponent({ name: "sideDoorOptions" });
    sideDoorOptionsWrapper.vm.initializeComponent = sideDoorOptions.methods.initializeComponent;

    const windshieldOptionsWrapper = wrapper.findComponent({ name: "windshieldOptions" });
    windshieldOptionsWrapper.vm.initializeComponent = windshieldOptions.methods.initializeComponent;

    const backGlassOptionsWrapper = wrapper.findComponent({ name: "replaceOptionsQuestion" });
    backGlassOptionsWrapper.vm.initializeComponent =
        replaceOptionsQuestion.methods.initializeComponent;

    const damageLocationQuestionWrapper = wrapper.findComponent({ name: "damageLocationQuestion" });
    damageLocationQuestionWrapper.vm.initializeComponent =
        damageLocationQuestion.methods.initializeComponent;

    wrapper.vm.setCmsContent = baseMixin.methods.setCmsContent;

    return { wrapper, apiPromise };
}
