@@ -5,6 +5,26 @@ import utils from "../../core/utils";
5
5
import registry from "../../core/registry" ;
6
6
import { jest } from "@jest/globals" ;
7
7
8
+ // Need to import for the ajax mock to work.
9
+ import "select2" ;
10
+
11
+ const mock_fetch_ajax = ( ...data ) => {
12
+ // Data format: [{id: str, text: str}, ... ], ...
13
+ // first batch ^ ^ second batch
14
+
15
+ // NOTE: You need to add a trailing comma if you add only one argument to
16
+ // make the multi-argument dereferencing work.
17
+
18
+ // Mock Select2
19
+ $ . fn . select2 . ajaxDefaults . transport = jest . fn ( ) . mockImplementation ( ( opts ) => {
20
+ // Get the batch page
21
+ const page = opts . data . page - 1 ;
22
+
23
+ // Return the data for the batch
24
+ return opts . success ( data [ page ] ) ;
25
+ } ) ;
26
+ } ;
27
+
8
28
var testutils = {
9
29
createInputElement : function ( c ) {
10
30
var cfg = c || { } ;
@@ -545,4 +565,188 @@ describe("pat-autosuggest", function () {
545
565
expect ( selected . length ) . toBe ( 0 ) ;
546
566
} ) ;
547
567
} ) ;
568
+
569
+ describe ( "6 - AJAX tests" , function ( ) {
570
+ it ( "6.1 - AJAX works with a simple data structure." , async function ( ) {
571
+ mock_fetch_ajax (
572
+ [
573
+ { id : "1" , text : "apple" } ,
574
+ { id : "2" , text : "orange" } ,
575
+ ] // Note the trailing comma to make the multi-argument dereferencing work.
576
+ ) ;
577
+
578
+ document . body . innerHTML = `
579
+ <input
580
+ type="text"
581
+ class="pat-autosuggest"
582
+ data-pat-autosuggest="
583
+ ajax-url: http://test.org/test;
584
+ ajax-timeout: 1;
585
+ " />
586
+ ` ;
587
+
588
+ const input = document . querySelector ( "input" ) ;
589
+ new pattern ( input ) ;
590
+ await utils . timeout ( 1 ) ; // wait a tick for async to settle.
591
+
592
+ $ ( ".select2-input" ) . click ( ) ;
593
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
594
+
595
+ const results = $ ( document . querySelectorAll ( ".select2-results li" ) ) ;
596
+ expect ( results . length ) . toBe ( 2 ) ;
597
+
598
+ $ ( results [ 0 ] ) . mouseup ( ) ;
599
+
600
+ const selected = document . querySelectorAll ( ".select2-search-choice" ) ;
601
+ expect ( selected . length ) . toBe ( 1 ) ;
602
+ expect ( selected [ 0 ] . textContent . trim ( ) ) . toBe ( "apple" ) ;
603
+ expect ( input . value ) . toBe ( "1" ) ;
604
+ } ) ;
605
+
606
+ // This test is so flaky, just skip it if it fails.
607
+ it . skip . failing ( "6.2 - AJAX works with batches." , async function ( ) {
608
+ mock_fetch_ajax (
609
+ [
610
+ { id : "1" , text : "one" } ,
611
+ { id : "2" , text : "two" } ,
612
+ { id : "3" , text : "three" } ,
613
+ { id : "4" , text : "four" } ,
614
+ ] ,
615
+ [
616
+ { id : "5" , text : "five" } ,
617
+ { id : "6" , text : "six" } ,
618
+ ] ,
619
+ [ { id : "7" , text : "seven" } ]
620
+ ) ;
621
+
622
+ document . body . innerHTML = `
623
+ <input
624
+ type="text"
625
+ class="pat-autosuggest"
626
+ data-pat-autosuggest="
627
+ ajax-url: http://test.org/test;
628
+ ajax-timeout: 1;
629
+ max-initial-size: 4;
630
+ ajax-batch-size: 2;
631
+ " />
632
+ ` ;
633
+
634
+ const input = document . querySelector ( "input" ) ;
635
+ new pattern ( input ) ;
636
+ await utils . timeout ( 1 ) ; // wait a tick for async to settle.
637
+
638
+ // Load batch 1 with batch size 4
639
+ $ ( ".select2-input" ) . click ( ) ;
640
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
641
+
642
+ const results_1 = $ (
643
+ document . querySelectorAll ( ".select2-results .select2-result" )
644
+ ) ;
645
+ expect ( results_1 . length ) . toBe ( 4 ) ;
646
+
647
+ const load_more_1 = $ (
648
+ document . querySelectorAll ( ".select2-results .select2-more-results" )
649
+ ) ;
650
+ expect ( load_more_1 . length ) . toBe ( 1 ) ;
651
+
652
+ // Load batch 2 with batch size 2
653
+ $ ( load_more_1 [ 0 ] ) . mouseup ( ) ;
654
+ // NOTE: Flaky behavior needs multiple timeouts 👌
655
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
656
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
657
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
658
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
659
+
660
+ const results_2 = $ (
661
+ document . querySelectorAll ( ".select2-results .select2-result" )
662
+ ) ;
663
+ console . log ( document . body . innerHTML ) ;
664
+ expect ( results_2 . length ) . toBe ( 6 ) ;
665
+
666
+ const load_more_2 = $ (
667
+ document . querySelectorAll ( ".select2-results .select2-more-results" )
668
+ ) ;
669
+ expect ( load_more_2 . length ) . toBe ( 1 ) ;
670
+
671
+ // Load final batch 2
672
+ $ ( load_more_2 [ 0 ] ) . mouseup ( ) ;
673
+ // NOTE: Flaky behavior needs multiple timeouts 🤘
674
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
675
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
676
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
677
+ await utils . timeout ( 1 ) ; // wait for ajax to finish.
678
+
679
+ const results_3 = $ (
680
+ document . querySelectorAll ( ".select2-results .select2-result" )
681
+ ) ;
682
+ expect ( results_3 . length ) . toBe ( 7 ) ;
683
+
684
+ const load_more_3 = $ (
685
+ document . querySelectorAll ( ".select2-results .select2-more-results" )
686
+ ) ;
687
+ expect ( load_more_3 . length ) . toBe ( 0 ) ;
688
+ } ) ;
689
+
690
+ describe ( "6.3 - Test the page_limit logic." , function ( ) {
691
+
692
+ it ( "6.3.1 - page_limit set only by ajax-batch-size." , async function ( ) {
693
+ document . body . innerHTML = `
694
+ <input
695
+ type="text"
696
+ class="pat-autosuggest"
697
+ data-pat-autosuggest="
698
+ ajax-url: http://test.org/test;
699
+ ajax-batch-size: 2;
700
+ " />
701
+ ` ;
702
+
703
+ const input = document . querySelector ( "input" ) ;
704
+ const instance = new pattern ( input ) ;
705
+ await utils . timeout ( 1 ) ; // wait a tick for async to settle.
706
+
707
+ expect ( instance . page_limit ( 1 ) ) . toBe ( 10 ) ;
708
+ expect ( instance . page_limit ( 2 ) ) . toBe ( 2 ) ;
709
+ } ) ;
710
+
711
+ it ( "6.3.2 - page_limit set by ajax-batch-size and max-initial-size." , async function ( ) {
712
+ document . body . innerHTML = `
713
+ <input
714
+ type="text"
715
+ class="pat-autosuggest"
716
+ data-pat-autosuggest="
717
+ ajax-url: http://test.org/test;
718
+ ajax-batch-size: 2;
719
+ max-initial-size: 4;
720
+ " />
721
+ ` ;
722
+
723
+ const input = document . querySelector ( "input" ) ;
724
+ const instance = new pattern ( input ) ;
725
+ await utils . timeout ( 1 ) ; // wait a tick for async to settle.
726
+
727
+ expect ( instance . page_limit ( 1 ) ) . toBe ( 4 ) ;
728
+ expect ( instance . page_limit ( 2 ) ) . toBe ( 2 ) ;
729
+ } ) ;
730
+
731
+ it ( "6.3.3 - page_limit set only by max-initial-size and batching not activated." , async function ( ) {
732
+ document . body . innerHTML = `
733
+ <input
734
+ type="text"
735
+ class="pat-autosuggest"
736
+ data-pat-autosuggest="
737
+ ajax-url: http://test.org/test;
738
+ max-initial-size: 4;
739
+ " />
740
+ ` ;
741
+
742
+ const input = document . querySelector ( "input" ) ;
743
+ const instance = new pattern ( input ) ;
744
+ await utils . timeout ( 1 ) ; // wait a tick for async to settle.
745
+
746
+ expect ( instance . page_limit ( 1 ) ) . toBe ( 4 ) ;
747
+ expect ( instance . page_limit ( 2 ) ) . toBe ( 0 ) ;
748
+ } ) ;
749
+
750
+ } ) ;
751
+ } ) ;
548
752
} ) ;
0 commit comments