11import { render , screen , waitFor } from '@testing-library/react' ;
2+ import { AppContext } from '@edx/frontend-platform/react' ;
23import userEvent from '@testing-library/user-event' ;
34import { MemoryRouter , Route , Routes } from 'react-router-dom' ;
45import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth' ;
56import { IntlProvider } from '@edx/frontend-platform/i18n' ;
67import { QueryClient , QueryClientProvider } from '@tanstack/react-query' ;
8+ import { ToastManagerProvider } from '@src/authz-module/data/context/ToastManagerContext' ;
79import AuditUserPage from './index' ;
810
911jest . mock ( '@edx/frontend-platform/auth' , ( ) => ( {
@@ -40,17 +42,32 @@ const renderWithRouter = (route = '/audit/johndoe') => {
4042 } ,
4143 } ) ;
4244
45+ const mockAppContext = {
46+ authenticatedUser : {
47+ username : 'testuser' ,
48+ 49+ } ,
50+ config : {
51+ // @ts -ignore
52+ ...process . env ,
53+ } ,
54+ } ;
55+
4356 return render (
44- < QueryClientProvider client = { queryClient } >
45- < IntlProvider locale = "en" >
46- < MemoryRouter initialEntries = { [ route ] } >
47- < Routes >
48- < Route path = "/audit/:username" element = { < AuditUserPage /> } />
49- < Route path = "/authz" element = { < div > Home Page</ div > } />
50- </ Routes >
51- </ MemoryRouter >
52- </ IntlProvider >
53- </ QueryClientProvider > ,
57+ < AppContext . Provider value = { mockAppContext } >
58+ < QueryClientProvider client = { queryClient } >
59+ < IntlProvider locale = "en" >
60+ < ToastManagerProvider >
61+ < MemoryRouter initialEntries = { [ route ] } >
62+ < Routes >
63+ < Route path = "/audit/:username" element = { < AuditUserPage /> } />
64+ < Route path = "/authz" element = { < div > Home Page</ div > } />
65+ </ Routes >
66+ </ MemoryRouter >
67+ </ ToastManagerProvider >
68+ </ IntlProvider >
69+ </ QueryClientProvider >
70+ </ AppContext . Provider > ,
5471 ) ;
5572} ;
5673
@@ -59,6 +76,11 @@ describe('AuditUserPage', () => {
5976 jest . clearAllMocks ( ) ;
6077 } ) ;
6178
79+ beforeAll ( ( ) => {
80+ // @ts -ignore
81+ global . logError = jest . fn ( ) ;
82+ } ) ;
83+
6284 it ( 'renders user info and table when data is loaded' , async ( ) => {
6385 ( getAuthenticatedHttpClient as jest . Mock ) . mockReturnValue ( {
6486 get : jest
@@ -185,4 +207,107 @@ describe('AuditUserPage', () => {
185207 expect ( screen . getByText ( mockUser . username , { selector : 'li[aria-current="page"]' } ) ) . toBeInTheDocument ( ) ;
186208 } ) ;
187209 } ) ;
210+
211+ it ( 'opens and closes the ConfirmDeletionModal when delete is clicked and cancel is pressed' , async ( ) => {
212+ ( getAuthenticatedHttpClient as jest . Mock ) . mockReturnValue ( {
213+ get : jest
214+ . fn ( )
215+ . mockResolvedValueOnce ( { data : mockUser } )
216+ . mockResolvedValueOnce ( { data : mockAssignments } ) ,
217+ } ) ;
218+
219+ renderWithRouter ( ) ;
220+
221+ await waitFor ( ( ) => {
222+ expect ( screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ) . toBeInTheDocument ( ) ;
223+ } ) ;
224+
225+ const user = userEvent . setup ( ) ;
226+ const deleteButton = screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ;
227+ await user . click ( deleteButton ) ;
228+
229+ await waitFor ( ( ) => {
230+ expect ( screen . getByRole ( 'dialog' ) ) . toBeInTheDocument ( ) ;
231+ expect ( screen . getByText ( / r e m o v e r o l e \? / i) ) . toBeInTheDocument ( ) ;
232+ expect ( screen . getByRole ( 'button' , { name : / c a n c e l / i } ) ) . toBeInTheDocument ( ) ;
233+ } ) ;
234+
235+ const cancelButton = screen . getByRole ( 'button' , { name : / c a n c e l / i } ) ;
236+ await user . click ( cancelButton ) ;
237+
238+ await waitFor ( ( ) => {
239+ expect ( screen . queryByRole ( 'dialog' ) ) . not . toBeInTheDocument ( ) ;
240+ } ) ;
241+ } ) ;
242+
243+ it ( 'calls onSave when confirming deletion in ConfirmDeletionModal' , async ( ) => {
244+ ( getAuthenticatedHttpClient as jest . Mock ) . mockReturnValue ( {
245+ get : jest
246+ . fn ( )
247+ . mockResolvedValueOnce ( { data : mockUser } )
248+ . mockResolvedValueOnce ( { data : mockAssignments } ) ,
249+ delete : jest . fn ( ) . mockResolvedValue ( { data : { errors : [ ] } } ) ,
250+ } ) ;
251+
252+ renderWithRouter ( ) ;
253+
254+ await waitFor ( ( ) => {
255+ expect ( screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ) . toBeInTheDocument ( ) ;
256+ } ) ;
257+
258+ const user = userEvent . setup ( ) ;
259+ const deleteButton = screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ;
260+ await user . click ( deleteButton ) ;
261+
262+ await waitFor ( ( ) => {
263+ expect ( screen . getByRole ( 'dialog' ) ) . toBeInTheDocument ( ) ;
264+ expect ( screen . getByRole ( 'button' , { name : / r e m o v e / i } ) ) . toBeInTheDocument ( ) ;
265+ } ) ;
266+
267+ const removeButton = screen . getByRole ( 'button' , { name : / r e m o v e / i } ) ;
268+ await user . click ( removeButton ) ;
269+
270+ await waitFor ( ( ) => {
271+ expect ( screen . queryByRole ( 'dialog' ) ) . not . toBeInTheDocument ( ) ;
272+ expect ( screen . getByText ( / r o l e h a s b e e n s u c c e s s f u l l y r e m o v e d / i) ) . toBeInTheDocument ( ) ;
273+ } ) ;
274+ } ) ;
275+
276+ it ( 'shows the extra warning when rolesCount is 1' , async ( ) => {
277+ ( getAuthenticatedHttpClient as jest . Mock ) . mockReturnValue ( {
278+ get : jest
279+ . fn ( )
280+ . mockResolvedValueOnce ( { data : mockUser } )
281+ . mockResolvedValueOnce ( {
282+ data : {
283+ count : 1 ,
284+ results : [
285+ {
286+ id : '1' ,
287+ role : 'library_admin' ,
288+ org : 'Test Org' ,
289+ scope : 'lib:test' ,
290+ permissionCount : 5 ,
291+ } ,
292+ ] ,
293+ next : null ,
294+ previous : null ,
295+ } ,
296+ } ) ,
297+ } ) ;
298+
299+ renderWithRouter ( ) ;
300+
301+ await waitFor ( ( ) => {
302+ expect ( screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ) . toBeInTheDocument ( ) ;
303+ } ) ;
304+
305+ const user = userEvent . setup ( ) ;
306+ const deleteButton = screen . getByRole ( 'button' , { name : / d e l e t e r o l e a c t i o n / i } ) ;
307+ await user . click ( deleteButton ) ;
308+
309+ await waitFor ( ( ) => {
310+ expect ( screen . getByText ( / t h i s i s t h e u s e r ' s o n l y r o l e / i) ) . toBeInTheDocument ( ) ;
311+ } ) ;
312+ } ) ;
188313} ) ;
0 commit comments