ISSUE-91 add lock icon indication for private events (#98)

This commit is contained in:
ducdonghiem
2025-09-11 14:17:54 +07:00
committed by GitHub
parent fbf4cf418c
commit 4b71a6e3c7
2 changed files with 96 additions and 3 deletions
@@ -2,7 +2,7 @@ import { CalendarApi } from "@fullcalendar/core";
import { jest } from "@jest/globals";
import { ThunkDispatch } from "@reduxjs/toolkit";
import "@testing-library/jest-dom";
import { act, screen } from "@testing-library/react";
import { act, screen, within } from "@testing-library/react";
import * as appHooks from "../../src/app/hooks";
import CalendarApp from "../../src/components/Calendar/Calendar";
import { renderWithProviders } from "../utils/Renderwithproviders";
@@ -101,4 +101,94 @@ describe("CalendarApp integration", () => {
}
});
});
const createPreloadedState = (eventProps = {}) => ({
user: {
userData: {
sub: "test",
email: "test@test.com",
sid: "mockSid",
openpaasId: "667037022b752d0026472254",
},
tokens: {
accessToken: "token"
},
},
calendars: {
list: {
"667037022b752d0026472254/cal1": {
name: "Calendar 1",
id: "667037022b752d0026472254/cal1",
color: "#FF0000",
ownerEmails: ["alice@example.com"],
events: {
event1: {
id: "event1",
calId: "667037022b752d0026472254/cal1",
uid: "event1",
start: new Date().toISOString(),
end: new Date(Date.now() + 3600000).toISOString(),
partstat: "ACCEPTED",
organizer: {
cn: "Alice",
cal_address: "alice@example.com",
},
attendee: [{
cn: "Alice",
partstat: "ACCEPTED",
rsvp: "TRUE",
role: "REQ-PARTICIPANT",
cutype: "INDIVIDUAL",
cal_address: "alice@example.com",
}, ],
...eventProps,
},
},
},
},
pending: false,
},
});
it("renders lock icon for private events on the calendar", async () => {
const preloadedState = createPreloadedState({
class: "PRIVATE",
title: "Private Event",
});
renderWithProviders(<CalendarApp />, preloadedState);
const eventEls = screen.getAllByText("Private Event");
const found = eventEls.some((eventEl) =>
within(eventEl.parentElement as HTMLElement).queryByTestId("lock-icon")
);
expect(found).toBe(true);
});
it("renders lock icon for confidential events on the calendar", async () => {
const preloadedState = createPreloadedState({
class: "CONFIDENTIAL",
title: "Confidential Event",
});
renderWithProviders(<CalendarApp />, preloadedState);
const eventEls = screen.getAllByText("Confidential Event");
const found = eventEls.some((eventEl) =>
within(eventEl.parentElement as HTMLElement).queryByTestId("lock-icon")
);
expect(found).toBe(true);
});
it("does NOT render a lock icon for public events on the calendar", async () => {
const preloadedState = createPreloadedState({
class: "PUBLIC",
title: "Public Event",
});
renderWithProviders(<CalendarApp />, preloadedState);
const eventEls = screen.getAllByText("Public Event");
const found = eventEls.some((eventEl) =>
within(eventEl.parentElement as HTMLElement).queryByTestId("lock-icon")
);
expect(found).toBe(false);
});
});
+5 -2
View File
@@ -31,6 +31,7 @@ import { createSelector } from "@reduxjs/toolkit";
import HelpOutlineIcon from "@mui/icons-material/HelpOutline";
import ClearIcon from "@mui/icons-material/Clear";
import AccessTimeIcon from "@mui/icons-material/AccessTime";
import LockIcon from '@mui/icons-material/Lock';
import { userAttendee } from "../../features/User/userDataTypes";
const computeStartOfTheWeek = (date: Date): Date => {
@@ -407,6 +408,7 @@ export default function CalendarApp() {
if (!calendars[arg.event._def.extendedProps.calId]) return;
const attendees = event._def.extendedProps.attendee || [];
const isPrivate = event._def.extendedProps.class === "PRIVATE" || event._def.extendedProps.class === "CONFIDENTIAL";
let Icon = null;
let titleStyle: React.CSSProperties = {};
const ownerEmails = new Set(
@@ -437,8 +439,9 @@ export default function CalendarApp() {
}
return (
<div>
{Icon && <Icon fontSize="small" />}
<div style={{ display: 'flex', alignItems: 'center' }}>
{isPrivate && <LockIcon data-testid="lock-icon" fontSize="small" style={{ marginRight: '4px' }} />}
{Icon && <Icon fontSize="small" style={{ marginRight: '4px' }}/>}
<span style={titleStyle}>{event.title}</span>
</div>
);