@@ -13,6 +13,10 @@ jest.mock('@edx/frontend-platform/auth', () => ({
1313 configure : jest . fn ( ) ,
1414} ) ) ;
1515
16+ jest . mock ( '@edx/frontend-platform/logging' , ( ) => ( {
17+ logError : jest . fn ( ) ,
18+ } ) ) ;
19+
1620const mockUser = {
1721 username : 'johndoe' ,
1822@@ -273,6 +277,76 @@ describe('AuditUserPage', () => {
273277 } ) ;
274278 } ) ;
275279
280+ it ( 'shows error toast when role revocation succeeds but returns errors' , async ( ) => {
281+ ( getAuthenticatedHttpClient as jest . Mock ) . mockReturnValue ( {
282+ get : jest
283+ . fn ( )
284+ . mockResolvedValueOnce ( { data : mockUser } )
285+ . mockResolvedValueOnce ( { data : mockAssignments } ) ,
286+ delete : jest . fn ( ) . mockResolvedValue ( {
287+ data : {
288+ errors : [ 'Failed to revoke user role' ] ,
289+ completed : [ ] ,
290+ } ,
291+ } ) ,
292+ } ) ;
293+
294+ renderWithRouter ( ) ;
295+
296+ await waitFor ( ( ) => {
297+ expect ( screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ) . toBeInTheDocument ( ) ;
298+ } ) ;
299+
300+ const user = userEvent . setup ( ) ;
301+ const deleteButton = screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ;
302+ await user . click ( deleteButton ) ;
303+
304+ await waitFor ( ( ) => {
305+ expect ( screen . getByRole ( 'dialog' ) ) . toBeInTheDocument ( ) ;
306+ expect ( screen . getByRole ( 'button' , { name : / r e m o v e / i } ) ) . toBeInTheDocument ( ) ;
307+ } ) ;
308+
309+ const removeButton = screen . getByRole ( 'button' , { name : / r e m o v e / i } ) ;
310+ await user . click ( removeButton ) ;
311+
312+ await waitFor ( ( ) => {
313+ expect ( screen . getByText ( / s o m e t h i n g w e n t w r o n g / i) ) . toBeInTheDocument ( ) ;
314+ } ) ;
315+ } ) ;
316+
317+ it ( 'shows error toast with retry when role revocation fails' , async ( ) => {
318+ ( getAuthenticatedHttpClient as jest . Mock ) . mockReturnValue ( {
319+ get : jest
320+ . fn ( )
321+ . mockResolvedValueOnce ( { data : mockUser } )
322+ . mockResolvedValueOnce ( { data : mockAssignments } ) ,
323+ delete : jest . fn ( ) . mockRejectedValue ( new Error ( 'Network error' ) ) ,
324+ } ) ;
325+
326+ renderWithRouter ( ) ;
327+
328+ await waitFor ( ( ) => {
329+ expect ( screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ) . toBeInTheDocument ( ) ;
330+ } ) ;
331+
332+ const user = userEvent . setup ( ) ;
333+ const deleteButton = screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ;
334+ await user . click ( deleteButton ) ;
335+
336+ await waitFor ( ( ) => {
337+ expect ( screen . getByRole ( 'dialog' ) ) . toBeInTheDocument ( ) ;
338+ expect ( screen . getByRole ( 'button' , { name : / r e m o v e / i } ) ) . toBeInTheDocument ( ) ;
339+ } ) ;
340+
341+ const removeButton = screen . getByRole ( 'button' , { name : / r e m o v e / i } ) ;
342+ await user . click ( removeButton ) ;
343+
344+ await waitFor ( ( ) => {
345+ expect ( screen . getByText ( / s o m e t h i n g w e n t w r o n g o n o u r e n d / i) ) . toBeInTheDocument ( ) ;
346+ expect ( screen . getByText ( / t r y a g a i n l a t e r / i) ) . toBeInTheDocument ( ) ;
347+ } ) ;
348+ } ) ;
349+
276350 it ( 'shows the extra warning when rolesCount is 1' , async ( ) => {
277351 ( getAuthenticatedHttpClient as jest . Mock ) . mockReturnValue ( {
278352 get : jest
0 commit comments