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])
})
})
})