@@ -125,6 +125,69 @@ describe('ViewsMenu', () => {
125125 container . remove ( )
126126 } )
127127
128+ it ( 'confirms before deleting a saved view' , ( ) => {
129+ const container = document . createElement ( 'div' )
130+ document . body . appendChild ( container )
131+ const root = createRoot ( container )
132+ const onDelete = vi . fn ( )
133+
134+ act ( ( ) => {
135+ root . render (
136+ < ViewsMenu
137+ views = { [ PRIMARY_VIEW , SECOND_VIEW ] }
138+ activeViewId = { PRIMARY_VIEW . id }
139+ onSelect = { vi . fn ( ) }
140+ onRename = { vi . fn ( ) }
141+ onSetDefault = { vi . fn ( ) }
142+ onDelete = { onDelete }
143+ onNewView = { vi . fn ( ) }
144+ canEdit
145+ />
146+ )
147+ } )
148+ act ( ( ) => container . querySelector < HTMLButtonElement > ( 'button[aria-label="Views"]' ) ?. click ( ) )
149+
150+ const getDeleteButton = ( ) =>
151+ [ ...document . body . querySelectorAll < HTMLButtonElement > ( 'button[aria-label="Delete"]' ) ] . find (
152+ ( button ) => button . getAttribute ( 'aria-disabled' ) !== 'true'
153+ )
154+ const getConfirmationDialog = ( ) =>
155+ [ ...document . body . querySelectorAll < HTMLElement > ( '[role="dialog"]' ) ] . find ( ( dialog ) =>
156+ dialog . textContent ?. includes ( 'This action cannot be undone.' )
157+ )
158+
159+ act ( ( ) => getDeleteButton ( ) ?. click ( ) )
160+
161+ expect ( onDelete ) . not . toHaveBeenCalled ( )
162+ const firstDialog = getConfirmationDialog ( )
163+ expect ( firstDialog ) . toHaveTextContent ( 'Delete View' )
164+ expect ( firstDialog ) . toHaveTextContent ( 'Second view' )
165+ expect ( firstDialog ) . toHaveTextContent ( 'This action cannot be undone.' )
166+
167+ const cancelButton = [
168+ ...( firstDialog ?. querySelectorAll < HTMLButtonElement > ( 'button' ) ?? [ ] ) ,
169+ ] . find ( ( button ) => button . textContent === 'Cancel' )
170+ act ( ( ) => cancelButton ?. click ( ) )
171+
172+ expect ( getConfirmationDialog ( ) ) . toBeUndefined ( )
173+ expect ( onDelete ) . not . toHaveBeenCalled ( )
174+
175+ act ( ( ) => container . querySelector < HTMLButtonElement > ( 'button[aria-label="Views"]' ) ?. click ( ) )
176+ act ( ( ) => getDeleteButton ( ) ?. click ( ) )
177+
178+ const dialog = getConfirmationDialog ( )
179+ const confirmButton = [ ...( dialog ?. querySelectorAll < HTMLButtonElement > ( 'button' ) ?? [ ] ) ] . find (
180+ ( button ) => button . textContent === 'Delete'
181+ )
182+ act ( ( ) => confirmButton ?. click ( ) )
183+
184+ expect ( onDelete ) . toHaveBeenCalledOnce ( )
185+ expect ( onDelete ) . toHaveBeenCalledWith ( SECOND_VIEW . id )
186+
187+ act ( ( ) => root . unmount ( ) )
188+ container . remove ( )
189+ } )
190+
128191 it ( 'keeps the menu open when keyboard focus moves from the trigger to the default pin' , ( ) => {
129192 vi . useFakeTimers ( )
130193 const container = document . createElement ( 'div' )
0 commit comments