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