import CalendarSelection from '@/components/Calendar/CalendarSelection'
import * as calendarThunks from '@/features/Calendars/services'
import '@testing-library/jest-dom'
import { cleanup, fireEvent, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { renderWithProviders } from '../utils/Renderwithproviders'
describe('CalendarSelection', () => {
beforeEach(() => {
localStorage.clear()
})
const baseUser = {
userData: {
sub: 'test',
email: 'test@test.com',
sid: 'mockSid',
openpaasId: 'user1'
},
tokens: { accessToken: 'token' }
}
const calendarsMock = {
'user1/cal1': {
name: 'Calendar personal',
id: 'user1/cal1',
color: '#FF0000',
owner: { emails: ['alice@example.com'], lastname: 'alice' }
},
'user2/cal1': {
name: 'Calendar delegated',
delegated: true,
id: 'user2/cal1',
color: '#00FF00',
owner: {
firstname: 'Bob',
lastname: 'Builder',
emails: ['bob@example.com']
}
},
'user3/cal1': {
name: 'Calendar shared',
id: 'user3/cal1',
color: '#0000FF',
owner: {
firstname: 'Charlie',
lastname: 'Chaplin',
emails: ['charlie@example.com']
}
}
}
beforeAll(() => {
jest.clearAllMocks()
cleanup()
})
it('renders personal, delegated and calendar.other', () => {
renderWithProviders(
,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false }
}
)
expect(screen.getByText('calendar.personal')).toBeInTheDocument()
expect(screen.getByText('calendar.delegated')).toBeInTheDocument()
expect(screen.getByText('calendar.other')).toBeInTheDocument()
expect(screen.getByLabelText('Calendar personal')).toBeChecked()
expect(screen.getByLabelText('Calendar delegated')).not.toBeChecked()
expect(screen.getByLabelText('Calendar shared')).not.toBeChecked()
})
it('toggles a calendar selection on click', () => {
const setSelectedCalendars = jest.fn()
renderWithProviders(
,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false }
}
)
const checkbox = screen.getByLabelText('Calendar personal')
fireEvent.click(checkbox)
expect(setSelectedCalendars).toHaveBeenCalledWith(expect.any(Function))
const updater = setSelectedCalendars.mock.calls[0][0]
expect(updater([])).toEqual(['user1/cal1'])
})
it('removes calendar from selection if already selected', () => {
const setSelectedCalendars = jest.fn()
renderWithProviders(
,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false }
}
)
const checkbox = screen.getByLabelText('Calendar personal')
fireEvent.click(checkbox)
const updater = setSelectedCalendars.mock.calls[0][0]
expect(updater(['user1/cal1'])).toEqual([])
})
it('opens CalendarPopover modal when personal Add button is clicked', async () => {
renderWithProviders(
,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false }
}
)
const addButtons = screen.getAllByRole('button')
fireEvent.click(addButtons[1])
await waitFor(() =>
expect(
screen.getByText('calendarPopover.tabs.addNew')
).toBeInTheDocument()
)
})
it('Navigates to deletion dialog and deletes personal cal', async () => {
const spy = jest
.spyOn(calendarThunks, 'removeCalendarAsync')
.mockImplementation(payload => {
return () => Promise.resolve(payload) as any
})
renderWithProviders(
,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false }
}
)
const addButtons = screen.getAllByTestId('MoreHorizIcon')
fireEvent.click(addButtons[0])
userEvent.click(screen.getByText(/delete/i))
await waitFor(() =>
expect(
screen.getByText('calendar.delete.title(name=Calendar personal)')
).toBeInTheDocument()
)
fireEvent.click(screen.getByRole('button', { name: /delete/i }))
await waitFor(() => expect(spy).toHaveBeenCalled())
})
it('Navigates to deletion dialog and deletes other cal', async () => {
const spy = jest
.spyOn(calendarThunks, 'removeCalendarAsync')
.mockImplementation(payload => {
return () => Promise.resolve(payload) as any
})
renderWithProviders(
,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false }
}
)
const addButtons = screen.getAllByTestId('MoreHorizIcon')
fireEvent.click(addButtons[1])
userEvent.click(screen.getByText(/remove/i))
await waitFor(() =>
expect(
screen.getByText('calendar.delete.title(name=Calendar delegated)')
).toBeInTheDocument()
)
fireEvent.click(screen.getByRole('button', { name: /remove/i }))
await waitFor(() => expect(spy).toHaveBeenCalled())
})
it('opens CalendarSearch modal when Other Add button is clicked', () => {
renderWithProviders(
,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false }
}
)
const addButtons = screen.getAllByTestId('AddIcon')
fireEvent.click(addButtons[1]) // seccond Add button (other)
expect(
screen.getByText('calendar.browseOtherCalendars')
).toBeInTheDocument()
})
it('when only calendar.personal are in the state, only calendar.personal and the title for other to be added are shown', () => {
renderWithProviders(
,
{
user: baseUser,
calendars: {
list: {
'user1/cal1': calendarsMock['user1/cal1']
},
pending: false
}
}
)
expect(screen.getByText('calendar.personal')).toBeInTheDocument()
expect(screen.queryByText('calendar.delegated')).not.toBeInTheDocument()
expect(screen.queryByText('calendar.other')).toBeInTheDocument()
})
it('renders nothing when no calendars are present', () => {
renderWithProviders(
,
{
user: baseUser,
calendars: { list: {}, pending: false }
}
)
expect(screen.queryByLabelText(/Calendar/)).not.toBeInTheDocument()
})
it('expands and collapses accordions when clicked', () => {
renderWithProviders(
,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false }
}
)
const delegatedAccordionSummary = screen
.getByText('calendar.delegated')
.closest('.MuiAccordionSummary-root')
fireEvent.click(delegatedAccordionSummary!)
expect(delegatedAccordionSummary).toHaveAttribute('aria-expanded', 'false')
fireEvent.click(delegatedAccordionSummary!)
expect(delegatedAccordionSummary).toHaveAttribute('aria-expanded', 'true')
})
it('renders owner name caption for non-personal, non-default calendars', () => {
renderWithProviders(
,
{ user: baseUser, calendars: { list: calendarsMock, pending: false } }
)
expect(screen.getByText('Bob Builder')).toBeInTheDocument()
expect(screen.getByText('Charlie Chaplin')).toBeInTheDocument()
// personal calendar should NOT show a caption
expect(screen.queryByText('alice')).not.toBeInTheDocument()
})
})