import { VueWrapper, shallowMount } from '@vue/test-utils' import { beforeEach, describe, expect, it } from 'vitest' import AmeliproCustomSelector from '../AmeliproCustomSelector.vue' import type { AmeliproCustomSelectorItem } from '../types' import type { ComponentProps } from 'vue-component-type-helpers' import type { ExpectedPropOptions } from '@tests/types' import type { PropType } from 'vue' import TestHelper from '@tests/helpers/TestHelper' const expectedPropOptions: ExpectedPropOptions = { required: { type: Boolean, default: false, }, disabled: { type: Boolean, default: false, }, groupLabel: { type: String, required: true, }, itemsPerLine: { type: Number, default: 1, }, labelDescription: { type: String, default: undefined, }, labelMarginBottom: { type: String, default: undefined, }, modelValue: { type: Array as PropType, default: () => [], }, multipleRequired: { type: Boolean, default: false, }, multipleRequiredErrorMessage: { type: String, default: 'Vous devez cocher au moins deux options', }, requiredErrorMessage: { type: String, default: 'SĂ©lection obligatoire', }, unique: { type: Boolean, default: false, }, uniqueId: { type: String, required: true, }, } // Values pour les props "required" const requiredPropValues = (): ComponentProps => ({ groupLabel: 'Required group label', uniqueId: 'required-unique-id', }) // Valeurs pour les props "modified" const modifiedPropValues = (): ComponentProps => ({ required: true, disabled: true, groupLabel: 'Modified group label', itemsPerLine: 2, labelDescription: 'Modified label description', // Doit ĂȘtre une valeur valide labelMarginBottom: '20px', modelValue: [ { isChecked: false, label: 'modified item label 1', value: 'modified-item-value-1', }, { isChecked: false, label: 'modified item label 2', value: 'modified-item-value-2', }, { isChecked: true, label: 'modified item label 3', value: 'modified-item-value-3', }, ] as AmeliproCustomSelectorItem[], multipleRequired: true, multipleRequiredErrorMessage: 'Modified multiple required error message', requiredErrorMessage: 'Modified required error message', unique: true, uniqueId: 'modified-unique-id', }) const testHelper = new TestHelper(AmeliproCustomSelector) testHelper.setExpectedPropOptions(expectedPropOptions) .setRequiredPropValues(requiredPropValues) .setModifiedPropValues(modifiedPropValues) describe('AmeliproCustomSelector', () => { describe('Snapshots', () => { testHelper.snapshots() }) describe('Properties', () => { testHelper.properties() }) describe('Setting props should update attributes of inner tags', () => { let wrapper: VueWrapper> beforeEach(() => { wrapper = shallowMount(AmeliproCustomSelector, { props: requiredPropValues() }) }) it('prop uniqueId sets id attribute on root', async () => { expect(wrapper.attributes('id')).toBe(`${testHelper.default('uniqueId')}-container`) const { uniqueId } = modifiedPropValues() await wrapper.setProps({ uniqueId }) expect(wrapper.attributes('id')).toBe(`${testHelper.modified('uniqueId')}-container`) }) it('prop labelMarginBottom sets style on label wrapper', async () => { expect(wrapper.find('.amelipro-custom-selector__label-wrapper').attributes('style')).toBe(`margin-bottom: 4px;`) const { labelMarginBottom } = modifiedPropValues() await wrapper.setProps({ labelMarginBottom }) expect(wrapper.find('.amelipro-custom-selector__label-wrapper').attributes('style')).toBe(`margin-bottom: ${testHelper.modified('labelMarginBottom')};`) }) it('prop groupLabel sets text on label', async () => { expect(wrapper.find('.amelipro-custom-selector__label').text()).toContain(testHelper.default('groupLabel')) const { groupLabel } = modifiedPropValues() await wrapper.setProps({ groupLabel }) expect(wrapper.find('.amelipro-custom-selector__label').text()).toContain(testHelper.modified('groupLabel')) }) it('prop required sets required on group', async () => { expect(wrapper.find('.amelipro-custom-selector__group').attributes('required')).toBeUndefined() const { required } = modifiedPropValues() await wrapper.setProps({ required }) expect(wrapper.find('.amelipro-custom-selector__group').attributes('required')).toBe('true') }) it('prop disabled sets aria-disabled on group', async () => { expect(wrapper.find('.amelipro-custom-selector__group').attributes('aria-disabled')).toBeUndefined() const { disabled } = modifiedPropValues() await wrapper.setProps({ disabled }) expect(wrapper.find('.amelipro-custom-selector__group').attributes('aria-disabled')).toBe('true') }) }) describe('Events', () => { it.skip('should react to change:selected event for unique', async () => { const wrapper = shallowMount(AmeliproCustomSelector, { props: modifiedPropValues() }) let inputWrappers = wrapper.findAll('.amelipro-custom-selector__item input') inputWrappers = wrapper.findAll('input') expect(wrapper.emitted('change:selected')).toBeUndefined() inputWrappers.at(0)?.trigger('input') await wrapper.vm.$nextTick() expect(wrapper.emitted('change:selected')).toStrictEqual([[ 'the-item-value-1', 'the-group-id', ]]) }) // skip this because there is an error "Cannot read property 'addApp' of null" we don't know where is this property 'addApp' // we tested with console.log and it seems to work well but the error is still here it.skip('should react to change:selected event for multiple', async () => { const wrapper = shallowMount(AmeliproCustomSelector, { props: modifiedPropValues() }) await wrapper.setProps({ unique: false }) let inputWrappers = wrapper.findAll('.amelipro-custom-selector__item input') inputWrappers = wrapper.findAll('input') await wrapper.vm.$nextTick() await inputWrappers.at(0)?.trigger('input') expect(wrapper.emitted('change:selected')).toStrictEqual([[ [ 'the-item-value-1', 'the-item-value-3', ], 'the-group-id', ]]) }) }) })