diff --git a/frontend/src/components/form/base/__tests__/ECheckbox.spec.js b/frontend/src/components/form/base/__tests__/ECheckbox.spec.js index 465508eceb..6c366db8b1 100644 --- a/frontend/src/components/form/base/__tests__/ECheckbox.spec.js +++ b/frontend/src/components/form/base/__tests__/ECheckbox.spec.js @@ -12,53 +12,66 @@ Vue.use(formBaseComponents) describe('An ECheckbox', () => { let vuetify - const mount = (options) => mountComponent(ECheckbox, { vuetify, ...options }) + const mount = (options) => { + const app = Vue.component('App', { + components: { ECheckbox }, + data: function () { + return { + data: null + } + }, + template: ` +
+ +
+ ` + }) + return mountComponent(app, { vuetify, attachTo: document.body, ...options }) + } beforeEach(() => { vuetify = new Vuetify() }) test('looks like a checkbox', async () => { const wrapper = mount() - await wrapper.setProps({ vModel: false }) + await wrapper.setData({ data: false }) expect(wrapper.element).toMatchSnapshot('unchecked') - await wrapper.setProps({ vModel: true }) + await wrapper.setData({ data: true }) expect(wrapper.element).toMatchSnapshot('checked') }) test('is checked when initialized checked', () => { const wrapper = mount({ - propsData: { - vModel: true + data: function () { + return { + data: true + } } }) - expect(wrapper.find('input[type=checkbox]').element.getAttribute('vmodel')).toBe('true') + expect(wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')).toBe('true') }) test('updates checkbox when vModel changes', async () => { const wrapper = mount() - expect(wrapper.find('input[type=checkbox]').element.getAttribute('vmodel')).toBeNull() + await wrapper.setData({ data: false }) + expect(wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')).toBe('false') - await wrapper.setProps({ vModel: true }) - expect(wrapper.find('input[type=checkbox]').element.getAttribute('vmodel')).toBe('true') + await wrapper.setData({ data: true }) + expect(wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')).toBe('true') - await wrapper.setProps({ vModel: false }) - expect(wrapper.find('input[type=checkbox]').element.getAttribute('vmodel')).toBeNull() + await wrapper.setData({ data: false }) + expect(wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')).toBe('false') }) test('updates vModel when user clicks on checkbox', async () => { const wrapper = mount() const input = wrapper.find('input') - const change = jest.fn() - wrapper.vm.$on('input', (event) => change(event)) - await input.trigger('click') - expect(change).toBeCalledTimes(1) - expect(change).toBeCalledWith(true) + expect(wrapper.vm.data).toBe(true) jest.resetAllMocks() await input.trigger('click') - expect(change).toBeCalledTimes(1) - expect(change).toBeCalledWith(false) + expect(wrapper.vm.data).toBe(false) }) }) diff --git a/frontend/src/components/form/base/__tests__/ESelect.spec.js b/frontend/src/components/form/base/__tests__/ESelect.spec.js new file mode 100644 index 0000000000..df4bf898ab --- /dev/null +++ b/frontend/src/components/form/base/__tests__/ESelect.spec.js @@ -0,0 +1,104 @@ +import Vue from 'vue' +import Vuetify from 'vuetify' + +import { formBaseComponents } from '@/plugins' + +import { mount as mountComponent } from '@vue/test-utils' +import ESelect from '../ESelect' + +Vue.use(Vuetify) +Vue.use(formBaseComponents) + +describe('An ESelect', () => { + let vuetify + + const FIRST_OPTION = { + value: 1, + text: 'firstOption' + } + const SECOND_OPTION = { + value: '2', + text: 'secondOption' + } + const THIRD_OPTION = { + value: { key: 'value', array: [1, 2, 3], nestedObject: { key: 'value' } }, + text: 'thirdOption' + } + const selectValues = [ + FIRST_OPTION, + SECOND_OPTION, + THIRD_OPTION + ] + + const mount = (options) => { + const app = Vue.component('App', { + components: { ESelect }, + data: function () { + return { + selectValues: selectValues, + data: null + } + }, + template: ` +
+ +
+ ` + }) + return mountComponent(app, { vuetify, attachTo: document.body, ...options }) + } + + beforeEach(() => { + vuetify = new Vuetify() + }) + test('looks like a dropdown', async () => { + const wrapper = mount() + expect(wrapper.element).toMatchSnapshot('no item selected') + + await wrapper.find('.v-input__slot').trigger('click') + expect(wrapper.element).toMatchSnapshot('dropdown open') + + await wrapper.findAll('[role="option"]').at(0).trigger('click') + expect(wrapper.element).toMatchSnapshot('dropdown closed with selected value') + + await wrapper.find('.v-input__slot').trigger('click') + expect(wrapper.element).toMatchSnapshot('dropdown open with selected value') + }) + + test('update viewmodel with selected value', async () => { + const wrapper = mount() + expect(wrapper.vm.data).toBeNull() + + await wrapper.find('.v-input__slot').trigger('click') + await wrapper.findAll('[role="option"]').at(0).trigger('click') + expect(wrapper.vm.data).toBe(FIRST_OPTION.value) + + await wrapper.find('.v-input__slot').trigger('click') + await wrapper.findAll('[role="option"]').at(2).trigger('click') + expect(wrapper.vm.data).toBe(THIRD_OPTION.value) + }) + + test('update selected value with viewmodel', async () => { + const wrapper = mount() + + await wrapper.setData({ data: SECOND_OPTION.value }) + expect(wrapper.html()).toContain(SECOND_OPTION.text) + expect(wrapper.html()).not.toContain(FIRST_OPTION.text) + + await wrapper.setData({ data: FIRST_OPTION.value }) + expect(wrapper.html()).toContain(FIRST_OPTION.text) + expect(wrapper.html()).not.toContain(SECOND_OPTION.text) + }) + + test('update selected value after it was open', async () => { + const wrapper = mount() + + await wrapper.find('.v-input__slot').trigger('click') + await wrapper.findAll('[role="option"]').at(0).trigger('click') + expect(wrapper.vm.data).toBe(FIRST_OPTION.value) + + await wrapper.setData({ data: SECOND_OPTION.value }) + expect(wrapper.findAll('[role="option"]').at(1).element.getAttribute('aria-selected')).toBe('true') + expect(wrapper.findAll('[role="option"]').at(0).element.getAttribute('aria-selected')).not.toBe('true') + }) +}) diff --git a/frontend/src/components/form/base/__tests__/ESwitch.spec.js b/frontend/src/components/form/base/__tests__/ESwitch.spec.js new file mode 100644 index 0000000000..e01d07a1fd --- /dev/null +++ b/frontend/src/components/form/base/__tests__/ESwitch.spec.js @@ -0,0 +1,102 @@ +import Vue from 'vue' +import Vuetify from 'vuetify' + +import formBaseComponents from '@/plugins/formBaseComponents' + +import { mount as mountComponent } from '@vue/test-utils' +import ESwitch from '@/components/form/base/ESwitch' +import { touch } from '@/test/util' + +Vue.use(Vuetify) +Vue.use(formBaseComponents) + +describe('An ESwitch', () => { + let vuetify + + const mount = (options) => { + const app = Vue.component('App', { + components: { ESwitch }, + data: function () { + return { + data: null + } + }, + template: ` +
+ +
+ ` + }) + return mountComponent(app, { vuetify, attachTo: document.body, ...options }) + } + beforeEach(() => { + vuetify = new Vuetify() + }) + test('looks like a switch', async () => { + const wrapper = mount() + await wrapper.setData({ data: false }) + expect(wrapper.element).toMatchSnapshot('unchecked') + + await wrapper.setData({ data: true }) + expect(wrapper.element).toMatchSnapshot('checked') + }) + + test('is checked when initialized checked', () => { + const wrapper = mount({ + data: function () { + return { + data: true + } + } + }) + expect(wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')).toBe('true') + }) + + test('updates switch when vModel changes', async () => { + const wrapper = mount() + expect(wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')).toBe('false') + + await wrapper.setData({ data: true }) + expect(wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')).toBe('true') + + await wrapper.setData({ data: false }) + expect(wrapper.find('input[type=checkbox]').element.getAttribute('aria-checked')).toBe('false') + }) + + test('updates vModel when user toggles with click', async () => { + const wrapper = mount() + const input = wrapper.find('input') + + await input.trigger('click') + expect(wrapper.vm.data).toBe(true) + + await input.trigger('click') + expect(wrapper.vm.data).toBe(false) + }) + + test('updates vModel when user toggles with touch swipe', async () => { + const wrapper = mount() + + touch(wrapper.find('.v-input--selection-controls__ripple')).start(0, 0).end(20, 0) + expect(wrapper.vm.data).toBe(true) + + jest.resetAllMocks() + touch(wrapper.find('.v-input--selection-controls__ripple')).start(0, 0).end(-20, 0) + expect(wrapper.vm.data).toBe(false) + }) + + test('updates vModel when user toggles with keys', async () => { + const wrapper = mount() + const input = wrapper.find('input') + + input.trigger('keydown.right') + expect(wrapper.vm.data).toBe(true) + + input.trigger('keydown.right') + expect(wrapper.vm.data).toBe(true) + + jest.resetAllMocks() + input.trigger('keydown.left') + expect(wrapper.vm.data).toBe(false) + }) +}) diff --git a/frontend/src/components/form/base/__tests__/__snapshots__/ECheckbox.spec.js.snap b/frontend/src/components/form/base/__tests__/__snapshots__/ECheckbox.spec.js.snap index f7abb6f855..ad1979f624 100644 --- a/frontend/src/components/form/base/__tests__/__snapshots__/ECheckbox.spec.js.snap +++ b/frontend/src/components/form/base/__tests__/__snapshots__/ECheckbox.spec.js.snap @@ -1,72 +1,79 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`An ECheckbox looks like a checkbox: checked 1`] = ` - -
+
+
-