import React from 'react' import { render } from '../__utils/test-utils' import userEvent from '@testing-library/user-event' import { ProductSwitcher } from '.' import { STUB_DATA, STUB_DATA_PLUS_ENSEMBLE } from './stub' import { breakpoints } from '@planview/pv-utilities' describe('ProductSwitcher', () => { describe('Initialization', () => { it('Should display loading if there are no apps', async () => { const { getByRole } = render() const trigger = getByRole('button', { name: 'Planview product switcher', }) expect(trigger).toBeInTheDocument() await userEvent.click(trigger) expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() expect(getByRole('menuitemradio')).toHaveAttribute( 'aria-label', 'Loading your Planview products' ) }) it('Should not display loading if apps have loaded', async () => { const { getAllByRole, getByRole } = render( ) const trigger = getByRole('button', { name: 'Planview product switcher', }) expect(trigger).toBeInTheDocument() await userEvent.click(trigger) expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() expect( getAllByRole('menuitemradio') .map((el) => el.getAttribute('aria-busy')) .filter(Boolean) ).toHaveLength(0) }) it('Should display organization branding if present', async () => { const { getByRole } = render( ) const trigger = getByRole('button', { name: 'Planview product switcher', }) expect(trigger).toBeInTheDocument() await userEvent.click(trigger) expect( getByRole('menu', { name: 'Planview product switcher for Example domain example-domain', }) ).toBeInTheDocument() }) }) describe('Breakpoints', () => { afterAll(() => { window.innerWidth = breakpoints.DESKTOP }) it('Should not display mobile header in breakpoints.DESKTOP', async () => { window.innerWidth = breakpoints.DESKTOP const { getByRole, queryByRole } = render( ) await userEvent.click( getByRole('button', { name: 'Planview product switcher' }) ) expect( queryByRole('button', { name: 'Close' }) ).not.toBeInTheDocument() }) it('Should display mobile header in breakpoints.PHONE', async () => { window.innerWidth = breakpoints.PHONE const { getByRole } = render( ) await userEvent.click( getByRole('button', { name: 'Planview product switcher' }) ) expect(getByRole('button', { name: 'Close' })).toBeInTheDocument() }) }) describe('Interaction', () => { it('open on enter', async () => { const { getByRole } = render( ) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{enter}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() }) it('open on space', async () => { const { getByRole } = render( ) await userEvent.keyboard('{Tab}') await userEvent.keyboard(' ') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() }) it('open on arrow-down', async () => { const { getByRole } = render( ) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{ArrowDown}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() }) it('close on escape', async () => { const { getByRole, queryByRole } = render( ) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{ArrowDown}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() await userEvent.keyboard('{escape}') expect( queryByRole('menu', { name: 'Planview product switcher' }) ).not.toBeInTheDocument() }) it('close on trigger click', async () => { const { getByRole, queryByRole } = render( ) const trigger = getByRole('button', { name: 'Planview product switcher', }) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{ArrowDown}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() await userEvent.click(trigger) expect( queryByRole('menu', { name: 'Planview product switcher' }) ).not.toBeInTheDocument() }) it('open and navigate to third item (without Planview.me)', async () => { const { getByRole } = render( p.name !== 'planview_me')} /> ) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{ArrowDown}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() //First item focused when opening list expect( getByRole('menuitemradio', { name: `${STUB_DATA[0].label} ${STUB_DATA[0].secondaryLabel}`, }) ).toHaveFocus() //Navigate down await userEvent.keyboard('{ArrowDown}') //Navigate down await userEvent.keyboard('{ArrowDown}') //Third item focused when opening list expect( getByRole('menuitemradio', { name: STUB_DATA[2].label, }) ).toHaveFocus() }) it('open and navigate to third item (with Planview.me)', async () => { const { getByRole } = render( ) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{ArrowDown}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() //First item focused when opening list expect( getByRole('menuitemradio', { name: `Planview.Me My Planview Home`, }) ).toHaveFocus() //Navigate down await userEvent.keyboard('{ArrowDown}') //Navigate down await userEvent.keyboard('{ArrowDown}') //Third item focused when opening list expect( getByRole('menuitemradio', { name: STUB_DATA[1].label, }) ).toHaveFocus() }) it('open and navigate to Ensemble', async () => { const spy = jest.fn() const { getByRole } = render( ) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{ArrowDown}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() //First item focused when opening list expect( getByRole('menuitemradio', { name: `Planview.Me My Planview Home`, }) ).toHaveFocus() //Navigate down await userEvent.keyboard('{ArrowDown}') //Second item focused expect( getByRole('menuitemradio', { name: 'Planview.Me Labs', }) ).toHaveFocus() await userEvent.keyboard('{Enter}') expect(spy).toHaveBeenCalledWith(STUB_DATA_PLUS_ENSEMBLE[0]) }) it('onActivate callback on space', async () => { const spy = jest.fn() const { getByRole } = render( ) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{ArrowDown}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() //Navigate down await userEvent.keyboard('{ArrowDown}') //Navigate down await userEvent.keyboard('{ArrowDown}') //Activate third item await userEvent.keyboard(' ') expect(spy).toHaveBeenCalledWith(STUB_DATA[1]) }) it('onActivate callback on enter', async () => { const spy = jest.fn() const { getByRole } = render( ) await userEvent.keyboard('{Tab}') await userEvent.keyboard('{ArrowDown}') expect( getByRole('menu', { name: 'Planview product switcher' }) ).toBeInTheDocument() //Navigate down await userEvent.keyboard('{ArrowDown}') //Navigate down await userEvent.keyboard('{ArrowDown}') //Activate second item await userEvent.keyboard('{enter}') expect(spy).toHaveBeenCalledWith(STUB_DATA[1]) }) }) })