test: add edge case tests for Menubar and eventUtils
- Add comprehensive edge case tests for Menubar avatar display logic - Add timezone fallback edge case tests for eventUtils - Cover null/undefined/empty string scenarios for user data - Cover invalid/missing timezone scenarios with UTC fallback - Ensure robust error handling and graceful degradation
This commit is contained in:
@@ -55,6 +55,139 @@ describe("Calendar App Component Display Tests", () => {
|
|||||||
expect(screen.getByText("t")).toBeInTheDocument();
|
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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderWithProviders(<Menubar />, 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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderWithProviders(<Menubar />, 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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderWithProviders(<Menubar />, 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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderWithProviders(<Menubar />, 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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderWithProviders(<Menubar />, 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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderWithProviders(<Menubar />, 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",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderWithProviders(<Menubar />, preloadedState);
|
||||||
|
// Should not crash and show empty string
|
||||||
|
const avatar = screen.getByRole("img", { hidden: true });
|
||||||
|
expect(avatar).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
it("shows AppsIcon when applist is not empty", () => {
|
it("shows AppsIcon when applist is not empty", () => {
|
||||||
(window as any).appList = [{ name: "test", icon: "test", link: "test" }];
|
(window as any).appList = [{ name: "test", icon: "test", link: "test" }];
|
||||||
renderWithProviders(<Menubar />, preloadedState);
|
renderWithProviders(<Menubar />, preloadedState);
|
||||||
|
|||||||
@@ -465,4 +465,168 @@ describe("calendarEventToJCal", () => {
|
|||||||
])
|
])
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Edge cases for timezone fallback
|
||||||
|
it("handles invalid timezone with UTC fallback", () => {
|
||||||
|
const mockEvent = {
|
||||||
|
uid: "event-invalid-tz",
|
||||||
|
title: "Invalid Timezone Event",
|
||||||
|
start: new Date("2025-07-23T10:00:00"),
|
||||||
|
end: new Date("2025-07-23T11:00:00"),
|
||||||
|
timezone: "Invalid/Timezone",
|
||||||
|
allday: false,
|
||||||
|
attendee: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = calendarEventToJCal(mockEvent as CalendarEvent);
|
||||||
|
|
||||||
|
expect(result[0]).toBe("vcalendar");
|
||||||
|
const [vevent, vtimezone] = result[2];
|
||||||
|
expect(vevent[0]).toBe("vevent");
|
||||||
|
expect(vtimezone[0]).toBe("vtimezone");
|
||||||
|
|
||||||
|
// Should use UTC timezone as fallback - check for UTC standard timezone
|
||||||
|
expect(vtimezone[2]).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
["standard", [
|
||||||
|
["tzoffsetfrom", {}, "utc-offset", "+00:00"],
|
||||||
|
["tzoffsetto", {}, "utc-offset", "+00:00"],
|
||||||
|
["tzname", {}, "text", "UTC"],
|
||||||
|
["dtstart", {}, "date-time", "1970-01-01T00:00:00"]
|
||||||
|
], []]
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles null timezone with UTC fallback", () => {
|
||||||
|
const mockEvent = {
|
||||||
|
uid: "event-null-tz",
|
||||||
|
title: "Null Timezone Event",
|
||||||
|
start: new Date("2025-07-23T10:00:00"),
|
||||||
|
end: new Date("2025-07-23T11:00:00"),
|
||||||
|
timezone: null,
|
||||||
|
allday: false,
|
||||||
|
attendee: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = calendarEventToJCal(mockEvent as CalendarEvent);
|
||||||
|
|
||||||
|
expect(result[0]).toBe("vcalendar");
|
||||||
|
const [vevent, vtimezone] = result[2];
|
||||||
|
expect(vevent[0]).toBe("vevent");
|
||||||
|
expect(vtimezone[0]).toBe("vtimezone");
|
||||||
|
|
||||||
|
// Should use UTC timezone as fallback
|
||||||
|
expect(vtimezone[2]).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
["standard", [
|
||||||
|
["tzoffsetfrom", {}, "utc-offset", "+00:00"],
|
||||||
|
["tzoffsetto", {}, "utc-offset", "+00:00"],
|
||||||
|
["tzname", {}, "text", "UTC"],
|
||||||
|
["dtstart", {}, "date-time", "1970-01-01T00:00:00"]
|
||||||
|
], []]
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles undefined timezone with UTC fallback", () => {
|
||||||
|
const mockEvent = {
|
||||||
|
uid: "event-undefined-tz",
|
||||||
|
title: "Undefined Timezone Event",
|
||||||
|
start: new Date("2025-07-23T10:00:00"),
|
||||||
|
end: new Date("2025-07-23T11:00:00"),
|
||||||
|
timezone: undefined,
|
||||||
|
allday: false,
|
||||||
|
attendee: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = calendarEventToJCal(mockEvent as CalendarEvent);
|
||||||
|
|
||||||
|
expect(result[0]).toBe("vcalendar");
|
||||||
|
const [vevent, vtimezone] = result[2];
|
||||||
|
expect(vevent[0]).toBe("vevent");
|
||||||
|
expect(vtimezone[0]).toBe("vtimezone");
|
||||||
|
|
||||||
|
// Should use UTC timezone as fallback
|
||||||
|
expect(vtimezone[2]).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
["standard", [
|
||||||
|
["tzoffsetfrom", {}, "utc-offset", "+00:00"],
|
||||||
|
["tzoffsetto", {}, "utc-offset", "+00:00"],
|
||||||
|
["tzname", {}, "text", "UTC"],
|
||||||
|
["dtstart", {}, "date-time", "1970-01-01T00:00:00"]
|
||||||
|
], []]
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles empty string timezone with UTC fallback", () => {
|
||||||
|
const mockEvent = {
|
||||||
|
uid: "event-empty-tz",
|
||||||
|
title: "Empty Timezone Event",
|
||||||
|
start: new Date("2025-07-23T10:00:00"),
|
||||||
|
end: new Date("2025-07-23T11:00:00"),
|
||||||
|
timezone: "",
|
||||||
|
allday: false,
|
||||||
|
attendee: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = calendarEventToJCal(mockEvent as CalendarEvent);
|
||||||
|
|
||||||
|
expect(result[0]).toBe("vcalendar");
|
||||||
|
const [vevent, vtimezone] = result[2];
|
||||||
|
expect(vevent[0]).toBe("vevent");
|
||||||
|
expect(vtimezone[0]).toBe("vtimezone");
|
||||||
|
|
||||||
|
// Should use UTC timezone as fallback
|
||||||
|
expect(vtimezone[2]).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
["standard", [
|
||||||
|
["tzoffsetfrom", {}, "utc-offset", "+00:00"],
|
||||||
|
["tzoffsetto", {}, "utc-offset", "+00:00"],
|
||||||
|
["tzname", {}, "text", "UTC"],
|
||||||
|
["dtstart", {}, "date-time", "1970-01-01T00:00:00"]
|
||||||
|
], []]
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("handles valid timezone correctly", () => {
|
||||||
|
const mockEvent = {
|
||||||
|
uid: "event-valid-tz",
|
||||||
|
title: "Valid Timezone Event",
|
||||||
|
start: new Date("2025-07-23T10:00:00"),
|
||||||
|
end: new Date("2025-07-23T11:00:00"),
|
||||||
|
timezone: "Europe/Paris",
|
||||||
|
allday: false,
|
||||||
|
attendee: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = calendarEventToJCal(mockEvent as CalendarEvent);
|
||||||
|
|
||||||
|
expect(result[0]).toBe("vcalendar");
|
||||||
|
const [vevent, vtimezone] = result[2];
|
||||||
|
expect(vevent[0]).toBe("vevent");
|
||||||
|
expect(vtimezone[0]).toBe("vtimezone");
|
||||||
|
|
||||||
|
// Should use the specified timezone - check for Europe/Paris timezone components
|
||||||
|
expect(vtimezone[2]).toEqual(
|
||||||
|
expect.arrayContaining([
|
||||||
|
["daylight", [
|
||||||
|
["tzoffsetfrom", {}, "utc-offset", "+01:00"],
|
||||||
|
["tzoffsetto", {}, "utc-offset", "+02:00"],
|
||||||
|
["tzname", {}, "text", "CEST"],
|
||||||
|
["dtstart", {}, "date-time", "1970-03-29T02:00:00"],
|
||||||
|
["rrule", {}, "recur", { byday: "-1SU", bymonth: 3, freq: "YEARLY" }]
|
||||||
|
], []],
|
||||||
|
["standard", [
|
||||||
|
["tzoffsetfrom", {}, "utc-offset", "+02:00"],
|
||||||
|
["tzoffsetto", {}, "utc-offset", "+01:00"],
|
||||||
|
["tzname", {}, "text", "CET"],
|
||||||
|
["dtstart", {}, "date-time", "1970-10-25T03:00:00"],
|
||||||
|
["rrule", {}, "recur", { byday: "-1SU", bymonth: 10, freq: "YEARLY" }]
|
||||||
|
], []]
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user