diff --git a/resources/js/components/fieldtypes/VideoFieldtype.vue b/resources/js/components/fieldtypes/VideoFieldtype.vue index 848a08d4fbf..5282a8b1a3a 100644 --- a/resources/js/components/fieldtypes/VideoFieldtype.vue +++ b/resources/js/components/fieldtypes/VideoFieldtype.vue @@ -7,7 +7,7 @@ :isReadOnly="isReadOnly" :placeholder="__(config.placeholder) || 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'" :aria-label="__('Video URL')" - @update:model-value="update" + @update:model-value="updateDebounced" @focus="$emit('focus')" @blur="$emit('blur')" input-class="border-s-0" diff --git a/resources/js/tests/components/fieldtypes/VideoFieldtype.test.js b/resources/js/tests/components/fieldtypes/VideoFieldtype.test.js new file mode 100644 index 00000000000..241092cdd86 --- /dev/null +++ b/resources/js/tests/components/fieldtypes/VideoFieldtype.test.js @@ -0,0 +1,62 @@ +import { mount } from '@vue/test-utils'; +import { afterEach, beforeEach, expect, test, vi } from 'vitest'; +import VideoFieldtype from '@/components/fieldtypes/VideoFieldtype.vue'; +import { publishContextKey } from '@/components/ui'; + +window.__ = (key) => key; + +beforeEach(() => { + vi.useFakeTimers(); + + window.IntersectionObserver = class { + observe() {} + disconnect() {} + }; +}); + +afterEach(() => { + vi.useRealTimers(); + vi.restoreAllMocks(); +}); + +const stub = (tag) => ({ + props: ['modelValue'], + emits: ['update:modelValue'], + template: `<${tag} :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />`, +}); + +const mountVideoField = (props = {}) => { + return mount(VideoFieldtype, { + props: { + handle: 'video', + config: {}, + meta: {}, + ...props, + }, + global: { + provide: { [publishContextKey]: {} }, + stubs: { + 'ui-input': stub('input'), + 'ui-input-group': { template: '