Skip to content

Commit 9e97e1e

Browse files
committed
fix: enhance role assignment logic to conditionally hide course roles based on view permissions
1 parent 24f2bcc commit 9e97e1e

2 files changed

Lines changed: 52 additions & 11 deletions

File tree

src/authz-module/role-assignation-wizard/AssignRoleWizardPage.test.tsx

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,26 @@ const allowAllPermissions = {
4949
isLoading: false,
5050
};
5151

52+
const mockPermissions = (
53+
manageData: typeof allowAllPermissions,
54+
{ courseViewAllowed = true } = {},
55+
) => (permissions: { action: string }[]) => {
56+
const isViewCall = permissions.some(
57+
(p) => p.action === CONTENT_LIBRARY_PERMISSIONS.VIEW_LIBRARY_TEAM
58+
|| p.action === CONTENT_COURSE_PERMISSIONS.VIEW_COURSE_TEAM,
59+
);
60+
if (isViewCall) {
61+
return {
62+
data: [
63+
{ action: CONTENT_LIBRARY_PERMISSIONS.VIEW_LIBRARY_TEAM, allowed: true },
64+
{ action: CONTENT_COURSE_PERMISSIONS.VIEW_COURSE_TEAM, allowed: courseViewAllowed },
65+
],
66+
isLoading: false,
67+
};
68+
}
69+
return manageData;
70+
};
71+
5272
const setupMocks = ({ users = '', from = '' } = {}) => {
5373
const { useSearchParams, useNavigate } = jest.requireMock('react-router-dom');
5474
const params = new URLSearchParams();
@@ -73,7 +93,7 @@ describe('AssignRoleWizardPage', () => {
7393
mutateAsync: jest.fn(),
7494
isPending: false,
7595
});
76-
mockUseValidatePermissions.mockReturnValue(allowAllPermissions);
96+
mockUseValidatePermissions.mockImplementation(mockPermissions(allowAllPermissions));
7797
});
7898

7999
it('renders the page with the wizard and title', () => {
@@ -147,10 +167,10 @@ describe('AssignRoleWizardPage', () => {
147167
});
148168

149169
it.each(scopeRoles)('shows only the roles for the allowed scope %#', ({ action, roles }) => {
150-
mockUseValidatePermissions.mockReturnValue({
170+
mockUseValidatePermissions.mockImplementation(mockPermissions({
151171
data: scopeRoles.map((scope) => ({ action: scope.action, allowed: scope.action === action })),
152172
isLoading: false,
153-
});
173+
}));
154174
setupMocks();
155175
renderPage();
156176

@@ -165,10 +185,10 @@ describe('AssignRoleWizardPage', () => {
165185
});
166186

167187
it('shows no roles when no scope is allowed', () => {
168-
mockUseValidatePermissions.mockReturnValue({
188+
mockUseValidatePermissions.mockImplementation(mockPermissions({
169189
data: scopeRoles.map(({ action }) => ({ action, allowed: false })),
170190
isLoading: false,
171-
});
191+
}));
172192
setupMocks();
173193
renderPage();
174194
allRoles.forEach((role) => {
@@ -177,15 +197,29 @@ describe('AssignRoleWizardPage', () => {
177197
});
178198

179199
it('ignores allowed permissions whose action is not a known role scope', () => {
180-
mockUseValidatePermissions.mockReturnValue({
200+
mockUseValidatePermissions.mockImplementation(mockPermissions({
181201
data: [{ action: 'some.unrelated.permission', allowed: true }],
182202
isLoading: false,
183-
});
203+
}));
184204
setupMocks();
185205
renderPage();
186206
allRoles.forEach((role) => {
187207
expect(screen.queryByText(role.name)).not.toBeInTheDocument();
188208
});
189209
});
210+
211+
it('hides course roles when VIEW_COURSE_TEAM is not allowed even if MANAGE_COURSE_TEAM is allowed', () => {
212+
mockUseValidatePermissions.mockImplementation(
213+
mockPermissions(allowAllPermissions, { courseViewAllowed: false }),
214+
);
215+
setupMocks();
216+
renderPage();
217+
courseRolesMetadata.forEach((role) => {
218+
expect(screen.queryByText(role.name)).not.toBeInTheDocument();
219+
});
220+
libraryRolesMetadata.forEach((role) => {
221+
expect(screen.getByText(role.name)).toBeInTheDocument();
222+
});
223+
});
190224
});
191225
});

src/authz-module/role-assignation-wizard/AssignRoleWizardPage.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ROUTES } from '../constants';
77
import messages from './messages';
88
import {
99
CONTENT_COURSE_PERMISSIONS, CONTENT_LIBRARY_PERMISSIONS, courseRolesMetadata, libraryRolesMetadata,
10-
MANAGE_TEAM_PERMISSIONS,
10+
MANAGE_TEAM_PERMISSIONS, VIEW_TEAM_PERMISSIONS,
1111
} from '../roles-permissions';
1212

1313
const AssignRoleWizardPage = () => {
@@ -23,12 +23,19 @@ const AssignRoleWizardPage = () => {
2323
? `${ROUTES.HOME_PATH}/user/${presetUser}`
2424
: returnTo;
2525

26-
const { data: permissionValidationResponse } = useValidateUserPermissionsNonSuspense(MANAGE_TEAM_PERMISSIONS);
26+
const { data: managePermissions } = useValidateUserPermissionsNonSuspense(MANAGE_TEAM_PERMISSIONS);
27+
const { data: viewPermissions } = useValidateUserPermissionsNonSuspense(VIEW_TEAM_PERMISSIONS);
2728

28-
const rolesAssignable = permissionValidationResponse?.flatMap((p) => {
29+
const isCourseViewAllowed = viewPermissions
30+
? viewPermissions.some((p) => p.action === CONTENT_COURSE_PERMISSIONS.VIEW_COURSE_TEAM && p.allowed)
31+
: true;
32+
33+
const rolesAssignable = managePermissions?.flatMap((p) => {
2934
if (!p.allowed) { return []; }
3035
if (p.action === CONTENT_LIBRARY_PERMISSIONS.MANAGE_LIBRARY_TEAM) { return libraryRolesMetadata; }
31-
if (p.action === CONTENT_COURSE_PERMISSIONS.MANAGE_COURSE_TEAM) { return courseRolesMetadata; }
36+
if (p.action === CONTENT_COURSE_PERMISSIONS.MANAGE_COURSE_TEAM) {
37+
return isCourseViewAllowed ? courseRolesMetadata : [];
38+
}
3239
return [];
3340
});
3441

0 commit comments

Comments
 (0)