4e57f6b342
* draft for tablet view * adapt sidebar to tablet view * split menubar to handle tablet and desktop separatly * split sidebar to handle tablet and desktop separatly * prettier day navigationin tablet view * added missing translations * coderabbit comments * fix UI of view switcher on tablet, remove hard text * fix style of selected view option * fix wrong I18n key * extracted menubar recurring components to own files * adjust test case of calendar component * refactor function change calendar view Co-authored-by: Camille Moussu <cmoussu@linagora.com> Co-authored-by: lethemanh <lethemanh@lethemanhs-MacBook-Pro.local>
1025 lines
30 KiB
TypeScript
1025 lines
30 KiB
TypeScript
import { CALENDAR_VIEWS } from '@/components/Calendar/utils/constants'
|
|
import { Menubar } from '@/components/Menubar/Menubar'
|
|
import * as oidcAuth from '@/features/User/oidcAuth'
|
|
import { redirectTo } from '@/utils/navigation'
|
|
import '@testing-library/jest-dom'
|
|
import { act, fireEvent, screen, waitFor } from '@testing-library/react'
|
|
import { renderWithProviders } from '../utils/Renderwithproviders'
|
|
|
|
jest.mock('@/utils/navigation', () => ({
|
|
redirectTo: jest.fn()
|
|
}))
|
|
|
|
describe('Calendar App Component Display Tests', () => {
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: 'test@test.com',
|
|
family_name: 'Doe',
|
|
name: 'John',
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
test('renders the Menubar component', () => {
|
|
;(window as any).appList = [
|
|
{ name: 'Twake', link: '/twake', icon: 'twake.svg' },
|
|
{ name: 'Calendar', link: '/calendar', icon: 'calendar.svg' }
|
|
]
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
const logoElement = screen.getByAltText('menubar.logoAlt')
|
|
expect(logoElement).toBeInTheDocument()
|
|
})
|
|
it('renders the main title', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
expect(screen.getByAltText('menubar.logoAlt')).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows avatar with user initials', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
expect(screen.getByText('JD')).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows avatar with email initials when no user name', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: 'test@test.com',
|
|
family_name: 'Doe',
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
expect(screen.getByText('T')).toBeInTheDocument()
|
|
})
|
|
|
|
// Edge cases for avatar display logic
|
|
it('handles user with only family_name', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: 'test@test.com',
|
|
family_name: 'Smith',
|
|
name: null,
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
expect(screen.getByText('T')).toBeInTheDocument()
|
|
})
|
|
|
|
it('handles user with only name', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: 'test@test.com',
|
|
family_name: null,
|
|
name: 'John',
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
expect(screen.getByText('T')).toBeInTheDocument()
|
|
})
|
|
|
|
it('handles user with both name and family_name', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: 'test@test.com',
|
|
family_name: 'Doe',
|
|
name: 'John',
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
expect(screen.getByText('JD')).toBeInTheDocument()
|
|
})
|
|
|
|
it('handles user with no name and family_name', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: 'test@test.com',
|
|
family_name: null,
|
|
name: null,
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
expect(screen.getByText('T')).toBeInTheDocument()
|
|
})
|
|
|
|
it('handles user with empty email', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: '',
|
|
family_name: null,
|
|
name: null,
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
// Should not crash and show empty string
|
|
const avatar = screen.getByRole('img', { hidden: true })
|
|
expect(avatar).toBeInTheDocument()
|
|
})
|
|
|
|
it('handles user with null email', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: null,
|
|
family_name: null,
|
|
name: null,
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
// Should not crash and show empty string
|
|
const avatar = screen.getByRole('img', { hidden: true })
|
|
expect(avatar).toBeInTheDocument()
|
|
})
|
|
|
|
it('handles user with undefined email', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: undefined,
|
|
family_name: null,
|
|
name: null,
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
}
|
|
}
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
// Should not crash and show empty string
|
|
const avatar = screen.getByRole('img', { hidden: true })
|
|
expect(avatar).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows apps button when applist is not empty', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
expect(screen.getByLabelText('menubar.apps')).toBeInTheDocument()
|
|
})
|
|
|
|
it('opens popover when clicking apps button', () => {
|
|
;(window as any).appList = [
|
|
{ name: 'Twake', icon: 'twake.svg', link: '/twake' },
|
|
{ name: 'Calendar', icon: 'calendar.svg', link: '/calendar' }
|
|
]
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
const appsButton = screen.getByLabelText('menubar.apps')
|
|
fireEvent.click(appsButton)
|
|
expect(screen.getByText('Twake')).toBeInTheDocument()
|
|
expect(screen.getByText('Calendar')).toBeInTheDocument()
|
|
})
|
|
|
|
it('renders app icons as links', () => {
|
|
;(window as any).appList = [{ name: 'test', icon: 'test', link: 'test' }]
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
const appsButton = screen.getByLabelText('menubar.apps')
|
|
fireEvent.click(appsButton)
|
|
|
|
const testLink = screen.getByRole('link', { name: /test/i })
|
|
expect(testLink).toHaveAttribute('href', 'test')
|
|
})
|
|
})
|
|
|
|
describe('Menubar interaction with expanded Dialog', () => {
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: 'test@test.com',
|
|
family_name: 'Doe',
|
|
name: 'John',
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
},
|
|
settings: {
|
|
language: 'en'
|
|
}
|
|
}
|
|
|
|
beforeEach(() => {
|
|
;(window as any).appList = [
|
|
{ name: 'Twake', link: '/twake', icon: 'twake.svg' },
|
|
{ name: 'Calendar', link: '/calendar', icon: 'calendar.svg' }
|
|
]
|
|
})
|
|
|
|
afterEach(() => {
|
|
document.body.classList.remove('fullscreen-view')
|
|
})
|
|
|
|
it('has navigation controls element with correct class', () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { container } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const navigationControls = container.querySelector('.navigation-controls')
|
|
expect(navigationControls).toBeInTheDocument()
|
|
expect(navigationControls).toHaveClass('navigation-controls')
|
|
})
|
|
|
|
it('has current date time element with correct class', () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { container } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const dateTimeDisplay = container.querySelector('.current-date-time')
|
|
expect(dateTimeDisplay).toBeInTheDocument()
|
|
expect(dateTimeDisplay).toHaveClass('current-date-time')
|
|
})
|
|
|
|
it('has refresh button element with correct class', () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { container } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const refreshButton = container.querySelector('.refresh-button')
|
|
expect(refreshButton).toBeInTheDocument()
|
|
expect(refreshButton).toHaveClass('refresh-button')
|
|
})
|
|
|
|
it('has view selector element with correct class', () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { container } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const selectDisplay = container.querySelector('.select-display')
|
|
expect(selectDisplay).toBeInTheDocument()
|
|
expect(selectDisplay).toHaveClass('select-display')
|
|
})
|
|
|
|
it('keeps logo visible when dialog is expanded', () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
document.body.classList.add('fullscreen-view')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const logoElement = screen.getByAltText('menubar.logoAlt')
|
|
expect(logoElement).toBeInTheDocument()
|
|
expect(logoElement).toBeVisible()
|
|
})
|
|
|
|
it('keeps apps icon clickable when dialog is expanded', () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
document.body.classList.add('fullscreen-view')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const appsButton = screen.getByLabelText('menubar.apps')
|
|
expect(appsButton).toBeVisible()
|
|
|
|
fireEvent.click(appsButton)
|
|
expect(screen.getByText('Twake')).toBeInTheDocument()
|
|
})
|
|
|
|
it('opens user dropdown menu when clicking avatar', async () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const avatar = screen.getByText('JD')
|
|
expect(avatar).toBeVisible()
|
|
|
|
fireEvent.click(avatar.closest('button')!)
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('John Doe')).toBeInTheDocument()
|
|
expect(screen.getByText('test@test.com')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
it('closes user dropdown menu when clicking outside', async () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const avatar = screen.getByText('JD')
|
|
fireEvent.click(avatar.closest('button')!)
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('John Doe')).toBeInTheDocument()
|
|
})
|
|
|
|
// Click outside the menu - MUI Menu closes on backdrop click
|
|
const backdrop = document.querySelector('.MuiBackdrop-root')
|
|
if (backdrop) {
|
|
fireEvent.click(backdrop)
|
|
} else {
|
|
// Fallback: click on body
|
|
fireEvent.mouseDown(document.body)
|
|
}
|
|
|
|
await waitFor(
|
|
() => {
|
|
expect(screen.queryByText('John Doe')).not.toBeInTheDocument()
|
|
},
|
|
{ timeout: 2000 }
|
|
)
|
|
})
|
|
|
|
it('displays user name and email in dropdown menu', async () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const avatar = screen.getByText('JD')
|
|
fireEvent.click(avatar.closest('button')!)
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText('John Doe')).toBeInTheDocument()
|
|
expect(screen.getByText('test@test.com')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
it('navigates to settings page when clicking Settings in dropdown', async () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const preloadedStateWithSettings = {
|
|
...preloadedState,
|
|
settings: {
|
|
language: 'en',
|
|
view: 'calendar'
|
|
}
|
|
}
|
|
|
|
const { store } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedStateWithSettings
|
|
)
|
|
|
|
const avatar = screen.getByText('JD')
|
|
fireEvent.click(avatar.closest('button')!)
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByText(/Settings/i)).toBeInTheDocument()
|
|
})
|
|
|
|
const settingsButton = screen.getByText(/Settings/i)
|
|
fireEvent.click(settingsButton)
|
|
|
|
await waitFor(() => {
|
|
const state = store.getState()
|
|
expect(state.settings.view).toBe('settings')
|
|
})
|
|
})
|
|
|
|
it('shows all elements in normal mode (not expanded)', () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { container } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const navigationControls = container.querySelector('.navigation-controls')
|
|
const dateTimeDisplay = container.querySelector('.current-date-time')
|
|
const refreshButton = container.querySelector('.refresh-button')
|
|
const selectDisplay = container.querySelector('.select-display')
|
|
|
|
expect(navigationControls).toBeVisible()
|
|
expect(dateTimeDisplay).toBeVisible()
|
|
expect(refreshButton).toBeVisible()
|
|
expect(selectDisplay).toBeVisible()
|
|
})
|
|
|
|
it('verifies CSS classes are correctly applied to elements', () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { container } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
expect(container.querySelector('.menubar')).toBeInTheDocument()
|
|
expect(container.querySelector('.navigation-controls')).toBeInTheDocument()
|
|
expect(container.querySelector('.current-date-time')).toBeInTheDocument()
|
|
expect(container.querySelector('.refresh-button')).toBeInTheDocument()
|
|
expect(container.querySelector('.select-display')).toBeInTheDocument()
|
|
})
|
|
})
|
|
|
|
describe('Menubar logout flow', () => {
|
|
const redirectToMock = redirectTo as jest.Mock
|
|
|
|
beforeEach(() => {
|
|
localStorage.clear()
|
|
sessionStorage.clear()
|
|
jest.clearAllMocks()
|
|
redirectToMock.mockReset()
|
|
})
|
|
|
|
afterEach(() => {
|
|
redirectToMock.mockReset()
|
|
})
|
|
|
|
function renderMenubar(user = { name: 'John', email: 'test@example.com' }) {
|
|
const preloadedState = {
|
|
user: { userData: user },
|
|
settings: { view: 'calendar' }
|
|
}
|
|
|
|
return renderWithProviders(
|
|
<Menubar
|
|
calendarRef={{ current: null }}
|
|
onRefresh={() => {}}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={new Date()}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
}
|
|
|
|
it('clears storage before redirecting', async () => {
|
|
sessionStorage.setItem('tokenSet', 'dummy')
|
|
const logoutSpy = jest
|
|
.spyOn(oidcAuth, 'Logout')
|
|
.mockResolvedValue(new URL('https://logout.url'))
|
|
|
|
await act(async () => {
|
|
renderMenubar()
|
|
})
|
|
await act(async () => {
|
|
fireEvent.click(screen.getByLabelText('menubar.userProfile'))
|
|
})
|
|
await act(async () => {
|
|
fireEvent.click(screen.getByText('menubar.logout'))
|
|
})
|
|
expect(logoutSpy).toHaveBeenCalled()
|
|
expect(redirectToMock).toHaveBeenCalledWith('https://logout.url/')
|
|
|
|
expect(sessionStorage.length).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('Logo click navigation to current week', () => {
|
|
const preloadedState = {
|
|
user: {
|
|
userData: {
|
|
sub: 'test',
|
|
email: 'test@test.com',
|
|
family_name: 'Doe',
|
|
name: 'John',
|
|
sid: 'mockSid',
|
|
openpaasId: '667037022b752d0026472254'
|
|
}
|
|
},
|
|
settings: {
|
|
view: 'calendar',
|
|
language: 'en'
|
|
}
|
|
}
|
|
|
|
beforeEach(() => {
|
|
;(window as any).appList = []
|
|
})
|
|
|
|
it('navigates to week view and current week when clicking logo from month view', async () => {
|
|
const mockChangeView = jest.fn()
|
|
const mockToday = jest.fn()
|
|
const mockGetDate = jest.fn(() => new Date())
|
|
const mockCalendarApi = {
|
|
changeView: mockChangeView,
|
|
today: mockToday,
|
|
getDate: mockGetDate
|
|
}
|
|
const mockCalendarRef = { current: mockCalendarApi as any }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockOnViewChange = jest.fn()
|
|
const mockOnDateChange = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { store } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
onViewChange={mockOnViewChange}
|
|
onDateChange={mockOnDateChange}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const logoElement = screen.getByAltText('menubar.logoAlt')
|
|
await act(async () => {
|
|
fireEvent.click(logoElement)
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(store.getState().settings.view).toBe('calendar')
|
|
})
|
|
|
|
expect(mockChangeView).toHaveBeenCalledWith(CALENDAR_VIEWS.timeGridWeek)
|
|
expect(mockToday).toHaveBeenCalled()
|
|
expect(mockOnViewChange).toHaveBeenCalledWith(CALENDAR_VIEWS.timeGridWeek)
|
|
expect(mockOnDateChange).toHaveBeenCalled()
|
|
})
|
|
|
|
it('navigates to week view and current week when clicking logo from day view', async () => {
|
|
const mockChangeView = jest.fn()
|
|
const mockToday = jest.fn()
|
|
const mockGetDate = jest.fn(() => new Date())
|
|
const mockCalendarApi = {
|
|
changeView: mockChangeView,
|
|
today: mockToday,
|
|
getDate: mockGetDate
|
|
}
|
|
const mockCalendarRef = { current: mockCalendarApi as any }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockOnViewChange = jest.fn()
|
|
const mockOnDateChange = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { store } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.timeGridDay}
|
|
onViewChange={mockOnViewChange}
|
|
onDateChange={mockOnDateChange}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const logoElement = screen.getByAltText('menubar.logoAlt')
|
|
await act(async () => {
|
|
fireEvent.click(logoElement)
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(store.getState().settings.view).toBe('calendar')
|
|
})
|
|
|
|
expect(mockChangeView).toHaveBeenCalledWith(CALENDAR_VIEWS.timeGridWeek)
|
|
expect(mockToday).toHaveBeenCalled()
|
|
expect(mockOnViewChange).toHaveBeenCalledWith(CALENDAR_VIEWS.timeGridWeek)
|
|
expect(mockOnDateChange).toHaveBeenCalled()
|
|
})
|
|
|
|
it('navigates to current week when clicking logo from week view (not current week)', async () => {
|
|
const mockChangeView = jest.fn()
|
|
const mockToday = jest.fn()
|
|
const mockGetDate = jest.fn(() => new Date())
|
|
const mockCalendarApi = {
|
|
changeView: mockChangeView,
|
|
today: mockToday,
|
|
getDate: mockGetDate
|
|
}
|
|
const mockCalendarRef = { current: mockCalendarApi as any }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockOnViewChange = jest.fn()
|
|
const mockOnDateChange = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { store } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.timeGridWeek}
|
|
onViewChange={mockOnViewChange}
|
|
onDateChange={mockOnDateChange}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const logoElement = screen.getByAltText('menubar.logoAlt')
|
|
await act(async () => {
|
|
fireEvent.click(logoElement)
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(store.getState().settings.view).toBe('calendar')
|
|
})
|
|
|
|
expect(mockChangeView).not.toHaveBeenCalled()
|
|
expect(mockToday).toHaveBeenCalled()
|
|
expect(mockOnDateChange).toHaveBeenCalled()
|
|
})
|
|
|
|
it('does not crash when calendarRef.current is null', async () => {
|
|
const mockCalendarRef = { current: null }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockOnViewChange = jest.fn()
|
|
const mockOnDateChange = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { store } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
onViewChange={mockOnViewChange}
|
|
onDateChange={mockOnDateChange}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const logoElement = screen.getByAltText('menubar.logoAlt')
|
|
await act(async () => {
|
|
fireEvent.click(logoElement)
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(store.getState().settings.view).toBe('calendar')
|
|
})
|
|
|
|
expect(mockOnViewChange).not.toHaveBeenCalled()
|
|
expect(mockOnDateChange).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('handles missing onViewChange and onDateChange callbacks', async () => {
|
|
const mockChangeView = jest.fn()
|
|
const mockToday = jest.fn()
|
|
const mockGetDate = jest.fn(() => new Date())
|
|
const mockCalendarApi = {
|
|
changeView: mockChangeView,
|
|
today: mockToday,
|
|
getDate: mockGetDate
|
|
}
|
|
const mockCalendarRef = { current: mockCalendarApi as any }
|
|
const mockOnRefresh = jest.fn()
|
|
const mockCurrentDate = new Date('2024-04-15')
|
|
|
|
const { store } = renderWithProviders(
|
|
<Menubar
|
|
calendarRef={mockCalendarRef}
|
|
onRefresh={mockOnRefresh}
|
|
onToggleSidebar={() => {}}
|
|
currentDate={mockCurrentDate}
|
|
currentView={CALENDAR_VIEWS.dayGridMonth}
|
|
/>,
|
|
preloadedState
|
|
)
|
|
|
|
const logoElement = screen.getByAltText('menubar.logoAlt')
|
|
await act(async () => {
|
|
fireEvent.click(logoElement)
|
|
})
|
|
|
|
await waitFor(() => {
|
|
expect(store.getState().settings.view).toBe('calendar')
|
|
})
|
|
|
|
expect(mockChangeView).toHaveBeenCalledWith(CALENDAR_VIEWS.timeGridWeek)
|
|
expect(mockToday).toHaveBeenCalled()
|
|
})
|
|
})
|