import { shallowMount } from "@vue/test-utils"; import questionChain from "@/digital-components/question-chain/question-chain.vue"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { nextTick } from "vue"; describe("Question Chain component", () => { describe("on create...", () => { test("Should populate questions data array", async () => { //Arrange const { wrapper } = setupMocks({}); const expectedFirstQuestionAnswer = { answerResult: "DB09410", buttonLabel: "Yes", nextQuestionSequence: null, questionSequence: 1, questionType: "answer", value: "1|answer|DB09410|Yes", }; //Act await nextTick(); //Assert expect(wrapper.vm.questions[0].answers[0]).toMatchObject(expectedFirstQuestionAnswer); }); test("Should not include suppressed questions on questions data array", async () => { //Arrange const { wrapper } = setupMocks({}); await wrapper.setData({ questionData: [ { questionSequence: 1, questionText: "Question here?", answers: [ { answerResult: "DB09410", answerText: "Yes", nextQuestionSequence: null, }, { answerResult: "DB10840", answerText: "No", nextQuestionSequence: null, }, ], suppressThisQuestion: true, }, ], }); //Act await nextTick(); //Assert expect(wrapper.vm.questions[0]).toBeFalsy(); }); }); describe("method handleAnswer...", () => { test("should run getQuestionChainAnswerIfComplete", () => { //Arrange const { wrapper } = setupMocks({}); const testQuestion = {}; const testReturnedAnswer = "aReturnedAnswer"; wrapper.vm.getQuestionChainAnswerIfComplete = jest.fn(); //Act wrapper.vm.handleAnswer(testQuestion, testReturnedAnswer); //Assert expect(wrapper.vm.getQuestionChainAnswerIfComplete).toBeCalled(); }); test("should emit update:modelValue if returnedAnswer contains 'answer'", () => { //Arrange const { wrapper } = setupMocks({}); const testQuestion = {}; const testReturnedAnswer = "1|answer|DB10840|No"; //Act wrapper.vm.handleAnswer(testQuestion, testReturnedAnswer); //Assert expect(wrapper.emitted()).toHaveProperty("update:modelValue"); expect(wrapper.emitted()["update:modelValue"][0][0]).toMatchObject({ answerResult: "DB10840", }); }); test("should NOT emit update:modelValue if no returnedAnswer", () => { //Arrange const { wrapper } = setupMocks({}); const testQuestion = {}; //Act wrapper.vm.handleAnswer(testQuestion); //Assert expect(wrapper.emitted()).not.toHaveProperty("update:modelValue"); }); test("should NOT emit update:modelValue if returnedAnswer contains 'nextQuestion'", () => { //Arrange const { wrapper } = setupMocks({}); const testQuestion = {}; const testReturnedAnswer = "1|nextQuestion|DB10840|No"; //Act wrapper.vm.handleAnswer(testQuestion, testReturnedAnswer); //Assert expect(wrapper.emitted()).not.toHaveProperty("update:modelValue"); }); }); describe("method getQuestionChainAnswerIfComplete...", () => { test("should return false if no returned answer", () => { //Arrange const { wrapper } = setupMocks({}); //Act const result = wrapper.vm.getQuestionChainAnswerIfComplete(); //Assert expect(result).toBeFalsy(); }); test("should set the answerSelected to match the answered one", async () => { //Arrange const { wrapper } = setupMocks({}); const testReturnedAnswer = "1|answer|DB10840|No"; await wrapper.setData({ questionData: [ { questionSequence: 1, questionText: "Question here?", answers: [ { answerResult: "DB09410", answerText: "Yes", nextQuestionSequence: null, }, { answerResult: "DB10840", answerText: "No", nextQuestionSequence: null, }, ], }, ], }); //Act wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer); //Assert expect(wrapper.vm.questions[0].answerSelected).toBe("1|answer|DB10840|No"); }); test("should remove answers of questions after the answered one", async () => { //Arrange const { wrapper } = setupMocks({}); const testReturnedAnswer = "1|answer|DB10840|No"; await wrapper.setData({ questionData: [ { questionSequence: 1, questionText: "Question here?", answers: [ { answerResult: "DB09410", answerText: "Yes", nextQuestionSequence: null, }, { answerResult: "DB10840", answerText: "No", nextQuestionSequence: null, }, ], }, { questionSequence: 2, questionText: "Question 2", answers: [ { answerResult: "2-yes", answerText: "Yes", nextQuestionSequence: null, }, { answerResult: "2-no", answerText: "No", nextQuestionSequence: null, }, ], answerSelected: "previously selected answer", }, ], }); //Act wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer); //Assert expect(wrapper.vm.questions[1].answerSelected).toBeUndefined; }); test("should return false if returnedAnswer is a nextQuestion (not a final answer)", async () => { //Arrange const { wrapper } = setupMocks({}); const testReturnedAnswer = "1|nextQuestion|DB10840|No"; //Act const result = wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer); //Assert expect(result).toBeFalsy(); }); test("should trigger scroll to .current-question if returnedAnswer is a nextQuestion (not a final answer)", async () => { //Arrange const { wrapper } = setupMocks({}); const testReturnedAnswer = "1|nextQuestion|DB10840|No"; //Act wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer); await nextTick(); //Assert expect(Element.prototype.scrollIntoView).toHaveBeenCalled(); }); test("should return answer object if returnedAnswer is a final matching answer", async () => { //Arrange const { wrapper } = setupMocks({}); const testReturnedAnswer = "1|answer|DB10840|No"; await wrapper.setData({ questions: [ { questionSequence: 1, questionText: "Question here?", answers: [ { answerResult: "DB09410", answerText: "Yes", nextQuestionSequence: null, }, { answerResult: "DB10840", answerText: "No", nextQuestionSequence: null, }, ], }, ], index: 0, }); //Act const result = wrapper.vm.getQuestionChainAnswerIfComplete(testReturnedAnswer); //Assert expect(result).toMatchObject({ answerResult: "DB10840", answeredQuestions: [ { questionNum: 1, questionText: "Question here?", selectedAnswerText: "No" }, { questionNum: 1, questionText: "Does only your center sliding piece need to be replaced?", selectedAnswerText: "No", }, ], index: 0, }); }); }); }); function setupMocks({ questionDataProp = [ { questionSequence: 1, questionText: "Does only your center sliding piece need to be replaced?", answers: [ { answerResult: "DB09410", answerText: "Yes", nextQuestionSequence: null, }, { answerResult: "DB10840", answerText: "No", nextQuestionSequence: null, }, ], }, ], }) { Element.prototype.scrollIntoView = jest.fn(); const mountOptions = getMountOptions({}); mountOptions.propsData = { questionData: questionDataProp, }; mountOptions["attachTo"] = document.body; const wrapper = shallowMount(questionChain, mountOptions); return { wrapper }; }