github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/model/search_params_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package model 5 6 import ( 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestSplitWords(t *testing.T) { 15 for _, testCase := range []struct { 16 Name string 17 Input string 18 19 Output []string 20 }{ 21 { 22 Name: "string is empty, output should be empty", 23 Input: "", 24 Output: []string{}, 25 }, 26 { 27 Name: "string is only spaces, output should be empty", 28 Input: " ", 29 Output: []string{}, 30 }, 31 { 32 Name: "string is a single word, output should be one word length", 33 Input: "word", 34 Output: []string{"word"}, 35 }, 36 { 37 Name: "string has a single \" character, output should be two words", 38 Input: "wo\"rd", 39 Output: []string{"wo", "\"rd"}, 40 }, 41 { 42 Name: "string has multiple \" characters, output should be two words", 43 Input: "wo\"rd\"", 44 Output: []string{"wo", "\"rd\""}, 45 }, 46 { 47 Name: "string has multiple \" characters and a -, output should be two words", 48 Input: "wo-\"rd\"", 49 Output: []string{"wo", "-\"rd\""}, 50 }, 51 { 52 Name: "string has multiple words, output should be 3 words", 53 Input: "word1 word2 word3", 54 Output: []string{"word1", "word2", "word3"}, 55 }, 56 { 57 Name: "string has multiple words with a \" in the middle, output should be 3 words", 58 Input: "word1 \"word2 word3", 59 Output: []string{"word1", "\"word2", "word3"}, 60 }, 61 { 62 Name: "string has multiple words with a \" at the start, output should be 3 words", 63 Input: "\"word1 word2 word3", 64 Output: []string{"\"word1", "word2", "word3"}, 65 }, 66 { 67 Name: "string has multiple words with a \" at the end, output should be 3 words and a \"", 68 Input: "word1 word2 word3\"", 69 Output: []string{"word1", "word2", "word3", "\""}, 70 }, 71 { 72 Name: "string has multiple words with # as a prefix, output should be 3 words and prefixes kept", 73 Input: "word1 #word2 ##word3", 74 Output: []string{"word1", "#word2", "##word3"}, 75 }, 76 { 77 Name: "string has multiple words with multiple space between them, output should still be 3 words", 78 Input: " word1 word2 word3", 79 Output: []string{"word1", "word2", "word3"}, 80 }, 81 { 82 Name: "string has a quoted word, output should also be quoted", 83 Input: "\"quoted\"", 84 Output: []string{"\"quoted\""}, 85 }, 86 { 87 Name: "string has a quoted word with a - prefix, output should also be quoted with the same prefix", 88 Input: "-\"quoted\"", 89 Output: []string{"-\"quoted\""}, 90 }, 91 { 92 Name: "string has multiple quoted words, output should not be splitted and quotes should be kept", 93 Input: "\"quoted multiple words\"", 94 Output: []string{"\"quoted multiple words\""}, 95 }, 96 { 97 Name: "string has a mix of qouted words and non quoted words, output should contain 5 entries, quoted words should not be split", 98 Input: "some stuff \"quoted multiple words\" more stuff", 99 Output: []string{"some", "stuff", "\"quoted multiple words\"", "more", "stuff"}, 100 }, 101 { 102 Name: "string has a mix of qouted words with a - prefix and non quoted words, output should contain 5 entries, quoted words should not be split, - should be kept", 103 Input: "some stuff -\"quoted multiple words\" more stuff", 104 Output: []string{"some", "stuff", "-\"quoted multiple words\"", "more", "stuff"}, 105 }, 106 { 107 Name: "string has a mix of multiple qouted words with a - prefix and non quoted words including a # character, output should contain 5 entries, quoted words should not be split, # and - should be kept", 108 Input: "some \"stuff\" \"quoted multiple words\" #some \"more stuff\"", 109 Output: []string{"some", "\"stuff\"", "\"quoted multiple words\"", "#some", "\"more stuff\""}, 110 }, 111 } { 112 t.Run(testCase.Name, func(t *testing.T) { 113 assert.Equal(t, testCase.Output, splitWords(testCase.Input)) 114 }) 115 } 116 117 } 118 119 func TestParseSearchFlags2(t *testing.T) { 120 for _, testCase := range []struct { 121 Name string 122 Input string 123 124 Words []searchWord 125 Flags []flag 126 }{ 127 { 128 Name: "string is empty", 129 Input: "", 130 Words: []searchWord{}, 131 Flags: []flag{}, 132 }, 133 { 134 Name: "string is a single word", 135 Input: "word", 136 Words: []searchWord{ 137 { 138 value: "word", 139 exclude: false, 140 }, 141 }, 142 Flags: []flag{}, 143 }, 144 { 145 Name: "string is a single word with a - prefix", 146 Input: "-word", 147 Words: []searchWord{ 148 { 149 value: "word", 150 exclude: true, 151 }, 152 }, 153 Flags: []flag{}, 154 }, 155 { 156 Name: "string is multiple words all with - prefix", 157 Input: "-apple -banana -cherry", 158 Words: []searchWord{ 159 { 160 value: "apple", 161 exclude: true, 162 }, 163 { 164 value: "banana", 165 exclude: true, 166 }, 167 { 168 value: "cherry", 169 exclude: true, 170 }, 171 }, 172 Flags: []flag{}, 173 }, 174 { 175 Name: "string is multiple words with a single - prefix", 176 Input: "apple -banana cherry", 177 Words: []searchWord{ 178 { 179 value: "apple", 180 exclude: false, 181 }, 182 { 183 value: "banana", 184 exclude: true, 185 }, 186 { 187 value: "cherry", 188 exclude: false, 189 }, 190 }, 191 Flags: []flag{}, 192 }, 193 { 194 Name: "string is multiple words containing a flag", 195 Input: "apple banana from:chan", 196 Words: []searchWord{ 197 { 198 value: "apple", 199 exclude: false, 200 }, 201 { 202 value: "banana", 203 exclude: false, 204 }, 205 }, 206 Flags: []flag{ 207 { 208 name: "from", 209 value: "chan", 210 }, 211 }, 212 }, 213 { 214 Name: "string is multiple words containing a flag and a - prefix", 215 Input: "apple -banana from:chan", 216 Words: []searchWord{ 217 { 218 value: "apple", 219 exclude: false, 220 }, 221 { 222 value: "banana", 223 exclude: true, 224 }, 225 }, 226 Flags: []flag{ 227 { 228 name: "from", 229 value: "chan", 230 }, 231 }, 232 }, 233 { 234 Name: "string is multiple words containing a flag and multiple - prefixes", 235 Input: "-apple -banana from:chan", 236 Words: []searchWord{ 237 { 238 value: "apple", 239 exclude: true, 240 }, 241 { 242 value: "banana", 243 exclude: true, 244 }, 245 }, 246 Flags: []flag{ 247 { 248 name: "from", 249 value: "chan", 250 }, 251 }, 252 }, 253 { 254 Name: "string is multiple words containing a flag and multiple # prefixes", 255 Input: "#apple #banana from:chan", 256 Words: []searchWord{ 257 { 258 value: "#apple", 259 exclude: false, 260 }, 261 { 262 value: "#banana", 263 exclude: false, 264 }, 265 }, 266 Flags: []flag{ 267 { 268 name: "from", 269 value: "chan", 270 }, 271 }, 272 }, 273 { 274 Name: "string is multiple words containing a flag with a single - and multiple # prefixes", 275 Input: "-#apple #banana from:chan", 276 Words: []searchWord{ 277 { 278 value: "#apple", 279 exclude: true, 280 }, 281 { 282 value: "#banana", 283 exclude: false, 284 }, 285 }, 286 Flags: []flag{ 287 { 288 name: "from", 289 value: "chan", 290 }, 291 }, 292 }, 293 { 294 Name: "string is multiple words containing a flag prefixed with - and multiple # prefixes", 295 Input: "#apple #banana -from:chan", 296 Words: []searchWord{ 297 { 298 value: "#apple", 299 exclude: false, 300 }, 301 { 302 value: "#banana", 303 exclude: false, 304 }, 305 }, 306 Flags: []flag{ 307 { 308 name: "from", 309 value: "chan", 310 exclude: true, 311 }, 312 }, 313 }, 314 { 315 Name: "string is multiple words containing a flag prefixed with multiple - and multiple # prefixes", 316 Input: "-#apple -#banana -from:chan", 317 Words: []searchWord{ 318 { 319 value: "#apple", 320 exclude: true, 321 }, 322 { 323 value: "#banana", 324 exclude: true, 325 }, 326 }, 327 Flags: []flag{ 328 { 329 name: "from", 330 value: "chan", 331 exclude: true, 332 }, 333 }, 334 }, 335 { 336 Name: "string is multiple words containing a flag with a space", 337 Input: "apple banana from: chan", 338 Words: []searchWord{ 339 { 340 value: "apple", 341 exclude: false, 342 }, 343 { 344 value: "banana", 345 exclude: false, 346 }, 347 }, 348 Flags: []flag{ 349 { 350 name: "from", 351 value: "chan", 352 }, 353 }, 354 }, 355 { 356 Name: "string is multiple words containing a in flag with a space", 357 Input: "apple banana in: chan", 358 Words: []searchWord{ 359 { 360 value: "apple", 361 exclude: false, 362 }, 363 { 364 value: "banana", 365 exclude: false, 366 }, 367 }, 368 Flags: []flag{ 369 { 370 name: "in", 371 value: "chan", 372 }, 373 }, 374 }, 375 { 376 Name: "string is multiple words containing a channel flag with a space", 377 Input: "apple banana channel: chan", 378 Words: []searchWord{ 379 { 380 value: "apple", 381 exclude: false, 382 }, 383 { 384 value: "banana", 385 exclude: false, 386 }, 387 }, 388 Flags: []flag{ 389 { 390 name: "channel", 391 value: "chan", 392 }, 393 }, 394 }, 395 { 396 Name: "string with a non-floag followed by :", 397 Input: "fruit: cherry", 398 Words: []searchWord{ 399 { 400 value: "fruit", 401 exclude: false, 402 }, 403 { 404 value: "cherry", 405 exclude: false, 406 }, 407 }, 408 Flags: []flag{}, 409 }, 410 { 411 Name: "string with the a flag but without the value for that flag should be threaded as a word", 412 Input: "channel:", 413 Words: []searchWord{ 414 { 415 value: "channel", 416 exclude: false, 417 }, 418 }, 419 Flags: []flag{}, 420 }, 421 { 422 Name: "string is a single flag which results in a single flag", 423 Input: "channel:first", 424 Words: []searchWord{}, 425 Flags: []flag{ 426 { 427 name: "channel", 428 value: "first", 429 }, 430 }, 431 }, 432 { 433 Name: "single flag with - which results in a excluded flag", 434 Input: "-channel:first", 435 Words: []searchWord{}, 436 Flags: []flag{ 437 { 438 name: "channel", 439 value: "first", 440 exclude: true, 441 }, 442 }, 443 }, 444 { 445 Name: "string is multiple flags which results in multiple unexcluded flags and a single search word", 446 Input: "channel: first in: second from:", 447 Words: []searchWord{ 448 { 449 value: "from", 450 exclude: false, 451 }, 452 }, 453 Flags: []flag{ 454 { 455 name: "channel", 456 value: "first", 457 exclude: false, 458 }, 459 { 460 name: "in", 461 value: "second", 462 exclude: false, 463 }, 464 }, 465 }, 466 { 467 Name: "string is multiple flags which results in multiple unexcluded and excluded flags and a single search word", 468 Input: "channel: first -in: second from:", 469 Words: []searchWord{ 470 { 471 value: "from", 472 exclude: false, 473 }, 474 }, 475 Flags: []flag{ 476 { 477 name: "channel", 478 value: "first", 479 exclude: false, 480 }, 481 { 482 name: "in", 483 value: "second", 484 exclude: true, 485 }, 486 }, 487 }, 488 { 489 Name: "string is multiple flags which results in multiple excluded and unexcluded flags and a single search word", 490 Input: "-channel: first in: second from:", 491 Words: []searchWord{ 492 { 493 value: "from", 494 exclude: false, 495 }, 496 }, 497 Flags: []flag{ 498 { 499 name: "channel", 500 value: "first", 501 exclude: true, 502 }, 503 { 504 name: "in", 505 value: "second", 506 exclude: false, 507 }, 508 }, 509 }, 510 { 511 Name: "string is four flags which results four unexcluded flags", 512 Input: "channel: first channel: second from: third from: fourth", 513 Words: []searchWord{}, 514 Flags: []flag{ 515 { 516 name: "channel", 517 value: "first", 518 exclude: false, 519 }, 520 { 521 name: "channel", 522 value: "second", 523 exclude: false, 524 }, 525 { 526 name: "from", 527 value: "third", 528 exclude: false, 529 }, 530 { 531 name: "from", 532 value: "fourth", 533 exclude: false, 534 }, 535 }, 536 }, 537 { 538 Name: "string is a single quoted flag which results in a single search word which is quoted", 539 Input: "\"quoted\"", 540 Words: []searchWord{ 541 { 542 value: "\"quoted\"", 543 exclude: false, 544 }, 545 }, 546 Flags: []flag{}, 547 }, 548 { 549 Name: "string is a single quoted flag prefixed with a - which results in a single search word which is quoted", 550 Input: "\"-quoted\"", 551 Words: []searchWord{ 552 { 553 value: "\"-quoted\"", 554 exclude: false, 555 }, 556 }, 557 Flags: []flag{}, 558 }, 559 { 560 Name: "string is a single quoted flag prefixed with a - which results in a single search word which is quoted and exported", 561 Input: "-\"quoted\"", 562 Words: []searchWord{ 563 { 564 value: "\"quoted\"", 565 exclude: true, 566 }, 567 }, 568 Flags: []flag{}, 569 }, 570 { 571 Name: "string is multiple quoted flags which results in a single search word which is quoted and unexported", 572 Input: "\"quoted multiple words\"", 573 Words: []searchWord{ 574 { 575 value: "\"quoted multiple words\"", 576 exclude: false, 577 }, 578 }, 579 Flags: []flag{}, 580 }, 581 { 582 Name: "string is multiple quoted flags prefixed with - which results in a single search word which is quoted and unexported", 583 Input: "\"quoted -multiple words\"", 584 Words: []searchWord{ 585 { 586 value: "\"quoted -multiple words\"", 587 exclude: false, 588 }, 589 }, 590 Flags: []flag{}, 591 }, 592 { 593 Name: "string is multiple quoted flags and unquoted words", 594 Input: "some \"stuff\" \"quoted multiple words\" some \"more stuff\"", 595 Words: []searchWord{ 596 { 597 value: "some", 598 exclude: false, 599 }, 600 { 601 value: "\"stuff\"", 602 exclude: false, 603 }, 604 { 605 value: "\"quoted multiple words\"", 606 exclude: false, 607 }, 608 { 609 value: "some", 610 exclude: false, 611 }, 612 { 613 value: "\"more stuff\"", 614 exclude: false, 615 }, 616 }, 617 Flags: []flag{}, 618 }, 619 { 620 Name: "string is multiple quoted flags and unquoted words some being prefixed with -", 621 Input: "some -\"stuff\" \"quoted multiple words\" some -\"more stuff\"", 622 Words: []searchWord{ 623 { 624 value: "some", 625 exclude: false, 626 }, 627 { 628 value: "\"stuff\"", 629 exclude: true, 630 }, 631 { 632 value: "\"quoted multiple words\"", 633 exclude: false, 634 }, 635 { 636 value: "some", 637 exclude: false, 638 }, 639 { 640 value: "\"more stuff\"", 641 exclude: true, 642 }, 643 }, 644 Flags: []flag{}, 645 }, 646 { 647 Name: "string is multiple quoted flags and unquoted words some being flags", 648 Input: "some in:here \"stuff\" \"quoted multiple words\" from:someone \"more stuff\"", 649 Words: []searchWord{ 650 { 651 value: "some", 652 exclude: false, 653 }, 654 { 655 value: "\"stuff\"", 656 exclude: false, 657 }, 658 { 659 value: "\"quoted multiple words\"", 660 exclude: false, 661 }, 662 { 663 value: "\"more stuff\"", 664 exclude: false, 665 }, 666 }, 667 Flags: []flag{ 668 { 669 name: "in", 670 value: "here", 671 exclude: false, 672 }, 673 { 674 name: "from", 675 value: "someone", 676 exclude: false, 677 }, 678 }, 679 }, 680 { 681 Name: "string is a single flag with multiple -", 682 Input: "after:2018-1-1", 683 Words: []searchWord{}, 684 Flags: []flag{ 685 { 686 name: "after", 687 value: "2018-1-1", 688 exclude: false, 689 }, 690 }, 691 }, 692 { 693 Name: "string is a single flag with multiple - prefixed with a -", 694 Input: "-after:2018-1-1", 695 Words: []searchWord{}, 696 Flags: []flag{ 697 { 698 name: "after", 699 value: "2018-1-1", 700 exclude: true, 701 }, 702 }, 703 }, 704 { 705 Name: "string is a single flag with multiple - prefixed with two words", 706 Input: "apple banana before:2018-1-1", 707 Words: []searchWord{ 708 { 709 value: "apple", 710 exclude: false, 711 }, 712 { 713 value: "banana", 714 exclude: false, 715 }, 716 }, 717 Flags: []flag{ 718 { 719 name: "before", 720 value: "2018-1-1", 721 exclude: false, 722 }, 723 }, 724 }, 725 { 726 Name: "string is a single before flag with multiple - prefixed with - and two words", 727 Input: "apple banana -before:2018-1-1", 728 Words: []searchWord{ 729 { 730 value: "apple", 731 exclude: false, 732 }, 733 { 734 value: "banana", 735 exclude: false, 736 }, 737 }, 738 Flags: []flag{ 739 { 740 name: "before", 741 value: "2018-1-1", 742 exclude: true, 743 }, 744 }, 745 }, 746 { 747 Name: "string is multiple before/after flags with two words before", 748 Input: "apple banana after:2018-1-1 before:2018-1-10", 749 Words: []searchWord{ 750 { 751 value: "apple", 752 exclude: false, 753 }, 754 { 755 value: "banana", 756 exclude: false, 757 }, 758 }, 759 Flags: []flag{ 760 { 761 name: "after", 762 value: "2018-1-1", 763 exclude: false, 764 }, 765 { 766 name: "before", 767 value: "2018-1-10", 768 exclude: false, 769 }, 770 }, 771 }, 772 { 773 Name: "string is multiple before/after flags prefixed with - with two words before", 774 Input: "apple banana -after:2018-1-1 -before:2018-1-10", 775 Words: []searchWord{ 776 { 777 value: "apple", 778 exclude: false, 779 }, 780 { 781 value: "banana", 782 exclude: false, 783 }, 784 }, 785 Flags: []flag{ 786 { 787 name: "after", 788 value: "2018-1-1", 789 exclude: true, 790 }, 791 { 792 name: "before", 793 value: "2018-1-10", 794 exclude: true, 795 }, 796 }, 797 }, 798 { 799 Name: "string is a single after flag with two words before which are prefixed with #", 800 Input: "#apple #banana after:2018-1-1", 801 Words: []searchWord{ 802 { 803 value: "#apple", 804 exclude: false, 805 }, 806 { 807 value: "#banana", 808 exclude: false, 809 }, 810 }, 811 Flags: []flag{ 812 { 813 name: "after", 814 value: "2018-1-1", 815 exclude: false, 816 }, 817 }, 818 }, 819 { 820 Name: "string is a single after flag with two words before which are prefixed with #", 821 Input: "#apple #banana before:2018-1-1", 822 Words: []searchWord{ 823 { 824 value: "#apple", 825 exclude: false, 826 }, 827 { 828 value: "#banana", 829 exclude: false, 830 }, 831 }, 832 Flags: []flag{ 833 { 834 name: "before", 835 value: "2018-1-1", 836 exclude: false, 837 }, 838 }, 839 }, 840 { 841 Name: "string is two after and before flags with two words before which are prefixed with #", 842 Input: "#apple #banana after:2018-1-1 before:2018-1-10", 843 Words: []searchWord{ 844 { 845 value: "#apple", 846 exclude: false, 847 }, 848 { 849 value: "#banana", 850 exclude: false, 851 }, 852 }, 853 Flags: []flag{ 854 { 855 name: "after", 856 value: "2018-1-1", 857 exclude: false, 858 }, 859 { 860 name: "before", 861 value: "2018-1-10", 862 exclude: false, 863 }, 864 }, 865 }, 866 { 867 Name: "string is a single after flag with two words before", 868 Input: "apple banana after: 2018-1-1", 869 Words: []searchWord{ 870 { 871 value: "apple", 872 exclude: false, 873 }, 874 { 875 value: "banana", 876 exclude: false, 877 }, 878 }, 879 Flags: []flag{ 880 { 881 name: "after", 882 value: "2018-1-1", 883 exclude: false, 884 }, 885 }, 886 }, 887 { 888 Name: "string is a single before flag with two words before", 889 Input: "apple banana before: 2018-1-1", 890 Words: []searchWord{ 891 { 892 value: "apple", 893 exclude: false, 894 }, 895 { 896 value: "banana", 897 exclude: false, 898 }, 899 }, 900 Flags: []flag{ 901 { 902 name: "before", 903 value: "2018-1-1", 904 exclude: false, 905 }, 906 }, 907 }, 908 { 909 Name: "string is two after and before flags with two words before", 910 Input: "apple banana after: 2018-1-1 before: 2018-1-10", 911 Words: []searchWord{ 912 { 913 value: "apple", 914 exclude: false, 915 }, 916 { 917 value: "banana", 918 exclude: false, 919 }, 920 }, 921 Flags: []flag{ 922 { 923 name: "after", 924 value: "2018-1-1", 925 exclude: false, 926 }, 927 { 928 name: "before", 929 value: "2018-1-10", 930 exclude: false, 931 }, 932 }, 933 }, 934 { 935 Name: "string is two after and before flags with two words before and a single after", 936 Input: "apple banana after: 2018-1-1 before: 2018-1-10 #fruit", 937 Words: []searchWord{ 938 { 939 value: "apple", 940 exclude: false, 941 }, 942 { 943 value: "banana", 944 exclude: false, 945 }, 946 { 947 value: "#fruit", 948 exclude: false, 949 }, 950 }, 951 Flags: []flag{ 952 { 953 name: "after", 954 value: "2018-1-1", 955 exclude: false, 956 }, 957 { 958 name: "before", 959 value: "2018-1-10", 960 exclude: false, 961 }, 962 }, 963 }, 964 { 965 Name: "string is one after flag with one word before", 966 Input: "test after:2018-7-1", 967 Words: []searchWord{ 968 { 969 value: "test", 970 exclude: false, 971 }, 972 }, 973 Flags: []flag{ 974 { 975 name: "after", 976 value: "2018-7-1", 977 exclude: false, 978 }, 979 }, 980 }, 981 { 982 Name: "string is one on flag with one word before", 983 Input: "test on:2018-7-1", 984 Words: []searchWord{ 985 { 986 value: "test", 987 exclude: false, 988 }, 989 }, 990 Flags: []flag{ 991 { 992 name: "on", 993 value: "2018-7-1", 994 exclude: false, 995 }, 996 }, 997 }, 998 { 999 Name: "string is one excluded on flag with one word after", 1000 Input: "-on:2018-7-1 test", 1001 Words: []searchWord{ 1002 { 1003 value: "test", 1004 exclude: false, 1005 }, 1006 }, 1007 Flags: []flag{ 1008 { 1009 name: "on", 1010 value: "2018-7-1", 1011 exclude: true, 1012 }, 1013 }, 1014 }, 1015 } { 1016 t.Run(testCase.Name, func(t *testing.T) { 1017 words, flags := parseSearchFlags(splitWords(testCase.Input)) 1018 require.Equal(t, testCase.Words, words) 1019 require.Equal(t, testCase.Flags, flags) 1020 }) 1021 } 1022 } 1023 1024 func TestParseSearchParams(t *testing.T) { 1025 for _, testCase := range []struct { 1026 Name string 1027 Input string 1028 1029 Output []*SearchParams 1030 }{ 1031 { 1032 Name: "input is empty should result in no params", 1033 Input: "", 1034 Output: []*SearchParams{}, 1035 }, 1036 { 1037 Name: "input is only spaces should result in no params", 1038 Input: " ", 1039 Output: []*SearchParams{}, 1040 }, 1041 { 1042 Name: "input is two words should result in one param", 1043 Input: "words words", 1044 Output: []*SearchParams{ 1045 { 1046 Terms: "words words", 1047 ExcludedTerms: "", 1048 IsHashtag: false, 1049 InChannels: []string{}, 1050 ExcludedChannels: []string{}, 1051 FromUsers: []string{}, 1052 ExcludedUsers: []string{}, 1053 }, 1054 }, 1055 }, 1056 { 1057 Name: "input is two words should result in one param with two excluded terms", 1058 Input: "-word1 -word2", 1059 Output: []*SearchParams{ 1060 { 1061 Terms: "", 1062 ExcludedTerms: "word1 word2", 1063 IsHashtag: false, 1064 InChannels: []string{}, 1065 ExcludedChannels: []string{}, 1066 FromUsers: []string{}, 1067 ExcludedUsers: []string{}, 1068 }, 1069 }, 1070 }, 1071 { 1072 Name: "input is two quoted words should result in one term", 1073 Input: "\"my stuff\"", 1074 Output: []*SearchParams{ 1075 { 1076 Terms: "\"my stuff\"", 1077 ExcludedTerms: "", 1078 IsHashtag: false, 1079 InChannels: []string{}, 1080 ExcludedChannels: []string{}, 1081 FromUsers: []string{}, 1082 ExcludedUsers: []string{}, 1083 }, 1084 }, 1085 }, 1086 { 1087 Name: "input is two quoted words should result in one excluded term", 1088 Input: "-\"my stuff\"", 1089 Output: []*SearchParams{ 1090 { 1091 Terms: "", 1092 ExcludedTerms: "\"my stuff\"", 1093 IsHashtag: false, 1094 InChannels: []string{}, 1095 ExcludedChannels: []string{}, 1096 FromUsers: []string{}, 1097 ExcludedUsers: []string{}, 1098 }, 1099 }, 1100 }, 1101 { 1102 Name: "input is two words prefixed with hashtags should result in one term", 1103 Input: "#words #words", 1104 Output: []*SearchParams{ 1105 { 1106 Terms: "#words #words", 1107 ExcludedTerms: "", 1108 IsHashtag: true, 1109 InChannels: []string{}, 1110 ExcludedChannels: []string{}, 1111 FromUsers: []string{}, 1112 ExcludedUsers: []string{}, 1113 }, 1114 }, 1115 }, 1116 { 1117 Name: "input is two words one is prefixed with a hashtag should result in two terms", 1118 Input: "#words words", 1119 Output: []*SearchParams{ 1120 { 1121 Terms: "words", 1122 ExcludedTerms: "", 1123 IsHashtag: false, 1124 InChannels: []string{}, 1125 ExcludedChannels: []string{}, 1126 FromUsers: []string{}, 1127 ExcludedUsers: []string{}, 1128 }, 1129 { 1130 Terms: "#words", 1131 ExcludedTerms: "", 1132 IsHashtag: true, 1133 InChannels: []string{}, 1134 ExcludedChannels: []string{}, 1135 FromUsers: []string{}, 1136 ExcludedUsers: []string{}, 1137 }, 1138 }, 1139 }, 1140 { 1141 Name: "input is one word prefixed with hashtag and a dash should result in one excluded term", 1142 Input: "-#hashtag", 1143 Output: []*SearchParams{ 1144 { 1145 Terms: "", 1146 ExcludedTerms: "#hashtag", 1147 IsHashtag: true, 1148 InChannels: []string{}, 1149 ExcludedChannels: []string{}, 1150 FromUsers: []string{}, 1151 ExcludedUsers: []string{}, 1152 }, 1153 }, 1154 }, 1155 { 1156 Name: "input is two words prefixed with hashtags and dashes should result in excluded term", 1157 Input: "-#hashtag1 -#hashtag2", 1158 Output: []*SearchParams{ 1159 { 1160 Terms: "", 1161 ExcludedTerms: "#hashtag1 #hashtag2", 1162 IsHashtag: true, 1163 InChannels: []string{}, 1164 ExcludedChannels: []string{}, 1165 FromUsers: []string{}, 1166 ExcludedUsers: []string{}, 1167 }, 1168 }, 1169 }, 1170 { 1171 Name: "input is two words prefixed with hashtags and one dash should result in excluded and nonexcluded term", 1172 Input: "#hashtag1 -#hashtag2", 1173 Output: []*SearchParams{ 1174 { 1175 Terms: "#hashtag1", 1176 ExcludedTerms: "#hashtag2", 1177 IsHashtag: true, 1178 InChannels: []string{}, 1179 ExcludedChannels: []string{}, 1180 FromUsers: []string{}, 1181 ExcludedUsers: []string{}, 1182 }, 1183 }, 1184 }, 1185 { 1186 Name: "input is 4 words prefixed with hashtags and a dash should result in excluded and nonexcluded multiple SearchParams", 1187 Input: "word1 #hashtag1 -#hashtag2 -word2", 1188 Output: []*SearchParams{ 1189 { 1190 Terms: "word1", 1191 ExcludedTerms: "word2", 1192 IsHashtag: false, 1193 InChannels: []string{}, 1194 ExcludedChannels: []string{}, 1195 FromUsers: []string{}, 1196 ExcludedUsers: []string{}, 1197 }, 1198 { 1199 Terms: "#hashtag1", 1200 ExcludedTerms: "#hashtag2", 1201 IsHashtag: true, 1202 InChannels: []string{}, 1203 ExcludedChannels: []string{}, 1204 FromUsers: []string{}, 1205 ExcludedUsers: []string{}, 1206 }, 1207 }, 1208 }, 1209 { 1210 Name: "input is two words seperated with : and should result in a single InChannel", 1211 Input: "in:channel", 1212 Output: []*SearchParams{ 1213 { 1214 Terms: "", 1215 ExcludedTerms: "", 1216 IsHashtag: false, 1217 InChannels: []string{"channel"}, 1218 ExcludedChannels: []string{}, 1219 FromUsers: []string{}, 1220 ExcludedUsers: []string{}, 1221 }, 1222 }, 1223 }, 1224 { 1225 Name: "input is two words seperated with :, prefied with - and should result in a single ExcludedChannel", 1226 Input: "-in:channel", 1227 Output: []*SearchParams{ 1228 { 1229 Terms: "", 1230 ExcludedTerms: "", 1231 IsHashtag: false, 1232 InChannels: []string{}, 1233 ExcludedChannels: []string{"channel"}, 1234 FromUsers: []string{}, 1235 ExcludedUsers: []string{}, 1236 }, 1237 }, 1238 }, 1239 { 1240 Name: "input is two words seperated with : with a prefixed word should result in a single InChannel and a term", 1241 Input: "testing in:channel", 1242 Output: []*SearchParams{ 1243 { 1244 Terms: "testing", 1245 ExcludedTerms: "", 1246 IsHashtag: false, 1247 InChannels: []string{"channel"}, 1248 ExcludedChannels: []string{}, 1249 FromUsers: []string{}, 1250 ExcludedUsers: []string{}, 1251 }, 1252 }, 1253 }, 1254 { 1255 Name: "input is two words seperated with : with a prefixed word should result in a single ExcludedChannel and a term", 1256 Input: "testing -in:channel", 1257 Output: []*SearchParams{ 1258 { 1259 Terms: "testing", 1260 ExcludedTerms: "", 1261 IsHashtag: false, 1262 InChannels: []string{}, 1263 ExcludedChannels: []string{"channel"}, 1264 FromUsers: []string{}, 1265 ExcludedUsers: []string{}, 1266 }, 1267 }, 1268 }, 1269 { 1270 Name: "input is two words seperated with : with a postfix word should result in a single InChannel and a term", 1271 Input: "in:channel testing", 1272 Output: []*SearchParams{ 1273 { 1274 Terms: "testing", 1275 ExcludedTerms: "", 1276 IsHashtag: false, 1277 InChannels: []string{"channel"}, 1278 ExcludedChannels: []string{}, 1279 FromUsers: []string{}, 1280 ExcludedUsers: []string{}, 1281 }, 1282 }, 1283 }, 1284 { 1285 Name: "input is four words seperated with : should result in a two InChannels", 1286 Input: "in:channel in:otherchannel", 1287 Output: []*SearchParams{ 1288 { 1289 Terms: "", 1290 ExcludedTerms: "", 1291 IsHashtag: false, 1292 InChannels: []string{"channel", "otherchannel"}, 1293 ExcludedChannels: []string{}, 1294 FromUsers: []string{}, 1295 ExcludedUsers: []string{}, 1296 }, 1297 }, 1298 }, 1299 { 1300 Name: "input is four words seperated with : prefixed with a word should result in two InChannels and one term", 1301 Input: "testing in:channel in:otherchannel", 1302 Output: []*SearchParams{ 1303 { 1304 Terms: "testing", 1305 ExcludedTerms: "", 1306 IsHashtag: false, 1307 InChannels: []string{"channel", "otherchannel"}, 1308 ExcludedChannels: []string{}, 1309 FromUsers: []string{}, 1310 ExcludedUsers: []string{}, 1311 }, 1312 }, 1313 }, 1314 { 1315 Name: "input is four words seperated with : prefixed with a word should result in one InChannel, one FromUser and one term", 1316 Input: "testing in:channel from:someone", 1317 Output: []*SearchParams{ 1318 { 1319 Terms: "testing", 1320 ExcludedTerms: "", 1321 IsHashtag: false, 1322 InChannels: []string{"channel"}, 1323 ExcludedChannels: []string{}, 1324 FromUsers: []string{"someone"}, 1325 ExcludedUsers: []string{}, 1326 }, 1327 }, 1328 }, 1329 { 1330 Name: "input is four words seperated with : prefixed with a word should result in one InChannel, one ExcludedUser and one term", 1331 Input: "testing in:channel -from:someone", 1332 Output: []*SearchParams{ 1333 { 1334 Terms: "testing", 1335 ExcludedTerms: "", 1336 IsHashtag: false, 1337 InChannels: []string{"channel"}, 1338 ExcludedChannels: []string{}, 1339 FromUsers: []string{}, 1340 ExcludedUsers: []string{"someone"}, 1341 }, 1342 }, 1343 }, 1344 { 1345 Name: "input is six words seperated with : prefixed with a word should result in one InChannel, one FromUser, one ExcludedUser and one term", 1346 Input: "testing in:channel from:someone -from:someoneelse", 1347 Output: []*SearchParams{ 1348 { 1349 Terms: "testing", 1350 ExcludedTerms: "", 1351 IsHashtag: false, 1352 InChannels: []string{"channel"}, 1353 ExcludedChannels: []string{}, 1354 FromUsers: []string{"someone"}, 1355 ExcludedUsers: []string{"someoneelse"}, 1356 }, 1357 }, 1358 }, 1359 { 1360 Name: "input is two words first one is prefixed with two #, should result in one term with IsHashtag = true, pluses should be removed", 1361 Input: "##hashtag +#plus+", 1362 Output: []*SearchParams{ 1363 { 1364 Terms: "#hashtag #plus", 1365 ExcludedTerms: "", 1366 IsHashtag: true, 1367 InChannels: []string{}, 1368 ExcludedChannels: []string{}, 1369 FromUsers: []string{}, 1370 ExcludedUsers: []string{}, 1371 }, 1372 }, 1373 }, 1374 { 1375 Name: "input is a wilrdcar with a *, should result in one term with a *", 1376 Input: "wildcar*", 1377 Output: []*SearchParams{ 1378 { 1379 Terms: "wildcar*", 1380 ExcludedTerms: "", 1381 IsHashtag: false, 1382 InChannels: []string{}, 1383 ExcludedChannels: []string{}, 1384 FromUsers: []string{}, 1385 ExcludedUsers: []string{}, 1386 }, 1387 }, 1388 }, 1389 { 1390 Name: "input is an after date with one word, should in one AfterDate and one term", 1391 Input: "after:2018-8-1 testing", 1392 Output: []*SearchParams{ 1393 { 1394 Terms: "testing", 1395 ExcludedTerms: "", 1396 AfterDate: "2018-8-1", 1397 ExcludedAfterDate: "", 1398 InChannels: []string{}, 1399 ExcludedChannels: []string{}, 1400 FromUsers: []string{}, 1401 ExcludedUsers: []string{}, 1402 }, 1403 }, 1404 }, 1405 { 1406 Name: "input is an after date with one word, should in one ExcludedAfterDate and one term", 1407 Input: "-after:2018-8-1 testing", 1408 Output: []*SearchParams{ 1409 { 1410 Terms: "testing", 1411 ExcludedTerms: "", 1412 AfterDate: "", 1413 ExcludedAfterDate: "2018-8-1", 1414 InChannels: []string{}, 1415 ExcludedChannels: []string{}, 1416 FromUsers: []string{}, 1417 ExcludedUsers: []string{}, 1418 }, 1419 }, 1420 }, 1421 { 1422 Name: "input is an on date with one word, should in one OnDate and one term", 1423 Input: "on:2018-8-1 testing", 1424 Output: []*SearchParams{ 1425 { 1426 Terms: "testing", 1427 ExcludedTerms: "", 1428 OnDate: "2018-8-1", 1429 AfterDate: "", 1430 ExcludedAfterDate: "", 1431 InChannels: []string{}, 1432 ExcludedChannels: []string{}, 1433 FromUsers: []string{}, 1434 ExcludedUsers: []string{}, 1435 }, 1436 }, 1437 }, 1438 { 1439 Name: "input is an on date with one word, should in one ExcludedDate and one term", 1440 Input: "-on:2018-8-1 testing", 1441 Output: []*SearchParams{ 1442 { 1443 Terms: "testing", 1444 ExcludedTerms: "", 1445 AfterDate: "", 1446 ExcludedDate: "2018-8-1", 1447 InChannels: []string{}, 1448 ExcludedChannels: []string{}, 1449 FromUsers: []string{}, 1450 ExcludedUsers: []string{}, 1451 }, 1452 }, 1453 }, 1454 { 1455 Name: "input is an after date, should in one AfterDate", 1456 Input: "after:2018-8-1", 1457 Output: []*SearchParams{ 1458 { 1459 Terms: "", 1460 ExcludedTerms: "", 1461 AfterDate: "2018-8-1", 1462 ExcludedDate: "", 1463 InChannels: []string{}, 1464 ExcludedChannels: []string{}, 1465 FromUsers: []string{}, 1466 ExcludedUsers: []string{}, 1467 }, 1468 }, 1469 }, 1470 { 1471 Name: "input is an before date, should in one BeforeDate", 1472 Input: "before:2018-8-1", 1473 Output: []*SearchParams{ 1474 { 1475 Terms: "", 1476 ExcludedTerms: "", 1477 BeforeDate: "2018-8-1", 1478 AfterDate: "", 1479 ExcludedDate: "", 1480 InChannels: []string{}, 1481 ExcludedChannels: []string{}, 1482 FromUsers: []string{}, 1483 ExcludedUsers: []string{}, 1484 }, 1485 }, 1486 }, 1487 { 1488 Name: "input is an before date, should in one ExcludedBeforeDate", 1489 Input: "-before:2018-8-1", 1490 Output: []*SearchParams{ 1491 { 1492 Terms: "", 1493 ExcludedTerms: "", 1494 BeforeDate: "", 1495 AfterDate: "", 1496 ExcludedBeforeDate: "2018-8-1", 1497 InChannels: []string{}, 1498 ExcludedChannels: []string{}, 1499 FromUsers: []string{}, 1500 ExcludedUsers: []string{}, 1501 }, 1502 }, 1503 }, 1504 } { 1505 t.Run(testCase.Name, func(t *testing.T) { 1506 require.Equal(t, testCase.Output, ParseSearchParams(testCase.Input, 0)) 1507 }) 1508 } 1509 } 1510 1511 func TestGetOnDateMillis(t *testing.T) { 1512 for _, testCase := range []struct { 1513 Name string 1514 Input string 1515 StartOnDate int64 1516 EndOnDate int64 1517 }{ 1518 { 1519 Name: "Valid date", 1520 Input: "2018-08-01", 1521 StartOnDate: 1533081600000, 1522 EndOnDate: 1533167999999, 1523 }, 1524 { 1525 Name: "Valid date but requires padding of zero", 1526 Input: "2018-8-1", 1527 StartOnDate: 1533081600000, 1528 EndOnDate: 1533167999999, 1529 }, 1530 { 1531 Name: "Invalid date, date not exist", 1532 Input: "2018-02-29", 1533 StartOnDate: 0, 1534 EndOnDate: 0, 1535 }, 1536 { 1537 Name: "Invalid date, not date format", 1538 Input: "holiday", 1539 StartOnDate: 0, 1540 EndOnDate: 0, 1541 }, 1542 } { 1543 t.Run(testCase.Name, func(t *testing.T) { 1544 sp := &SearchParams{OnDate: testCase.Input, TimeZoneOffset: 0} 1545 startOnDate, endOnDate := sp.GetOnDateMillis() 1546 assert.Equal(t, testCase.StartOnDate, startOnDate) 1547 assert.Equal(t, testCase.EndOnDate, endOnDate) 1548 }) 1549 } 1550 } 1551 1552 func TestGetBeforeDateMillis(t *testing.T) { 1553 for _, testCase := range []struct { 1554 Name string 1555 Input string 1556 BeforeDate int64 1557 }{ 1558 { 1559 Name: "Valid date", 1560 Input: "2018-08-01", 1561 BeforeDate: 1533081599999, 1562 }, 1563 { 1564 Name: "Valid date but requires padding of zero", 1565 Input: "2018-8-1", 1566 BeforeDate: 1533081599999, 1567 }, 1568 { 1569 Name: "Invalid date, date not exist", 1570 Input: "2018-02-29", 1571 BeforeDate: 0, 1572 }, 1573 { 1574 Name: "Invalid date, not date format", 1575 Input: "holiday", 1576 BeforeDate: 0, 1577 }, 1578 } { 1579 t.Run(testCase.Name, func(t *testing.T) { 1580 sp := &SearchParams{BeforeDate: testCase.Input, TimeZoneOffset: 0} 1581 beforeDate := sp.GetBeforeDateMillis() 1582 assert.Equal(t, testCase.BeforeDate, beforeDate) 1583 }) 1584 } 1585 } 1586 1587 func TestGetAfterDateMillis(t *testing.T) { 1588 for _, testCase := range []struct { 1589 Name string 1590 Input string 1591 AfterDate int64 1592 }{ 1593 { 1594 Name: "Valid date", 1595 Input: "2018-08-01", 1596 AfterDate: 1533168000000, 1597 }, 1598 { 1599 Name: "Valid date but requires padding of zero", 1600 Input: "2018-8-1", 1601 AfterDate: 1533168000000, 1602 }, 1603 { 1604 Name: "Invalid date, date not exist", 1605 Input: "2018-02-29", 1606 AfterDate: GetStartOfDayMillis(time.Now().Add(time.Hour*24), 0), 1607 }, 1608 { 1609 Name: "Invalid date, not date format", 1610 Input: "holiday", 1611 AfterDate: GetStartOfDayMillis(time.Now().Add(time.Hour*24), 0), 1612 }, 1613 } { 1614 t.Run(testCase.Name, func(t *testing.T) { 1615 sp := &SearchParams{AfterDate: testCase.Input, TimeZoneOffset: 0} 1616 afterDate := sp.GetAfterDateMillis() 1617 assert.Equal(t, testCase.AfterDate, afterDate) 1618 }) 1619 } 1620 }