From a1f5d577a0c6b83bfc232e22644d178a170f9836 Mon Sep 17 00:00:00 2001 From: brydon1 Date: Mon, 10 Jul 2023 13:22:31 -0400 Subject: [PATCH] Adding tests for textarea question component --- .../textarea-question.spec.js | 349 +++++++++++++++++- .../textarea-question/textarea-question.vue | 42 +-- .../contact-details/contact-details.vue | 3 +- src/layouts/part-questions/part-questions.vue | 2 +- .../vehicle-lookup/vehicle-lookup.spec.js | 5 + 5 files changed, 376 insertions(+), 25 deletions(-) diff --git a/src/digital-components/textarea-question/textarea-question.spec.js b/src/digital-components/textarea-question/textarea-question.spec.js index a9c60f39..8e4d93c6 100644 --- a/src/digital-components/textarea-question/textarea-question.spec.js +++ b/src/digital-components/textarea-question/textarea-question.spec.js @@ -1 +1,348 @@ -// TODO finish +// Components +import textareaQuestion from '@/digital-components/textarea-question/textarea-question.vue'; + +// Supporting Files +import { shallowMount } from '@vue/test-utils'; +import { getRandomString, getRandomInt } from '@/helpers/data-generation'; +import { nextTick } from 'vue'; +import { defineRule } from 'vee-validate'; +import { required } from '@/helpers/validation-rules'; + +describe('textarea-question.vue', () => { + const mockMixin = { + methods: { + getCmsContent: jest.fn().mockImplementation(() => + getRandomString(10, 20)), + setCmsContent: jest.fn() + } + }; + describe('Expected components rendered', () => { + test('Label rendered', () => { + // Arrange + const questionText = getRandomString(10, 20); + const mixinWithQuestion = { + methods: { + getCmsContent: jest.fn().mockImplementation(() => + questionText), + setCmsContent: jest.fn() + } + }; + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20) + }, + mixins: [mixinWithQuestion] + }); + + // Act + const label = wrapper.find('label'); + + // Assert + expect(label.exists()).toBe(true); + expect(wrapper.text()).toContain(questionText); + }); + test('Textarea rendered', () => { + // Arrange + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20) + }, + mixins: [mockMixin] + }); + + // Act + const textarea = wrapper.find('textarea'); + + // Assert + expect(textarea.exists()).toBe(true); + }); + test('Character count rendered', () => { + // Arrange + const maxLength = getRandomInt(100, 900); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + maxLength + }, + mixins: [mockMixin] + }); + const expected = `0/${maxLength}`; + + // Act + // Assert + expect(wrapper.text()).toContain(expected); + }); + test('Error rendered', async () => { + // Arrange + const maxLength = getRandomInt(100, 900); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + maxLength + }, + mixins: [mockMixin] + }); + + // Act + const errorComponent = wrapper.find('#error-message'); + expect(errorComponent.text()).toBe(''); + + const errorMessage = getRandomString(20, 30); + wrapper.vm.resetField({ + errors: [errorMessage] + }); + await nextTick(); + + // Assert + expect(errorComponent.text()).toBe(errorMessage); + }); + test('Not required => optional text rendered', () => { + // Arrange + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + isRequired: false + }, + mixins: [mockMixin] + }); + + // Act + // Assert + expect(wrapper.text()).toContain('Optional'); + }); + test('Required => optional text not rendered', () => { + // Arrange + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + isRequired: true + }, + mixins: [mockMixin] + }); + + // Act + // Assert + expect(wrapper.text()).not.toContain('Optional'); + }); + }); + describe('Computed properties rendered', () => { + describe('characterCount', () => { + test('Model value null => character count is 0 ', () => { + // Arrange + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + modelValue: null + }, + mixins: [mockMixin] + }); + + // Act + // Assert + expect(wrapper.vm.characterCount).toBe(0); + }); + test('Model value undefined => character count is 0', () => { + // Arrange + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + modelValue: undefined + }, + mixins: [mockMixin] + }); + + // Act + // Assert + expect(wrapper.vm.characterCount).toBe(0); + }); + test('Model value empty string => character count is 0', () => { + // Arrange + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + modelValue: '' + }, + mixins: [mockMixin] + }); + + // Act + // Assert + expect(wrapper.vm.characterCount).toBe(0); + }); + test('Model value non-empty string => character count is as expected', () => { + // Arrange + const length = getRandomInt(10, 30); + const value = getRandomString(length, length); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + modelValue: value + }, + mixins: [mockMixin] + }); + + // Act + // Assert + expect(wrapper.vm.characterCount).toBe(length); + }); + }); + describe('value', () => { + test('Get value corresponds to modelValue', () => { + // Arrange + const modelValue = getRandomString(10, 20); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + modelValue + }, + mixins: [mockMixin] + }); + + // Act + // Assert + expect(wrapper.vm.value).toBe(modelValue); + }); + test('Set value => update modelValue event emitted with new value', () => { + // Arrange + const modelValue = getRandomString(10, 20); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + modelValue + }, + mixins: [mockMixin] + }); + const newValue = getRandomString(10, 20); + + // Act + wrapper.vm.value = newValue; + + // Assert + expect(wrapper.emitted('update:modelValue')).toBeTruthy(); + expect(wrapper.emitted('update:modelValue')[0][0]).toEqual(newValue); + }); + }); + }); + describe('Properties properly affect initial state', () => { + test('Placeholder text sets placeholder text of text area', () => { + // Arrange + const placeholderText = getRandomString(10, 20); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + placeholderText + }, + mixins: [mockMixin] + }); + + // Act + const textarea = wrapper.find('textarea'); + + // Assert + expect(textarea.attributes().placeholder).toBe(placeholderText); + }); + test('isDisabled true => textarea disabled', () => { + // Arrange + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + isDisabled: true + }, + mixins: [mockMixin] + }); + + // Act + const textarea = wrapper.find('textarea'); + + // Assert + expect(textarea.attributes().disabled).toBeDefined(); + }); + test('isRequired true => textarea required', () => { + // Arrange + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + isRequired: true + }, + mixins: [mockMixin] + }); + + // Act + const textarea = wrapper.find('textarea'); + + // Assert + expect(textarea.attributes().required).toBeDefined(); + }); + test('validationRules set rules of text area', () => { + // Arrange + const rule = getRandomString(10, 20); + const errorMessage = getRandomString(20, 30); + defineRule(rule, required(errorMessage)); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + validationRules: rule + }, + mixins: [mockMixin] + }); + + // Act + const textarea = wrapper.find('textarea'); + + // Assert + expect(textarea.attributes().validationrules).toBe(rule); + }); + test('maxLength set max length of text area', () => { + // Arrange + const maxLength = toString(getRandomInt(100, 900)); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + maxLength + }, + mixins: [mockMixin] + }); + + // Act + const textarea = wrapper.find('textarea'); + + // Assert + expect(textarea.attributes().maxlength).toBe(maxLength); + }); + test('inputRows set input rows of text area', () => { + // Arrange + const inputRows = getRandomInt(10, 20); + const wrapper = shallowMount(textareaQuestion, { + propsData: { + inputId: getRandomString(10, 20), + cmsWidgetName: getRandomString(10, 20), + inputRows + }, + mixins: [mockMixin] + }); + + // Act + const textarea = wrapper.find('textarea'); + + // Assert + expect(textarea.attributes().rows).toBe(`${inputRows}`); + }); + }); +}); diff --git a/src/digital-components/textarea-question/textarea-question.vue b/src/digital-components/textarea-question/textarea-question.vue index 83a7ca5c..24776aed 100644 --- a/src/digital-components/textarea-question/textarea-question.vue +++ b/src/digital-components/textarea-question/textarea-question.vue @@ -1,7 +1,7 @@