import { mount } from '@vue/test-utils' import { computed, defineComponent, nextTick, ref } from 'vue' import { afterEach, describe, expect, it, vi } from 'vitest' import { useMobileSupportGate } from '../../composables/useMobileSupportGate' function mockMatchMedia(initialMatches: boolean) { const listeners = new Set<(event: MediaQueryListEvent) => void>() const queryList = { matches: initialMatches, media: '', onchange: null, addEventListener: vi.fn((_event: string, listener: (event: MediaQueryListEvent) => void) => { listeners.add(listener) }), removeEventListener: vi.fn((_event: string, listener: (event: MediaQueryListEvent) => void) => { listeners.delete(listener) }), addListener: vi.fn((listener: (event: MediaQueryListEvent) => void) => { listeners.add(listener) }), removeListener: vi.fn((listener: (event: MediaQueryListEvent) => void) => { listeners.delete(listener) }), dispatchEvent: vi.fn(), } as unknown as MediaQueryList Object.defineProperty(window, 'matchMedia', { configurable: true, value: vi.fn(() => queryList), }) return { setMatches(matches: boolean) { Object.defineProperty(queryList, 'matches', { configurable: true, value: matches, }) listeners.forEach(listener => listener({ matches } as MediaQueryListEvent)) }, } } describe('useMobileSupportGate', () => { afterEach(() => { vi.restoreAllMocks() }) it('computes the unsupported state from viewport and supported sources', async () => { const media = mockMatchMedia(true) const supported = ref(false) const wrapper = mount(defineComponent({ setup() { const gate = useMobileSupportGate({ supported: computed(() => supported.value), }) return gate }, template: '
{{ shouldShowUnsupported }}
', })) await nextTick() expect(wrapper.text()).toBe('true') supported.value = true await nextTick() expect(wrapper.text()).toBe('false') supported.value = false media.setMatches(false) await nextTick() expect(wrapper.text()).toBe('false') }) })