@@ -7,7 +7,7 @@ import { MantineProvider } from '@mantine/core';
77import { notifications } from '@mantine/notifications' ;
88import userEvent from '@testing-library/user-event' ;
99
10- describe ( 'Exec Group Management Panel read tests' , ( ) => {
10+ describe ( 'Exec Group Management Panel tests' , ( ) => {
1111 const renderComponent = async (
1212 fetchMembers : ( ) => Promise < any [ ] > ,
1313 updateMembers : ( ) => Promise < any >
@@ -33,18 +33,18 @@ describe('Exec Group Management Panel read tests', () => {
3333
3434 await renderComponent ( fetchMembers , updateMembers ) ;
3535
36- expect ( screen . getByText ( 'Current Members ' ) ) . toBeInTheDocument ( ) ;
37- expect ( screen . queryByText ( / .* @ i l l i n o i s \. e d u / ) ) . not . toBeInTheDocument ( ) ;
36+ expect ( screen . getByText ( 'Exec Council Group Management ' ) ) . toBeInTheDocument ( ) ;
37+ expect ( screen . queryByText ( / .* @ . * / ) ) . not . toBeInTheDocument ( ) ;
3838 } ) ;
3939
4040 it ( 'renders with a single member' , async ( ) => {
4141 const fetchMembers = async ( ) => [ { name :
'Doe, John' , email :
'[email protected] ' } ] ; 42- const updateMembers = async ( ) => ( {
43- success :
[ { email :
'[email protected] ' } ] , 44- } ) ;
42+ const updateMembers = async ( ) => ( { success :
[ { email :
'[email protected] ' } ] } ) ; 4543
4644 await renderComponent ( fetchMembers , updateMembers ) ;
47- expect ( screen . getByText ( / D o e , J o h n \( j d o e @ i l l i n o i s \. e d u \) / ) ) . toBeInTheDocument ( ) ;
45+ expect (
46+ screen . getByText ( ( content , element ) => element ?. textContent === 'Doe, [email protected] ' ) 47+ ) . toBeInTheDocument ( ) ;
4848 } ) ;
4949
5050 it ( 'renders with multiple members' , async ( ) => {
@@ -61,24 +61,21 @@ describe('Exec Group Management Panel read tests', () => {
6161 ] ,
6262 } ) ;
6363
64- await renderComponent ( fetchMembers , updateMembers ) ;
65- expect ( screen . getByText ( / D o e , J o h n \( j d o e @ i l l i n o i s \. e d u \) / ) ) . toBeInTheDocument ( ) ;
66- expect ( screen . getByText ( / S m i t h , J a n e \( j s m i t h @ i l l i n o i s \. e d u \) / ) ) . toBeInTheDocument ( ) ;
67- expect ( screen . getByText ( / B r o w n , B o b \( b b r o w n @ i l l i n o i s \. e d u \) / ) ) . toBeInTheDocument ( ) ;
68- } ) ;
69-
70- it ( 'displays all required UI elements' , async ( ) => {
71- const fetchMembers = async ( ) => [ ] ;
72- const updateMembers = async ( ) => ( { success : [ ] } ) ;
73-
7464 await renderComponent ( fetchMembers , updateMembers ) ;
7565
76- expect ( screen . getByText ( 'Exec Council Group Management' ) ) . toBeInTheDocument ( ) ;
77- expect ( screen . getByText ( 'Current Members' ) ) . toBeInTheDocument ( ) ;
78- expect ( screen . getByLabelText ( 'Add Member' ) ) . toBeInTheDocument ( ) ;
79- expect ( screen . getByPlaceholderText ( 'Enter email' ) ) . toBeInTheDocument ( ) ;
80- expect ( screen . getByRole ( 'button' , { name : 'Add Member' } ) ) . toBeInTheDocument ( ) ;
81- expect ( screen . getByRole ( 'button' , { name : 'Save Changes' } ) ) . toBeDisabled ( ) ;
66+ expect (
67+ screen . getByText ( ( content , element ) => element ?. textContent === 'Doe, [email protected] ' ) 68+ ) . toBeInTheDocument ( ) ;
69+ expect (
70+ screen . getByText (
71+ ( content , element ) => element ?. textContent === 'Smith, [email protected] ' 72+ )
73+ ) . toBeInTheDocument ( ) ;
74+ expect (
75+ screen . getByText (
76+ ( content , element ) => element ?. textContent === 'Brown, [email protected] ' 77+ )
78+ ) . toBeInTheDocument ( ) ;
8279 } ) ;
8380
8481 it ( 'adds a new member and saves changes' , async ( ) => {
@@ -100,108 +97,36 @@ describe('Exec Group Management Panel read tests', () => {
10097 const addButton = screen . getByRole ( 'button' , { name : 'Add Member' } ) ;
10198 await user . click ( addButton ) ;
10299
103- // Verify member appears with "Queued for addition" badge
100+ // Match the queued member
101+ expect ( screen . getByText ( 'member' ) ) . toBeInTheDocument ( ) ;
104102 expect ( screen . getByText ( '[email protected] ' ) ) . toBeInTheDocument ( ) ; 105- expect ( screen . getByText ( 'Queued for addition' ) ) . toBeInTheDocument ( ) ;
106103
107- // Click Save Changes which opens modal
104+ // Save Changes
108105 const saveButton = screen . getByRole ( 'button' , { name : 'Save Changes' } ) ;
109106 expect ( saveButton ) . toBeEnabled ( ) ;
110107 await user . click ( saveButton ) ;
111108
112- // Wait for the modal to appear with title
113109 await screen . findByText ( 'Confirm Changes' ) ;
114-
115- // Find and click confirm button in modal
116110 const confirmButton = screen . getByRole ( 'button' , { name : 'Confirm and Save' } ) ;
117111 await user . click ( confirmButton ) ;
118112
119- // Verify updateMembers was called with correct parameters
120113 expect ( updateMembers ) . toHaveBeenCalledWith ( [ '[email protected] ' ] , [ ] ) ; 121-
122- // Verify list is updated - "Queued for addition" badge should be gone
123- expect ( screen . getByText ( / m e m b e r \( m e m b e r @ i l l i n o i s \. e d u \) / ) ) . toBeInTheDocument ( ) ;
124- expect ( screen . queryByText ( 'Queued for addition' ) ) . not . toBeInTheDocument ( ) ;
125-
126- // Verify notifications were shown
127- expect ( notificationsMock ) . toHaveBeenCalledWith (
128- expect . objectContaining ( {
129- message : 'All changes processed successfully!' ,
130- color : 'green' ,
131- } )
132- ) ;
133-
134- // Verify Save Changes button is disabled again after successful update
135- expect ( screen . getByRole ( 'button' , { name : 'Save Changes' } ) ) . toBeDisabled ( ) ;
136-
137- // Clean up
138114 notificationsMock . mockRestore ( ) ;
139115 } ) ;
140- it ( 'handles failed member updates correctly' , async ( ) => {
141- const notificationsMock = vi . spyOn ( notifications , 'show' ) ;
142- const user = userEvent . setup ( ) ;
143- const fetchMembers = async ( ) => [ ] ;
144- const updateMembers = vi . fn ( ) . mockResolvedValue ( {
145- success : [ ] ,
146- failure : [
147- {
148- 149- message : 'User does not exist in directory' ,
150- } ,
151- ] ,
152- } ) ;
153-
154- await renderComponent ( fetchMembers , updateMembers ) ;
155-
156- // Add a member that will fail
157- const emailInput = screen . getByPlaceholderText ( 'Enter email' ) ;
158- await user . type ( emailInput , '[email protected] ' ) ; 159- await user . click ( screen . getByRole ( 'button' , { name : 'Add Member' } ) ) ;
160-
161- // Verify member shows in queue
162- expect ( screen . getByText ( '[email protected] ' ) ) . toBeInTheDocument ( ) ; 163- expect ( screen . getByText ( 'Queued for addition' ) ) . toBeInTheDocument ( ) ;
164116
165- // Try to save changes
166- await user . click ( screen . getByRole ( 'button' , { name : 'Save Changes' } ) ) ;
167- await screen . findByText ( 'Confirm Changes' ) ;
168- await user . click ( screen . getByRole ( 'button' , { name : 'Confirm and Save' } ) ) ;
169-
170- expect ( notificationsMock ) . toHaveBeenCalledWith (
171- expect . objectContaining ( {
172- title :
'Error adding [email protected] ' , 173- message : 'User does not exist in directory' ,
174- color : 'red' ,
175- } )
176- ) ;
177-
178- // Verify member is no longer shown as queued (since queues are cleared)
179- expect ( screen . queryByText ( 'Queued for addition' ) ) . not . toBeInTheDocument ( ) ;
180-
181- // Verify Save Changes button is disabled since queues are cleared
182- expect ( screen . getByRole ( 'button' , { name : 'Save Changes' } ) ) . toBeDisabled ( ) ;
183-
184- notificationsMock . mockRestore ( ) ;
185- } ) ;
186-
187- it ( 'removes an existing member' , async ( ) => {
117+ it ( 'removes an existing member and saves changes' , async ( ) => {
188118 const notificationsMock = vi . spyOn ( notifications , 'show' ) ;
189119 const user = userEvent . setup ( ) ;
190- const fetchMembers = async ( ) => [
191- {
192- name : 'Existing Member' ,
193- 194- } ,
195- ] ;
120+ const fetchMembers = async ( ) => [ { name :
'Existing Member' , email :
'[email protected] ' } ] ; 196121 const updateMembers = vi . fn ( ) . mockResolvedValue ( {
197122 success :
[ { email :
'[email protected] ' } ] , 198123 failure : [ ] ,
199124 } ) ;
200125
201126 await renderComponent ( fetchMembers , updateMembers ) ;
202127
203- // Click remove button for the existing member using data-testid
204- const removeButton = screen . getByTestId ( '[email protected] ' ) ; 128+ // Click remove button for the existing member
129+ const removeButton = screen . getByRole ( 'button' , { name : / R e m o v e / } ) ;
205130 await user . click ( removeButton ) ;
206131
207132 // Verify member shows removal badge
@@ -217,10 +142,7 @@ describe('Exec Group Management Panel read tests', () => {
217142 await user . click ( confirmButton ) ;
218143
219144 // Verify updateMembers was called with correct parameters
220- expect ( updateMembers ) . toHaveBeenCalledWith (
221- [ ] , // toAdd
222- 223- ) ;
145+ expect ( updateMembers ) . toHaveBeenCalledWith ( [ ] , [ '[email protected] ' ] ) ; 224146
225147 // Verify member is removed from the list
226148 expect (
@@ -237,106 +159,49 @@ describe('Exec Group Management Panel read tests', () => {
237159
238160 notificationsMock . mockRestore ( ) ;
239161 } ) ;
240- it ( 'handles multiple member changes with mixed success/failure results' , async ( ) => {
162+
163+ it ( 'handles failed member updates correctly' , async ( ) => {
241164 const notificationsMock = vi . spyOn ( notifications , 'show' ) ;
242165 const user = userEvent . setup ( ) ;
243-
244- // Start with two existing members
245- const fetchMembers = async ( ) => [
246- { name :
'Stay Member' , email :
'[email protected] ' } , 247- { name :
'Remove Success' , email :
'[email protected] ' } , 248- { name :
'Remove Fail' , email :
'[email protected] ' } , 249- ] ;
250-
251- // Mock mixed success/failure response
166+ const fetchMembers = async ( ) => [ ] ;
252167 const updateMembers = vi . fn ( ) . mockResolvedValue ( {
253- success : [
254- { email :
'[email protected] ' } , // removal succeeded 255- { email :
'[email protected] ' } , // addition succeeded 256- ] ,
168+ success : [ ] ,
257169 failure : [
258170 {
259- 260- message : 'Cannot remove admin user' ,
261- } ,
262- {
263- 264- message : 'User not found in directory' ,
171+ 172+ message : 'User does not exist in directory' ,
265173 } ,
266174 ] ,
267175 } ) ;
268176
269177 await renderComponent ( fetchMembers , updateMembers ) ;
270178
271- // Add two new members - one will succeed, one will fail
179+ // Add a member that will fail
272180 const emailInput = screen . getByPlaceholderText ( 'Enter email' ) ;
273-
274- await user . type ( emailInput , '[email protected] ' ) ; 275- await user . click ( screen . getByRole ( 'button' , { name : 'Add Member' } ) ) ;
276-
277- await user . type ( emailInput , '[email protected] ' ) ; 181+ await user . type ( emailInput , '[email protected] ' ) ; 278182 await user . click ( screen . getByRole ( 'button' , { name : 'Add Member' } ) ) ;
279183
280- // Remove two existing members - one will succeed, one will fail
281- await user . click ( screen . getByTestId ( '[email protected] ' ) ) ; 282- await user . click ( screen . getByTestId ( '[email protected] ' ) ) ; 283-
284- // Verify queued states before save
285- expect ( screen . getByText ( '[email protected] ' ) ) . toBeInTheDocument ( ) ; 286- expect ( screen . getByText ( '[email protected] ' ) ) . toBeInTheDocument ( ) ; 287- expect ( screen . getAllByText ( 'Queued for addition' ) ) . toHaveLength ( 2 ) ;
288- expect ( screen . getAllByText ( 'Queued for removal' ) ) . toHaveLength ( 2 ) ;
289-
290- // Save changes
291- const saveButton = screen . getByRole ( 'button' , { name : 'Save Changes' } ) ;
292- expect ( saveButton ) . toBeEnabled ( ) ;
293- await user . click ( saveButton ) ;
184+ // Verify member shows in queue
185+ expect ( screen . getByText ( '[email protected] ' ) ) . toBeInTheDocument ( ) ; 186+ expect ( screen . getByText ( 'Queued for addition' ) ) . toBeInTheDocument ( ) ;
294187
295- // Confirm in modal
188+ // Try to save changes
189+ await user . click ( screen . getByRole ( 'button' , { name : 'Save Changes' } ) ) ;
296190 await screen . findByText ( 'Confirm Changes' ) ;
297- const confirmButton = screen . getByRole ( 'button' , { name : 'Confirm and Save' } ) ;
298- await user . click ( confirmButton ) ;
299-
300- // Verify updateMembers was called with all changes
301- expect ( updateMembers ) . toHaveBeenCalledWith (
302- 303- 304- ) ;
305-
306- // Verify error notifications for failures
307- expect ( notificationsMock ) . toHaveBeenCalledWith (
308- expect . objectContaining ( {
309- title :
'Error adding [email protected] ' , 310- message : 'User not found in directory' ,
311- color : 'red' ,
312- } )
313- ) ;
191+ await user . click ( screen . getByRole ( 'button' , { name : 'Confirm and Save' } ) ) ;
314192
315193 expect ( notificationsMock ) . toHaveBeenCalledWith (
316194 expect . objectContaining ( {
317- title : 'Error removing removefail @illinois.edu' ,
318- message : 'Cannot remove admin user ' ,
195+ title : 'Error with member @illinois.edu' ,
196+ message : 'User does not exist in directory ' ,
319197 color : 'red' ,
320198 } )
321199 ) ;
322200
323- // Verify end state of member list
324- // Success cases
325- expect ( screen . queryByText ( / r e m o v e s u c c e s s @ i l l i n o i s \. e d u / ) ) . not . toBeInTheDocument ( ) ; // Successfully removed
326- expect ( screen . getByText ( / a d d s u c c e s s @ i l l i n o i s \. e d u / ) ) . toBeInTheDocument ( ) ; // Successfully added
327-
328- // Failure cases
329- expect ( screen . getByText ( / r e m o v e f a i l @ i l l i n o i s \. e d u / ) ) . toBeInTheDocument ( ) ; // Failed to remove
330- expect ( screen . queryByText ( / a d d f a i l @ i l l i n o i s \. e d u / ) ) . not . toBeInTheDocument ( ) ; // Failed to add
331-
332- // Unchanged member
333- expect ( screen . getByText ( / s t a y @ i l l i n o i s \. e d u / ) ) . toBeInTheDocument ( ) ;
334-
335- // Verify queued badges are cleared
201+ // Verify member is no longer shown as queued
336202 expect ( screen . queryByText ( 'Queued for addition' ) ) . not . toBeInTheDocument ( ) ;
337- expect ( screen . queryByText ( 'Queued for removal' ) ) . not . toBeInTheDocument ( ) ;
338203
339- // Verify Save Changes button is disabled after operation
204+ // Verify Save Changes button is disabled
340205 expect ( screen . getByRole ( 'button' , { name : 'Save Changes' } ) ) . toBeDisabled ( ) ;
341206
342207 notificationsMock . mockRestore ( ) ;
0 commit comments