From b21c5752b872feb96670f720ef5ca81303a4ac50 Mon Sep 17 00:00:00 2001 From: jtubau Date: Wed, 30 Apr 2025 10:41:49 +0200 Subject: [PATCH 1/4] test: refs #7069 add unit tests for VnAccountNumber component --- .../__tests__/vnAccountNumber.spec.js | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/components/__tests__/vnAccountNumber.spec.js diff --git a/src/components/__tests__/vnAccountNumber.spec.js b/src/components/__tests__/vnAccountNumber.spec.js new file mode 100644 index 000000000..937ed171c --- /dev/null +++ b/src/components/__tests__/vnAccountNumber.spec.js @@ -0,0 +1,58 @@ +import { describe, expect, it, vi, beforeEach } from 'vitest'; +import { createWrapper } from 'app/test/vitest/helper'; +import VnAccountNumber from 'src/components/common/VnAccountNumber.vue'; + +const VnInputStub = { + name: 'VnInput', + props: ['modelValue'], + emits: ['input', 'keydown', 'blur'], + template: ` + + `, +}; + +describe('VnAccountNumber', () => { + let wrapper; + let input; + let spyShort; + + beforeEach(() => { + wrapper = createWrapper(VnAccountNumber, { + props: { modelValue: '' }, + global: { stubs: { VnInput: VnInputStub } }, + }); + wrapper = wrapper.wrapper; + input = wrapper.findComponent(VnInputStub); + spyShort = vi.spyOn(wrapper.vm, 'useAccountShortToStandard'); + }); + + it('should filters out non-numeric characters on input event', async () => { + await input.vm.$emit('input', { target: { value: 'abc123.45!@#' } }); + const emitted = wrapper.emitted('update:modelValue'); + expect(emitted.pop()[0]).toBe('123.45'); + expect(spyShort).not.toHaveBeenCalled(); + }); + + it('should applies conversion on blur when valid short value provided', async () => { + await input.vm.$emit('input', { target: { value: '123.45' } }); + await input.trigger('keydown.tab'); + + const emitted = wrapper.emitted('update:modelValue'); + expect(emitted.pop()[0]).toBe('1230000045'); + expect(spyShort).toHaveBeenCalled(); + }); + + it('should does not change value for invalid input values', async () => { + await input.vm.$emit('input', { target: { value: '123' } }); + await input.trigger('keydown.tab'); + + const emitted = wrapper.emitted('update:modelValue'); + expect(emitted.pop()[0]).toBe('123'); + expect(spyShort).toHaveBeenCalled(); + }); +}); \ No newline at end of file From c723608d6b7cfc424bcc3eb5f2a2457ac821b6b6 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 9 May 2025 09:09:57 +0200 Subject: [PATCH 2/4] refactor: refs #7069 simplify VnInput emits and update event handling in tests --- .../__tests__/vnAccountNumber.spec.js | 41 ++++++------------- src/components/common/VnInput.vue | 11 +---- 2 files changed, 15 insertions(+), 37 deletions(-) diff --git a/src/components/__tests__/vnAccountNumber.spec.js b/src/components/__tests__/vnAccountNumber.spec.js index 937ed171c..688e50e6a 100644 --- a/src/components/__tests__/vnAccountNumber.spec.js +++ b/src/components/__tests__/vnAccountNumber.spec.js @@ -2,57 +2,42 @@ import { describe, expect, it, vi, beforeEach } from 'vitest'; import { createWrapper } from 'app/test/vitest/helper'; import VnAccountNumber from 'src/components/common/VnAccountNumber.vue'; -const VnInputStub = { - name: 'VnInput', - props: ['modelValue'], - emits: ['input', 'keydown', 'blur'], - template: ` - - `, -}; - describe('VnAccountNumber', () => { let wrapper; let input; + let vnInput; let spyShort; beforeEach(() => { - wrapper = createWrapper(VnAccountNumber, { - props: { modelValue: '' }, - global: { stubs: { VnInput: VnInputStub } }, - }); + wrapper = createWrapper(VnAccountNumber); wrapper = wrapper.wrapper; - input = wrapper.findComponent(VnInputStub); + input = wrapper.find('input'); + vnInput = wrapper.findComponent({ name: 'VnInput' }); spyShort = vi.spyOn(wrapper.vm, 'useAccountShortToStandard'); }); - it('should filters out non-numeric characters on input event', async () => { - await input.vm.$emit('input', { target: { value: 'abc123.45!@#' } }); + it('should filter out non-numeric characters on input event', async () => { + await input.setValue('abc123.45!@#'); const emitted = wrapper.emitted('update:modelValue'); expect(emitted.pop()[0]).toBe('123.45'); expect(spyShort).not.toHaveBeenCalled(); }); - it('should applies conversion on blur when valid short value provided', async () => { - await input.vm.$emit('input', { target: { value: '123.45' } }); - await input.trigger('keydown.tab'); + it('should apply conversion on blur when valid short value is provided', async () => { + await input.setValue('123.45'); + await vnInput.trigger('blur'); const emitted = wrapper.emitted('update:modelValue'); expect(emitted.pop()[0]).toBe('1230000045'); expect(spyShort).toHaveBeenCalled(); }); - it('should does not change value for invalid input values', async () => { - await input.vm.$emit('input', { target: { value: '123' } }); - await input.trigger('keydown.tab'); + it('should not change value for invalid input values', async () => { + await input.setValue('123'); + await vnInput.trigger('blur'); const emitted = wrapper.emitted('update:modelValue'); expect(emitted.pop()[0]).toBe('123'); expect(spyShort).toHaveBeenCalled(); }); -}); \ No newline at end of file +}); diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue index 474d68116..0941f7228 100644 --- a/src/components/common/VnInput.vue +++ b/src/components/common/VnInput.vue @@ -6,13 +6,7 @@ import { useRequired } from 'src/composables/useRequired'; const $attrs = useAttrs(); const { isRequired, requiredFieldRule } = useRequired($attrs); const { t } = useI18n(); -const emit = defineEmits([ - 'update:modelValue', - 'update:options', - 'keyup.enter', - 'remove', - 'blur', -]); +const emit = defineEmits(['update:modelValue', 'update:options', 'remove']); const $props = defineProps({ modelValue: { @@ -134,10 +128,9 @@ const handleUppercase = () => { ref="vnInputRef" v-model="value" v-bind="{ ...$attrs, ...styleAttrs }" + v-on="$attrs" :type="$attrs.type" :class="{ required: isRequired }" - @keyup.enter="emit('keyup.enter')" - @blur="emit('blur')" @keydown="handleKeydown" :clearable="false" :rules="mixinRules" From 43258214e1afc79cb083f46521e0d17581156741 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 9 May 2025 09:46:06 +0200 Subject: [PATCH 3/4] feat: refs #7069 add keyup.enter and blur event emissions to VnInput component --- src/components/common/VnInput.vue | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue index 0941f7228..474d68116 100644 --- a/src/components/common/VnInput.vue +++ b/src/components/common/VnInput.vue @@ -6,7 +6,13 @@ import { useRequired } from 'src/composables/useRequired'; const $attrs = useAttrs(); const { isRequired, requiredFieldRule } = useRequired($attrs); const { t } = useI18n(); -const emit = defineEmits(['update:modelValue', 'update:options', 'remove']); +const emit = defineEmits([ + 'update:modelValue', + 'update:options', + 'keyup.enter', + 'remove', + 'blur', +]); const $props = defineProps({ modelValue: { @@ -128,9 +134,10 @@ const handleUppercase = () => { ref="vnInputRef" v-model="value" v-bind="{ ...$attrs, ...styleAttrs }" - v-on="$attrs" :type="$attrs.type" :class="{ required: isRequired }" + @keyup.enter="emit('keyup.enter')" + @blur="emit('blur')" @keydown="handleKeydown" :clearable="false" :rules="mixinRules" From 649686f12805a479c7d226a180be7c8a1d8d4b02 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 9 May 2025 09:53:42 +0200 Subject: [PATCH 4/4] refactor: refs #7069 remove keyup.enter and blur event emissions from VnInput component --- src/components/common/VnInput.vue | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue index 474d68116..3097ade81 100644 --- a/src/components/common/VnInput.vue +++ b/src/components/common/VnInput.vue @@ -6,13 +6,7 @@ import { useRequired } from 'src/composables/useRequired'; const $attrs = useAttrs(); const { isRequired, requiredFieldRule } = useRequired($attrs); const { t } = useI18n(); -const emit = defineEmits([ - 'update:modelValue', - 'update:options', - 'keyup.enter', - 'remove', - 'blur', -]); +const emit = defineEmits(['update:modelValue', 'update:options', 'remove']); const $props = defineProps({ modelValue: { @@ -126,6 +120,14 @@ const handleInsertMode = (e) => { const handleUppercase = () => { value.value = value.value?.toUpperCase() || ''; }; + +const listeners = computed(() => + Object.fromEntries( + Object.entries($attrs).filter( + ([key, val]) => key.startsWith('on') && typeof val === 'function', + ), + ), +);