11import React from 'react' ;
2- import { render , screen , userEvent } from '@mongodb-js/testing-library-compass' ;
2+ import {
3+ render ,
4+ screen ,
5+ userEvent ,
6+ waitFor ,
7+ } from '@mongodb-js/testing-library-compass' ;
38import { expect } from 'chai' ;
49import sinon from 'sinon' ;
510import { ContextMenuProvider } from '@mongodb-js/compass-context-menu' ;
611import { useContextMenuItems , ContextMenu } from './context-menu' ;
712import type { ContextMenuItem } from '@mongodb-js/compass-context-menu' ;
813
914describe ( 'useContextMenuItems' , function ( ) {
15+ let items : ContextMenuItem [ ] ;
16+ let onAction : sinon . SinonSpy ;
17+
18+ function assertMenuItemsExist ( items : ContextMenuItem [ ] ) {
19+ for ( let i = 0 ; i < items . length ; i ++ ) {
20+ expect ( screen . getByTestId ( `menu-group-0-item-${ i } ` ) ) . to . exist ;
21+ }
22+ }
23+
24+ function assertMenuItemsDoNotExist ( items : ContextMenuItem [ ] ) {
25+ for ( let i = 0 ; i < items . length ; i ++ ) {
26+ expect ( screen . queryByTestId ( `menu-group-0-item-${ i } ` ) ) . not . to . exist ;
27+ }
28+ }
29+
30+ beforeEach ( function ( ) {
31+ onAction = sinon . spy ( ) ;
32+ items = [
33+ {
34+ label : 'Test Item 1' ,
35+ onAction : ( ) => onAction ( 1 ) ,
36+ } ,
37+ {
38+ label : 'Test Item 2' ,
39+ onAction : ( ) => onAction ( 2 ) ,
40+ } ,
41+ ] ;
42+ } ) ;
43+
44+ afterEach ( function ( ) {
45+ sinon . restore ( ) ;
46+ } ) ;
47+
1048 const menuTestTriggerId = 'test-trigger' ;
1149
1250 const TestComponent = ( {
@@ -29,13 +67,6 @@ describe('useContextMenuItems', function () {
2967 } ;
3068
3169 it ( 'works with nested providers, using the parent provider' , function ( ) {
32- const items = [
33- {
34- label : 'Test Item' ,
35- onAction : ( ) => { } ,
36- } ,
37- ] ;
38-
3970 const { container } = render (
4071 < ContextMenuProvider menuWrapper = { ContextMenu } >
4172 < ContextMenuProvider menuWrapper = { ContextMenu } >
@@ -53,53 +84,22 @@ describe('useContextMenuItems', function () {
5384 } ) ;
5485
5586 it ( 'renders without error' , function ( ) {
56- const items = [
57- {
58- label : 'Test Item' ,
59- onAction : ( ) => { } ,
60- } ,
61- ] ;
62-
6387 render ( < TestComponent items = { items } /> ) ;
6488
6589 expect ( screen . getByTestId ( menuTestTriggerId ) ) . to . exist ;
6690 } ) ;
6791
6892 it ( 'shows context menu with items on right click' , function ( ) {
69- const items = [
70- {
71- label : 'Test Item 1' ,
72- onAction : ( ) => { } ,
73- } ,
74- {
75- label : 'Test Item 2' ,
76- onAction : ( ) => { } ,
77- } ,
78- ] ;
79-
8093 render ( < TestComponent items = { items } /> ) ;
8194
8295 const trigger = screen . getByTestId ( menuTestTriggerId ) ;
8396 userEvent . click ( trigger , { button : 2 } ) ;
8497
8598 // The menu items should be rendered
86- expect ( screen . getByTestId ( 'menu-group-0-item-0' ) ) . to . exist ;
87- expect ( screen . getByTestId ( 'menu-group-0-item-1' ) ) . to . exist ;
99+ assertMenuItemsExist ( items ) ;
88100 } ) ;
89101
90102 it ( 'triggers the correct action when menu item is clicked' , function ( ) {
91- const onAction = sinon . spy ( ) ;
92- const items = [
93- {
94- label : 'Test Item 1' ,
95- onAction : ( ) => onAction ( 1 ) ,
96- } ,
97- {
98- label : 'Test Item 2' ,
99- onAction : ( ) => onAction ( 2 ) ,
100- } ,
101- ] ;
102-
103103 render ( < TestComponent items = { items } /> ) ;
104104
105105 const trigger = screen . getByTestId ( menuTestTriggerId ) ;
@@ -111,21 +111,47 @@ describe('useContextMenuItems', function () {
111111 expect ( onAction ) . to . have . been . calledOnceWithExactly ( 2 ) ;
112112 } ) ;
113113
114+ it ( 'closes the menu when an item is clicked' , async function ( ) {
115+ render ( < TestComponent items = { items } /> ) ;
116+
117+ const trigger = screen . getByTestId ( menuTestTriggerId ) ;
118+
119+ // Open the menu with right-click
120+ userEvent . click ( trigger , { button : 2 } ) ;
121+
122+ // Verify the menu is open (items exist)
123+ assertMenuItemsExist ( items ) ;
124+
125+ // Click on a menu item
126+ const menuItem = screen . getByTestId ( 'menu-group-0-item-0' ) ;
127+ userEvent . click ( menuItem ) ;
128+
129+ // Verify the menu is closed (items do not exist)
130+ await waitFor ( ( ) => assertMenuItemsDoNotExist ( items ) ) ;
131+ } ) ;
132+
133+ it ( 'closes the menu when clicking outside the menu' , async function ( ) {
134+ render ( < TestComponent items = { items } /> ) ;
135+
136+ const trigger = screen . getByTestId ( menuTestTriggerId ) ;
137+
138+ // Open the menu with right-click
139+ userEvent . click ( trigger , { button : 2 } ) ;
140+
141+ // Verify the menu is open (items exist)
142+ assertMenuItemsExist ( items ) ;
143+
144+ // Click outside the menu (on document body)
145+ userEvent . click ( document . body ) ;
146+
147+ // Verify the menu is closed (items do not exist)
148+ await waitFor ( ( ) => assertMenuItemsDoNotExist ( items ) ) ;
149+ } ) ;
150+
114151 describe ( 'with nested components' , function ( ) {
115152 const childTriggerId = 'child-trigger' ;
116153
117154 beforeEach ( function ( ) {
118- const items = [
119- {
120- label : 'Test Item 1' ,
121- onAction : ( ) => { } ,
122- } ,
123- {
124- label : 'Test Item 2' ,
125- onAction : ( ) => { } ,
126- } ,
127- ] ;
128-
129155 const childItems = [
130156 {
131157 label : 'Child Item 1' ,
0 commit comments