1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2// See LICENSE.txt for license information.
3
4package searchtest
5
6import (
7	"testing"
8
9	"github.com/stretchr/testify/require"
10
11	"github.com/mattermost/mattermost-server/v6/model"
12	"github.com/mattermost/mattermost-server/v6/store"
13)
14
15var searchUserStoreTests = []searchTest{
16	{
17		Name: "Should retrieve all users in a channel if the search term is empty",
18		Fn:   testGetAllUsersInChannelWithEmptyTerm,
19		Tags: []string{EngineAll},
20	},
21	{
22		Name: "Should honor channel restrictions when autocompleting users",
23		Fn:   testHonorChannelRestrictionsAutocompletingUsers,
24		Tags: []string{EngineAll},
25	},
26	{
27		Name: "Should honor team restrictions when autocompleting users",
28		Fn:   testHonorTeamRestrictionsAutocompletingUsers,
29		Tags: []string{EngineElasticSearch, EngineBleve},
30	},
31	{
32		Name:        "Should return nothing if the user can't access the channels of a given search",
33		Fn:          testShouldReturnNothingWithoutProperAccess,
34		Tags:        []string{EngineAll},
35		Skip:        true,
36		SkipMessage: "Failing when the ListOfAllowedChannels property is empty",
37	},
38	{
39		Name: "Should autocomplete for user using username",
40		Fn:   testAutocompleteUserByUsername,
41		Tags: []string{EngineAll},
42	},
43	{
44		Name: "Should autocomplete user searching by first name",
45		Fn:   testAutocompleteUserByFirstName,
46		Tags: []string{EngineAll},
47	},
48	{
49		Name: "Should autocomplete user searching by last name",
50		Fn:   testAutocompleteUserByLastName,
51		Tags: []string{EngineAll},
52	},
53	{
54		Name: "Should autocomplete for user using nickname",
55		Fn:   testAutocompleteUserByNickName,
56		Tags: []string{EngineAll},
57	},
58	{
59		Name:        "Should autocomplete for user using email",
60		Fn:          testAutocompleteUserByEmail,
61		Tags:        []string{EngineAll},
62		Skip:        true,
63		SkipMessage: "Failing for multiple different reasons in the engines",
64	},
65	{
66		Name: "Should be able not to match specific queries with mail",
67		Fn:   testShouldNotMatchSpecificQueriesEmail,
68		Tags: []string{EngineAll},
69	},
70	{
71		Name: "Should be able to autocomplete a user by part of its username splitted by Dot",
72		Fn:   testAutocompleteUserByUsernameWithDot,
73		Tags: []string{EngineElasticSearch, EngineBleve},
74	},
75	{
76		Name: "Should be able to autocomplete a user by part of its username splitted by underscore",
77		Fn:   testAutocompleteUserByUsernameWithUnderscore,
78		Tags: []string{EngineElasticSearch, EngineBleve},
79	},
80	{
81		Name: "Should be able to autocomplete a user by part of its username splitted by hyphen",
82		Fn:   testAutocompleteUserByUsernameWithHyphen,
83		Tags: []string{EngineElasticSearch, EngineBleve},
84	},
85	{
86		Name: "Should escape the percentage character",
87		Fn:   testShouldEscapePercentageCharacter,
88		Tags: []string{EngineAll},
89	},
90	{
91		Name: "Should escape the dash character",
92		Fn:   testShouldEscapeUnderscoreCharacter,
93		Tags: []string{EngineAll},
94	},
95	{
96		Name: "Should be able to search inactive users",
97		Fn:   testShouldBeAbleToSearchInactiveUsers,
98		Tags: []string{EngineMySql, EnginePostgres, EngineElasticSearch},
99	},
100	{
101		Name: "Should be able to search filtering by role",
102		Fn:   testShouldBeAbleToSearchFilteringByRole,
103		Tags: []string{EngineMySql, EnginePostgres, EngineElasticSearch},
104	},
105	{
106		Name: "Should ignore leading @ when searching users",
107		Fn:   testShouldIgnoreLeadingAtSymbols,
108		Tags: []string{EngineAll},
109	},
110	{
111		Name: "Should search users in a case insensitive manner",
112		Fn:   testSearchUsersShouldBeCaseInsensitive,
113		Tags: []string{EngineAll},
114	},
115	{
116		Name: "Should support one or two character usernames and first/last names in search",
117		Fn:   testSearchOneTwoCharUsersnameAndFirstLastNames,
118		Tags: []string{EngineAll},
119	},
120	{
121		Name: "Should support Korean characters",
122		Fn:   testShouldSupportKoreanCharacters,
123		Tags: []string{EngineAll},
124	},
125	{
126		Name: "Should support search with a hyphen at the end of the term",
127		Fn:   testSearchWithHyphenAtTheEndOfTheTerm,
128		Tags: []string{EngineAll},
129	},
130	{
131		Name: "Should support search all users in a team",
132		Fn:   testSearchUsersInTeam,
133		Tags: []string{EngineElasticSearch},
134	},
135	{
136		Name: "Should support search users by full name",
137		Fn:   testSearchUsersByFullName,
138		Tags: []string{EngineAll},
139	},
140	{
141		Name: "Should support search all users in a team with username containing a dot",
142		Fn:   testSearchUsersInTeamUsernameWithDot,
143		Tags: []string{EngineAll},
144	},
145	{
146		Name: "Should support search all users in a team with username containing a hyphen",
147		Fn:   testSearchUsersInTeamUsernameWithHyphen,
148		Tags: []string{EngineAll},
149	},
150	{
151		Name: "Should support search all users in a team with username containing a underscore",
152		Fn:   testSearchUsersInTeamUsernameWithUnderscore,
153		Tags: []string{EngineAll},
154	},
155}
156
157func TestSearchUserStore(t *testing.T, s store.Store, testEngine *SearchTestEngine) {
158	th := &SearchTestHelper{
159		Store: s,
160	}
161	err := th.SetupBasicFixtures()
162	require.NoError(t, err)
163	defer th.CleanFixtures()
164	runTestSearch(t, testEngine, searchUserStoreTests, th)
165}
166
167func testGetAllUsersInChannelWithEmptyTerm(t *testing.T, th *SearchTestHelper) {
168	options := &model.UserSearchOptions{
169		AllowFullNames: true,
170		Limit:          model.UserSearchDefaultLimit,
171	}
172	users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
173	require.NoError(t, err)
174	th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
175	th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
176
177	t.Run("Should be able to correctly honor limit when autocompleting", func(t *testing.T) {
178		result, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
179		require.NoError(t, err)
180		require.Len(t, result.InChannel, 1)
181		require.Len(t, result.OutOfChannel, 1)
182	})
183
184	t.Run("Return all users in team", func(t *testing.T) {
185		options := createDefaultOptions(true, false, false)
186		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
187		require.NoError(t, err)
188		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
189		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
190	})
191
192	t.Run("Return all users in teams even though some of them don't have a team associated", func(t *testing.T) {
193		options := createDefaultOptions(true, false, false)
194		userAlternate, err := th.createUser("user-alternate", "user-alternate", "user", "alternate")
195		require.NoError(t, err)
196		defer th.deleteUser(userAlternate)
197		userGuest, err := th.createGuest("user-guest", "user-guest", "user", "guest")
198		require.NoError(t, err)
199		defer th.deleteUser(userGuest)
200
201		// In case teamId and channelId are empty our current logic goes through Search
202		users, err := th.Store.User().Search("", "", options)
203		require.NoError(t, err)
204		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, th.User2, th.UserAnotherTeam,
205			userAlternate, userGuest}, users)
206	})
207}
208
209func testHonorChannelRestrictionsAutocompletingUsers(t *testing.T, th *SearchTestHelper) {
210	userAlternate, err := th.createUser("user-alternate", "user-alternate", "user", "alternate")
211	require.NoError(t, err)
212	defer th.deleteUser(userAlternate)
213	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
214	require.NoError(t, err)
215	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
216	require.NoError(t, err)
217	guest, err := th.createGuest("guest", "guest", "guest", "one")
218	require.NoError(t, err)
219	err = th.addUserToTeams(guest, []string{th.Team.Id})
220	require.NoError(t, err)
221	err = th.addUserToChannels(guest, []string{th.ChannelBasic.Id})
222	require.NoError(t, err)
223	defer th.deleteUser(guest)
224	t.Run("Autocomplete users with channel restrictions", func(t *testing.T) {
225		options := createDefaultOptions(true, false, false)
226		options.ViewRestrictions = &model.ViewUsersRestrictions{Channels: []string{th.ChannelBasic.Id}}
227		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
228		require.NoError(t, err)
229		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, userAlternate, guest}, users.InChannel)
230		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
231	})
232	t.Run("Autocomplete users with term and channel restrictions", func(t *testing.T) {
233		options := createDefaultOptions(true, false, false)
234		options.ViewRestrictions = &model.ViewUsersRestrictions{Channels: []string{th.ChannelBasic.Id}}
235		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "alt", options)
236		require.NoError(t, err)
237		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
238		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
239	})
240	t.Run("Autocomplete users with all channels restricted", func(t *testing.T) {
241		options := createDefaultOptions(true, false, false)
242		options.ViewRestrictions = &model.ViewUsersRestrictions{Teams: []string{}, Channels: []string{}}
243		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
244		require.NoError(t, err)
245		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.InChannel)
246		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
247	})
248	t.Run("Autocomplete users with all channels restricted but with empty team", func(t *testing.T) {
249		options := createDefaultOptions(true, false, false)
250		options.ViewRestrictions = &model.ViewUsersRestrictions{Teams: []string{}, Channels: []string{}}
251		users, err := th.Store.User().AutocompleteUsersInChannel("", th.ChannelBasic.Id, "", options)
252		require.NoError(t, err)
253		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.InChannel)
254		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
255	})
256	t.Run("Autocomplete users with empty team and channels restricted", func(t *testing.T) {
257		options := createDefaultOptions(true, false, false)
258		options.ViewRestrictions = &model.ViewUsersRestrictions{Channels: []string{th.ChannelBasic.Id}}
259		// In case teamId and channelId are empty our current logic goes through Search
260		users, err := th.Store.User().Search("", "", options)
261		require.NoError(t, err)
262		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate, guest, th.User}, users)
263	})
264}
265
266func testHonorTeamRestrictionsAutocompletingUsers(t *testing.T, th *SearchTestHelper) {
267	t.Run("Should return results for users in the team", func(t *testing.T) {
268		options := createDefaultOptions(true, false, false)
269		options.ViewRestrictions = &model.ViewUsersRestrictions{Teams: []string{th.Team.Id}}
270		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
271		require.NoError(t, err)
272		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
273		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
274	})
275	t.Run("Should return empty because we're filtering all the teams", func(t *testing.T) {
276		options := createDefaultOptions(true, false, false)
277		options.ViewRestrictions = &model.ViewUsersRestrictions{Teams: []string{}, Channels: []string{}}
278		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
279		require.NoError(t, err)
280		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.InChannel)
281		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
282	})
283	t.Run("Should return empty when searching in one team and filtering by another", func(t *testing.T) {
284		options := createDefaultOptions(true, false, false)
285		options.ViewRestrictions = &model.ViewUsersRestrictions{Teams: []string{th.AnotherTeam.Id}}
286		users, err := th.Store.User().Search(th.Team.Id, "", options)
287		require.NoError(t, err)
288		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users)
289
290		acusers, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
291		require.NoError(t, err)
292		th.assertUsersMatchInAnyOrder(t, []*model.User{}, acusers.InChannel)
293		th.assertUsersMatchInAnyOrder(t, []*model.User{}, acusers.OutOfChannel)
294	})
295}
296func testShouldReturnNothingWithoutProperAccess(t *testing.T, th *SearchTestHelper) {
297	t.Run("Should return results users for the defined channel in the list", func(t *testing.T) {
298		options := createDefaultOptions(true, false, false)
299		options.ListOfAllowedChannels = []string{th.ChannelBasic.Id}
300		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
301		require.NoError(t, err)
302		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
303		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
304	})
305	t.Run("Should return empty because we're filtering all the channels", func(t *testing.T) {
306		options := createDefaultOptions(true, false, false)
307		options.ListOfAllowedChannels = []string{}
308		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
309		require.NoError(t, err)
310		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.InChannel)
311		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
312	})
313}
314func testAutocompleteUserByUsername(t *testing.T, th *SearchTestHelper) {
315	userAlternate, err := th.createUser("alternateusername", "alternatenick", "user", "alternate")
316	require.NoError(t, err)
317	defer th.deleteUser(userAlternate)
318	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
319	require.NoError(t, err)
320	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
321	require.NoError(t, err)
322	options := createDefaultOptions(false, false, false)
323	users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "basicusername", options)
324	require.NoError(t, err)
325	th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
326	th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
327}
328func testAutocompleteUserByFirstName(t *testing.T, th *SearchTestHelper) {
329	userAlternate, err := th.createUser("user-alternate", "user-alternate", "altfirstname", "lastname")
330	require.NoError(t, err)
331	defer th.deleteUser(userAlternate)
332	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
333	require.NoError(t, err)
334	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
335	require.NoError(t, err)
336	t.Run("Should autocomplete users when the first name is unique", func(t *testing.T) {
337		options := createDefaultOptions(true, false, false)
338		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "altfirstname", options)
339		require.NoError(t, err)
340		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
341		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
342	})
343	t.Run("Should autocomplete users for in the channel and out of the channel with the same first name", func(t *testing.T) {
344		options := createDefaultOptions(true, false, false)
345		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "basicfirstname", options)
346		require.NoError(t, err)
347		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
348		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
349	})
350}
351func testAutocompleteUserByLastName(t *testing.T, th *SearchTestHelper) {
352	userAlternate, err := th.createUser("user-alternate", "user-alternate", "firstname", "altlastname")
353	require.NoError(t, err)
354	defer th.deleteUser(userAlternate)
355	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
356	require.NoError(t, err)
357	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
358	require.NoError(t, err)
359	t.Run("Should return results when the last name is unique", func(t *testing.T) {
360		options := createDefaultOptions(true, false, false)
361		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "altlastname", options)
362		require.NoError(t, err)
363		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
364		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
365	})
366	t.Run("Should return results for in the channel and out of the channel with the same last name", func(t *testing.T) {
367		options := createDefaultOptions(true, false, false)
368		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "basiclastname", options)
369		require.NoError(t, err)
370		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
371		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
372	})
373}
374func testAutocompleteUserByNickName(t *testing.T, th *SearchTestHelper) {
375	userAlternate, err := th.createUser("alternateusername", "alternatenickname", "firstname", "altlastname")
376	require.NoError(t, err)
377	defer th.deleteUser(userAlternate)
378	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
379	require.NoError(t, err)
380	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
381	require.NoError(t, err)
382	t.Run("Should return results when the nickname is unique", func(t *testing.T) {
383		options := createDefaultOptions(true, false, false)
384		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "alternatenickname", options)
385		require.NoError(t, err)
386		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
387		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
388	})
389	t.Run("Should return users that share the same part of the nickname", func(t *testing.T) {
390		options := createDefaultOptions(true, false, false)
391		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "basicnickname", options)
392		require.NoError(t, err)
393		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
394		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
395	})
396}
397func testAutocompleteUserByEmail(t *testing.T, th *SearchTestHelper) {
398	userAlternate, err := th.createUser("alternateusername", "alternatenickname", "firstname", "altlastname")
399	require.NoError(t, err)
400	userAlternate.Email = "useralt@test.email.com"
401	_, err = th.Store.User().Update(userAlternate, false)
402	require.NoError(t, err)
403	defer th.deleteUser(userAlternate)
404	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
405	require.NoError(t, err)
406	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
407	require.NoError(t, err)
408	t.Run("Should autocomplete users when the email is unique", func(t *testing.T) {
409		options := createDefaultOptions(false, true, false)
410		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "useralt@test.email.com", options)
411		require.NoError(t, err)
412		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
413		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
414	})
415	t.Run("Should autocomplete users that share the same email user prefix", func(t *testing.T) {
416		options := createDefaultOptions(false, true, false)
417		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "success_", options)
418		require.NoError(t, err)
419		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
420		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
421	})
422	t.Run("Should autocomplete users that share the same email domain", func(t *testing.T) {
423		options := createDefaultOptions(false, true, false)
424		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "simulator.amazon.com", options)
425		require.NoError(t, err)
426		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
427		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
428	})
429	t.Run("Should search users when the email is unique", func(t *testing.T) {
430		options := createDefaultOptions(false, true, false)
431		users, err := th.Store.User().Search(th.Team.Id, "useralt@test.email.com", options)
432		require.NoError(t, err)
433		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users)
434	})
435	t.Run("Should search users that share the same email user prefix", func(t *testing.T) {
436		options := createDefaultOptions(false, true, false)
437		users, err := th.Store.User().Search(th.Team.Id, "success_", options)
438		require.NoError(t, err)
439		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users)
440	})
441	t.Run("Should search users that share the same email domain", func(t *testing.T) {
442		options := createDefaultOptions(false, true, false)
443		users, err := th.Store.User().Search(th.Team.Id, "simulator.amazon.com", options)
444		require.NoError(t, err)
445		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users)
446	})
447}
448func testShouldNotMatchSpecificQueriesEmail(t *testing.T, th *SearchTestHelper) {
449	options := createDefaultOptions(false, false, false)
450	users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "success_", options)
451	require.NoError(t, err)
452	th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.InChannel)
453	th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
454}
455func testAutocompleteUserByUsernameWithDot(t *testing.T, th *SearchTestHelper) {
456	userAlternate, err := th.createUser("alternate.username", "alternatenickname", "firstname", "altlastname")
457	require.NoError(t, err)
458	defer th.deleteUser(userAlternate)
459	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
460	require.NoError(t, err)
461	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
462	require.NoError(t, err)
463	t.Run("Should return results when searching for the whole username with Dot", func(t *testing.T) {
464		options := createDefaultOptions(false, false, false)
465		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "alternate.username", options)
466		require.NoError(t, err)
467		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
468		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
469	})
470	t.Run("Should return results when searching for part of the username including the Dot", func(t *testing.T) {
471		options := createDefaultOptions(false, false, false)
472		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, ".username", options)
473		require.NoError(t, err)
474		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
475		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
476	})
477	t.Run("Should return results when searching for part of the username not including the Dot", func(t *testing.T) {
478		options := createDefaultOptions(false, false, false)
479		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "username", options)
480		require.NoError(t, err)
481		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
482		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
483	})
484}
485func testAutocompleteUserByUsernameWithUnderscore(t *testing.T, th *SearchTestHelper) {
486	userAlternate, err := th.createUser("alternate_username", "alternatenickname", "firstname", "altlastname")
487	require.NoError(t, err)
488	defer th.deleteUser(userAlternate)
489	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
490	require.NoError(t, err)
491	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
492	require.NoError(t, err)
493	t.Run("Should return results when searching for the whole username with underscore", func(t *testing.T) {
494		options := createDefaultOptions(false, false, false)
495		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "alternate_username", options)
496		require.NoError(t, err)
497		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
498		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
499	})
500	t.Run("Should return results when searching for part of the username including the underscore", func(t *testing.T) {
501		options := createDefaultOptions(false, false, false)
502		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "_username", options)
503		require.NoError(t, err)
504		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
505		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
506	})
507	t.Run("Should return results when searching for part of the username not including the underscore", func(t *testing.T) {
508		options := createDefaultOptions(false, false, false)
509		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "username", options)
510		require.NoError(t, err)
511		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
512		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
513	})
514}
515func testAutocompleteUserByUsernameWithHyphen(t *testing.T, th *SearchTestHelper) {
516	userAlternate, err := th.createUser("alternate-username", "alternatenickname", "firstname", "altlastname")
517	require.NoError(t, err)
518	defer th.deleteUser(userAlternate)
519	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
520	require.NoError(t, err)
521	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
522	require.NoError(t, err)
523	t.Run("Should return results when searching for the whole username with hyphen", func(t *testing.T) {
524		options := createDefaultOptions(false, false, false)
525		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "alternate-username", options)
526		require.NoError(t, err)
527		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
528		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
529	})
530	t.Run("Should return results when searching for part of the username including the hyphen", func(t *testing.T) {
531		options := createDefaultOptions(false, false, false)
532		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "-username", options)
533		require.NoError(t, err)
534		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
535		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
536	})
537	t.Run("Should return results when searching for part of the username not including the hyphen", func(t *testing.T) {
538		options := createDefaultOptions(false, false, false)
539		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "username", options)
540		require.NoError(t, err)
541		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
542		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
543	})
544}
545func testShouldEscapePercentageCharacter(t *testing.T, th *SearchTestHelper) {
546	userAlternate, err := th.createUser("alternateusername", "alternate%nickname", "firstname", "altlastname")
547	require.NoError(t, err)
548
549	defer th.deleteUser(userAlternate)
550	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
551	require.NoError(t, err)
552	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
553	require.NoError(t, err)
554	t.Run("Should autocomplete users escaping percentage symbol", func(t *testing.T) {
555		options := createDefaultOptions(false, false, false)
556		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "alternate%", options)
557		require.NoError(t, err)
558		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
559		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
560	})
561	t.Run("Should search users escaping percentage symbol", func(t *testing.T) {
562		options := createDefaultOptions(false, false, false)
563		users, err := th.Store.User().Search(th.Team.Id, "alternate%", options)
564		require.NoError(t, err)
565		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users)
566	})
567}
568func testShouldEscapeUnderscoreCharacter(t *testing.T, th *SearchTestHelper) {
569	userAlternate, err := th.createUser("alternate_username", "alternatenickname", "firstname", "altlastname")
570	require.NoError(t, err)
571	defer th.deleteUser(userAlternate)
572	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
573	require.NoError(t, err)
574	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
575	require.NoError(t, err)
576	t.Run("Should autocomplete users escaping underscore symbol", func(t *testing.T) {
577		options := createDefaultOptions(false, false, false)
578		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "alternate_", options)
579		require.NoError(t, err)
580		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
581		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
582	})
583	t.Run("Should search users escaping underscore symbol", func(t *testing.T) {
584		options := createDefaultOptions(false, false, false)
585		users, err := th.Store.User().Search(th.Team.Id, "alternate_", options)
586		require.NoError(t, err)
587		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users)
588	})
589}
590
591func testShouldBeAbleToSearchInactiveUsers(t *testing.T, th *SearchTestHelper) {
592	userAlternate, err := th.createUser("basicusernamealternate", "alternatenickname", "firstname", "altlastname")
593	require.NoError(t, err)
594	userAlternate.DeleteAt = model.GetMillis()
595	_, err = th.Store.User().Update(userAlternate, true)
596	require.NoError(t, err)
597	defer th.deleteUser(userAlternate)
598	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
599	require.NoError(t, err)
600	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
601	require.NoError(t, err)
602	t.Run("Should autocomplete inactive users if we allow it", func(t *testing.T) {
603		options := createDefaultOptions(false, false, true)
604		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "basicusername", options)
605		require.NoError(t, err)
606		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, userAlternate}, users.InChannel)
607		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
608	})
609	t.Run("Should search inactive users if we allow it", func(t *testing.T) {
610		options := createDefaultOptions(false, false, true)
611		users, err := th.Store.User().Search(th.Team.Id, "basicusername", options)
612		require.NoError(t, err)
613		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, th.User2, userAlternate}, users)
614	})
615	t.Run("Shouldn't autocomplete inactive users if we don't allow it", func(t *testing.T) {
616		options := createDefaultOptions(false, false, false)
617		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "basicusername", options)
618		require.NoError(t, err)
619		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
620		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
621	})
622	t.Run("Shouldn't search inactive users if we don't allow it", func(t *testing.T) {
623		options := createDefaultOptions(false, false, false)
624		users, err := th.Store.User().Search(th.Team.Id, "basicusername", options)
625		require.NoError(t, err)
626		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, th.User2}, users)
627	})
628}
629
630func testShouldBeAbleToSearchFilteringByRole(t *testing.T, th *SearchTestHelper) {
631	userAlternate, err := th.createUser("basicusernamealternate", "alternatenickname", "firstname", "altlastname")
632	require.NoError(t, err)
633	userAlternate.Roles = "system_admin system_user"
634	_, err = th.Store.User().Update(userAlternate, true)
635	require.NoError(t, err)
636	defer th.deleteUser(userAlternate)
637	userAlternate2, err := th.createUser("basicusernamealternate2", "alternatenickname2", "firstname2", "altlastname2")
638	require.NoError(t, err)
639	userAlternate2.Roles = "system_user"
640	_, err = th.Store.User().Update(userAlternate2, true)
641	require.NoError(t, err)
642	defer th.deleteUser(userAlternate2)
643	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
644	require.NoError(t, err)
645	err = th.addUserToTeams(userAlternate2, []string{th.Team.Id})
646	require.NoError(t, err)
647	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
648	require.NoError(t, err)
649	t.Run("Should autocomplete users filtering by roles", func(t *testing.T) {
650		options := createDefaultOptions(false, false, true)
651		options.Role = "system_admin"
652		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "", options)
653		require.NoError(t, err)
654		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
655		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
656	})
657	t.Run("Should search users filtering by roles", func(t *testing.T) {
658		options := createDefaultOptions(false, false, true)
659		options.Role = "system_admin"
660		users, err := th.Store.User().Search(th.Team.Id, "", options)
661		require.NoError(t, err)
662		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users)
663	})
664}
665
666func testShouldIgnoreLeadingAtSymbols(t *testing.T, th *SearchTestHelper) {
667	t.Run("Should autocomplete ignoring the @ symbol at the beginning", func(t *testing.T) {
668		options := createDefaultOptions(false, false, false)
669		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "@basicusername", options)
670		require.NoError(t, err)
671		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
672		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
673	})
674	t.Run("Should search ignoring the @ symbol at the beginning", func(t *testing.T) {
675		options := createDefaultOptions(false, false, false)
676		users, err := th.Store.User().Search(th.Team.Id, "@basicusername", options)
677		require.NoError(t, err)
678		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, th.User2}, users)
679	})
680}
681
682func testSearchUsersShouldBeCaseInsensitive(t *testing.T, th *SearchTestHelper) {
683	options := createDefaultOptions(false, false, false)
684	users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "BaSiCUsErNaMe", options)
685	require.NoError(t, err)
686	th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users.InChannel)
687	th.assertUsersMatchInAnyOrder(t, []*model.User{th.User2}, users.OutOfChannel)
688}
689
690func testSearchOneTwoCharUsersnameAndFirstLastNames(t *testing.T, th *SearchTestHelper) {
691	userAlternate, err := th.createUser("ho", "alternatenickname", "zi", "k")
692	require.NoError(t, err)
693
694	defer th.deleteUser(userAlternate)
695	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
696	require.NoError(t, err)
697	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
698	require.NoError(t, err)
699	t.Run("Should support two characters in the full name", func(t *testing.T) {
700		options := createDefaultOptions(true, false, false)
701		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "zi", options)
702		require.NoError(t, err)
703		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
704		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
705	})
706	t.Run("Should support two characters in the username", func(t *testing.T) {
707		options := createDefaultOptions(true, false, false)
708		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "ho", options)
709		require.NoError(t, err)
710		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
711		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
712	})
713}
714
715func testShouldSupportKoreanCharacters(t *testing.T, th *SearchTestHelper) {
716	userAlternate, err := th.createUser("alternate-username", "alternate-nickname", "서강준", "안신원")
717	require.NoError(t, err)
718	defer th.deleteUser(userAlternate)
719
720	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
721	require.NoError(t, err)
722	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
723	require.NoError(t, err)
724	t.Run("Should support hanja korean characters", func(t *testing.T) {
725		options := createDefaultOptions(true, false, false)
726		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "서강준", options)
727		require.NoError(t, err)
728		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
729		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
730	})
731	t.Run("Should support hangul korean characters", func(t *testing.T) {
732		options := createDefaultOptions(true, false, false)
733		users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "안신원", options)
734		require.NoError(t, err)
735		th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
736		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
737	})
738}
739
740func testSearchWithHyphenAtTheEndOfTheTerm(t *testing.T, th *SearchTestHelper) {
741	userAlternate, err := th.createUser("alternate-username", "alternate-nickname", "altfirst", "altlast")
742	require.NoError(t, err)
743	defer th.deleteUser(userAlternate)
744	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
745	require.NoError(t, err)
746	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
747	require.NoError(t, err)
748	options := createDefaultOptions(true, false, false)
749	users, err := th.Store.User().AutocompleteUsersInChannel(th.Team.Id, th.ChannelBasic.Id, "alternate-", options)
750	require.NoError(t, err)
751	th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users.InChannel)
752	th.assertUsersMatchInAnyOrder(t, []*model.User{}, users.OutOfChannel)
753}
754
755func testSearchUsersInTeam(t *testing.T, th *SearchTestHelper) {
756	t.Run("Should return all the team users", func(t *testing.T) {
757		options := createDefaultOptions(false, false, false)
758		users, err := th.Store.User().Search(th.Team.Id, "", options)
759		require.NoError(t, err)
760		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, th.User2}, users)
761	})
762	t.Run("Should return all the team users with no team id", func(t *testing.T) {
763		options := createDefaultOptions(false, false, false)
764		users, err := th.Store.User().Search("", "basicusername", options)
765		require.NoError(t, err)
766		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, th.User2, th.UserAnotherTeam}, users)
767	})
768	t.Run("Should return all the team users filtered by username", func(t *testing.T) {
769		options := createDefaultOptions(false, false, false)
770		users, err := th.Store.User().Search(th.Team.Id, "basicusername1", options)
771		require.NoError(t, err)
772		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users)
773	})
774	t.Run("Should not return spurious results", func(t *testing.T) {
775		options := createDefaultOptions(false, false, false)
776		users, err := th.Store.User().Search(th.Team.Id, "falseuser", options)
777		require.NoError(t, err)
778		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users)
779	})
780	t.Run("Should return all the team users filtered by username and with channel restrictions", func(t *testing.T) {
781		options := createDefaultOptions(false, false, false)
782		options.ViewRestrictions = &model.ViewUsersRestrictions{Channels: []string{th.ChannelBasic.Id}}
783		users, err := th.Store.User().Search(th.Team.Id, "basicusername", options)
784		require.NoError(t, err)
785		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users)
786	})
787	t.Run("Should return all the team users filtered by username and with all channel restricted", func(t *testing.T) {
788		options := createDefaultOptions(false, false, false)
789		options.ViewRestrictions = &model.ViewUsersRestrictions{Channels: []string{}}
790		users, err := th.Store.User().Search(th.Team.Id, "basicusername1", options)
791		require.NoError(t, err)
792		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users)
793	})
794	t.Run("Should honor the limit when searching users in team", func(t *testing.T) {
795		optionsWithLimit := &model.UserSearchOptions{
796			Limit: 1,
797		}
798
799		users, err := th.Store.User().Search(th.Team.Id, "", optionsWithLimit)
800		require.NoError(t, err)
801		require.Len(t, users, 1)
802	})
803}
804
805func testSearchUsersInTeamUsernameWithDot(t *testing.T, th *SearchTestHelper) {
806	userAlternate, err := th.createUser("alternate.username", "altnickname", "altfirst", "altlast")
807	require.NoError(t, err)
808	defer th.deleteUser(userAlternate)
809	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
810	require.NoError(t, err)
811	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
812	require.NoError(t, err)
813	options := createDefaultOptions(true, false, false)
814	users, err := th.Store.User().Search(th.Team.Id, "alternate.", options)
815	require.NoError(t, err)
816	th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users)
817}
818
819func testSearchUsersInTeamUsernameWithHyphen(t *testing.T, th *SearchTestHelper) {
820	userAlternate, err := th.createUser("alternate-username", "altnickname", "altfirst", "altlast")
821	require.NoError(t, err)
822	defer th.deleteUser(userAlternate)
823	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
824	require.NoError(t, err)
825	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
826	require.NoError(t, err)
827	options := createDefaultOptions(true, false, false)
828	users, err := th.Store.User().Search(th.Team.Id, "alternate-", options)
829	require.NoError(t, err)
830	th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users)
831}
832
833func testSearchUsersInTeamUsernameWithUnderscore(t *testing.T, th *SearchTestHelper) {
834	userAlternate, err := th.createUser("alternate_username", "altnickname", "altfirst", "altlast")
835	require.NoError(t, err)
836	defer th.deleteUser(userAlternate)
837	err = th.addUserToTeams(userAlternate, []string{th.Team.Id})
838	require.NoError(t, err)
839	err = th.addUserToChannels(userAlternate, []string{th.ChannelBasic.Id})
840	require.NoError(t, err)
841	options := createDefaultOptions(true, false, false)
842	users, err := th.Store.User().Search(th.Team.Id, "alternate_", options)
843	require.NoError(t, err)
844	th.assertUsersMatchInAnyOrder(t, []*model.User{userAlternate}, users)
845}
846
847func testSearchUsersByFullName(t *testing.T, th *SearchTestHelper) {
848	t.Run("Should search users by full name", func(t *testing.T) {
849		options := createDefaultOptions(true, false, false)
850		users, err := th.Store.User().Search(th.Team.Id, "basicfirstname", options)
851		require.NoError(t, err)
852		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User, th.User2}, users)
853	})
854	t.Run("Should search user by full name", func(t *testing.T) {
855		options := createDefaultOptions(true, false, false)
856		users, err := th.Store.User().Search(th.Team.Id, "basicfirstname1", options)
857		require.NoError(t, err)
858		th.assertUsersMatchInAnyOrder(t, []*model.User{th.User}, users)
859	})
860	t.Run("Should return empty when search by full name and is deactivated", func(t *testing.T) {
861		options := createDefaultOptions(false, false, false)
862		users, err := th.Store.User().Search(th.Team.Id, "basicfirstname1", options)
863		require.NoError(t, err)
864		th.assertUsersMatchInAnyOrder(t, []*model.User{}, users)
865	})
866}
867
868func createDefaultOptions(allowFullName, allowEmails, allowInactive bool) *model.UserSearchOptions {
869	return &model.UserSearchOptions{
870		AllowFullNames: allowFullName,
871		AllowEmails:    allowEmails,
872		AllowInactive:  allowInactive,
873		Limit:          model.UserSearchDefaultLimit,
874	}
875}
876