Skip to content

Commit bf526ae

Browse files
committed
fix: address feedback
1 parent 6d2b7a3 commit bf526ae

13 files changed

Lines changed: 56 additions & 54 deletions

File tree

src/authz-module/data/api.test.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -277,30 +277,33 @@ describe('API functions', () => {
277277
it('should fetch scopes successfully', async () => {
278278
const mockResponse = {
279279
data: {
280-
scopes: [
280+
results: [
281281
{ displayName: 'Library 1', scope: 'lib:test1' },
282282
],
283+
count: 1,
284+
next: null,
285+
previous: null,
283286
},
284287
};
285288

286289
getAuthenticatedHttpClient.mockReturnValue({
287290
get: jest.fn().mockResolvedValue(mockResponse),
288291
});
289292

290-
const result = await getScopes();
293+
const result = await getScopes({});
291294

292-
expect(result.scopes).toHaveLength(1);
295+
expect(result.results).toHaveLength(1);
293296
expect(getAuthenticatedHttpClient).toHaveBeenCalled();
294297
});
295298

296299
it('should handle search, page, and pageSize parameters', async () => {
297-
const mockResponse = { data: { scopes: [] } };
300+
const mockResponse = { data: { results: [], count: 0, next: null, previous: null } };
298301
const mockGet = jest.fn().mockResolvedValue(mockResponse);
299302
getAuthenticatedHttpClient.mockReturnValue({
300303
get: mockGet,
301304
});
302305

303-
await getScopes('library', 3, 50);
306+
await getScopes({ search: 'library', page: 3, pageSize: 50 });
304307

305308
expect(mockGet).toHaveBeenCalled();
306309
const calledUrl = mockGet.mock.calls[0][0];

src/authz-module/data/hooks.test.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,9 @@ describe('useUserAssignedRoles', () => {
938938

939939
describe('useScopes', () => {
940940
const mockScopesData = {
941+
count: 2,
942+
next: null,
943+
previous: null,
941944
results: [
942945
{
943946
displayName: 'Test Library 1',
@@ -966,21 +969,21 @@ describe('useScopes', () => {
966969
await waitFor(() => expect(result.current.isSuccess).toBe(true));
967970

968971
expect(getAuthenticatedHttpClient).toHaveBeenCalled();
969-
expect(result.current.data).toEqual(mockScopesData);
970-
expect(result.current.data?.results).toHaveLength(2);
972+
expect(result.current.data?.pages[0]).toEqual(mockScopesData);
973+
expect(result.current.data?.pages[0].results).toHaveLength(2);
971974
});
972975

973976
it('handles search parameter', async () => {
974977
getAuthenticatedHttpClient.mockReturnValue({
975-
get: jest.fn().mockResolvedValue({ data: { results: [mockScopesData.results[0]] } }),
978+
get: jest.fn().mockResolvedValue({ data: { count: 1, next: null, previous: null, results: [mockScopesData.results[0]] } }),
976979
});
977980

978-
const { result } = renderHook(() => useScopes('library'), {
981+
const { result } = renderHook(() => useScopes({ search: 'library' }), {
979982
wrapper: createWrapper(),
980983
});
981984

982985
await waitFor(() => expect(result.current.isSuccess).toBe(true));
983-
expect(result.current.data?.results).toHaveLength(1);
986+
expect(result.current.data?.pages[0].results).toHaveLength(1);
984987
});
985988

986989
it('handles error when API call fails', async () => {

src/authz-module/data/hooks.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,20 @@ export const useLibrary = (libraryId: string) => useSuspenseQuery<LibraryMetadat
8787
*/
8888
export const useAssignTeamMembersRole = () => {
8989
const queryClient = useQueryClient();
90-
const { querySettings: defaultQuerySettings } = useQuerySettings();
9190
return useMutation({
9291
mutationFn: async ({ data }: {
9392
data: AssignTeamMembersRoleRequest
9493
}) => assignTeamMembersRole(data),
9594
onSettled: (_data, error, { data: { scopes } }) => {
9695
if (!error) {
97-
queryClient.invalidateQueries({ queryKey: authzQueryKeys.teamMembers(scopes[0], defaultQuerySettings) });
98-
queryClient.invalidateQueries({ queryKey: authzQueryKeys.permissionsByRole(scopes[0]) });
96+
scopes.forEach((scope) => {
97+
queryClient.invalidateQueries({ queryKey: authzQueryKeys.teamMembersAll(scope) });
98+
queryClient.invalidateQueries({ queryKey: authzQueryKeys.permissionsByRole(scope) });
99+
});
99100
queryClient.invalidateQueries({ queryKey: [...authzQueryKeys.all, 'userRoles'] });
101+
queryClient.invalidateQueries({
102+
predicate: (query) => query.queryKey.includes('allRoleAssignments'),
103+
});
100104
}
101105
},
102106
});

src/authz-module/libraries-manager/messages.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,6 @@ const messages = defineMessages({
7171
defaultMessage: 'See full documentation',
7272
description: 'Libraries AuthZ link for the course roles alert',
7373
},
74-
'library.authz.manage.add.role.button': {
75-
id: 'library.authz.manage.add.role.button',
76-
defaultMessage: 'Assign Role',
77-
description: 'Button label to add a role to a user in libraries management',
78-
},
7974
'library.authz.team.remove.user.toast.success.description': {
8075
id: 'library.authz.team.remove.user.toast.success.description',
8176
defaultMessage: 'The {role} role has been successfully removed.{rolesCount, plural, =0 { The user no longer has access to this library and has been removed from the member list.} other {}}',

src/authz-module/role-assignation-wizard/components/DefineApplicationScopeStep.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useIntl } from '@edx/frontend-platform/i18n';
33
import { Alert } from '@openedx/paragon';
44
import { courseRolesMetadata } from '@src/authz-module/roles-permissions/course/constants';
55
import { libraryRolesMetadata } from '@src/authz-module/roles-permissions/library/constants';
6-
import useScopeListData from './useScopeListData';
6+
import useScopeListData from '../hooks/useScopeListData';
77
import ScopeFilterBar from './ScopeFilterBar';
88
import ScopeList from './ScopeList';
99
import messages from '../messages';

src/authz-module/role-assignation-wizard/components/OrgSection.tsx

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,7 @@ import { ExpandLess, ExpandMore } from '@openedx/paragon/icons';
44
import { useIntl } from '@edx/frontend-platform/i18n';
55
import { Scope } from 'types';
66
import messages from '../messages';
7-
8-
interface ScopeCheckboxItemProps {
9-
scope: Scope;
10-
checked: boolean;
11-
onToggle: (scopeId: string) => void;
12-
}
13-
14-
export const ScopeCheckboxItem = ({ scope, checked, onToggle }: ScopeCheckboxItemProps) => (
15-
<div className="mb-2">
16-
<div className="pgn__form-checkbox">
17-
<input
18-
type="checkbox"
19-
id={`scope-${scope.externalKey}`}
20-
className="pgn__form-checkbox-input"
21-
checked={checked}
22-
onChange={() => onToggle(scope.externalKey)}
23-
/>
24-
<label
25-
className="pgn__form-label"
26-
htmlFor={`scope-${scope.externalKey}`}
27-
data-testid="toggle-scope"
28-
>
29-
{scope.displayName}
30-
</label>
31-
</div>
32-
{scope.description && (
33-
<small className="d-block text-muted pl-4">{scope.description}</small>
34-
)}
35-
</div>
36-
);
7+
import ScopeCheckboxItem from './ScopeCheckboxItem';
378

389
export interface OrgSectionProps {
3910
orgName: string;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { Form } from '@openedx/paragon';
2+
import { Scope } from 'types';
3+
4+
interface ScopeCheckboxItemProps {
5+
scope: Scope;
6+
checked: boolean;
7+
onToggle: (scopeId: string) => void;
8+
}
9+
10+
const ScopeCheckboxItem = ({ scope, checked, onToggle }: ScopeCheckboxItemProps) => (
11+
<div className="mb-2">
12+
<Form.Checkbox
13+
checked={checked}
14+
onChange={() => onToggle(scope.externalKey)}
15+
data-testid="toggle-scope"
16+
>
17+
{scope.displayName}
18+
</Form.Checkbox>
19+
{scope.description && (
20+
<small className="d-block text-muted pl-4">{scope.description}</small>
21+
)}
22+
</div>
23+
);
24+
25+
export default ScopeCheckboxItem;

src/authz-module/role-assignation-wizard/components/ScopeList.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { useEffect, useRef } from 'react';
22
import { Spinner } from '@openedx/paragon';
33
import { useIntl } from '@edx/frontend-platform/i18n';
44
import { Org, Scope } from 'types';
5-
import OrgSection, { ScopeCheckboxItem } from './OrgSection';
5+
import OrgSection from './OrgSection';
6+
import ScopeCheckboxItem from './ScopeCheckboxItem';
67
import messages from '../messages';
78

89
interface ScopeListQueryState {
@@ -93,7 +94,7 @@ const ScopeList = ({
9394
externalKey: contextType === 'course' ? `course-v1:${org}+*` : `lib:${org}:*`,
9495
displayName: aggregateLabel,
9596
description: aggregateDescription,
96-
org: { id: 0, name: org, shortName: org },
97+
org: { id: '', name: org, shortName: org },
9798
}
9899
: undefined;
99100

src/authz-module/role-assignation-wizard/components/useScopeListData.test.ts renamed to src/authz-module/role-assignation-wizard/hooks/useScopeListData.test.ts

File renamed without changes.

src/authz-module/role-assignation-wizard/components/useScopeListData.ts renamed to src/authz-module/role-assignation-wizard/hooks/useScopeListData.ts

File renamed without changes.

0 commit comments

Comments
 (0)