import { mount } from '@vue/test-utils' import { afterEach, describe, expect, it, vi } from 'vitest' import { nextTick } from 'vue' import MobileSupportGate from '../../components/MobileSupportGate.vue' 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('MobileSupportGate', () => { afterEach(() => { vi.restoreAllMocks() }) it('shows the unsupported message on mobile when the route is unsupported', async () => { mockMatchMedia(true) const wrapper = mount(MobileSupportGate, { props: { supported: false, }, slots: { default: '
Workspace content
', }, }) await nextTick() expect(wrapper.find('[data-testid="mobile-unsupported"]').exists()).toBe(true) expect(wrapper.text()).toContain('Desktop workspace recommended') expect(wrapper.find('[data-testid="content"]').exists()).toBe(false) }) it('renders content on desktop even when the route is mobile-unsupported', async () => { mockMatchMedia(false) const wrapper = mount(MobileSupportGate, { props: { supported: false, }, slots: { default: '
Workspace content
', }, }) await nextTick() expect(wrapper.find('[data-testid="mobile-unsupported"]').exists()).toBe(false) expect(wrapper.find('[data-testid="content"]').exists()).toBe(true) }) it('renders content on mobile when the route is supported', async () => { mockMatchMedia(true) const wrapper = mount(MobileSupportGate, { props: { supported: true, }, slots: { default: '
Workspace content
', }, }) await nextTick() expect(wrapper.find('[data-testid="mobile-unsupported"]').exists()).toBe(false) expect(wrapper.find('[data-testid="content"]').exists()).toBe(true) }) it('reacts when the viewport moves into the mobile query', async () => { const media = mockMatchMedia(false) const wrapper = mount(MobileSupportGate, { props: { supported: false, }, slots: { default: '
Workspace content
', }, }) await nextTick() expect(wrapper.find('[data-testid="content"]').exists()).toBe(true) media.setMatches(true) await nextTick() expect(wrapper.find('[data-testid="mobile-unsupported"]').exists()).toBe(true) }) })