diff --git a/src/common-components/textbox-question/textbox-question.spec.js b/src/common-components/textbox-question/textbox-question.spec.js index d5d1de4e6..e3c7b315d 100644 --- a/src/common-components/textbox-question/textbox-question.spec.js +++ b/src/common-components/textbox-question/textbox-question.spec.js @@ -197,4 +197,252 @@ describe("textboxQuestion.vue", () => { // Assert expect(wrapper.vm.handleChange).toHaveBeenCalled; }); + + it("Should not display camera or spinner icon when disabled", () => { + // Arrange + const inputId = "test"; + + const wrapper = shallowMount(textboxQuestion, { + global: { + directives: { + maska: maska, + }, + }, + propsData: { + modelValue: "", + includeImageQuestion: true, + inputId: inputId, + isDisabled: true, + }, + mixins: [mockMixin], + attachTo: document.body, + }); + + // Act + const cameraIcon = wrapper.find('[data-test="image-upload"]'); + const loadingIcon = wrapper.findComponent("loader"); + + // Assert + expect(cameraIcon.exists()).toBe(false); + expect(loadingIcon.exists()).toBe(false); + }); + + describe("Image Uploading", () => { + it("Should call this.handleChange & emit update when fully valid image is submitted.", async () => { + // Arrange + const inputId = "test"; + const responseValue = "testResponse"; + + const imageHandler = jest.fn().mockImplementation( + () => + new Promise((resolve, reject) => { + resolve({ + data: [responseValue], + }); + }) + ); + + const wrapper = shallowMount(textboxQuestion, { + global: { + directives: { + maska: maska, + }, + }, + propsData: { + modelValue: "", + "onUpdate:modelValue": (v) => wrapper.setProps({ modelValue: v }), + includeImageQuestion: true, + inputId: inputId, + imageQuestionSubmitHandler: imageHandler, + }, + mixins: [mockMixin], + attachTo: document.body, + }); + + wrapper.vm.handleChange = jest.fn().mockImplementation(() => {}); + wrapper.vm.isImageValid = jest.fn().mockImplementation(() => true); + + // Act + const imageUploadField = wrapper.find('[data-test="image-upload"]'); + + await imageUploadField.trigger("change"); + + await wrapper.vm.$nextTick(); + + // Assert + + expect(wrapper.vm.imageQuestionSubmitHandler).toHaveBeenCalled(); + expect(wrapper.vm.handleChange).toHaveBeenCalled(); + expect(wrapper.emitted()).toHaveProperty("update:modelValue"); + }); + + it("Should not call handler and emit image-lookup-error when image is invalid.", async () => { + // Arrange + const inputId = "test"; + const responseValue = "testResponse"; + + const imageHandler = jest.fn().mockImplementation( + () => + new Promise((resolve, reject) => { + resolve({ + data: [responseValue], + }); + }) + ); + + const wrapper = shallowMount(textboxQuestion, { + global: { + directives: { + maska: maska, + }, + }, + propsData: { + modelValue: "", + "onUpdate:modelValue": (v) => wrapper.setProps({ modelValue: v }), + includeImageQuestion: true, + inputId: inputId, + imageQuestionSubmitHandler: imageHandler, + }, + mixins: [mockMixin], + attachTo: document.body, + }); + + wrapper.vm.handleChange = jest.fn().mockImplementation(() => {}); + wrapper.vm.isImageValid = jest.fn().mockImplementation(() => false); + + // Act + const imageUploadField = wrapper.find('[data-test="image-upload"]'); + + await imageUploadField.trigger("change"); + + await wrapper.vm.$nextTick(); + + // Assert + expect(wrapper.vm.imageQuestionSubmitHandler).not.toHaveBeenCalled(); + expect(wrapper.vm.handleChange).not.toHaveBeenCalled(); + expect(wrapper.emitted()).toHaveProperty("imageValidityError"); + }); + + it("Should emit image-lookup-error when image lookup responds with an error.", async () => { + // Arrange + const inputId = "test"; + + const imageHandler = jest.fn().mockImplementation( + () => + new Promise((resolve, reject) => { + reject({}); + }) + ); + + const wrapper = shallowMount(textboxQuestion, { + global: { + directives: { + maska: maska, + }, + }, + propsData: { + modelValue: "", + "onUpdate:modelValue": (v) => wrapper.setProps({ modelValue: v }), + includeImageQuestion: true, + inputId: inputId, + imageQuestionSubmitHandler: imageHandler, + }, + mixins: [mockMixin], + attachTo: document.body, + }); + + wrapper.vm.handleChange = jest.fn().mockImplementation(() => {}); + wrapper.vm.isImageValid = jest.fn().mockImplementation(() => true); + + // Act + const imageUploadField = wrapper.find('[data-test="image-upload"]'); + + await imageUploadField.trigger("change"); + + await wrapper.vm.$nextTick(); + + // Assert + expect(wrapper.vm.imageQuestionSubmitHandler).toHaveBeenCalled(); + expect(wrapper.vm.handleChange).not.toHaveBeenCalled(); + expect(wrapper.emitted()).toHaveProperty("imageLookupError"); + }); + }); + + describe("Image Validation", () => { + it("Should return true if a valid image is tested.", () => { + // Arrange + const wrapper = shallowMount(textboxQuestion, { + global: { + directives: { + maska: maska, + }, + }, + propsData: { + inputId: "input ID", + maxFileSize: 5140 * 1028, + }, + mixins: [mockMixin], + }); + + const image = { + size: 100 * 1028, + }; + + // Act + const result = wrapper.vm.isImageValid(image); + + // Assert + expect(result).toBeTruthy(); + }); + + it("Should return false if null image is tested.", () => { + // Arrange + const wrapper = shallowMount(textboxQuestion, { + global: { + directives: { + maska: maska, + }, + }, + propsData: { + inputId: "input ID", + maxFileSize: 5140 * 1028, + }, + mixins: [mockMixin], + }); + + const image = null; + + // Act + const result = wrapper.vm.isImageValid(image); + + // Assert + expect(result).toBeFalsy(); + }); + + it("Should return false if oversized image is tested.", () => { + // Arrange + const wrapper = shallowMount(textboxQuestion, { + global: { + directives: { + maska: maska, + }, + }, + propsData: { + inputId: "input ID", + maxFileSize: 5140 * 1028, + }, + mixins: [mockMixin], + }); + + const image = { + size: 10000000 * 1028, + }; + + // Act + const result = wrapper.vm.isImageValid(image); + + // Assert + expect(result).toBeFalsy(); + }); + }); }); diff --git a/src/common-components/textbox-question/textbox-question.vue b/src/common-components/textbox-question/textbox-question.vue index 957f59f36..658bb4bb7 100644 --- a/src/common-components/textbox-question/textbox-question.vue +++ b/src/common-components/textbox-question/textbox-question.vue @@ -6,7 +6,12 @@ class="form-label" :class="[questionAlignment === 'center' ? 'text-center w-100 mb-5' : '']" v-html="labelText"> -