@@ -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' , ( ) => ( {
@@ -228,3 +228,103 @@ describe('usePermissionsByRole', () => {
228228 } ) ;
229229 } ) ;
230230} ) ;
231+
232+ describe ( 'useRevokeUserRoles' , ( ) => {
233+ beforeEach ( ( ) => {
234+ jest . clearAllMocks ( ) ;
235+ } ) ;
236+
237+ it ( 'successfully revokes user roles' , async ( ) => {
238+ const mockResponse = {
239+ completed : [
240+ {
241+ userIdentifiers : 'jdoe' ,
242+ status : 'role_removed' ,
243+ } ,
244+ ] ,
245+ errors : [ ] ,
246+ } ;
247+
248+ getAuthenticatedHttpClient . mockReturnValue ( {
249+ delete : jest . fn ( ) . mockResolvedValue ( { data : mockResponse } ) ,
250+ } ) ;
251+
252+ const { result } = renderHook ( ( ) => useRevokeUserRoles ( ) , {
253+ wrapper : createWrapper ( ) ,
254+ } ) ;
255+
256+ const revokeRoleData = {
257+ scope : 'lib:123' ,
258+ users : 'jdoe' ,
259+ role : 'author' ,
260+ } ;
261+
262+ await act ( async ( ) => {
263+ result . current . mutate ( { data : revokeRoleData } ) ;
264+ } ) ;
265+
266+ await waitFor ( ( ) => expect ( result . current . isSuccess ) . toBe ( true ) ) ;
267+
268+ expect ( getAuthenticatedHttpClient ) . toHaveBeenCalled ( ) ;
269+ expect ( result . current . data ) . toEqual ( mockResponse ) ;
270+ } ) ;
271+
272+ it ( 'handles error when revoking roles fails' , async ( ) => {
273+ getAuthenticatedHttpClient . mockReturnValue ( {
274+ delete : jest . fn ( ) . mockRejectedValue ( new Error ( 'Failed to revoke roles' ) ) ,
275+ } ) ;
276+
277+ const { result } = renderHook ( ( ) => useRevokeUserRoles ( ) , {
278+ wrapper : createWrapper ( ) ,
279+ } ) ;
280+
281+ const revokeRoleData = {
282+ scope : 'lib:123' ,
283+ users : 'jdoe' ,
284+ role : 'author' ,
285+ } ;
286+
287+ await act ( async ( ) => {
288+ result . current . mutate ( { data : revokeRoleData } ) ;
289+ } ) ;
290+
291+ await waitFor ( ( ) => expect ( result . current . isError ) . toBe ( true ) ) ;
292+
293+ expect ( getAuthenticatedHttpClient ) . toHaveBeenCalled ( ) ;
294+ expect ( result . current . error ) . toEqual ( new Error ( 'Failed to revoke roles' ) ) ;
295+ } ) ;
296+
297+ it ( 'constructs URL with correct query parameters' , async ( ) => {
298+ const mockDelete = jest . fn ( ) . mockResolvedValue ( {
299+ data : { completed : [ ] , errors : [ ] } ,
300+ } ) ;
301+
302+ getAuthenticatedHttpClient . mockReturnValue ( {
303+ delete : mockDelete ,
304+ } ) ;
305+
306+ const { result } = renderHook ( ( ) => useRevokeUserRoles ( ) , {
307+ wrapper : createWrapper ( ) ,
308+ } ) ;
309+
310+ const revokeRoleData = {
311+ scope : 'lib:org/test-lib' ,
312+ 313+ role : 'instructor' ,
314+ } ;
315+
316+ await act ( async ( ) => {
317+ result . current . mutate ( { data : revokeRoleData } ) ;
318+ } ) ;
319+
320+ await waitFor ( ( ) => expect ( result . current . isSuccess ) . toBe ( true ) ) ;
321+
322+ expect ( mockDelete ) . toHaveBeenCalled ( ) ;
323+ const calledUrl = new URL ( mockDelete . mock . calls [ 0 ] [ 0 ] ) ;
324+
325+ // Verify the URL contains the correct query parameters
326+ expect ( calledUrl . searchParams . get ( 'users' ) ) . toBe ( revokeRoleData . users ) ;
327+ expect ( calledUrl . searchParams . get ( 'role' ) ) . toBe ( revokeRoleData . role ) ;
328+ expect ( calledUrl . searchParams . get ( 'scope' ) ) . toBe ( revokeRoleData . scope ) ;
329+ } ) ;
330+ } ) ;
0 commit comments