@@ -2,7 +2,6 @@ import React from 'react';
2
2
import { expect } from 'chai' ;
3
3
import sinon from 'sinon' ;
4
4
import {
5
- fireEvent ,
6
5
render ,
7
6
screen ,
8
7
cleanup ,
@@ -128,7 +127,7 @@ describe('CrudToolbar Component', function () {
128
127
} ) ;
129
128
130
129
expect ( getPageSpy . called ) . to . be . false ;
131
- fireEvent . click ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) ;
130
+ userEvent . click ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) ;
132
131
133
132
expect ( getPageSpy . calledOnce ) . to . be . true ;
134
133
expect ( getPageSpy . firstCall . args [ 0 ] ) . to . equal ( 1 ) ;
@@ -141,7 +140,7 @@ describe('CrudToolbar Component', function () {
141
140
} ) ;
142
141
143
142
expect ( getPageSpy . called ) . to . be . false ;
144
- fireEvent . click ( screen . getByTestId ( 'docs-toolbar-prev-page-btn' ) ) ;
143
+ userEvent . click ( screen . getByTestId ( 'docs-toolbar-prev-page-btn' ) ) ;
145
144
146
145
expect ( screen . getByTestId ( 'docs-toolbar-prev-page-btn' ) ) . to . have . attribute (
147
146
'aria-disabled' ,
@@ -164,7 +163,7 @@ describe('CrudToolbar Component', function () {
164
163
end : 50 ,
165
164
} ) ;
166
165
expect ( getPageSpy . called ) . to . be . false ;
167
- fireEvent . click ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) ;
166
+ userEvent . click ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) ;
168
167
169
168
expect (
170
169
screen . getByTestId ( 'docs-toolbar-next-page-btn' )
@@ -184,7 +183,7 @@ describe('CrudToolbar Component', function () {
184
183
end : 25 ,
185
184
} ) ;
186
185
expect ( getPageSpy . called ) . to . be . false ;
187
- fireEvent . click ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) ;
186
+ userEvent . click ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) ;
188
187
189
188
expect (
190
189
screen . getByTestId ( 'docs-toolbar-next-page-btn' )
@@ -209,7 +208,7 @@ describe('CrudToolbar Component', function () {
209
208
) ;
210
209
211
210
expect ( getPageSpy . called ) . to . be . false ;
212
- fireEvent . click ( screen . getByTestId ( 'docs-toolbar-prev-page-btn' ) ) ;
211
+ userEvent . click ( screen . getByTestId ( 'docs-toolbar-prev-page-btn' ) ) ;
213
212
214
213
expect ( getPageSpy . calledOnce ) . to . be . true ;
215
214
expect ( getPageSpy . firstCall . args [ 0 ] ) . to . equal ( 0 ) ;
@@ -226,7 +225,7 @@ describe('CrudToolbar Component', function () {
226
225
} ) ;
227
226
228
227
expect ( getPageSpy . called ) . to . be . false ;
229
- fireEvent . click ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) ;
228
+ userEvent . click ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) ;
230
229
231
230
expect ( screen . getByTestId ( 'docs-toolbar-next-page-btn' ) ) . to . have . attribute (
232
231
'aria-disabled' ,
@@ -248,7 +247,7 @@ describe('CrudToolbar Component', function () {
248
247
expect ( nextButton ) . to . have . attribute ( 'aria-disabled' , 'false' ) ;
249
248
250
249
expect ( getPageSpy . called ) . to . be . false ;
251
- fireEvent . click ( nextButton ) ;
250
+ userEvent . click ( nextButton ) ;
252
251
253
252
expect ( getPageSpy . calledOnce ) . to . be . true ;
254
253
expect ( getPageSpy . firstCall . args [ 0 ] ) . to . equal ( 3 ) ;
@@ -295,8 +294,8 @@ describe('CrudToolbar Component', function () {
295
294
} ) ;
296
295
297
296
expect ( exportSpy . called ) . to . be . false ;
298
- fireEvent . click ( screen . getByText ( 'Export Data' ) ) ;
299
- fireEvent . click ( screen . getByText ( 'Export the full collection' ) ) ;
297
+ userEvent . click ( screen . getByText ( 'Export Data' ) ) ;
298
+ userEvent . click ( screen . getByText ( 'Export the full collection' ) ) ;
300
299
301
300
expect ( exportSpy . calledOnce ) . to . be . true ;
302
301
expect ( exportSpy . firstCall . args [ 0 ] ) . to . be . true ;
@@ -527,4 +526,262 @@ describe('CrudToolbar Component', function () {
527
526
expect ( stub ) . to . be . calledWithExactly ( 75 ) ;
528
527
} ) ;
529
528
} ) ;
529
+
530
+ describe ( 'context menu' , function ( ) {
531
+ beforeEach ( async function ( ) {
532
+ await preferences . savePreferences ( { enableImportExport : true } ) ;
533
+ } ) ;
534
+
535
+ it ( 'should open context menu on right click' , function ( ) {
536
+ renderCrudToolbar ( ) ;
537
+
538
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
539
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
540
+
541
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
542
+ expect ( within ( contextMenu ) . getByText ( 'Expand all documents' ) ) . to . be
543
+ . visible ;
544
+ expect ( within ( contextMenu ) . getByText ( 'Refresh' ) ) . to . be . visible ;
545
+ } ) ;
546
+
547
+ it ( 'should call onExpandAllClicked when "Expand all documents" is clicked' , function ( ) {
548
+ const onExpandAllClicked = sinon . spy ( ) ;
549
+ renderCrudToolbar ( { onExpandAllClicked } ) ;
550
+
551
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
552
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
553
+
554
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
555
+ const expandMenuItem = within ( contextMenu ) . getByText (
556
+ 'Expand all documents'
557
+ ) ;
558
+ userEvent . click ( expandMenuItem ) ;
559
+
560
+ expect ( onExpandAllClicked ) . to . have . been . calledOnce ;
561
+ } ) ;
562
+
563
+ it ( 'should call onCollapseAllClicked when "Collapse all documents" is clicked' , function ( ) {
564
+ const onCollapseAllClicked = sinon . spy ( ) ;
565
+ renderCrudToolbar ( { onCollapseAllClicked } ) ;
566
+
567
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
568
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
569
+
570
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
571
+ const collapseMenuItem = within ( contextMenu ) . getByText (
572
+ 'Collapse all documents'
573
+ ) ;
574
+ userEvent . click ( collapseMenuItem ) ;
575
+
576
+ expect ( onCollapseAllClicked ) . to . have . been . called ;
577
+ } ) ;
578
+
579
+ it ( 'should call insertDataHandler with "import-file" when "Import JSON or CSV file" is clicked' , function ( ) {
580
+ const insertDataHandler = sinon . spy ( ) ;
581
+ renderCrudToolbar ( { insertDataHandler } ) ;
582
+
583
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
584
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
585
+
586
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
587
+ const importMenuItem = within ( contextMenu ) . getByText (
588
+ 'Import JSON or CSV file'
589
+ ) ;
590
+ userEvent . click ( importMenuItem ) ;
591
+
592
+ expect ( insertDataHandler ) . to . have . been . calledOnceWithExactly (
593
+ 'import-file'
594
+ ) ;
595
+ } ) ;
596
+
597
+ it ( 'should call insertDataHandler with "insert-document" when "Insert document..." is clicked' , function ( ) {
598
+ const insertDataHandler = sinon . spy ( ) ;
599
+ renderCrudToolbar ( { insertDataHandler } ) ;
600
+
601
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
602
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
603
+
604
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
605
+ const insertMenuItem =
606
+ within ( contextMenu ) . getByText ( 'Insert document...' ) ;
607
+ userEvent . click ( insertMenuItem ) ;
608
+
609
+ expect ( insertDataHandler ) . to . have . been . calledOnceWithExactly (
610
+ 'insert-document'
611
+ ) ;
612
+ } ) ;
613
+
614
+ it ( 'should call openExportFileDialog with false when "Export query results..." is clicked' , function ( ) {
615
+ const openExportFileDialog = sinon . spy ( ) ;
616
+ renderCrudToolbar ( { openExportFileDialog } ) ;
617
+
618
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
619
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
620
+
621
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
622
+ const exportQueryMenuItem = within ( contextMenu ) . getByText (
623
+ 'Export query results...'
624
+ ) ;
625
+ userEvent . click ( exportQueryMenuItem ) ;
626
+
627
+ expect ( openExportFileDialog ) . to . have . been . calledOnceWithExactly ( false ) ;
628
+ } ) ;
629
+
630
+ it ( 'should call openExportFileDialog with true when "Export full collection..." is clicked' , function ( ) {
631
+ const openExportFileDialog = sinon . spy ( ) ;
632
+ renderCrudToolbar ( { openExportFileDialog } ) ;
633
+
634
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
635
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
636
+
637
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
638
+ const exportCollectionMenuItem = within ( contextMenu ) . getByText (
639
+ 'Export full collection...'
640
+ ) ;
641
+ userEvent . click ( exportCollectionMenuItem ) ;
642
+
643
+ expect ( openExportFileDialog ) . to . have . been . calledOnceWithExactly ( true ) ;
644
+ } ) ;
645
+
646
+ it ( 'should call onUpdateButtonClicked when "Bulk update" is clicked' , function ( ) {
647
+ const onUpdateButtonClicked = sinon . spy ( ) ;
648
+ renderCrudToolbar ( { onUpdateButtonClicked } ) ;
649
+
650
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
651
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
652
+
653
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
654
+ const updateMenuItem = within ( contextMenu ) . getByText ( 'Bulk update' ) ;
655
+ userEvent . click ( updateMenuItem ) ;
656
+
657
+ expect ( onUpdateButtonClicked ) . to . have . been . calledOnce ;
658
+ } ) ;
659
+
660
+ it ( 'should call onDeleteButtonClicked when "Bulk delete" is clicked' , function ( ) {
661
+ const onDeleteButtonClicked = sinon . spy ( ) ;
662
+ renderCrudToolbar ( { onDeleteButtonClicked } ) ;
663
+
664
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
665
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
666
+
667
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
668
+ const deleteMenuItem = within ( contextMenu ) . getByText ( 'Bulk delete' ) ;
669
+ userEvent . click ( deleteMenuItem ) ;
670
+
671
+ expect ( onDeleteButtonClicked ) . to . have . been . calledOnce ;
672
+ } ) ;
673
+
674
+ it ( 'should call refreshDocuments when "Refresh" is clicked' , function ( ) {
675
+ const refreshDocuments = sinon . spy ( ) ;
676
+ renderCrudToolbar ( { refreshDocuments } ) ;
677
+
678
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
679
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
680
+
681
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
682
+ const refreshMenuItem = within ( contextMenu ) . getByText ( 'Refresh' ) ;
683
+ userEvent . click ( refreshMenuItem ) ;
684
+
685
+ expect ( refreshDocuments ) . to . have . been . calledOnce ;
686
+ } ) ;
687
+
688
+ describe ( 'conditional menu items' , function ( ) {
689
+ it ( 'should not show import/export items when enableImportExport is false' , async function ( ) {
690
+ await preferences . savePreferences ( { enableImportExport : false } ) ;
691
+ renderCrudToolbar ( ) ;
692
+
693
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
694
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
695
+
696
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
697
+ expect ( within ( contextMenu ) . queryByText ( 'Import JSON or CSV file' ) ) . to
698
+ . not . exist ;
699
+ expect ( within ( contextMenu ) . queryByText ( 'Export query results...' ) ) . to
700
+ . not . exist ;
701
+ expect ( within ( contextMenu ) . queryByText ( 'Export full collection...' ) ) . to
702
+ . not . exist ;
703
+ } ) ;
704
+
705
+ it ( 'should not show insert document item when readonly is true' , function ( ) {
706
+ renderCrudToolbar ( { readonly : true } ) ;
707
+
708
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
709
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
710
+
711
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
712
+ expect ( within ( contextMenu ) . queryByText ( 'Insert document...' ) ) . to . not
713
+ . exist ;
714
+ } ) ;
715
+
716
+ it ( 'should not show bulk operations when readonly is true' , function ( ) {
717
+ renderCrudToolbar ( { readonly : true } ) ;
718
+
719
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
720
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
721
+
722
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
723
+ expect ( within ( contextMenu ) . queryByText ( 'Bulk update' ) ) . to . not . exist ;
724
+ expect ( within ( contextMenu ) . queryByText ( 'Bulk delete' ) ) . to . not . exist ;
725
+ } ) ;
726
+
727
+ it ( 'should not show bulk operations when isWritable is false' , function ( ) {
728
+ renderCrudToolbar ( { isWritable : false } ) ;
729
+
730
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
731
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
732
+
733
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
734
+ expect ( within ( contextMenu ) . queryByText ( 'Bulk update' ) ) . to . not . exist ;
735
+ expect ( within ( contextMenu ) . queryByText ( 'Bulk delete' ) ) . to . not . exist ;
736
+ } ) ;
737
+
738
+ it ( 'should not show bulk operations when query has skip' , function ( ) {
739
+ renderCrudToolbar ( { querySkip : 10 } ) ;
740
+
741
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
742
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
743
+
744
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
745
+ expect ( within ( contextMenu ) . queryByText ( 'Bulk update' ) ) . to . not . exist ;
746
+ } ) ;
747
+
748
+ it ( 'should not show bulk operations when query has limit' , function ( ) {
749
+ renderCrudToolbar ( { queryLimit : 10 } ) ;
750
+
751
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
752
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
753
+
754
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
755
+ expect ( within ( contextMenu ) . queryByText ( 'Bulk update' ) ) . to . not . exist ;
756
+ expect ( within ( contextMenu ) . queryByText ( 'Bulk delete' ) ) . to . not . exist ;
757
+ } ) ;
758
+
759
+ it ( 'should show all applicable items when conditions are met' , function ( ) {
760
+ renderCrudToolbar ( {
761
+ readonly : false ,
762
+ isWritable : true ,
763
+ querySkip : 0 ,
764
+ queryLimit : 0 ,
765
+ } ) ;
766
+
767
+ const toolbar = screen . getByTestId ( 'query-bar' ) . closest ( 'div' ) ;
768
+ userEvent . click ( toolbar ! , { button : 2 } ) ;
769
+
770
+ const contextMenu = screen . getByTestId ( 'context-menu' ) ;
771
+ expect ( within ( contextMenu ) . getByText ( 'Expand all documents' ) ) . to . be
772
+ . visible ;
773
+ expect ( within ( contextMenu ) . getByText ( 'Import JSON or CSV file' ) ) . to . be
774
+ . visible ;
775
+ expect ( within ( contextMenu ) . getByText ( 'Insert document...' ) ) . to . be
776
+ . visible ;
777
+ expect ( within ( contextMenu ) . getByText ( 'Export query results...' ) ) . to . be
778
+ . visible ;
779
+ expect ( within ( contextMenu ) . getByText ( 'Export full collection...' ) ) . to . be
780
+ . visible ;
781
+ expect ( within ( contextMenu ) . getByText ( 'Bulk update' ) ) . to . be . visible ;
782
+ expect ( within ( contextMenu ) . getByText ( 'Bulk delete' ) ) . to . be . visible ;
783
+ expect ( within ( contextMenu ) . getByText ( 'Refresh' ) ) . to . be . visible ;
784
+ } ) ;
785
+ } ) ;
786
+ } ) ;
530
787
} ) ;
0 commit comments