diff --git a/packages/_vue3-migration-test/src/components/index.ts b/packages/_vue3-migration-test/src/components/index.ts index 1722fbb29c..77985e8f78 100644 --- a/packages/_vue3-migration-test/src/components/index.ts +++ b/packages/_vue3-migration-test/src/components/index.ts @@ -19,3 +19,4 @@ export { default as TestSearch } from './test-search.vue'; export { default as TestTagging } from './tagging/test-tagging.vue'; export { default as TestRenderlessExtraParam } from './extra-params/test-renderless-extra-param.vue'; export { default as TestIcons } from './icons/test-icons.vue'; +export { default as TestDisplayEmitter } from './test-display-emitter.vue'; diff --git a/packages/_vue3-migration-test/src/components/test-display-emitter.vue b/packages/_vue3-migration-test/src/components/test-display-emitter.vue new file mode 100644 index 0000000000..29b8fa6463 --- /dev/null +++ b/packages/_vue3-migration-test/src/components/test-display-emitter.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/packages/_vue3-migration-test/src/main.ts b/packages/_vue3-migration-test/src/main.ts index 3ba06cd5e2..f52b222ea7 100644 --- a/packages/_vue3-migration-test/src/main.ts +++ b/packages/_vue3-migration-test/src/main.ts @@ -91,7 +91,8 @@ const adapter = { } }) ); - } + }, + tagging: () => new Promise(resolve => resolve()) } as unknown as XComponentsAdapter; const store = createStore({}); diff --git a/packages/_vue3-migration-test/src/router.ts b/packages/_vue3-migration-test/src/router.ts index f03d8da35b..c040f9f98c 100644 --- a/packages/_vue3-migration-test/src/router.ts +++ b/packages/_vue3-migration-test/src/router.ts @@ -49,7 +49,8 @@ import { TestTagging, TestRenderlessExtraParam, TestAnimationFactory, - TestIcons + TestIcons, + TestDisplayEmitter } from './'; const routes = [ @@ -302,6 +303,11 @@ const routes = [ path: '/icons', name: 'Icons', component: TestIcons + }, + { + path: '/display-emitter', + name: 'DisplayEmitter', + component: TestDisplayEmitter } ]; diff --git a/packages/x-components/src/components/__tests__/display-emitter.spec.ts b/packages/x-components/src/components/__tests__/display-emitter.spec.ts index 6f6285106a..0a436d073d 100644 --- a/packages/x-components/src/components/__tests__/display-emitter.spec.ts +++ b/packages/x-components/src/components/__tests__/display-emitter.spec.ts @@ -1,6 +1,5 @@ -import { mount, Wrapper } from '@vue/test-utils'; -import Vue, { ref, nextTick, Ref } from 'vue'; -import { TaggingRequest } from '@empathyco/x-types'; +import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import { useEmitDisplayEvent } from '../../composables/use-on-display'; import DisplayEmitter from '../display-emitter.vue'; import { getDataTestSelector } from '../../__tests__/utils'; @@ -8,108 +7,72 @@ import { getDataTestSelector } from '../../__tests__/utils'; jest.mock('../../composables/use-on-display', () => ({ useEmitDisplayEvent: jest.fn() })); - -let emitDisplayEventElementSpy: Ref = ref(null); -let emitDisplayEventPayloadSpy: TaggingRequest = { url: '', params: {} }; const unwatchDisplaySpy = jest.fn(); -const refElementVisibility = ref(false); -(useEmitDisplayEvent as jest.Mock).mockImplementation(({ element, taggingRequest }) => { - // jest doesn't handle well evaluation of dynamic references with `toHaveBeenCalledWith` - // so we need a spy - emitDisplayEventElementSpy = element; - emitDisplayEventPayloadSpy = taggingRequest; - - return { - isElementVisible: refElementVisibility, - unwatchDisplay: unwatchDisplaySpy - }; -}); - -/** - * Renders the {@link DisplayEmitter} component, exposing a basic API for testing. - * - * @param options - The options to render the component with. - * - * @returns The API for testing the `DisplayEmitter` component. - */ -function renderDisplayEmitter( - { payload }: RenderDisplayEmitterOptions = { payload: { url: '', params: {} } } -): RenderDisplayEmitterAPI { - const wrapper = mount( - { - components: { - DisplayEmitter - }, - template: ` - -
- `, - props: ['payload'] - }, - { - propsData: { - payload - } - } - ); +(useEmitDisplayEvent as jest.Mock).mockReturnValue({ unwatchDisplay: unwatchDisplaySpy }); + +function render({ + payload = { url: 'tagging/url', params: { test: 'param' } }, + eventMetadata = { test: 'param' } +} = {}) { + const wrapper = mount({ + components: { DisplayEmitter }, + template: ` + +
+ `, + data: () => ({ payload, eventMetadata }) + }); return { - wrapper + wrapper: wrapper.findComponent(DisplayEmitter), + element: wrapper.find(getDataTestSelector('child')).element, + payload, + eventMetadata }; } describe('testing DisplayEmitter component', () => { beforeEach(() => { - refElementVisibility.value = false; + (useEmitDisplayEvent as jest.Mock).mockClear(); + unwatchDisplaySpy.mockClear(); }); it('renders everything passed to its default slot', () => { - const { wrapper } = renderDisplayEmitter(); + const { wrapper } = render(); - expect(wrapper.find(getDataTestSelector('child')).exists()).toBe(true); + expect(wrapper.find(getDataTestSelector('child')).exists()).toBeTruthy(); }); - it('uses `useEmitDisplayEvent` underneath', () => { - renderDisplayEmitter(); + it('executes `useEmitDisplayEvent` composable underneath', () => { + render(); expect(useEmitDisplayEvent).toHaveBeenCalled(); }); it('provides `useEmitDisplayEvent` with the element in the slot to watch', async () => { - renderDisplayEmitter(); + const { element } = render(); await nextTick(); - expect(emitDisplayEventElementSpy.value).not.toBe(null); - expect(emitDisplayEventElementSpy.value?.$el.getAttribute('data-test')).toBe('child'); + expect(useEmitDisplayEvent).toHaveBeenCalledWith(expect.objectContaining({ element })); }); - // eslint-disable-next-line max-len - it('provides `useEmitDisplayEvent` with the payload to emit with the display event', () => { - const payload = { url: 'test-url', params: { test: 'param' } }; - renderDisplayEmitter({ - payload - }); + it('provides `useEmitDisplayEvent` with the payload and metadata to emit with the display event', async () => { + const { payload, eventMetadata } = render(); - expect(useEmitDisplayEvent).toHaveBeenCalled(); - expect(emitDisplayEventPayloadSpy).toBe(payload); + await nextTick(); + + expect(useEmitDisplayEvent).toHaveBeenCalledWith( + expect.objectContaining({ taggingRequest: payload, eventMetadata }) + ); }); it('removes the watcher on unmount', async () => { - const { wrapper } = renderDisplayEmitter(); + const { wrapper } = render(); wrapper.destroy(); await nextTick(); + expect(unwatchDisplaySpy).toHaveBeenCalled(); }); }); - -interface RenderDisplayEmitterOptions { - /** The payload to provide. */ - payload?: TaggingRequest; -} - -interface RenderDisplayEmitterAPI { - /** The wrapper testing component instance. */ - wrapper: Wrapper; -} diff --git a/packages/x-components/src/components/display-emitter.vue b/packages/x-components/src/components/display-emitter.vue index bd5e18229e..ee55f2881c 100644 --- a/packages/x-components/src/components/display-emitter.vue +++ b/packages/x-components/src/components/display-emitter.vue @@ -1,55 +1,56 @@ - -