diff --git a/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.spec.js b/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.spec.js
new file mode 100644
index 00000000..b9cd7e02
--- /dev/null
+++ b/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.spec.js
@@ -0,0 +1,77 @@
+import addressVehiclesQuestion from "@/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue";
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+
+describe("address-vehicles-question.vue", () => {
+ test("Selected vehicle is emitted upon selection", async () => {
+ //Arrange
+ const { wrapper } = setupMocks({ modelValueProp: "2020 Audi A6" });
+ const vehicleToSelect = "2016 Jaguar F-Type";
+
+ //Act
+ wrapper.setValue({ selectedVehicle: vehicleToSelect });
+ await wrapper.vm.$nextTick();
+
+ //Assert
+ expect(wrapper.emitted()["update:modelValue"][0]).toEqual([
+ { selectedVehicle: "2016 Jaguar F-Type" },
+ ]);
+ });
+ test("Should return content for differentVehicleAlertHeader", () => {
+ // Arrange
+ const wrapper = shallowMount(addressVehiclesQuestion, {
+ mixins: [mockMixin],
+ });
+
+ // Assert
+ expect(wrapper.vm.differentVehicleAlertHeader).toEqual("FoundWindshieldTestReturn");
+ });
+ test("Should return content for differentVehicleAlertBody", () => {
+ // Arrange
+ const wrapper = shallowMount(addressVehiclesQuestion, {
+ mixins: [mockMixin],
+ propsData: {
+ vehicles: ["1", "2"],
+ modelValue: ["1", "2"],
+ },
+ });
+
+ // Assert
+ expect(wrapper.vm.differentVehicleAlertBody).toEqual("FoundWindshieldTestReturn");
+ });
+});
+
+const mockMixin = {
+ methods: {
+ getCmsContent: jest.fn((contentName) => {
+ if (contentName === "FoundWindshield") {
+ return "FoundWindshieldTestReturn";
+ }
+ return null;
+ }),
+ vehicles: jest.fn(() => {
+ return [{ vehicle: "test" }];
+ }),
+ },
+};
+
+function setupMocks({
+ modelValueProp = "TESTCAR",
+ cmsQuestionText = "CMS text goes here",
+}) {
+
+ const mountOptions = getMountOptions();
+
+ //Mock props
+ mountOptions.propsData = {
+ modelValue: modelValueProp,
+ };
+
+ const wrapper = shallowMount(addressVehiclesQuestion, mountOptions);
+
+ //Mock CMS content
+ const cmsContent = {
+ QuestionText: cmsQuestionText,
+ };
+ return { wrapper, cmsContent };
+}
\ No newline at end of file
diff --git a/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue b/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue
new file mode 100644
index 00000000..0ab1512e
--- /dev/null
+++ b/src/layouts/address-vehicles/address-vehicles-question/address-vehicles-question.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/layouts/address-vehicles/address-vehicles.spec.js b/src/layouts/address-vehicles/address-vehicles.spec.js
new file mode 100644
index 00000000..76aebdf0
--- /dev/null
+++ b/src/layouts/address-vehicles/address-vehicles.spec.js
@@ -0,0 +1,252 @@
+import addressVehicles from "@/layouts/address-vehicles/address-vehicles";
+import { settleAllPromises } from "@/helpers/layout-helper.js";
+import { shallowMount } from "@vue/test-utils";
+import { getMountOptions } from "@/helpers/unit-test-helper.js";
+import { useMainStore } from "@/store";
+import { fetchCmsContentForPage } from "@/helpers/cms-content-helper";
+
+jest.mock("@/helpers/damage-helper", () => ({
+ isGlassAvailableForCarId: jest.fn().mockImplementation(() => true),
+ getDamageString: jest.fn(),
+}));
+
+// Mock fetchCmsContentForPage
+jest.mock("@/helpers/cms-content-helper", () => ({
+ fetchCmsContentForPage: jest.fn(),
+ doesCopyContainRouterLink: jest.fn(),
+ splitCopyOnCMSPlaceHolder: jest.fn().mockImplementation(() => "test"),
+ getRouterLinkRouteFromCopy: jest.fn(),
+ getRouterLinkDisplayTextFromCopy: jest.fn(),
+ splitCMSCopyOnParagraphTag: jest.fn(),
+}));
+
+// Mock our module for promises.
+jest.mock("@/helpers/layout-helper.js", () => ({
+ settleAllPromises: jest.fn(),
+}));
+
+describe("address-vehicles.vue", () => {
+ test("Should navigate to CLICKED_BACK if backButtonAction is run", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+
+ // Act
+ await wrapper.vm.backButtonAction();
+
+ //Assert
+ expect(wrapper.vm.$router.navigate).toBeCalled();
+ });
+
+ test("navigateForward should be called if forwardButtonAction is run", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ const lookupVinResponse = {
+ data: {
+ carId: "456"
+ }
+ }
+
+ wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
+ wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
+ wrapper.vm.lookupVin = jest.fn(() => Promise.resolve(lookupVinResponse));
+ wrapper.vm.$router.navigate = jest.fn();
+ wrapper.vm.saveVin = jest.fn().mockImplementation(() => {});
+ wrapper.vm.navigateForward = jest.fn().mockImplementation(() => {});
+
+ // Act
+ await wrapper.setData({
+ selectedVehicleVin: "5NMS3CADXLH233004",
+ });
+
+ await wrapper.vm.forwardButtonAction();
+ wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.navigateForward).toHaveBeenCalled();
+ });
+
+ test("Should return out of forwardButtonAction is lookupVin returns an error", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
+
+ const lookupVinResponse = {
+ error: "there is an error",
+ };
+
+ wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
+ wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
+ wrapper.vm.lookupVin = jest.fn(() => Promise.reject(lookupVinResponse));
+ wrapper.vm.$router.navigate = jest.fn();
+ wrapper.vm.saveVin = jest.fn().mockImplementation(() => {});
+
+ // Act
+ await wrapper.setData({
+ selectedVehicleVin: "5NMS3CADXLH233004",
+ });
+
+ await wrapper.vm.forwardButtonAction();
+ wrapper.vm.$nextTick();
+
+ // Assert
+ expect(wrapper.vm.forwardButtonAction).toReturn;
+ });
+
+ test("Should navigate to CLICKED_FORWARD scenario if carId is different and selected glass not available for vehicle on navigateForward", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
+ wrapper.vm.$router.navigate = jest.fn();
+
+ // Act
+ await wrapper.setData({
+ selectedVehicleVin: "5NMS3CADXLH233004",
+ isSelectedGlassAvailableForVehicle: false,
+ isCarIdDifferent: true,
+ });
+ await wrapper.vm.navigateForward();
+
+ //Assert
+ expect(wrapper.vm.$router.navigate).toBeCalledTimes(1);
+ });
+
+ test("carId is not different on navigateForward (car was found) => Should handle navigating forward with car match", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
+ wrapper.vm.navigateForwardWithSingleCarMatch = jest.fn();
+
+ // Act
+ await wrapper.setData({
+ isCarIdDifferent: false,
+ });
+ await wrapper.vm.navigateForward();
+
+ //Assert
+ expect(wrapper.vm.navigateForwardWithSingleCarMatch).toBeCalledTimes(1);
+
+ });
+
+ test("Should return true for valid page requisites if carId exists", async () => {
+ // Arrange
+ const { wrapper } = setupMocks({});
+ useMainStore().order.vehicle.carId = "CR00000395";
+
+ // Act
+ addressVehicles.beforeRouteEnter.call(
+ wrapper.vm,
+ { query: { issPage: "address-vehicles" } },
+ undefined,
+ (c) => c(wrapper.vm)
+ );
+
+ let arePagePrerequisitesValid = wrapper.vm.arePagePrerequisitesValid();
+
+ // Assert
+ expect(arePagePrerequisitesValid).toBe(true);
+ });
+});
+
+function setupMocks({
+ route = null,
+ lookupVehicleByVinResponse,
+})
+{
+ useMainStore().applicationUser = {
+ pageData: {
+ "address-vehicles":
+ [
+ {
+ vehicle: {
+ carId: "CR00069309",
+ category: "SUV",
+ imageUrl:
+ "https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg",
+ imageVifColor: "white",
+ imageVifNumber: "13769",
+ make: "Hyundai",
+ model: "Santa Fe",
+ style: "4 door utility",
+ year: 2020,
+ },
+ vin: "5NMS3CADXLH233004",
+ },
+ ],
+ }
+ };
+
+ useMainStore().lookupVehicleByVin = jest.fn().mockImplementation(() => {
+ return Promise.resolve({
+ data: lookupVehicleByVinResponse
+ ? lookupVehicleByVinResponse : {
+ vehicle: {
+ carId: "CARID"
+ },
+ },
+ })
+ });
+
+ const mountOptions = getMountOptions({
+ route: route ? route : undefined,
+ router: {
+ navigate: jest.fn(),
+ },
+ mainStore: {
+ order: {
+ vehicle: {
+ carId: "CR00069309",
+ category: "SUV",
+ imageUrl:
+ "https://dbhdyzvm8lm25.cloudfront.net/color_0320_032/MY2020/13769/13769_cc0320_032_WW8.jpg",
+ imageVifColor: "white",
+ imageVifNumber: "13769",
+ make: "Hyundai",
+ model: "Santa Fe",
+ style: "4 door utility",
+ year: 2020,
+ },
+ vin: "5NMS3CADXLH233004",
+ },
+ },
+ },
+ );
+
+ const apiResponses = {
+ cmsContent: {},
+ };
+
+ settleAllPromises.mockImplementation(() => apiResponses);
+ fetchCmsContentForPage.mockImplementation(() => Promise.resolve());
+
+
+ //Mock props
+ const mockMixin = {
+ methods: {
+ getCmsContent: jest.fn((contentName) => {
+ if (contentName === "FoundMultipleVehicles") {
+ return "FoundMultipleVehiclesTestReturn";
+ }
+ if (contentName === "ProvideVinAlert") {
+ return "ProvideVinAlertTestReturn";
+ }
+ return null;
+ }),
+ },
+ computed: {
+ dynamicStrings() {
+ return { ROUTER_LINK: "routerLink:" };
+ },
+ },
+ };
+
+ mountOptions.mixins = [mockMixin];
+
+ const wrapper = shallowMount(addressVehicles, mountOptions);
+
+ wrapper.vm.getCmsContent = jest.fn().mockImplementation(() => "");
+ wrapper.vm.setCmsContent = jest.fn();
+ wrapper.vm.$refs.siteFooter.updateButtonText = jest.fn();
+ wrapper.vm.$refs.siteFooter.removeLoader = jest.fn();
+
+ return { wrapper };
+}
diff --git a/src/layouts/address-vehicles/address-vehicles.vue b/src/layouts/address-vehicles/address-vehicles.vue
index b6e1835b..8f6cbb2e 100644
--- a/src/layouts/address-vehicles/address-vehicles.vue
+++ b/src/layouts/address-vehicles/address-vehicles.vue
@@ -2,66 +2,103 @@