Files
workavia-calendar-front/__test__/features/Calendars/TimezoneInGrid.test.tsx
T
Camille Moussu 4e57f6b342 [#668] Tablet view (#716)
* 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>
2026-04-03 08:49:37 +02:00

261 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import CalendarApp from '@/components/Calendar/Calendar'
import * as calendarUtils from '@/components/Calendar/utils/calendarUtils'
import { updateSlotLabelVisibility } from '@/components/Calendar/utils/calendarUtils'
import EventPreviewModal from '@/features/Events/EventPreview'
import { CalendarEvent } from '@/features/Events/EventsTypes'
import * as SettingsSlice from '@/features/Settings/SettingsSlice'
import { fireEvent, screen, waitFor } from '@testing-library/react'
import { renderWithProviders } from '../../utils/Renderwithproviders'
describe('Calendar - Timezone Integration', () => {
const mockCalendarRef = { current: null }
const baseState = {
user: {
userData: {
sub: 'test',
email: 'test@test.com',
sid: 'testSid',
openpaasId: 'user1'
}
},
calendars: {
list: {
'user1/cal1': {
id: 'user1/cal1',
link: '/calendars/user1/cal1.json',
name: 'Test Calendar',
description: '',
color: '#33B679',
owner: { firstname: 'user1', emails: ['test@test.com'] },
visibility: 'public',
events: {}
}
},
timeZone: 'America/New_York',
pending: false
}
}
beforeEach(() => {
jest.clearAllMocks()
})
it('renders TimezoneSelector in week view', async () => {
renderWithProviders(
<CalendarApp
setCurrentView={jest.fn()}
onViewChange={jest.fn()}
openSidebar={false}
onCloseSidebar={jest.fn()}
currentView="timeGridWeek"
calendarRef={mockCalendarRef}
/>,
baseState
)
// Look for timezone selector button (should show offset)
await waitFor(() => {
expect(screen.getByText(/UTC/)).toBeInTheDocument()
})
})
it('dispatches setTimeZone action when timezone is changed', async () => {
const setTimeZoneSpy = jest.spyOn(SettingsSlice, 'setTimeZone')
renderWithProviders(
<CalendarApp
setCurrentView={jest.fn()}
onViewChange={jest.fn()}
openSidebar={false}
onCloseSidebar={jest.fn()}
currentView="timeGridWeek"
calendarRef={mockCalendarRef}
/>,
baseState
)
// Find and click timezone selector
await waitFor(() => {
const timezoneButton = screen.getByText(/UTC/i)
fireEvent.click(timezoneButton)
// Select a different timezone
const autocomplete = screen.getByRole('combobox')
fireEvent.change(autocomplete, { target: { value: 'Tokyo' } })
})
const option = await screen.findByText(/Tokyo/i)
fireEvent.click(option)
expect(setTimeZoneSpy).toHaveBeenCalledWith('Asia/Tokyo')
})
})
describe('Calendar - Timezone Slot Label Visibility', () => {
it('hides slot labels within 15 minutes of current time', () => {
const currentTime = new Date('2025-01-15T14:30:00Z')
const timezone = 'UTC'
jest
.spyOn(calendarUtils, 'checkIfCurrentWeekOrDay')
.mockImplementation(() => true)
// 14:25 - within 15 minutes
const slot1425 = { text: '14:25' }
expect(updateSlotLabelVisibility(currentTime, slot1425, timezone)).toBe(
'timegrid-slot-label-hidden'
)
// 14:30 - exact match
const slot1430 = { text: '14:30' }
expect(updateSlotLabelVisibility(currentTime, slot1430, timezone)).toBe(
'timegrid-slot-label-hidden'
)
// 14:35 - within 15 minutes
const slot1435 = { text: '14:35' }
expect(updateSlotLabelVisibility(currentTime, slot1435, timezone)).toBe(
'timegrid-slot-label-hidden'
)
})
it('shows slot labels more than 15 minutes from current time', () => {
jest
.spyOn(calendarUtils, 'checkIfCurrentWeekOrDay')
.mockImplementation(() => true)
const currentTime = new Date('2025-01-15T14:30:00')
const timezone = 'UTC'
// 14:00 - 30 minutes before
const slot1400 = { text: '14:00' }
expect(updateSlotLabelVisibility(currentTime, slot1400, timezone)).toBe(
'fc-timegrid-slot-label'
)
// 15:00 - 30 minutes after
const slot1500 = { text: '15:00' }
expect(updateSlotLabelVisibility(currentTime, slot1500, timezone)).toBe(
'fc-timegrid-slot-label'
)
})
it('returns visible class when not in current week/day', () => {
jest
.spyOn(calendarUtils, 'checkIfCurrentWeekOrDay')
.mockImplementation(() => false)
const currentTime = new Date('2025-01-15T14:30:00')
const timezone = 'UTC'
const slot = { text: '14:30' }
// Should return visible class when not in current view
const result = updateSlotLabelVisibility(currentTime, slot, timezone)
expect(result).toBe('fc-timegrid-slot-label')
})
})
describe('EventDisplayPreview - Timezone Display', () => {
const mockOnClose = jest.fn()
const baseEvent: CalendarEvent = {
uid: 'event1',
title: 'Team Meeting',
start: new Date('2025-01-15T14:00:00Z'),
end: new Date('2025-01-15T15:00:00Z'),
calendarId: 'user1/cal1',
allday: false
}
const allDayEvent = {
...baseEvent,
allday: true,
start: new Date('2025-01-15'),
end: new Date('2025-01-16')
}
const baseState = {
user: {
userData: {
sub: 'test',
email: 'test@test.com',
sid: 'testSid',
openpaasId: 'user1'
}
},
calendars: {
list: {
'user1/cal1': {
id: 'user1/cal1',
name: 'Test Calendar',
color: '#33B679',
owner: { firstname: 'user1', emails: ['test@test.com'] },
visibility: 'public',
events: {
event1: baseEvent,
allDayEvent
}
}
},
timeZone: 'America/New_York',
pending: false
}
}
beforeEach(() => {
jest.clearAllMocks()
})
it('does not show timezone offset for all-day events', async () => {
renderWithProviders(
<EventPreviewModal
open={true}
onClose={mockOnClose}
eventId="allDayEvent"
calId="user1/cal1"
/>,
baseState
)
await waitFor(() => {
const title = screen.getByText(/Team Meeting/i)
expect(title).toBeInTheDocument()
})
// Should not show UTC offset
expect(screen.queryByText(/UTC[+-]\d+/i)).not.toBeInTheDocument()
})
it('displays correct timezone offset for different timezones', async () => {
const timezones = [
{ tz: 'America/New_York', expectedOffset: /UTC[-][45]/ },
{ tz: 'Europe/Paris', expectedOffset: /UTC\+[12]/ },
{ tz: 'Asia/Tokyo', expectedOffset: /UTC\+9/ },
{ tz: 'Australia/Sydney', expectedOffset: /UTC\+1[01]/ },
{ tz: 'Asia/Kolkata', expectedOffset: /UTC\+5:30/ }
]
for (const { tz, expectedOffset } of timezones) {
const state = {
...baseState,
settings: {
timeZone: tz
}
}
renderWithProviders(
<EventPreviewModal
open={true}
eventId="event1"
calId="user1/cal1"
onClose={mockOnClose}
/>,
state
)
await waitFor(() => {
const content = document.body.textContent || ''
expect(content).toMatch(expectedOffset)
})
}
})
})