From ce29d22bd3b401199314dff4e7af6934c6349cbc Mon Sep 17 00:00:00 2001 From: Zein Sleiman Date: Tue, 21 Apr 2026 15:55:16 -0500 Subject: [PATCH 1/2] fix(permissions): Allow non-orgadmin users to access Notifications Log RHCLOUD-29703 The Notifications Log page was incorrectly gated behind the canReadNotifications permission (notifications:notifications:read), which controls access to notification configuration/settings. Since the Notifications Log page displays the same data as the notification drawer (which is accessible to all authenticated users), it should not require this permission. Co-Authored-By: Claude Opus 4.6 --- src/components/CheckReadPermissions.tsx | 4 + .../__tests__/CheckReadPermissions.test.tsx | 120 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 src/components/__tests__/CheckReadPermissions.test.tsx diff --git a/src/components/CheckReadPermissions.tsx b/src/components/CheckReadPermissions.tsx index 5ca5d16d..3fe544df 100644 --- a/src/components/CheckReadPermissions.tsx +++ b/src/components/CheckReadPermissions.tsx @@ -22,6 +22,10 @@ export const CheckReadPermissions: React.FunctionComponent { + return () => ({ + getApp: mockGetApp, + isBeta: () => false, + getEnvironment: () => 'ci', + }); +}); + +const childText = 'Authorized Content'; + +describe('CheckReadPermissions', () => { + beforeEach(() => { + appWrapperSetup(); + fetchMock.get(`/api/featureflags/v0`, { + body: { toggles: [] }, + }); + }); + + afterEach(() => { + appWrapperCleanup(); + }); + + it('Shows children when user has canReadNotifications for notification pages', () => { + mockGetApp.mockReturnValue('notifications'); + const Wrapper = getConfiguredAppWrapper({ + router: { initialEntries: ['/rhel'] }, + appContext: { rbac: { canReadNotifications: true } }, + }); + + render( + +
{childText}
+
, + { wrapper: Wrapper } + ); + + expect(screen.getByText(childText)).toBeVisible(); + }); + + it('Shows unauthorized when user lacks canReadNotifications for notification pages', () => { + mockGetApp.mockReturnValue('notifications'); + const Wrapper = getConfiguredAppWrapper({ + router: { initialEntries: ['/rhel'] }, + appContext: { rbac: { canReadNotifications: false } }, + }); + + render( + +
{childText}
+
, + { wrapper: Wrapper } + ); + + expect(screen.queryByText(childText)).not.toBeInTheDocument(); + }); + + it('Shows children for /notificationslog regardless of canReadNotifications', () => { + mockGetApp.mockReturnValue('notifications'); + const Wrapper = getConfiguredAppWrapper({ + router: { initialEntries: ['/notificationslog'] }, + appContext: { rbac: { canReadNotifications: false } }, + }); + + render( + +
{childText}
+
, + { wrapper: Wrapper } + ); + + expect(screen.getByText(childText)).toBeVisible(); + }); + + it('Shows children for /eventlog when user has canReadEvents', () => { + mockGetApp.mockReturnValue('notifications'); + const Wrapper = getConfiguredAppWrapper({ + router: { initialEntries: ['/eventlog'] }, + appContext: { rbac: { canReadEvents: true } }, + }); + + render( + +
{childText}
+
, + { wrapper: Wrapper } + ); + + expect(screen.getByText(childText)).toBeVisible(); + }); + + it('Shows unauthorized for /eventlog when user lacks canReadEvents', () => { + mockGetApp.mockReturnValue('notifications'); + const Wrapper = getConfiguredAppWrapper({ + router: { initialEntries: ['/eventlog'] }, + appContext: { rbac: { canReadEvents: false } }, + }); + + render( + +
{childText}
+
, + { wrapper: Wrapper } + ); + + expect(screen.queryByText(childText)).not.toBeInTheDocument(); + }); +}); From 7bd431ce4270998e829e06944f84ca590dc1afb1 Mon Sep 17 00:00:00 2001 From: Zein Sleiman Date: Tue, 21 Apr 2026 16:05:37 -0500 Subject: [PATCH 2/2] test(permissions): Harden negative-path assertions in CheckReadPermissions RHCLOUD-29703 Assert NotAuthorizedPage renders (via User Preferences link) in unauthorized test cases, preventing false positives when nothing renders. --- src/components/__tests__/CheckReadPermissions.test.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/__tests__/CheckReadPermissions.test.tsx b/src/components/__tests__/CheckReadPermissions.test.tsx index e4ca76e0..e7a3747d 100644 --- a/src/components/__tests__/CheckReadPermissions.test.tsx +++ b/src/components/__tests__/CheckReadPermissions.test.tsx @@ -65,6 +65,7 @@ describe('CheckReadPermissions', () => { ); expect(screen.queryByText(childText)).not.toBeInTheDocument(); + expect(screen.getByRole('link', { name: /User Preferences/i })).toBeInTheDocument(); }); it('Shows children for /notificationslog regardless of canReadNotifications', () => { @@ -116,5 +117,6 @@ describe('CheckReadPermissions', () => { ); expect(screen.queryByText(childText)).not.toBeInTheDocument(); + expect(screen.getByRole('link', { name: /User Preferences/i })).toBeInTheDocument(); }); });