Files
workavia-calendar-front/__test__/features/Calendars/TimezoneInGrid.test.tsx
T
Camille Moussu cfb2b59584 [DELEGATION] Edit attendance and events, delete event for someone (#553)
* [#523] added way to manage attendance for delegated calendars

* [DELEGATION] #523 & #524 changed eventURL calculation for delegated events to have the rigth one

* [#524] added drag and drop authorisation to delegated event

* [#524] added tests

* [#524] support for the permission access

* [#524] no edit when delegated event is not public
2026-02-19 09:50:29 +01:00

247 lines
6.8 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/EventDisplayPreview";
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 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 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);
});
}
});
});