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  }