@@ -3,7 +3,7 @@ import { act, renderHook, waitFor } from '@testing-library/react';
33import { QueryClient , QueryClientProvider } from '@tanstack/react-query' ;
44import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth' ;
55import {
6- useLibrary , usePermissionsByRole , useTeamMembers , useAssignTeamMembersRole ,
6+ useLibrary , usePermissionsByRole , useTeamMembers , useAssignTeamMembersRole , useRevokeUserRoles ,
77} from './hooks' ;
88
99jest . mock ( '@edx/frontend-platform/auth' , ( ) => ( {
@@ -240,3 +240,103 @@ describe('usePermissionsByRole', () => {
240240 } ) ;
241241 } ) ;
242242} ) ;
243+
244+ describe ( 'useRevokeUserRoles' , ( ) => {
245+ beforeEach ( ( ) => {
246+ jest . clearAllMocks ( ) ;
247+ } ) ;
248+
249+ it ( 'successfully revokes user roles' , async ( ) => {
250+ const mockResponse = {
251+ completed : [
252+ {
253+ userIdentifiers : 'jdoe' ,
254+ status : 'role_removed' ,
255+ } ,
256+ ] ,
257+ errors : [ ] ,
258+ } ;
259+
260+ getAuthenticatedHttpClient . mockReturnValue ( {
261+ delete : jest . fn ( ) . mockResolvedValue ( { data : mockResponse } ) ,
262+ } ) ;
263+
264+ const { result } = renderHook ( ( ) => useRevokeUserRoles ( ) , {
265+ wrapper : createWrapper ( ) ,
266+ } ) ;
267+
268+ const revokeRoleData = {
269+ scope : 'lib:123' ,
270+ users : 'jdoe' ,
271+ role : 'author' ,
272+ } ;
273+
274+ await act ( async ( ) => {
275+ result . current . mutate ( { data : revokeRoleData } ) ;
276+ } ) ;
277+
278+ await waitFor ( ( ) => expect ( result . current . isSuccess ) . toBe ( true ) ) ;
279+
280+ expect ( getAuthenticatedHttpClient ) . toHaveBeenCalled ( ) ;
281+ expect ( result . current . data ) . toEqual ( mockResponse ) ;
282+ } ) ;
283+
284+ it ( 'handles error when revoking roles fails' , async ( ) => {
285+ getAuthenticatedHttpClient . mockReturnValue ( {
286+ delete : jest . fn ( ) . mockRejectedValue ( new Error ( 'Failed to revoke roles' ) ) ,
287+ } ) ;
288+
289+ const { result } = renderHook ( ( ) => useRevokeUserRoles ( ) , {
290+ wrapper : createWrapper ( ) ,
291+ } ) ;
292+
293+ const revokeRoleData = {
294+ scope : 'lib:123' ,
295+ users : 'jdoe' ,
296+ role : 'author' ,
297+ } ;
298+
299+ await act ( async ( ) => {
300+ result . current . mutate ( { data : revokeRoleData } ) ;
301+ } ) ;
302+
303+ await waitFor ( ( ) => expect ( result . current . isError ) . toBe ( true ) ) ;
304+
305+ expect ( getAuthenticatedHttpClient ) . toHaveBeenCalled ( ) ;
306+ expect ( result . current . error ) . toEqual ( new Error ( 'Failed to revoke roles' ) ) ;
307+ } ) ;
308+
309+ it ( 'constructs URL with correct query parameters' , async ( ) => {
310+ const mockDelete = jest . fn ( ) . mockResolvedValue ( {
311+ data : { completed : [ ] , errors : [ ] } ,
312+ } ) ;
313+
314+ getAuthenticatedHttpClient . mockReturnValue ( {
315+ delete : mockDelete ,
316+ } ) ;
317+
318+ const { result } = renderHook ( ( ) => useRevokeUserRoles ( ) , {
319+ wrapper : createWrapper ( ) ,
320+ } ) ;
321+
322+ const revokeRoleData = {
323+ scope : 'lib:org/test-lib' ,
324+ users : 'user1@example.com' ,
325+ role : 'instructor' ,
326+ } ;
327+
328+ await act ( async ( ) => {
329+ result . current . mutate ( { data : revokeRoleData } ) ;
330+ } ) ;
331+
332+ await waitFor ( ( ) => expect ( result . current . isSuccess ) . toBe ( true ) ) ;
333+
334+ expect ( mockDelete ) . toHaveBeenCalled ( ) ;
335+ const calledUrl = new URL ( mockDelete . mock . calls [ 0 ] [ 0 ] ) ;
336+
337+ // Verify the URL contains the correct query parameters
338+ expect ( calledUrl . searchParams . get ( 'users' ) ) . toBe ( revokeRoleData . users ) ;
339+ expect ( calledUrl . searchParams . get ( 'role' ) ) . toBe ( revokeRoleData . role ) ;
340+ expect ( calledUrl . searchParams . get ( 'scope' ) ) . toBe ( revokeRoleData . scope ) ;
341+ } ) ;
342+ } ) ;
0 commit comments