1// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
2// See LICENSE.txt for license information.
3
4package storetest
5
6import (
7	"errors"
8	"fmt"
9	"math"
10	"sort"
11	"strings"
12	"testing"
13	"time"
14
15	"github.com/stretchr/testify/assert"
16	"github.com/stretchr/testify/require"
17
18	"github.com/mattermost/mattermost-server/v6/model"
19	"github.com/mattermost/mattermost-server/v6/store"
20	"github.com/mattermost/mattermost-server/v6/utils"
21)
22
23func TestGroupStore(t *testing.T, ss store.Store) {
24	t.Run("Create", func(t *testing.T) { testGroupStoreCreate(t, ss) })
25	t.Run("Get", func(t *testing.T) { testGroupStoreGet(t, ss) })
26	t.Run("GetByName", func(t *testing.T) { testGroupStoreGetByName(t, ss) })
27	t.Run("GetByIDs", func(t *testing.T) { testGroupStoreGetByIDs(t, ss) })
28	t.Run("GetByRemoteID", func(t *testing.T) { testGroupStoreGetByRemoteID(t, ss) })
29	t.Run("GetAllBySource", func(t *testing.T) { testGroupStoreGetAllByType(t, ss) })
30	t.Run("GetByUser", func(t *testing.T) { testGroupStoreGetByUser(t, ss) })
31	t.Run("Update", func(t *testing.T) { testGroupStoreUpdate(t, ss) })
32	t.Run("Delete", func(t *testing.T) { testGroupStoreDelete(t, ss) })
33
34	t.Run("GetMemberUsers", func(t *testing.T) { testGroupGetMemberUsers(t, ss) })
35	t.Run("GetMemberUsersPage", func(t *testing.T) { testGroupGetMemberUsersPage(t, ss) })
36
37	t.Run("GetMemberUsersInTeam", func(t *testing.T) { testGroupGetMemberUsersInTeam(t, ss) })
38	t.Run("GetMemberUsersNotInChannel", func(t *testing.T) { testGroupGetMemberUsersNotInChannel(t, ss) })
39
40	t.Run("UpsertMember", func(t *testing.T) { testUpsertMember(t, ss) })
41	t.Run("DeleteMember", func(t *testing.T) { testGroupDeleteMember(t, ss) })
42	t.Run("PermanentDeleteMembersByUser", func(t *testing.T) { testGroupPermanentDeleteMembersByUser(t, ss) })
43
44	t.Run("CreateGroupSyncable", func(t *testing.T) { testCreateGroupSyncable(t, ss) })
45	t.Run("GetGroupSyncable", func(t *testing.T) { testGetGroupSyncable(t, ss) })
46	t.Run("GetAllGroupSyncablesByGroupId", func(t *testing.T) { testGetAllGroupSyncablesByGroup(t, ss) })
47	t.Run("UpdateGroupSyncable", func(t *testing.T) { testUpdateGroupSyncable(t, ss) })
48	t.Run("DeleteGroupSyncable", func(t *testing.T) { testDeleteGroupSyncable(t, ss) })
49
50	t.Run("TeamMembersToAdd", func(t *testing.T) { testTeamMembersToAdd(t, ss) })
51	t.Run("TeamMembersToAdd_SingleTeam", func(t *testing.T) { testTeamMembersToAddSingleTeam(t, ss) })
52
53	t.Run("ChannelMembersToAdd", func(t *testing.T) { testChannelMembersToAdd(t, ss) })
54	t.Run("ChannelMembersToAdd_SingleChannel", func(t *testing.T) { testChannelMembersToAddSingleChannel(t, ss) })
55
56	t.Run("TeamMembersToRemove", func(t *testing.T) { testTeamMembersToRemove(t, ss) })
57	t.Run("TeamMembersToRemove_SingleTeam", func(t *testing.T) { testTeamMembersToRemoveSingleTeam(t, ss) })
58
59	t.Run("ChannelMembersToRemove", func(t *testing.T) { testChannelMembersToRemove(t, ss) })
60	t.Run("ChannelMembersToRemove_SingleChannel", func(t *testing.T) { testChannelMembersToRemoveSingleChannel(t, ss) })
61
62	t.Run("GetGroupsByChannel", func(t *testing.T) { testGetGroupsByChannel(t, ss) })
63	t.Run("GetGroupsAssociatedToChannelsByTeam", func(t *testing.T) { testGetGroupsAssociatedToChannelsByTeam(t, ss) })
64	t.Run("GetGroupsByTeam", func(t *testing.T) { testGetGroupsByTeam(t, ss) })
65
66	t.Run("GetGroups", func(t *testing.T) { testGetGroups(t, ss) })
67
68	t.Run("TeamMembersMinusGroupMembers", func(t *testing.T) { testTeamMembersMinusGroupMembers(t, ss) })
69	t.Run("ChannelMembersMinusGroupMembers", func(t *testing.T) { testChannelMembersMinusGroupMembers(t, ss) })
70
71	t.Run("GetMemberCount", func(t *testing.T) { groupTestGetMemberCount(t, ss) })
72
73	t.Run("AdminRoleGroupsForSyncableMember_Channel", func(t *testing.T) { groupTestAdminRoleGroupsForSyncableMemberChannel(t, ss) })
74	t.Run("AdminRoleGroupsForSyncableMember_Team", func(t *testing.T) { groupTestAdminRoleGroupsForSyncableMemberTeam(t, ss) })
75	t.Run("PermittedSyncableAdmins_Team", func(t *testing.T) { groupTestPermittedSyncableAdminsTeam(t, ss) })
76	t.Run("PermittedSyncableAdmins_Channel", func(t *testing.T) { groupTestPermittedSyncableAdminsChannel(t, ss) })
77	t.Run("UpdateMembersRole_Team", func(t *testing.T) { groupTestpUpdateMembersRoleTeam(t, ss) })
78	t.Run("UpdateMembersRole_Channel", func(t *testing.T) { groupTestpUpdateMembersRoleChannel(t, ss) })
79
80	t.Run("GroupCount", func(t *testing.T) { groupTestGroupCount(t, ss) })
81	t.Run("GroupTeamCount", func(t *testing.T) { groupTestGroupTeamCount(t, ss) })
82	t.Run("GroupChannelCount", func(t *testing.T) { groupTestGroupChannelCount(t, ss) })
83	t.Run("GroupMemberCount", func(t *testing.T) { groupTestGroupMemberCount(t, ss) })
84	t.Run("DistinctGroupMemberCount", func(t *testing.T) { groupTestDistinctGroupMemberCount(t, ss) })
85	t.Run("GroupCountWithAllowReference", func(t *testing.T) { groupTestGroupCountWithAllowReference(t, ss) })
86}
87
88func testGroupStoreCreate(t *testing.T, ss store.Store) {
89	// Save a new group
90	g1 := &model.Group{
91		Name:        model.NewString(model.NewId()),
92		DisplayName: model.NewId(),
93		Source:      model.GroupSourceLdap,
94		Description: model.NewId(),
95		RemoteId:    model.NewId(),
96	}
97
98	// Happy path
99	d1, err := ss.Group().Create(g1)
100	require.NoError(t, err)
101	require.Len(t, d1.Id, 26)
102	require.Equal(t, *g1.Name, *d1.Name)
103	require.Equal(t, g1.DisplayName, d1.DisplayName)
104	require.Equal(t, g1.Description, d1.Description)
105	require.Equal(t, g1.RemoteId, d1.RemoteId)
106	require.NotZero(t, d1.CreateAt)
107	require.NotZero(t, d1.UpdateAt)
108	require.Zero(t, d1.DeleteAt)
109
110	// Requires display name
111	g2 := &model.Group{
112		Name:        model.NewString(model.NewId()),
113		DisplayName: "",
114		Source:      model.GroupSourceLdap,
115		RemoteId:    model.NewId(),
116	}
117	data, err := ss.Group().Create(g2)
118	require.Nil(t, data)
119	require.Error(t, err)
120	var appErr *model.AppError
121	require.True(t, errors.As(err, &appErr))
122	require.Equal(t, appErr.Id, "model.group.display_name.app_error")
123
124	// Won't accept a duplicate name
125	g4 := &model.Group{
126		Name:        model.NewString(model.NewId()),
127		DisplayName: model.NewId(),
128		Source:      model.GroupSourceLdap,
129		RemoteId:    model.NewId(),
130	}
131	_, err = ss.Group().Create(g4)
132	require.NoError(t, err)
133	g4b := &model.Group{
134		Name:        g4.Name,
135		DisplayName: model.NewId(),
136		Source:      model.GroupSourceLdap,
137		RemoteId:    model.NewId(),
138	}
139	data, err = ss.Group().Create(g4b)
140	require.Nil(t, data)
141	require.Error(t, err)
142	require.Contains(t, err.Error(), fmt.Sprintf("Group with name %s already exists", *g4b.Name))
143
144	// Fields cannot be greater than max values
145	g5 := &model.Group{
146		Name:        model.NewString(strings.Repeat("x", model.GroupNameMaxLength)),
147		DisplayName: strings.Repeat("x", model.GroupDisplayNameMaxLength),
148		Description: strings.Repeat("x", model.GroupDescriptionMaxLength),
149		Source:      model.GroupSourceLdap,
150		RemoteId:    model.NewId(),
151	}
152	require.Nil(t, g5.IsValidForCreate())
153
154	g5.Name = model.NewString(*g5.Name + "x")
155	require.Equal(t, g5.IsValidForCreate().Id, "model.group.name.invalid_length.app_error")
156	g5.Name = model.NewString(model.NewId())
157	require.Nil(t, g5.IsValidForCreate())
158
159	g5.DisplayName = g5.DisplayName + "x"
160	require.Equal(t, g5.IsValidForCreate().Id, "model.group.display_name.app_error")
161	g5.DisplayName = model.NewId()
162	require.Nil(t, g5.IsValidForCreate())
163
164	g5.Description = g5.Description + "x"
165	require.Equal(t, g5.IsValidForCreate().Id, "model.group.description.app_error")
166	g5.Description = model.NewId()
167	require.Nil(t, g5.IsValidForCreate())
168
169	// Must use a valid type
170	g6 := &model.Group{
171		Name:        model.NewString(model.NewId()),
172		DisplayName: model.NewId(),
173		Description: model.NewId(),
174		Source:      model.GroupSource("fake"),
175		RemoteId:    model.NewId(),
176	}
177	require.Equal(t, g6.IsValidForCreate().Id, "model.group.source.app_error")
178
179	//must use valid characters
180	g7 := &model.Group{
181		Name:        model.NewString("%^#@$$"),
182		DisplayName: model.NewId(),
183		Description: model.NewId(),
184		Source:      model.GroupSourceLdap,
185		RemoteId:    model.NewId(),
186	}
187	require.Equal(t, g7.IsValidForCreate().Id, "model.group.name.invalid_chars.app_error")
188}
189
190func testGroupStoreGet(t *testing.T, ss store.Store) {
191	// Create a group
192	g1 := &model.Group{
193		Name:        model.NewString(model.NewId()),
194		DisplayName: model.NewId(),
195		Description: model.NewId(),
196		Source:      model.GroupSourceLdap,
197		RemoteId:    model.NewId(),
198	}
199	d1, err := ss.Group().Create(g1)
200	require.NoError(t, err)
201	require.Len(t, d1.Id, 26)
202
203	// Get the group
204	d2, err := ss.Group().Get(d1.Id)
205	require.NoError(t, err)
206	require.Equal(t, d1.Id, d2.Id)
207	require.Equal(t, *d1.Name, *d2.Name)
208	require.Equal(t, d1.DisplayName, d2.DisplayName)
209	require.Equal(t, d1.Description, d2.Description)
210	require.Equal(t, d1.RemoteId, d2.RemoteId)
211	require.Equal(t, d1.CreateAt, d2.CreateAt)
212	require.Equal(t, d1.UpdateAt, d2.UpdateAt)
213	require.Equal(t, d1.DeleteAt, d2.DeleteAt)
214
215	// Get an invalid group
216	_, err = ss.Group().Get(model.NewId())
217	require.Error(t, err)
218	var nfErr *store.ErrNotFound
219	require.True(t, errors.As(err, &nfErr))
220}
221
222func testGroupStoreGetByName(t *testing.T, ss store.Store) {
223	// Create a group
224	g1 := &model.Group{
225		Name:        model.NewString(model.NewId()),
226		DisplayName: model.NewId(),
227		Description: model.NewId(),
228		Source:      model.GroupSourceLdap,
229		RemoteId:    model.NewId(),
230	}
231	g1Opts := model.GroupSearchOpts{
232		FilterAllowReference: false,
233	}
234
235	d1, err := ss.Group().Create(g1)
236	require.NoError(t, err)
237	require.Len(t, d1.Id, 26)
238
239	// Get the group
240	d2, err := ss.Group().GetByName(*d1.Name, g1Opts)
241	require.NoError(t, err)
242	require.Equal(t, d1.Id, d2.Id)
243	require.Equal(t, *d1.Name, *d2.Name)
244	require.Equal(t, d1.DisplayName, d2.DisplayName)
245	require.Equal(t, d1.Description, d2.Description)
246	require.Equal(t, d1.RemoteId, d2.RemoteId)
247	require.Equal(t, d1.CreateAt, d2.CreateAt)
248	require.Equal(t, d1.UpdateAt, d2.UpdateAt)
249	require.Equal(t, d1.DeleteAt, d2.DeleteAt)
250
251	// Get an invalid group
252	_, err = ss.Group().GetByName(model.NewId(), g1Opts)
253	require.Error(t, err)
254	var nfErr *store.ErrNotFound
255	require.True(t, errors.As(err, &nfErr))
256}
257
258func testGroupStoreGetByIDs(t *testing.T, ss store.Store) {
259	var group1 *model.Group
260	var group2 *model.Group
261
262	for i := 0; i < 2; i++ {
263		group := &model.Group{
264			Name:        model.NewString(model.NewId()),
265			DisplayName: model.NewId(),
266			Description: model.NewId(),
267			Source:      model.GroupSourceLdap,
268			RemoteId:    model.NewId(),
269		}
270		group, err := ss.Group().Create(group)
271		require.NoError(t, err)
272		switch i {
273		case 0:
274			group1 = group
275		case 1:
276			group2 = group
277		}
278	}
279
280	groups, err := ss.Group().GetByIDs([]string{group1.Id, group2.Id})
281	require.NoError(t, err)
282	require.Len(t, groups, 2)
283
284	for i := 0; i < 2; i++ {
285		require.True(t, (groups[i].Id == group1.Id || groups[i].Id == group2.Id))
286	}
287
288	require.True(t, groups[0].Id != groups[1].Id)
289}
290
291func testGroupStoreGetByRemoteID(t *testing.T, ss store.Store) {
292	// Create a group
293	g1 := &model.Group{
294		Name:        model.NewString(model.NewId()),
295		DisplayName: model.NewId(),
296		Description: model.NewId(),
297		Source:      model.GroupSourceLdap,
298		RemoteId:    model.NewId(),
299	}
300	d1, err := ss.Group().Create(g1)
301	require.NoError(t, err)
302	require.Len(t, d1.Id, 26)
303
304	// Get the group
305	d2, err := ss.Group().GetByRemoteID(d1.RemoteId, model.GroupSourceLdap)
306	require.NoError(t, err)
307	require.Equal(t, d1.Id, d2.Id)
308	require.Equal(t, *d1.Name, *d2.Name)
309	require.Equal(t, d1.DisplayName, d2.DisplayName)
310	require.Equal(t, d1.Description, d2.Description)
311	require.Equal(t, d1.RemoteId, d2.RemoteId)
312	require.Equal(t, d1.CreateAt, d2.CreateAt)
313	require.Equal(t, d1.UpdateAt, d2.UpdateAt)
314	require.Equal(t, d1.DeleteAt, d2.DeleteAt)
315
316	// Get an invalid group
317	_, err = ss.Group().GetByRemoteID(model.NewId(), model.GroupSource("fake"))
318	require.Error(t, err)
319	var nfErr *store.ErrNotFound
320	require.True(t, errors.As(err, &nfErr))
321}
322
323func testGroupStoreGetAllByType(t *testing.T, ss store.Store) {
324	numGroups := 10
325
326	groups := []*model.Group{}
327
328	// Create groups
329	for i := 0; i < numGroups; i++ {
330		g := &model.Group{
331			Name:        model.NewString(model.NewId()),
332			DisplayName: model.NewId(),
333			Description: model.NewId(),
334			Source:      model.GroupSourceLdap,
335			RemoteId:    model.NewId(),
336		}
337		groups = append(groups, g)
338		_, err := ss.Group().Create(g)
339		require.NoError(t, err)
340	}
341
342	// Returns all the groups
343	d1, err := ss.Group().GetAllBySource(model.GroupSourceLdap)
344	require.NoError(t, err)
345	require.Condition(t, func() bool { return len(d1) >= numGroups })
346	for _, expectedGroup := range groups {
347		present := false
348		for _, dbGroup := range d1 {
349			if dbGroup.Id == expectedGroup.Id {
350				present = true
351				break
352			}
353		}
354		require.True(t, present)
355	}
356}
357
358func testGroupStoreGetByUser(t *testing.T, ss store.Store) {
359	// Save a group
360	g1 := &model.Group{
361		Name:        model.NewString(model.NewId()),
362		DisplayName: model.NewId(),
363		Description: model.NewId(),
364		Source:      model.GroupSourceLdap,
365		RemoteId:    model.NewId(),
366	}
367	g1, err := ss.Group().Create(g1)
368	require.NoError(t, err)
369
370	g2 := &model.Group{
371		Name:        model.NewString(model.NewId()),
372		DisplayName: model.NewId(),
373		Description: model.NewId(),
374		Source:      model.GroupSourceLdap,
375		RemoteId:    model.NewId(),
376	}
377	g2, err = ss.Group().Create(g2)
378	require.NoError(t, err)
379
380	u1 := &model.User{
381		Email:    MakeEmail(),
382		Username: model.NewId(),
383	}
384	u1, nErr := ss.User().Save(u1)
385	require.NoError(t, nErr)
386
387	_, err = ss.Group().UpsertMember(g1.Id, u1.Id)
388	require.NoError(t, err)
389	_, err = ss.Group().UpsertMember(g2.Id, u1.Id)
390	require.NoError(t, err)
391
392	u2 := &model.User{
393		Email:    MakeEmail(),
394		Username: model.NewId(),
395	}
396	u2, nErr = ss.User().Save(u2)
397	require.NoError(t, nErr)
398
399	_, err = ss.Group().UpsertMember(g2.Id, u2.Id)
400	require.NoError(t, err)
401
402	groups, err := ss.Group().GetByUser(u1.Id)
403	require.NoError(t, err)
404	assert.Equal(t, 2, len(groups))
405	found1 := false
406	found2 := false
407	for _, g := range groups {
408		if g.Id == g1.Id {
409			found1 = true
410		}
411		if g.Id == g2.Id {
412			found2 = true
413		}
414	}
415	assert.True(t, found1)
416	assert.True(t, found2)
417
418	groups, err = ss.Group().GetByUser(u2.Id)
419	require.NoError(t, err)
420	require.Equal(t, 1, len(groups))
421	assert.Equal(t, g2.Id, groups[0].Id)
422
423	groups, err = ss.Group().GetByUser(model.NewId())
424	require.NoError(t, err)
425	assert.Equal(t, 0, len(groups))
426}
427
428func testGroupStoreUpdate(t *testing.T, ss store.Store) {
429	// Save a new group
430	g1 := &model.Group{
431		Name:        model.NewString("g1-test"),
432		DisplayName: model.NewId(),
433		Source:      model.GroupSourceLdap,
434		Description: model.NewId(),
435		RemoteId:    model.NewId(),
436	}
437
438	// Create a group
439	d1, err := ss.Group().Create(g1)
440	require.NoError(t, err)
441
442	// Update happy path
443	g1Update := &model.Group{}
444	*g1Update = *g1
445	g1Update.Name = model.NewString(model.NewId())
446	g1Update.DisplayName = model.NewId()
447	g1Update.Description = model.NewId()
448	g1Update.RemoteId = model.NewId()
449
450	ud1, err := ss.Group().Update(g1Update)
451	require.NoError(t, err)
452	// Not changed...
453	require.Equal(t, d1.Id, ud1.Id)
454	require.Equal(t, d1.CreateAt, ud1.CreateAt)
455	require.Equal(t, d1.Source, ud1.Source)
456	// Still zero...
457	require.Zero(t, ud1.DeleteAt)
458	// Updated...
459	require.Equal(t, *g1Update.Name, *ud1.Name)
460	require.Equal(t, g1Update.DisplayName, ud1.DisplayName)
461	require.Equal(t, g1Update.Description, ud1.Description)
462	require.Equal(t, g1Update.RemoteId, ud1.RemoteId)
463
464	// Requires display name
465	data, err := ss.Group().Update(&model.Group{
466		Id:          d1.Id,
467		Name:        model.NewString(model.NewId()),
468		DisplayName: "",
469		Source:      model.GroupSourceLdap,
470		RemoteId:    model.NewId(),
471	})
472	require.Nil(t, data)
473	require.Error(t, err)
474	var appErr *model.AppError
475	require.True(t, errors.As(err, &appErr))
476	require.Equal(t, appErr.Id, "model.group.display_name.app_error")
477
478	// Create another Group
479	g2 := &model.Group{
480		Name:        model.NewString(model.NewId()),
481		DisplayName: model.NewId(),
482		Source:      model.GroupSourceLdap,
483		Description: model.NewId(),
484		RemoteId:    model.NewId(),
485	}
486	d2, err := ss.Group().Create(g2)
487	require.NoError(t, err)
488
489	// Can't update the name to be a duplicate of an existing group's name
490	_, err = ss.Group().Update(&model.Group{
491		Id:          d2.Id,
492		Name:        g1Update.Name,
493		DisplayName: model.NewId(),
494		Source:      model.GroupSourceLdap,
495		Description: model.NewId(),
496		RemoteId:    model.NewId(),
497	})
498	require.Error(t, err)
499	require.Contains(t, err.Error(), fmt.Sprintf("Group with name %s already exists", *g1Update.Name))
500
501	// Cannot update CreateAt
502	someVal := model.GetMillis()
503	d1.CreateAt = someVal
504	d3, err := ss.Group().Update(d1)
505	require.NoError(t, err)
506	require.NotEqual(t, someVal, d3.CreateAt)
507
508	// Cannot update DeleteAt to non-zero
509	d1.DeleteAt = 1
510	_, err = ss.Group().Update(d1)
511	require.Error(t, err)
512	require.Contains(t, err.Error(), "DeleteAt should be 0 when updating")
513
514	//...except for 0 for DeleteAt
515	d1.DeleteAt = 0
516	d4, err := ss.Group().Update(d1)
517	require.NoError(t, err)
518	require.Zero(t, d4.DeleteAt)
519}
520
521func testGroupStoreDelete(t *testing.T, ss store.Store) {
522	// Save a group
523	g1 := &model.Group{
524		Name:        model.NewString(model.NewId()),
525		DisplayName: model.NewId(),
526		Description: model.NewId(),
527		Source:      model.GroupSourceLdap,
528		RemoteId:    model.NewId(),
529	}
530
531	d1, err := ss.Group().Create(g1)
532	require.NoError(t, err)
533	require.Len(t, d1.Id, 26)
534
535	// Check the group is retrievable
536	_, err = ss.Group().Get(d1.Id)
537	require.NoError(t, err)
538
539	// Get the before count
540	d7, err := ss.Group().GetAllBySource(model.GroupSourceLdap)
541	require.NoError(t, err)
542	beforeCount := len(d7)
543
544	// Delete the group
545	_, err = ss.Group().Delete(d1.Id)
546	require.NoError(t, err)
547
548	// Check the group is deleted
549	d4, err := ss.Group().Get(d1.Id)
550	require.NoError(t, err)
551	require.NotZero(t, d4.DeleteAt)
552
553	// Check the after count
554	d5, err := ss.Group().GetAllBySource(model.GroupSourceLdap)
555	require.NoError(t, err)
556	afterCount := len(d5)
557	require.Condition(t, func() bool { return beforeCount == afterCount+1 })
558
559	// Try and delete a nonexistent group
560	_, err = ss.Group().Delete(model.NewId())
561	require.Error(t, err)
562	var nfErr *store.ErrNotFound
563	require.True(t, errors.As(err, &nfErr))
564
565	// Cannot delete again
566	_, err = ss.Group().Delete(d1.Id)
567	require.True(t, errors.As(err, &nfErr))
568}
569
570func testGroupGetMemberUsers(t *testing.T, ss store.Store) {
571	// Save a group
572	g1 := &model.Group{
573		Name:        model.NewString(model.NewId()),
574		DisplayName: model.NewId(),
575		Description: model.NewId(),
576		Source:      model.GroupSourceLdap,
577		RemoteId:    model.NewId(),
578	}
579	group, err := ss.Group().Create(g1)
580	require.NoError(t, err)
581
582	u1 := &model.User{
583		Email:    MakeEmail(),
584		Username: model.NewId(),
585	}
586	user1, nErr := ss.User().Save(u1)
587	require.NoError(t, nErr)
588
589	_, err = ss.Group().UpsertMember(group.Id, user1.Id)
590	require.NoError(t, err)
591
592	u2 := &model.User{
593		Email:    MakeEmail(),
594		Username: model.NewId(),
595	}
596	user2, nErr := ss.User().Save(u2)
597	require.NoError(t, nErr)
598
599	_, err = ss.Group().UpsertMember(group.Id, user2.Id)
600	require.NoError(t, err)
601
602	// Check returns members
603	groupMembers, err := ss.Group().GetMemberUsers(group.Id)
604	require.NoError(t, err)
605	require.Equal(t, 2, len(groupMembers))
606
607	// Check madeup id
608	groupMembers, err = ss.Group().GetMemberUsers(model.NewId())
609	require.NoError(t, err)
610	require.Equal(t, 0, len(groupMembers))
611
612	// Delete a member
613	_, err = ss.Group().DeleteMember(group.Id, user1.Id)
614	require.NoError(t, err)
615
616	// Should not return deleted members
617	groupMembers, err = ss.Group().GetMemberUsers(group.Id)
618	require.NoError(t, err)
619	require.Equal(t, 1, len(groupMembers))
620}
621
622func testGroupGetMemberUsersPage(t *testing.T, ss store.Store) {
623	// Save a group
624	g1 := &model.Group{
625		Name:        model.NewString(model.NewId()),
626		DisplayName: model.NewId(),
627		Description: model.NewId(),
628		Source:      model.GroupSourceLdap,
629		RemoteId:    model.NewId(),
630	}
631	group, err := ss.Group().Create(g1)
632	require.NoError(t, err)
633
634	u1 := &model.User{
635		Email:    MakeEmail(),
636		Username: model.NewId(),
637	}
638	user1, nErr := ss.User().Save(u1)
639	require.NoError(t, nErr)
640
641	_, err = ss.Group().UpsertMember(group.Id, user1.Id)
642	require.NoError(t, err)
643
644	u2 := &model.User{
645		Email:    MakeEmail(),
646		Username: model.NewId(),
647	}
648	user2, nErr := ss.User().Save(u2)
649	require.NoError(t, nErr)
650
651	_, err = ss.Group().UpsertMember(group.Id, user2.Id)
652	require.NoError(t, err)
653
654	u3 := &model.User{
655		Email:    MakeEmail(),
656		Username: model.NewId(),
657	}
658	user3, nErr := ss.User().Save(u3)
659	require.NoError(t, nErr)
660
661	_, err = ss.Group().UpsertMember(group.Id, user3.Id)
662	require.NoError(t, err)
663
664	// Check returns members
665	groupMembers, err := ss.Group().GetMemberUsersPage(group.Id, 0, 100)
666	require.NoError(t, err)
667	require.Equal(t, 3, len(groupMembers))
668
669	// Check page 1
670	groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 0, 2)
671	require.NoError(t, err)
672	require.Equal(t, 2, len(groupMembers))
673	require.Equal(t, user3.Id, groupMembers[0].Id)
674	require.Equal(t, user2.Id, groupMembers[1].Id)
675
676	// Check page 2
677	groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 1, 2)
678	require.NoError(t, err)
679	require.Equal(t, 1, len(groupMembers))
680	require.Equal(t, user1.Id, groupMembers[0].Id)
681
682	// Check madeup id
683	groupMembers, err = ss.Group().GetMemberUsersPage(model.NewId(), 0, 100)
684	require.NoError(t, err)
685	require.Equal(t, 0, len(groupMembers))
686
687	// Delete a member
688	_, err = ss.Group().DeleteMember(group.Id, user1.Id)
689	require.NoError(t, err)
690
691	// Should not return deleted members
692	groupMembers, err = ss.Group().GetMemberUsersPage(group.Id, 0, 100)
693	require.NoError(t, err)
694	require.Equal(t, 2, len(groupMembers))
695}
696
697func testGroupGetMemberUsersInTeam(t *testing.T, ss store.Store) {
698	// Save a team
699	team := &model.Team{
700		DisplayName: "Name",
701		Description: "Some description",
702		CompanyName: "Some company name",
703		Name:        "z-z-" + model.NewId() + "a",
704		Email:       "success+" + model.NewId() + "@simulator.amazonses.com",
705		Type:        model.TeamOpen,
706	}
707	team, err := ss.Team().Save(team)
708	require.NoError(t, err)
709
710	// Save a group
711	g1 := &model.Group{
712		Name:        model.NewString(model.NewId()),
713		DisplayName: model.NewId(),
714		Description: model.NewId(),
715		Source:      model.GroupSourceLdap,
716		RemoteId:    model.NewId(),
717	}
718	group, err := ss.Group().Create(g1)
719	require.NoError(t, err)
720
721	u1 := &model.User{
722		Email:    MakeEmail(),
723		Username: model.NewId(),
724	}
725	user1, err := ss.User().Save(u1)
726	require.NoError(t, err)
727
728	_, err = ss.Group().UpsertMember(group.Id, user1.Id)
729	require.NoError(t, err)
730
731	u2 := &model.User{
732		Email:    MakeEmail(),
733		Username: model.NewId(),
734	}
735	user2, err := ss.User().Save(u2)
736	require.NoError(t, err)
737
738	_, err = ss.Group().UpsertMember(group.Id, user2.Id)
739	require.NoError(t, err)
740
741	u3 := &model.User{
742		Email:    MakeEmail(),
743		Username: model.NewId(),
744	}
745	user3, err := ss.User().Save(u3)
746	require.NoError(t, err)
747
748	_, err = ss.Group().UpsertMember(group.Id, user3.Id)
749	require.NoError(t, err)
750
751	// returns no members when team does not exist
752	groupMembers, err := ss.Group().GetMemberUsersInTeam(group.Id, "non-existent-channel-id")
753	require.NoError(t, err)
754	require.Equal(t, 0, len(groupMembers))
755
756	// returns no members when group has no members in the team
757	groupMembers, err = ss.Group().GetMemberUsersInTeam(group.Id, team.Id)
758	require.NoError(t, err)
759	require.Equal(t, 0, len(groupMembers))
760
761	m1 := &model.TeamMember{TeamId: team.Id, UserId: user1.Id}
762	_, nErr := ss.Team().SaveMember(m1, -1)
763	require.NoError(t, nErr)
764
765	// returns single member in team
766	groupMembers, err = ss.Group().GetMemberUsersInTeam(group.Id, team.Id)
767	require.NoError(t, err)
768	require.Equal(t, 1, len(groupMembers))
769
770	m2 := &model.TeamMember{TeamId: team.Id, UserId: user2.Id}
771	m3 := &model.TeamMember{TeamId: team.Id, UserId: user3.Id}
772	_, nErr = ss.Team().SaveMember(m2, -1)
773	require.NoError(t, nErr)
774	_, nErr = ss.Team().SaveMember(m3, -1)
775	require.NoError(t, nErr)
776
777	// returns all members when all members are in team
778	groupMembers, err = ss.Group().GetMemberUsersInTeam(group.Id, team.Id)
779	require.NoError(t, err)
780	require.Equal(t, 3, len(groupMembers))
781}
782
783func testGroupGetMemberUsersNotInChannel(t *testing.T, ss store.Store) {
784	// Save a team
785	team := &model.Team{
786		DisplayName: "Name",
787		Description: "Some description",
788		CompanyName: "Some company name",
789		Name:        "z-z-" + model.NewId() + "a",
790		Email:       "success+" + model.NewId() + "@simulator.amazonses.com",
791		Type:        model.TeamOpen,
792	}
793	team, err := ss.Team().Save(team)
794	require.NoError(t, err)
795
796	// Save a group
797	g1 := &model.Group{
798		Name:        model.NewString(model.NewId()),
799		DisplayName: model.NewId(),
800		Description: model.NewId(),
801		Source:      model.GroupSourceLdap,
802		RemoteId:    model.NewId(),
803	}
804	group, err := ss.Group().Create(g1)
805	require.NoError(t, err)
806
807	u1 := &model.User{
808		Email:    MakeEmail(),
809		Username: model.NewId(),
810	}
811	user1, err := ss.User().Save(u1)
812	require.NoError(t, err)
813
814	_, err = ss.Group().UpsertMember(group.Id, user1.Id)
815	require.NoError(t, err)
816
817	u2 := &model.User{
818		Email:    MakeEmail(),
819		Username: model.NewId(),
820	}
821	user2, err := ss.User().Save(u2)
822	require.NoError(t, err)
823
824	_, err = ss.Group().UpsertMember(group.Id, user2.Id)
825	require.NoError(t, err)
826
827	u3 := &model.User{
828		Email:    MakeEmail(),
829		Username: model.NewId(),
830	}
831	user3, err := ss.User().Save(u3)
832	require.NoError(t, err)
833
834	_, err = ss.Group().UpsertMember(group.Id, user3.Id)
835	require.NoError(t, err)
836
837	// Create Channel
838	channel := &model.Channel{
839		TeamId:      team.Id,
840		DisplayName: "Channel",
841		Name:        model.NewId(),
842		Type:        model.ChannelTypeOpen, // Query does not look at type so this shouldn't matter.
843	}
844	channel, nErr := ss.Channel().Save(channel, 9999)
845	require.NoError(t, nErr)
846
847	// returns no members when channel does not exist
848	groupMembers, err := ss.Group().GetMemberUsersNotInChannel(group.Id, "non-existent-channel-id")
849	require.NoError(t, err)
850	require.Equal(t, 0, len(groupMembers))
851
852	// returns no members when group has no members in the team that the channel belongs to
853	groupMembers, err = ss.Group().GetMemberUsersNotInChannel(group.Id, channel.Id)
854	require.NoError(t, err)
855	require.Equal(t, 0, len(groupMembers))
856
857	m1 := &model.TeamMember{TeamId: team.Id, UserId: user1.Id}
858	_, nErr = ss.Team().SaveMember(m1, -1)
859	require.NoError(t, nErr)
860
861	// returns single member in team and not in channel
862	groupMembers, err = ss.Group().GetMemberUsersNotInChannel(group.Id, channel.Id)
863	require.NoError(t, err)
864	require.Equal(t, 1, len(groupMembers))
865
866	m2 := &model.TeamMember{TeamId: team.Id, UserId: user2.Id}
867	m3 := &model.TeamMember{TeamId: team.Id, UserId: user3.Id}
868	_, nErr = ss.Team().SaveMember(m2, -1)
869	require.NoError(t, nErr)
870	_, nErr = ss.Team().SaveMember(m3, -1)
871	require.NoError(t, nErr)
872
873	// returns all members when all members are in team and not in channel
874	groupMembers, err = ss.Group().GetMemberUsersNotInChannel(group.Id, channel.Id)
875	require.NoError(t, err)
876	require.Equal(t, 3, len(groupMembers))
877
878	cm1 := &model.ChannelMember{
879		ChannelId:   channel.Id,
880		UserId:      user1.Id,
881		SchemeGuest: false,
882		SchemeUser:  true,
883		SchemeAdmin: false,
884		NotifyProps: model.GetDefaultChannelNotifyProps(),
885	}
886	_, err = ss.Channel().SaveMember(cm1)
887	require.NoError(t, err)
888
889	// returns both members not yet added to channel
890	groupMembers, err = ss.Group().GetMemberUsersNotInChannel(group.Id, channel.Id)
891	require.NoError(t, err)
892	require.Equal(t, 2, len(groupMembers))
893
894	cm2 := &model.ChannelMember{
895		ChannelId:   channel.Id,
896		UserId:      user2.Id,
897		SchemeGuest: false,
898		SchemeUser:  true,
899		SchemeAdmin: false,
900		NotifyProps: model.GetDefaultChannelNotifyProps(),
901	}
902	cm3 := &model.ChannelMember{
903		ChannelId:   channel.Id,
904		UserId:      user3.Id,
905		SchemeGuest: false,
906		SchemeUser:  true,
907		SchemeAdmin: false,
908		NotifyProps: model.GetDefaultChannelNotifyProps(),
909	}
910
911	_, err = ss.Channel().SaveMember(cm2)
912	require.NoError(t, err)
913	_, err = ss.Channel().SaveMember(cm3)
914	require.NoError(t, err)
915
916	// returns none when all members have been added to team and channel
917	groupMembers, err = ss.Group().GetMemberUsersNotInChannel(group.Id, channel.Id)
918	require.NoError(t, err)
919	require.Equal(t, 0, len(groupMembers))
920}
921
922func testUpsertMember(t *testing.T, ss store.Store) {
923	// Create group
924	g1 := &model.Group{
925		Name:        model.NewString(model.NewId()),
926		DisplayName: model.NewId(),
927		Source:      model.GroupSourceLdap,
928		RemoteId:    model.NewId(),
929	}
930	group, err := ss.Group().Create(g1)
931	require.NoError(t, err)
932
933	// Create user
934	u1 := &model.User{
935		Email:    MakeEmail(),
936		Username: model.NewId(),
937	}
938	user, nErr := ss.User().Save(u1)
939	require.NoError(t, nErr)
940
941	// Happy path
942	d2, err := ss.Group().UpsertMember(group.Id, user.Id)
943	require.NoError(t, err)
944	require.Equal(t, d2.GroupId, group.Id)
945	require.Equal(t, d2.UserId, user.Id)
946	require.NotZero(t, d2.CreateAt)
947	require.Zero(t, d2.DeleteAt)
948
949	// Duplicate composite key (GroupId, UserId)
950	// Ensure new CreateAt > previous CreateAt for the same (groupId, userId)
951	time.Sleep(1 * time.Millisecond)
952	_, err = ss.Group().UpsertMember(group.Id, user.Id)
953	require.NoError(t, err)
954
955	// Invalid GroupId
956	_, err = ss.Group().UpsertMember(model.NewId(), user.Id)
957	require.Error(t, err)
958	require.Contains(t, err.Error(), "failed to get UserGroup with")
959
960	// Restores a deleted member
961	// Ensure new CreateAt > previous CreateAt for the same (groupId, userId)
962	time.Sleep(1 * time.Millisecond)
963	_, err = ss.Group().UpsertMember(group.Id, user.Id)
964	require.NoError(t, err)
965
966	_, err = ss.Group().DeleteMember(group.Id, user.Id)
967	require.NoError(t, err)
968
969	groupMembers, err := ss.Group().GetMemberUsers(group.Id)
970	require.NoError(t, err)
971	beforeRestoreCount := len(groupMembers)
972
973	_, err = ss.Group().UpsertMember(group.Id, user.Id)
974	require.NoError(t, err)
975
976	groupMembers, err = ss.Group().GetMemberUsers(group.Id)
977	require.NoError(t, err)
978	afterRestoreCount := len(groupMembers)
979
980	require.Equal(t, beforeRestoreCount+1, afterRestoreCount)
981}
982
983func testGroupDeleteMember(t *testing.T, ss store.Store) {
984	// Create group
985	g1 := &model.Group{
986		Name:        model.NewString(model.NewId()),
987		DisplayName: model.NewId(),
988		Source:      model.GroupSourceLdap,
989		RemoteId:    model.NewId(),
990	}
991	group, err := ss.Group().Create(g1)
992	require.NoError(t, err)
993
994	// Create user
995	u1 := &model.User{
996		Email:    MakeEmail(),
997		Username: model.NewId(),
998	}
999	user, nErr := ss.User().Save(u1)
1000	require.NoError(t, nErr)
1001
1002	// Create member
1003	d1, err := ss.Group().UpsertMember(group.Id, user.Id)
1004	require.NoError(t, err)
1005
1006	// Happy path
1007	d2, err := ss.Group().DeleteMember(group.Id, user.Id)
1008	require.NoError(t, err)
1009	require.Equal(t, d2.GroupId, group.Id)
1010	require.Equal(t, d2.UserId, user.Id)
1011	require.Equal(t, d2.CreateAt, d1.CreateAt)
1012	require.NotZero(t, d2.DeleteAt)
1013
1014	// Delete an already deleted member
1015	_, err = ss.Group().DeleteMember(group.Id, user.Id)
1016	var nfErr *store.ErrNotFound
1017	require.True(t, errors.As(err, &nfErr))
1018
1019	// Delete with non-existent User
1020	_, err = ss.Group().DeleteMember(group.Id, model.NewId())
1021	require.True(t, errors.As(err, &nfErr))
1022
1023	// Delete non-existent Group
1024	_, err = ss.Group().DeleteMember(model.NewId(), group.Id)
1025	require.True(t, errors.As(err, &nfErr))
1026}
1027
1028func testGroupPermanentDeleteMembersByUser(t *testing.T, ss store.Store) {
1029	var g *model.Group
1030	var groups []*model.Group
1031	numberOfGroups := 5
1032
1033	for i := 0; i < numberOfGroups; i++ {
1034		g = &model.Group{
1035			Name:        model.NewString(model.NewId()),
1036			DisplayName: model.NewId(),
1037			Source:      model.GroupSourceLdap,
1038			RemoteId:    model.NewId(),
1039		}
1040		group, err := ss.Group().Create(g)
1041		groups = append(groups, group)
1042		require.NoError(t, err)
1043	}
1044
1045	// Create user
1046	u1 := &model.User{
1047		Email:    MakeEmail(),
1048		Username: model.NewId(),
1049	}
1050	user, err := ss.User().Save(u1)
1051	require.NoError(t, err)
1052
1053	// Create members
1054	for _, group := range groups {
1055		_, err = ss.Group().UpsertMember(group.Id, user.Id)
1056		require.NoError(t, err)
1057	}
1058
1059	// Happy path
1060	err = ss.Group().PermanentDeleteMembersByUser(user.Id)
1061	require.NoError(t, err)
1062}
1063
1064func testCreateGroupSyncable(t *testing.T, ss store.Store) {
1065	// Invalid GroupID
1066	_, err := ss.Group().CreateGroupSyncable(model.NewGroupTeam("x", model.NewId(), false))
1067	var appErr *model.AppError
1068	require.True(t, errors.As(err, &appErr))
1069	require.Equal(t, appErr.Id, "model.group_syncable.group_id.app_error")
1070
1071	// Create Group
1072	g1 := &model.Group{
1073		Name:        model.NewString(model.NewId()),
1074		DisplayName: model.NewId(),
1075		Source:      model.GroupSourceLdap,
1076		RemoteId:    model.NewId(),
1077	}
1078	group, err := ss.Group().Create(g1)
1079	require.NoError(t, err)
1080
1081	// Create Team
1082	t1 := &model.Team{
1083		DisplayName:     "Name",
1084		Description:     "Some description",
1085		CompanyName:     "Some company name",
1086		AllowOpenInvite: false,
1087		InviteId:        "inviteid0",
1088		Name:            "z-z-" + model.NewId() + "a",
1089		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
1090		Type:            model.TeamOpen,
1091	}
1092	team, nErr := ss.Team().Save(t1)
1093	require.NoError(t, nErr)
1094
1095	// New GroupSyncable, happy path
1096	gt1 := model.NewGroupTeam(group.Id, team.Id, false)
1097	d1, err := ss.Group().CreateGroupSyncable(gt1)
1098	require.NoError(t, err)
1099	require.Equal(t, gt1.SyncableId, d1.SyncableId)
1100	require.Equal(t, gt1.GroupId, d1.GroupId)
1101	require.Equal(t, gt1.AutoAdd, d1.AutoAdd)
1102	require.NotZero(t, d1.CreateAt)
1103	require.Zero(t, d1.DeleteAt)
1104}
1105
1106func testGetGroupSyncable(t *testing.T, ss store.Store) {
1107	// Create a group
1108	g1 := &model.Group{
1109		Name:        model.NewString(model.NewId()),
1110		DisplayName: model.NewId(),
1111		Description: model.NewId(),
1112		Source:      model.GroupSourceLdap,
1113		RemoteId:    model.NewId(),
1114	}
1115	group, err := ss.Group().Create(g1)
1116	require.NoError(t, err)
1117
1118	// Create Team
1119	t1 := &model.Team{
1120		DisplayName:     "Name",
1121		Description:     "Some description",
1122		CompanyName:     "Some company name",
1123		AllowOpenInvite: false,
1124		InviteId:        "inviteid0",
1125		Name:            "z-z-" + model.NewId() + "a",
1126		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
1127		Type:            model.TeamOpen,
1128	}
1129	team, nErr := ss.Team().Save(t1)
1130	require.NoError(t, nErr)
1131
1132	// Create GroupSyncable
1133	gt1 := model.NewGroupTeam(group.Id, team.Id, false)
1134	groupTeam, err := ss.Group().CreateGroupSyncable(gt1)
1135	require.NoError(t, err)
1136
1137	// Get GroupSyncable
1138	dgt, err := ss.Group().GetGroupSyncable(groupTeam.GroupId, groupTeam.SyncableId, model.GroupSyncableTypeTeam)
1139	require.NoError(t, err)
1140	require.Equal(t, gt1.GroupId, dgt.GroupId)
1141	require.Equal(t, gt1.SyncableId, dgt.SyncableId)
1142	require.Equal(t, gt1.AutoAdd, dgt.AutoAdd)
1143	require.NotZero(t, gt1.CreateAt)
1144	require.NotZero(t, gt1.UpdateAt)
1145	require.Zero(t, gt1.DeleteAt)
1146}
1147
1148func testGetAllGroupSyncablesByGroup(t *testing.T, ss store.Store) {
1149	numGroupSyncables := 10
1150
1151	// Create group
1152	g := &model.Group{
1153		Name:        model.NewString(model.NewId()),
1154		DisplayName: model.NewId(),
1155		Description: model.NewId(),
1156		Source:      model.GroupSourceLdap,
1157		RemoteId:    model.NewId(),
1158	}
1159	group, err := ss.Group().Create(g)
1160	require.NoError(t, err)
1161
1162	groupTeams := []*model.GroupSyncable{}
1163
1164	// Create groupTeams
1165	for i := 0; i < numGroupSyncables; i++ {
1166		// Create Team
1167		t1 := &model.Team{
1168			DisplayName:     "Name",
1169			Description:     "Some description",
1170			CompanyName:     "Some company name",
1171			AllowOpenInvite: false,
1172			InviteId:        "inviteid0",
1173			Name:            "z-z-" + model.NewId() + "a",
1174			Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
1175			Type:            model.TeamOpen,
1176		}
1177		var team *model.Team
1178		team, nErr := ss.Team().Save(t1)
1179		require.NoError(t, nErr)
1180
1181		// create groupteam
1182		var groupTeam *model.GroupSyncable
1183		gt := model.NewGroupTeam(group.Id, team.Id, false)
1184		gt.SchemeAdmin = true
1185		groupTeam, err = ss.Group().CreateGroupSyncable(gt)
1186		require.NoError(t, err)
1187		groupTeams = append(groupTeams, groupTeam)
1188	}
1189
1190	// Returns all the group teams
1191	d1, err := ss.Group().GetAllGroupSyncablesByGroupId(group.Id, model.GroupSyncableTypeTeam)
1192	require.NoError(t, err)
1193	require.Condition(t, func() bool { return len(d1) >= numGroupSyncables })
1194	for _, expectedGroupTeam := range groupTeams {
1195		present := false
1196		for _, dbGroupTeam := range d1 {
1197			if dbGroupTeam.GroupId == expectedGroupTeam.GroupId && dbGroupTeam.SyncableId == expectedGroupTeam.SyncableId {
1198				require.True(t, dbGroupTeam.SchemeAdmin)
1199				present = true
1200				break
1201			}
1202		}
1203		require.True(t, present)
1204	}
1205}
1206
1207func testUpdateGroupSyncable(t *testing.T, ss store.Store) {
1208	// Create Group
1209	g1 := &model.Group{
1210		Name:        model.NewString(model.NewId()),
1211		DisplayName: model.NewId(),
1212		Source:      model.GroupSourceLdap,
1213		RemoteId:    model.NewId(),
1214	}
1215	group, err := ss.Group().Create(g1)
1216	require.NoError(t, err)
1217
1218	// Create Team
1219	t1 := &model.Team{
1220		DisplayName:     "Name",
1221		Description:     "Some description",
1222		CompanyName:     "Some company name",
1223		AllowOpenInvite: false,
1224		InviteId:        "inviteid0",
1225		Name:            "z-z-" + model.NewId() + "a",
1226		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
1227		Type:            model.TeamOpen,
1228	}
1229	team, nErr := ss.Team().Save(t1)
1230	require.NoError(t, nErr)
1231
1232	// New GroupSyncable, happy path
1233	gt1 := model.NewGroupTeam(group.Id, team.Id, false)
1234	d1, err := ss.Group().CreateGroupSyncable(gt1)
1235	require.NoError(t, err)
1236
1237	// Update existing group team
1238	gt1.AutoAdd = true
1239	d2, err := ss.Group().UpdateGroupSyncable(gt1)
1240	require.NoError(t, err)
1241	require.True(t, d2.AutoAdd)
1242
1243	// Non-existent Group
1244	gt2 := model.NewGroupTeam(model.NewId(), team.Id, false)
1245	_, err = ss.Group().UpdateGroupSyncable(gt2)
1246	var nfErr *store.ErrNotFound
1247	require.True(t, errors.As(err, &nfErr))
1248
1249	// Non-existent Team
1250	gt3 := model.NewGroupTeam(group.Id, model.NewId(), false)
1251	_, err = ss.Group().UpdateGroupSyncable(gt3)
1252	require.True(t, errors.As(err, &nfErr))
1253
1254	// Cannot update CreateAt or DeleteAt
1255	origCreateAt := d1.CreateAt
1256	d1.CreateAt = model.GetMillis()
1257	d1.AutoAdd = true
1258	d3, err := ss.Group().UpdateGroupSyncable(d1)
1259	require.NoError(t, err)
1260	require.Equal(t, origCreateAt, d3.CreateAt)
1261
1262	// Cannot update DeleteAt to arbitrary value
1263	d1.DeleteAt = 1
1264	_, err = ss.Group().UpdateGroupSyncable(d1)
1265	require.Error(t, err)
1266	require.Contains(t, err.Error(), "DeleteAt should be 0 when updating")
1267
1268	// Can update DeleteAt to 0
1269	d1.DeleteAt = 0
1270	d4, err := ss.Group().UpdateGroupSyncable(d1)
1271	require.NoError(t, err)
1272	require.Zero(t, d4.DeleteAt)
1273}
1274
1275func testDeleteGroupSyncable(t *testing.T, ss store.Store) {
1276	// Create Group
1277	g1 := &model.Group{
1278		Name:        model.NewString(model.NewId()),
1279		DisplayName: model.NewId(),
1280		Source:      model.GroupSourceLdap,
1281		RemoteId:    model.NewId(),
1282	}
1283	group, err := ss.Group().Create(g1)
1284	require.NoError(t, err)
1285
1286	// Create Team
1287	t1 := &model.Team{
1288		DisplayName:     "Name",
1289		Description:     "Some description",
1290		CompanyName:     "Some company name",
1291		AllowOpenInvite: false,
1292		InviteId:        "inviteid0",
1293		Name:            "z-z-" + model.NewId() + "a",
1294		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
1295		Type:            model.TeamOpen,
1296	}
1297	team, nErr := ss.Team().Save(t1)
1298	require.NoError(t, nErr)
1299
1300	// Create GroupSyncable
1301	gt1 := model.NewGroupTeam(group.Id, team.Id, false)
1302	groupTeam, err := ss.Group().CreateGroupSyncable(gt1)
1303	require.NoError(t, err)
1304
1305	// Non-existent Group
1306	_, err = ss.Group().DeleteGroupSyncable(model.NewId(), groupTeam.SyncableId, model.GroupSyncableTypeTeam)
1307	var nfErr *store.ErrNotFound
1308	require.True(t, errors.As(err, &nfErr))
1309
1310	// Non-existent Team
1311	_, err = ss.Group().DeleteGroupSyncable(groupTeam.GroupId, model.NewId(), model.GroupSyncableTypeTeam)
1312	require.True(t, errors.As(err, &nfErr))
1313
1314	// Happy path...
1315	d1, err := ss.Group().DeleteGroupSyncable(groupTeam.GroupId, groupTeam.SyncableId, model.GroupSyncableTypeTeam)
1316	require.NoError(t, err)
1317	require.NotZero(t, d1.DeleteAt)
1318	require.Equal(t, d1.GroupId, groupTeam.GroupId)
1319	require.Equal(t, d1.SyncableId, groupTeam.SyncableId)
1320	require.Equal(t, d1.AutoAdd, groupTeam.AutoAdd)
1321	require.Equal(t, d1.CreateAt, groupTeam.CreateAt)
1322	require.Condition(t, func() bool { return d1.UpdateAt > groupTeam.UpdateAt })
1323
1324	// Record already deleted
1325	_, err = ss.Group().DeleteGroupSyncable(d1.GroupId, d1.SyncableId, d1.Type)
1326	require.Error(t, err)
1327	var invErr *store.ErrInvalidInput
1328	require.True(t, errors.As(err, &invErr))
1329}
1330
1331func testTeamMembersToAdd(t *testing.T, ss store.Store) {
1332	// Create Group
1333	group, err := ss.Group().Create(&model.Group{
1334		Name:        model.NewString(model.NewId()),
1335		DisplayName: "TeamMembersToAdd Test Group",
1336		RemoteId:    model.NewId(),
1337		Source:      model.GroupSourceLdap,
1338	})
1339	require.NoError(t, err)
1340
1341	// Create User
1342	user := &model.User{
1343		Email:    MakeEmail(),
1344		Username: model.NewId(),
1345	}
1346	user, nErr := ss.User().Save(user)
1347	require.NoError(t, nErr)
1348
1349	// Create GroupMember
1350	_, err = ss.Group().UpsertMember(group.Id, user.Id)
1351	require.NoError(t, err)
1352
1353	// Create Team
1354	team := &model.Team{
1355		DisplayName:     "Name",
1356		Description:     "Some description",
1357		CompanyName:     "Some company name",
1358		AllowOpenInvite: false,
1359		InviteId:        "inviteid0",
1360		Name:            "z-z-" + model.NewId() + "a",
1361		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
1362		Type:            model.TeamOpen,
1363	}
1364	team, nErr = ss.Team().Save(team)
1365	require.NoError(t, nErr)
1366
1367	// Create GroupTeam
1368	syncable, err := ss.Group().CreateGroupSyncable(model.NewGroupTeam(group.Id, team.Id, true))
1369	require.NoError(t, err)
1370
1371	// Time before syncable was created
1372	teamMembers, err := ss.Group().TeamMembersToAdd(syncable.CreateAt-1, nil, false)
1373	require.NoError(t, err)
1374	require.Len(t, teamMembers, 1)
1375	require.Equal(t, user.Id, teamMembers[0].UserID)
1376	require.Equal(t, team.Id, teamMembers[0].TeamID)
1377
1378	// Time after syncable was created
1379	teamMembers, err = ss.Group().TeamMembersToAdd(syncable.CreateAt+1, nil, false)
1380	require.NoError(t, err)
1381	require.Empty(t, teamMembers)
1382
1383	// Delete and restore GroupMember should return result
1384	_, err = ss.Group().DeleteMember(group.Id, user.Id)
1385	require.NoError(t, err)
1386	_, err = ss.Group().UpsertMember(group.Id, user.Id)
1387	require.NoError(t, err)
1388	teamMembers, err = ss.Group().TeamMembersToAdd(syncable.CreateAt+1, nil, false)
1389	require.NoError(t, err)
1390	require.Len(t, teamMembers, 1)
1391
1392	pristineSyncable := *syncable
1393
1394	_, err = ss.Group().UpdateGroupSyncable(syncable)
1395	require.NoError(t, err)
1396
1397	// Time before syncable was updated
1398	teamMembers, err = ss.Group().TeamMembersToAdd(syncable.UpdateAt-1, nil, false)
1399	require.NoError(t, err)
1400	require.Len(t, teamMembers, 1)
1401	require.Equal(t, user.Id, teamMembers[0].UserID)
1402	require.Equal(t, team.Id, teamMembers[0].TeamID)
1403
1404	// Time after syncable was updated
1405	teamMembers, err = ss.Group().TeamMembersToAdd(syncable.UpdateAt+1, nil, false)
1406	require.NoError(t, err)
1407	require.Empty(t, teamMembers)
1408
1409	// Only includes if auto-add
1410	syncable.AutoAdd = false
1411	_, err = ss.Group().UpdateGroupSyncable(syncable)
1412	require.NoError(t, err)
1413	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1414	require.NoError(t, err)
1415	require.Empty(t, teamMembers)
1416
1417	// reset state of syncable and verify
1418	_, err = ss.Group().UpdateGroupSyncable(&pristineSyncable)
1419	require.NoError(t, err)
1420	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1421	require.NoError(t, err)
1422	require.Len(t, teamMembers, 1)
1423
1424	// No result if Group deleted
1425	_, err = ss.Group().Delete(group.Id)
1426	require.NoError(t, err)
1427	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1428	require.NoError(t, err)
1429	require.Empty(t, teamMembers)
1430
1431	// reset state of group and verify
1432	group.DeleteAt = 0
1433	_, err = ss.Group().Update(group)
1434	require.NoError(t, err)
1435	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1436	require.NoError(t, err)
1437	require.Len(t, teamMembers, 1)
1438
1439	// No result if Team deleted
1440	team.DeleteAt = model.GetMillis()
1441	team, nErr = ss.Team().Update(team)
1442	require.NoError(t, nErr)
1443	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1444	require.NoError(t, err)
1445	require.Empty(t, teamMembers)
1446
1447	// reset state of team and verify
1448	team.DeleteAt = 0
1449	team, nErr = ss.Team().Update(team)
1450	require.NoError(t, nErr)
1451	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1452	require.NoError(t, err)
1453	require.Len(t, teamMembers, 1)
1454
1455	// No result if GroupTeam deleted
1456	_, err = ss.Group().DeleteGroupSyncable(group.Id, team.Id, model.GroupSyncableTypeTeam)
1457	require.NoError(t, err)
1458	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1459	require.NoError(t, err)
1460	require.Empty(t, teamMembers)
1461
1462	// reset GroupTeam and verify
1463	_, err = ss.Group().UpdateGroupSyncable(&pristineSyncable)
1464	require.NoError(t, err)
1465	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1466	require.NoError(t, err)
1467	require.Len(t, teamMembers, 1)
1468
1469	// No result if GroupMember deleted
1470	_, err = ss.Group().DeleteMember(group.Id, user.Id)
1471	require.NoError(t, err)
1472	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1473	require.NoError(t, err)
1474	require.Empty(t, teamMembers)
1475
1476	// restore group member and verify
1477	_, err = ss.Group().UpsertMember(group.Id, user.Id)
1478	require.NoError(t, err)
1479	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1480	require.NoError(t, err)
1481	require.Len(t, teamMembers, 1)
1482
1483	// adding team membership stops returning result
1484	_, nErr = ss.Team().SaveMember(&model.TeamMember{
1485		TeamId: team.Id,
1486		UserId: user.Id,
1487	}, 999)
1488	require.NoError(t, nErr)
1489	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1490	require.NoError(t, err)
1491	require.Empty(t, teamMembers)
1492
1493	// Leaving Team should still not return result
1494	_, nErr = ss.Team().UpdateMember(&model.TeamMember{
1495		TeamId:   team.Id,
1496		UserId:   user.Id,
1497		DeleteAt: model.GetMillis(),
1498	})
1499	require.NoError(t, nErr)
1500	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, false)
1501	require.NoError(t, err)
1502	require.Empty(t, teamMembers)
1503
1504	// If includeRemovedMembers is set to true, removed members should be added back in
1505	teamMembers, err = ss.Group().TeamMembersToAdd(0, nil, true)
1506	require.NoError(t, err)
1507	require.Len(t, teamMembers, 1)
1508}
1509
1510func testTeamMembersToAddSingleTeam(t *testing.T, ss store.Store) {
1511	group1, err := ss.Group().Create(&model.Group{
1512		Name:        model.NewString(model.NewId()),
1513		DisplayName: "TeamMembersToAdd Test Group",
1514		RemoteId:    model.NewId(),
1515		Source:      model.GroupSourceLdap,
1516	})
1517	require.NoError(t, err)
1518
1519	group2, err := ss.Group().Create(&model.Group{
1520		Name:        model.NewString(model.NewId()),
1521		DisplayName: "TeamMembersToAdd Test Group",
1522		RemoteId:    model.NewId(),
1523		Source:      model.GroupSourceLdap,
1524	})
1525	require.NoError(t, err)
1526
1527	user1 := &model.User{
1528		Email:    MakeEmail(),
1529		Username: model.NewId(),
1530	}
1531	user1, nErr := ss.User().Save(user1)
1532	require.NoError(t, nErr)
1533
1534	user2 := &model.User{
1535		Email:    MakeEmail(),
1536		Username: model.NewId(),
1537	}
1538	user2, nErr = ss.User().Save(user2)
1539	require.NoError(t, nErr)
1540
1541	user3 := &model.User{
1542		Email:    MakeEmail(),
1543		Username: model.NewId(),
1544	}
1545	user3, nErr = ss.User().Save(user3)
1546	require.NoError(t, nErr)
1547
1548	for _, user := range []*model.User{user1, user2} {
1549		_, err = ss.Group().UpsertMember(group1.Id, user.Id)
1550		require.NoError(t, err)
1551	}
1552	_, err = ss.Group().UpsertMember(group2.Id, user3.Id)
1553	require.NoError(t, err)
1554
1555	team1 := &model.Team{
1556		DisplayName:     "Name",
1557		Description:     "Some description",
1558		CompanyName:     "Some company name",
1559		AllowOpenInvite: false,
1560		InviteId:        "inviteid0",
1561		Name:            "z-z-" + model.NewId() + "a",
1562		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
1563		Type:            model.TeamOpen,
1564	}
1565	team1, nErr = ss.Team().Save(team1)
1566	require.NoError(t, nErr)
1567
1568	team2 := &model.Team{
1569		DisplayName:     "Name",
1570		Description:     "Some description",
1571		CompanyName:     "Some company name",
1572		AllowOpenInvite: false,
1573		InviteId:        "inviteid0",
1574		Name:            "z-z-" + model.NewId() + "a",
1575		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
1576		Type:            model.TeamOpen,
1577	}
1578	team2, nErr = ss.Team().Save(team2)
1579	require.NoError(t, nErr)
1580
1581	_, err = ss.Group().CreateGroupSyncable(model.NewGroupTeam(group1.Id, team1.Id, true))
1582	require.NoError(t, err)
1583
1584	_, err = ss.Group().CreateGroupSyncable(model.NewGroupTeam(group2.Id, team2.Id, true))
1585	require.NoError(t, err)
1586
1587	teamMembers, err := ss.Group().TeamMembersToAdd(0, nil, false)
1588	require.NoError(t, err)
1589	require.Len(t, teamMembers, 3)
1590
1591	teamMembers, err = ss.Group().TeamMembersToAdd(0, &team1.Id, false)
1592	require.NoError(t, err)
1593	require.Len(t, teamMembers, 2)
1594
1595	teamMembers, err = ss.Group().TeamMembersToAdd(0, &team2.Id, false)
1596	require.NoError(t, err)
1597	require.Len(t, teamMembers, 1)
1598}
1599
1600func testChannelMembersToAdd(t *testing.T, ss store.Store) {
1601	// Create Group
1602	group, err := ss.Group().Create(&model.Group{
1603		Name:        model.NewString(model.NewId()),
1604		DisplayName: "ChannelMembersToAdd Test Group",
1605		RemoteId:    model.NewId(),
1606		Source:      model.GroupSourceLdap,
1607	})
1608	require.NoError(t, err)
1609
1610	// Create User
1611	user := &model.User{
1612		Email:    MakeEmail(),
1613		Username: model.NewId(),
1614	}
1615	user, nErr := ss.User().Save(user)
1616	require.NoError(t, nErr)
1617
1618	// Create GroupMember
1619	_, err = ss.Group().UpsertMember(group.Id, user.Id)
1620	require.NoError(t, err)
1621
1622	// Create Channel
1623	channel := &model.Channel{
1624		TeamId:      model.NewId(),
1625		DisplayName: "A Name",
1626		Name:        model.NewId(),
1627		Type:        model.ChannelTypeOpen, // Query does not look at type so this shouldn't matter.
1628	}
1629	channel, nErr = ss.Channel().Save(channel, 9999)
1630	require.NoError(t, nErr)
1631
1632	// Create GroupChannel
1633	syncable, err := ss.Group().CreateGroupSyncable(model.NewGroupChannel(group.Id, channel.Id, true))
1634	require.NoError(t, err)
1635
1636	// Time before syncable was created
1637	channelMembers, err := ss.Group().ChannelMembersToAdd(syncable.CreateAt-1, nil, false)
1638	require.NoError(t, err)
1639	require.Len(t, channelMembers, 1)
1640	require.Equal(t, user.Id, channelMembers[0].UserID)
1641	require.Equal(t, channel.Id, channelMembers[0].ChannelID)
1642
1643	// Time after syncable was created
1644	channelMembers, err = ss.Group().ChannelMembersToAdd(syncable.CreateAt+1, nil, false)
1645	require.NoError(t, err)
1646	require.Empty(t, channelMembers)
1647
1648	// Delete and restore GroupMember should return result
1649	_, err = ss.Group().DeleteMember(group.Id, user.Id)
1650	require.NoError(t, err)
1651	_, err = ss.Group().UpsertMember(group.Id, user.Id)
1652	require.NoError(t, err)
1653	channelMembers, err = ss.Group().ChannelMembersToAdd(syncable.CreateAt+1, nil, false)
1654	require.NoError(t, err)
1655	require.Len(t, channelMembers, 1)
1656
1657	pristineSyncable := *syncable
1658
1659	_, err = ss.Group().UpdateGroupSyncable(syncable)
1660	require.NoError(t, err)
1661
1662	// Time before syncable was updated
1663	channelMembers, err = ss.Group().ChannelMembersToAdd(syncable.UpdateAt-1, nil, false)
1664	require.NoError(t, err)
1665	require.Len(t, channelMembers, 1)
1666	require.Equal(t, user.Id, channelMembers[0].UserID)
1667	require.Equal(t, channel.Id, channelMembers[0].ChannelID)
1668
1669	// Time after syncable was updated
1670	channelMembers, err = ss.Group().ChannelMembersToAdd(syncable.UpdateAt+1, nil, false)
1671	require.NoError(t, err)
1672	require.Empty(t, channelMembers)
1673
1674	// Only includes if auto-add
1675	syncable.AutoAdd = false
1676	_, err = ss.Group().UpdateGroupSyncable(syncable)
1677	require.NoError(t, err)
1678	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1679	require.NoError(t, err)
1680	require.Empty(t, channelMembers)
1681
1682	// reset state of syncable and verify
1683	_, err = ss.Group().UpdateGroupSyncable(&pristineSyncable)
1684	require.NoError(t, err)
1685	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1686	require.NoError(t, err)
1687	require.Len(t, channelMembers, 1)
1688
1689	// No result if Group deleted
1690	_, err = ss.Group().Delete(group.Id)
1691	require.NoError(t, err)
1692	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1693	require.NoError(t, err)
1694	require.Empty(t, channelMembers)
1695
1696	// reset state of group and verify
1697	group.DeleteAt = 0
1698	_, err = ss.Group().Update(group)
1699	require.NoError(t, err)
1700	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1701	require.NoError(t, err)
1702	require.Len(t, channelMembers, 1)
1703
1704	// No result if Channel deleted
1705	nErr = ss.Channel().Delete(channel.Id, model.GetMillis())
1706	require.NoError(t, nErr)
1707	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1708	require.NoError(t, err)
1709	require.Empty(t, channelMembers)
1710
1711	// reset state of channel and verify
1712	channel.DeleteAt = 0
1713	_, nErr = ss.Channel().Update(channel)
1714	require.NoError(t, nErr)
1715	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1716	require.NoError(t, err)
1717	require.Len(t, channelMembers, 1)
1718
1719	// No result if GroupChannel deleted
1720	_, err = ss.Group().DeleteGroupSyncable(group.Id, channel.Id, model.GroupSyncableTypeChannel)
1721	require.NoError(t, err)
1722	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1723	require.NoError(t, err)
1724	require.Empty(t, channelMembers)
1725
1726	// reset GroupChannel and verify
1727	_, err = ss.Group().UpdateGroupSyncable(&pristineSyncable)
1728	require.NoError(t, err)
1729	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1730	require.NoError(t, err)
1731	require.Len(t, channelMembers, 1)
1732
1733	// No result if GroupMember deleted
1734	_, err = ss.Group().DeleteMember(group.Id, user.Id)
1735	require.NoError(t, err)
1736	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1737	require.NoError(t, err)
1738	require.Empty(t, channelMembers)
1739
1740	// restore group member and verify
1741	_, err = ss.Group().UpsertMember(group.Id, user.Id)
1742	require.NoError(t, err)
1743	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1744	require.NoError(t, err)
1745	require.Len(t, channelMembers, 1)
1746
1747	// Adding Channel (ChannelMemberHistory) should stop returning result
1748	nErr = ss.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis())
1749	require.NoError(t, nErr)
1750	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1751	require.NoError(t, err)
1752	require.Empty(t, channelMembers)
1753
1754	// Leaving Channel (ChannelMemberHistory) should still not return result
1755	nErr = ss.ChannelMemberHistory().LogLeaveEvent(user.Id, channel.Id, model.GetMillis())
1756	require.NoError(t, nErr)
1757	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1758	require.NoError(t, err)
1759	require.Empty(t, channelMembers)
1760
1761	// Purging ChannelMemberHistory re-returns the result
1762	_, _, nErr = ss.ChannelMemberHistory().PermanentDeleteBatchForRetentionPolicies(
1763		0, model.GetMillis()+1, 100, model.RetentionPolicyCursor{})
1764	require.NoError(t, nErr)
1765	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, false)
1766	require.NoError(t, err)
1767	require.Len(t, channelMembers, 1)
1768
1769	// If includeRemovedMembers is set to true, removed members should be added back in
1770	nErr = ss.ChannelMemberHistory().LogLeaveEvent(user.Id, channel.Id, model.GetMillis())
1771	require.NoError(t, nErr)
1772	channelMembers, err = ss.Group().ChannelMembersToAdd(0, nil, true)
1773	require.NoError(t, err)
1774	require.Len(t, channelMembers, 1)
1775}
1776
1777func testChannelMembersToAddSingleChannel(t *testing.T, ss store.Store) {
1778	group1, err := ss.Group().Create(&model.Group{
1779		Name:        model.NewString(model.NewId()),
1780		DisplayName: "TeamMembersToAdd Test Group",
1781		RemoteId:    model.NewId(),
1782		Source:      model.GroupSourceLdap,
1783	})
1784	require.NoError(t, err)
1785
1786	group2, err := ss.Group().Create(&model.Group{
1787		Name:        model.NewString(model.NewId()),
1788		DisplayName: "TeamMembersToAdd Test Group",
1789		RemoteId:    model.NewId(),
1790		Source:      model.GroupSourceLdap,
1791	})
1792	require.NoError(t, err)
1793
1794	user1 := &model.User{
1795		Email:    MakeEmail(),
1796		Username: model.NewId(),
1797	}
1798	user1, nErr := ss.User().Save(user1)
1799	require.NoError(t, nErr)
1800
1801	user2 := &model.User{
1802		Email:    MakeEmail(),
1803		Username: model.NewId(),
1804	}
1805	user2, nErr = ss.User().Save(user2)
1806	require.NoError(t, nErr)
1807
1808	user3 := &model.User{
1809		Email:    MakeEmail(),
1810		Username: model.NewId(),
1811	}
1812	user3, nErr = ss.User().Save(user3)
1813	require.NoError(t, nErr)
1814
1815	for _, user := range []*model.User{user1, user2} {
1816		_, err = ss.Group().UpsertMember(group1.Id, user.Id)
1817		require.NoError(t, err)
1818	}
1819	_, err = ss.Group().UpsertMember(group2.Id, user3.Id)
1820	require.NoError(t, err)
1821
1822	channel1 := &model.Channel{
1823		DisplayName: "Name",
1824		Name:        "z-z-" + model.NewId() + "a",
1825		Type:        model.ChannelTypeOpen,
1826	}
1827	channel1, nErr = ss.Channel().Save(channel1, 999)
1828	require.NoError(t, nErr)
1829
1830	channel2 := &model.Channel{
1831		DisplayName: "Name",
1832		Name:        "z-z-" + model.NewId() + "a",
1833		Type:        model.ChannelTypeOpen,
1834	}
1835	channel2, nErr = ss.Channel().Save(channel2, 999)
1836	require.NoError(t, nErr)
1837
1838	_, err = ss.Group().CreateGroupSyncable(model.NewGroupChannel(group1.Id, channel1.Id, true))
1839	require.NoError(t, err)
1840
1841	_, err = ss.Group().CreateGroupSyncable(model.NewGroupChannel(group2.Id, channel2.Id, true))
1842	require.NoError(t, err)
1843
1844	channelMembers, err := ss.Group().ChannelMembersToAdd(0, nil, false)
1845	require.NoError(t, err)
1846	require.GreaterOrEqual(t, len(channelMembers), 3)
1847
1848	channelMembers, err = ss.Group().ChannelMembersToAdd(0, &channel1.Id, false)
1849	require.NoError(t, err)
1850	require.Len(t, channelMembers, 2)
1851
1852	channelMembers, err = ss.Group().ChannelMembersToAdd(0, &channel2.Id, false)
1853	require.NoError(t, err)
1854	require.Len(t, channelMembers, 1)
1855}
1856
1857func testTeamMembersToRemove(t *testing.T, ss store.Store) {
1858	data := pendingMemberRemovalsDataSetup(t, ss)
1859
1860	// one result when both users are in the group (for user C)
1861	teamMembers, err := ss.Group().TeamMembersToRemove(nil)
1862	require.NoError(t, err)
1863	require.Len(t, teamMembers, 1)
1864	require.Equal(t, data.UserC.Id, teamMembers[0].UserId)
1865
1866	_, err = ss.Group().DeleteMember(data.Group.Id, data.UserB.Id)
1867	require.NoError(t, err)
1868
1869	// user b and c should now be returned
1870	teamMembers, err = ss.Group().TeamMembersToRemove(nil)
1871	require.NoError(t, err)
1872	require.Len(t, teamMembers, 2)
1873
1874	var userIDs []string
1875	for _, item := range teamMembers {
1876		userIDs = append(userIDs, item.UserId)
1877	}
1878	require.Contains(t, userIDs, data.UserB.Id)
1879	require.Contains(t, userIDs, data.UserC.Id)
1880	require.Equal(t, data.ConstrainedTeam.Id, teamMembers[0].TeamId)
1881	require.Equal(t, data.ConstrainedTeam.Id, teamMembers[1].TeamId)
1882
1883	_, err = ss.Group().DeleteMember(data.Group.Id, data.UserA.Id)
1884	require.NoError(t, err)
1885
1886	teamMembers, err = ss.Group().TeamMembersToRemove(nil)
1887	require.NoError(t, err)
1888	require.Len(t, teamMembers, 3)
1889
1890	// Make one of them a bot
1891	teamMembers, err = ss.Group().TeamMembersToRemove(nil)
1892	require.NoError(t, err)
1893	teamMember := teamMembers[0]
1894	bot := &model.Bot{
1895		UserId:      teamMember.UserId,
1896		Username:    "un_" + model.NewId(),
1897		DisplayName: "dn_" + model.NewId(),
1898		OwnerId:     teamMember.UserId,
1899	}
1900	bot, nErr := ss.Bot().Save(bot)
1901	require.NoError(t, nErr)
1902
1903	// verify that bot is not returned in results
1904	teamMembers, err = ss.Group().TeamMembersToRemove(nil)
1905	require.NoError(t, err)
1906	require.Len(t, teamMembers, 2)
1907
1908	// delete the bot
1909	nErr = ss.Bot().PermanentDelete(bot.UserId)
1910	require.NoError(t, nErr)
1911
1912	// Should be back to 3 users
1913	teamMembers, err = ss.Group().TeamMembersToRemove(nil)
1914	require.NoError(t, err)
1915	require.Len(t, teamMembers, 3)
1916
1917	// add users back to groups
1918	res := ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserA.Id)
1919	require.NoError(t, res)
1920	res = ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserB.Id)
1921	require.NoError(t, res)
1922	res = ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserC.Id)
1923	require.NoError(t, res)
1924	nErr = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserA.Id)
1925	require.NoError(t, nErr)
1926	nErr = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserB.Id)
1927	require.NoError(t, nErr)
1928	nErr = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserC.Id)
1929	require.NoError(t, nErr)
1930}
1931
1932func testTeamMembersToRemoveSingleTeam(t *testing.T, ss store.Store) {
1933	user1 := &model.User{
1934		Email:    MakeEmail(),
1935		Username: model.NewId(),
1936	}
1937	user1, err := ss.User().Save(user1)
1938	require.NoError(t, err)
1939
1940	user2 := &model.User{
1941		Email:    MakeEmail(),
1942		Username: model.NewId(),
1943	}
1944	user2, err = ss.User().Save(user2)
1945	require.NoError(t, err)
1946
1947	user3 := &model.User{
1948		Email:    MakeEmail(),
1949		Username: model.NewId(),
1950	}
1951	user3, err = ss.User().Save(user3)
1952	require.NoError(t, err)
1953
1954	team1 := &model.Team{
1955		DisplayName:      "Name",
1956		Description:      "Some description",
1957		CompanyName:      "Some company name",
1958		AllowOpenInvite:  false,
1959		InviteId:         "inviteid0",
1960		Name:             "z-z-" + model.NewId() + "a",
1961		Email:            "success+" + model.NewId() + "@simulator.amazonses.com",
1962		Type:             model.TeamOpen,
1963		GroupConstrained: model.NewBool(true),
1964	}
1965	team1, nErr := ss.Team().Save(team1)
1966	require.NoError(t, nErr)
1967
1968	team2 := &model.Team{
1969		DisplayName:      "Name",
1970		Description:      "Some description",
1971		CompanyName:      "Some company name",
1972		AllowOpenInvite:  false,
1973		InviteId:         "inviteid0",
1974		Name:             "z-z-" + model.NewId() + "a",
1975		Email:            "success+" + model.NewId() + "@simulator.amazonses.com",
1976		Type:             model.TeamOpen,
1977		GroupConstrained: model.NewBool(true),
1978	}
1979	team2, nErr = ss.Team().Save(team2)
1980	require.NoError(t, nErr)
1981
1982	for _, user := range []*model.User{user1, user2} {
1983		_, nErr = ss.Team().SaveMember(&model.TeamMember{
1984			TeamId: team1.Id,
1985			UserId: user.Id,
1986		}, 999)
1987		require.NoError(t, nErr)
1988	}
1989
1990	_, nErr = ss.Team().SaveMember(&model.TeamMember{
1991		TeamId: team2.Id,
1992		UserId: user3.Id,
1993	}, 999)
1994	require.NoError(t, nErr)
1995
1996	teamMembers, err := ss.Group().TeamMembersToRemove(nil)
1997	require.NoError(t, err)
1998	require.Len(t, teamMembers, 3)
1999
2000	teamMembers, err = ss.Group().TeamMembersToRemove(&team1.Id)
2001	require.NoError(t, err)
2002	require.Len(t, teamMembers, 2)
2003
2004	teamMembers, err = ss.Group().TeamMembersToRemove(&team2.Id)
2005	require.NoError(t, err)
2006	require.Len(t, teamMembers, 1)
2007}
2008
2009func testChannelMembersToRemove(t *testing.T, ss store.Store) {
2010	data := pendingMemberRemovalsDataSetup(t, ss)
2011
2012	// one result when both users are in the group (for user C)
2013	channelMembers, err := ss.Group().ChannelMembersToRemove(nil)
2014	require.NoError(t, err)
2015	require.Len(t, channelMembers, 1)
2016	require.Equal(t, data.UserC.Id, channelMembers[0].UserId)
2017
2018	_, err = ss.Group().DeleteMember(data.Group.Id, data.UserB.Id)
2019	require.NoError(t, err)
2020
2021	// user b and c should now be returned
2022	channelMembers, err = ss.Group().ChannelMembersToRemove(nil)
2023	require.NoError(t, err)
2024	require.Len(t, channelMembers, 2)
2025
2026	var userIDs []string
2027	for _, item := range channelMembers {
2028		userIDs = append(userIDs, item.UserId)
2029	}
2030	require.Contains(t, userIDs, data.UserB.Id)
2031	require.Contains(t, userIDs, data.UserC.Id)
2032	require.Equal(t, data.ConstrainedChannel.Id, channelMembers[0].ChannelId)
2033	require.Equal(t, data.ConstrainedChannel.Id, channelMembers[1].ChannelId)
2034
2035	_, err = ss.Group().DeleteMember(data.Group.Id, data.UserA.Id)
2036	require.NoError(t, err)
2037
2038	channelMembers, err = ss.Group().ChannelMembersToRemove(nil)
2039	require.NoError(t, err)
2040	require.Len(t, channelMembers, 3)
2041
2042	// Make one of them a bot
2043	channelMembers, err = ss.Group().ChannelMembersToRemove(nil)
2044	require.NoError(t, err)
2045	channelMember := channelMembers[0]
2046	bot := &model.Bot{
2047		UserId:      channelMember.UserId,
2048		Username:    "un_" + model.NewId(),
2049		DisplayName: "dn_" + model.NewId(),
2050		OwnerId:     channelMember.UserId,
2051	}
2052	bot, nErr := ss.Bot().Save(bot)
2053	require.NoError(t, nErr)
2054
2055	// verify that bot is not returned in results
2056	channelMembers, err = ss.Group().ChannelMembersToRemove(nil)
2057	require.NoError(t, err)
2058	require.Len(t, channelMembers, 2)
2059
2060	// delete the bot
2061	nErr = ss.Bot().PermanentDelete(bot.UserId)
2062	require.NoError(t, nErr)
2063
2064	// Should be back to 3 users
2065	channelMembers, err = ss.Group().ChannelMembersToRemove(nil)
2066	require.NoError(t, err)
2067	require.Len(t, channelMembers, 3)
2068
2069	// add users back to groups
2070	res := ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserA.Id)
2071	require.NoError(t, res)
2072	res = ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserB.Id)
2073	require.NoError(t, res)
2074	res = ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserC.Id)
2075	require.NoError(t, res)
2076	nErr = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserA.Id)
2077	require.NoError(t, nErr)
2078	nErr = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserB.Id)
2079	require.NoError(t, nErr)
2080	nErr = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserC.Id)
2081	require.NoError(t, nErr)
2082}
2083
2084func testChannelMembersToRemoveSingleChannel(t *testing.T, ss store.Store) {
2085	user1 := &model.User{
2086		Email:    MakeEmail(),
2087		Username: model.NewId(),
2088	}
2089	user1, err := ss.User().Save(user1)
2090	require.NoError(t, err)
2091
2092	user2 := &model.User{
2093		Email:    MakeEmail(),
2094		Username: model.NewId(),
2095	}
2096	user2, err = ss.User().Save(user2)
2097	require.NoError(t, err)
2098
2099	user3 := &model.User{
2100		Email:    MakeEmail(),
2101		Username: model.NewId(),
2102	}
2103	user3, err = ss.User().Save(user3)
2104	require.NoError(t, err)
2105
2106	channel1 := &model.Channel{
2107		DisplayName:      "Name",
2108		Name:             "z-z-" + model.NewId() + "a",
2109		Type:             model.ChannelTypeOpen,
2110		GroupConstrained: model.NewBool(true),
2111	}
2112	channel1, nErr := ss.Channel().Save(channel1, 999)
2113	require.NoError(t, nErr)
2114
2115	channel2 := &model.Channel{
2116		DisplayName:      "Name",
2117		Name:             "z-z-" + model.NewId() + "a",
2118		Type:             model.ChannelTypeOpen,
2119		GroupConstrained: model.NewBool(true),
2120	}
2121	channel2, nErr = ss.Channel().Save(channel2, 999)
2122	require.NoError(t, nErr)
2123
2124	for _, user := range []*model.User{user1, user2} {
2125		_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
2126			ChannelId:   channel1.Id,
2127			UserId:      user.Id,
2128			NotifyProps: model.GetDefaultChannelNotifyProps(),
2129		})
2130		require.NoError(t, nErr)
2131	}
2132
2133	_, nErr = ss.Channel().SaveMember(&model.ChannelMember{
2134		ChannelId:   channel2.Id,
2135		UserId:      user3.Id,
2136		NotifyProps: model.GetDefaultChannelNotifyProps(),
2137	})
2138	require.NoError(t, nErr)
2139
2140	channelMembers, err := ss.Group().ChannelMembersToRemove(nil)
2141	require.NoError(t, err)
2142	require.Len(t, channelMembers, 3)
2143
2144	channelMembers, err = ss.Group().ChannelMembersToRemove(&channel1.Id)
2145	require.NoError(t, err)
2146	require.Len(t, channelMembers, 2)
2147
2148	channelMembers, err = ss.Group().ChannelMembersToRemove(&channel2.Id)
2149	require.NoError(t, err)
2150	require.Len(t, channelMembers, 1)
2151}
2152
2153type removalsData struct {
2154	UserA                *model.User
2155	UserB                *model.User
2156	UserC                *model.User
2157	ConstrainedChannel   *model.Channel
2158	UnconstrainedChannel *model.Channel
2159	ConstrainedTeam      *model.Team
2160	UnconstrainedTeam    *model.Team
2161	Group                *model.Group
2162}
2163
2164func pendingMemberRemovalsDataSetup(t *testing.T, ss store.Store) *removalsData {
2165	// create group
2166	group, err := ss.Group().Create(&model.Group{
2167		Name:        model.NewString(model.NewId()),
2168		DisplayName: "Pending[Channel|Team]MemberRemovals Test Group",
2169		RemoteId:    model.NewId(),
2170		Source:      model.GroupSourceLdap,
2171	})
2172	require.NoError(t, err)
2173
2174	// create users
2175	// userA will get removed from the group
2176	userA := &model.User{
2177		Email:    MakeEmail(),
2178		Username: model.NewId(),
2179	}
2180	userA, nErr := ss.User().Save(userA)
2181	require.NoError(t, nErr)
2182
2183	// userB will not get removed from the group
2184	userB := &model.User{
2185		Email:    MakeEmail(),
2186		Username: model.NewId(),
2187	}
2188	userB, nErr = ss.User().Save(userB)
2189	require.NoError(t, nErr)
2190
2191	// userC was never in the group
2192	userC := &model.User{
2193		Email:    MakeEmail(),
2194		Username: model.NewId(),
2195	}
2196	userC, nErr = ss.User().Save(userC)
2197	require.NoError(t, nErr)
2198
2199	// add users to group (but not userC)
2200	_, err = ss.Group().UpsertMember(group.Id, userA.Id)
2201	require.NoError(t, err)
2202
2203	_, err = ss.Group().UpsertMember(group.Id, userB.Id)
2204	require.NoError(t, err)
2205
2206	// create channels
2207	channelConstrained := &model.Channel{
2208		TeamId:           model.NewId(),
2209		DisplayName:      "A Name",
2210		Name:             model.NewId(),
2211		Type:             model.ChannelTypePrivate,
2212		GroupConstrained: model.NewBool(true),
2213	}
2214	channelConstrained, nErr = ss.Channel().Save(channelConstrained, 9999)
2215	require.NoError(t, nErr)
2216
2217	channelUnconstrained := &model.Channel{
2218		TeamId:      model.NewId(),
2219		DisplayName: "A Name",
2220		Name:        model.NewId(),
2221		Type:        model.ChannelTypePrivate,
2222	}
2223	channelUnconstrained, nErr = ss.Channel().Save(channelUnconstrained, 9999)
2224	require.NoError(t, nErr)
2225
2226	// create teams
2227	teamConstrained := &model.Team{
2228		DisplayName:      "Name",
2229		Description:      "Some description",
2230		CompanyName:      "Some company name",
2231		AllowOpenInvite:  false,
2232		InviteId:         "inviteid0",
2233		Name:             "z-z-" + model.NewId() + "a",
2234		Email:            "success+" + model.NewId() + "@simulator.amazonses.com",
2235		Type:             model.TeamInvite,
2236		GroupConstrained: model.NewBool(true),
2237	}
2238	teamConstrained, nErr = ss.Team().Save(teamConstrained)
2239	require.NoError(t, nErr)
2240
2241	teamUnconstrained := &model.Team{
2242		DisplayName:     "Name",
2243		Description:     "Some description",
2244		CompanyName:     "Some company name",
2245		AllowOpenInvite: false,
2246		InviteId:        "inviteid1",
2247		Name:            "z-z-" + model.NewId() + "a",
2248		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
2249		Type:            model.TeamInvite,
2250	}
2251	teamUnconstrained, nErr = ss.Team().Save(teamUnconstrained)
2252	require.NoError(t, nErr)
2253
2254	// create groupteams
2255	_, err = ss.Group().CreateGroupSyncable(model.NewGroupTeam(group.Id, teamConstrained.Id, true))
2256	require.NoError(t, err)
2257
2258	_, err = ss.Group().CreateGroupSyncable(model.NewGroupTeam(group.Id, teamUnconstrained.Id, true))
2259	require.NoError(t, err)
2260
2261	// create groupchannels
2262	_, err = ss.Group().CreateGroupSyncable(model.NewGroupChannel(group.Id, channelConstrained.Id, true))
2263	require.NoError(t, err)
2264
2265	_, err = ss.Group().CreateGroupSyncable(model.NewGroupChannel(group.Id, channelUnconstrained.Id, true))
2266	require.NoError(t, err)
2267
2268	// add users to teams
2269	userIDTeamIDs := [][]string{
2270		{userA.Id, teamConstrained.Id},
2271		{userB.Id, teamConstrained.Id},
2272		{userC.Id, teamConstrained.Id},
2273		{userA.Id, teamUnconstrained.Id},
2274		{userB.Id, teamUnconstrained.Id},
2275		{userC.Id, teamUnconstrained.Id},
2276	}
2277
2278	for _, item := range userIDTeamIDs {
2279		_, nErr = ss.Team().SaveMember(&model.TeamMember{
2280			UserId: item[0],
2281			TeamId: item[1],
2282		}, 99)
2283		require.NoError(t, nErr)
2284	}
2285
2286	// add users to channels
2287	userIDChannelIDs := [][]string{
2288		{userA.Id, channelConstrained.Id},
2289		{userB.Id, channelConstrained.Id},
2290		{userC.Id, channelConstrained.Id},
2291		{userA.Id, channelUnconstrained.Id},
2292		{userB.Id, channelUnconstrained.Id},
2293		{userC.Id, channelUnconstrained.Id},
2294	}
2295
2296	for _, item := range userIDChannelIDs {
2297		_, err := ss.Channel().SaveMember(&model.ChannelMember{
2298			UserId:      item[0],
2299			ChannelId:   item[1],
2300			NotifyProps: model.GetDefaultChannelNotifyProps(),
2301		})
2302		require.NoError(t, err)
2303	}
2304
2305	return &removalsData{
2306		UserA:                userA,
2307		UserB:                userB,
2308		UserC:                userC,
2309		ConstrainedChannel:   channelConstrained,
2310		UnconstrainedChannel: channelUnconstrained,
2311		ConstrainedTeam:      teamConstrained,
2312		UnconstrainedTeam:    teamUnconstrained,
2313		Group:                group,
2314	}
2315}
2316
2317func testGetGroupsByChannel(t *testing.T, ss store.Store) {
2318	// Create Channel1
2319	channel1 := &model.Channel{
2320		TeamId:      model.NewId(),
2321		DisplayName: "Channel1",
2322		Name:        model.NewId(),
2323		Type:        model.ChannelTypeOpen,
2324	}
2325	channel1, err := ss.Channel().Save(channel1, 9999)
2326	require.NoError(t, err)
2327
2328	// Create Groups 1, 2 and a deleted group
2329	group1, err := ss.Group().Create(&model.Group{
2330		Name:           model.NewString(model.NewId()),
2331		DisplayName:    "group-1",
2332		RemoteId:       model.NewId(),
2333		Source:         model.GroupSourceLdap,
2334		AllowReference: true,
2335	})
2336	require.NoError(t, err)
2337
2338	group2, err := ss.Group().Create(&model.Group{
2339		Name:           model.NewString(model.NewId()),
2340		DisplayName:    "group-2",
2341		RemoteId:       model.NewId(),
2342		Source:         model.GroupSourceLdap,
2343		AllowReference: false,
2344	})
2345	require.NoError(t, err)
2346
2347	deletedGroup, err := ss.Group().Create(&model.Group{
2348		Name:           model.NewString(model.NewId()),
2349		DisplayName:    "group-deleted",
2350		RemoteId:       model.NewId(),
2351		Source:         model.GroupSourceLdap,
2352		AllowReference: true,
2353		DeleteAt:       1,
2354	})
2355	require.NoError(t, err)
2356
2357	// And associate them with Channel1
2358	for _, g := range []*model.Group{group1, group2, deletedGroup} {
2359		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
2360			AutoAdd:    true,
2361			SyncableId: channel1.Id,
2362			Type:       model.GroupSyncableTypeChannel,
2363			GroupId:    g.Id,
2364		})
2365		require.NoError(t, err)
2366	}
2367
2368	// Create Channel2
2369	channel2 := &model.Channel{
2370		TeamId:      model.NewId(),
2371		DisplayName: "Channel2",
2372		Name:        model.NewId(),
2373		Type:        model.ChannelTypeOpen,
2374	}
2375	channel2, nErr := ss.Channel().Save(channel2, 9999)
2376	require.NoError(t, nErr)
2377
2378	// Create Group3
2379	group3, err := ss.Group().Create(&model.Group{
2380		Name:           model.NewString(model.NewId()),
2381		DisplayName:    "group-3",
2382		RemoteId:       model.NewId(),
2383		Source:         model.GroupSourceLdap,
2384		AllowReference: true,
2385	})
2386	require.NoError(t, err)
2387
2388	// And associate it to Channel2
2389	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
2390		AutoAdd:    true,
2391		SyncableId: channel2.Id,
2392		Type:       model.GroupSyncableTypeChannel,
2393		GroupId:    group3.Id,
2394	})
2395	require.NoError(t, err)
2396
2397	// add members
2398	u1 := &model.User{
2399		Email:    MakeEmail(),
2400		Username: model.NewId(),
2401	}
2402	user1, err := ss.User().Save(u1)
2403	require.NoError(t, err)
2404
2405	u2 := &model.User{
2406		Email:    MakeEmail(),
2407		Username: model.NewId(),
2408	}
2409	user2, err := ss.User().Save(u2)
2410	require.NoError(t, err)
2411
2412	_, err = ss.Group().UpsertMember(group1.Id, user1.Id)
2413	require.NoError(t, err)
2414
2415	_, err = ss.Group().UpsertMember(group1.Id, user2.Id)
2416	require.NoError(t, err)
2417
2418	user2.DeleteAt = 1
2419	_, err = ss.User().Update(user2, true)
2420	require.NoError(t, err)
2421
2422	group1WithMemberCount := *group1
2423	group1WithMemberCount.MemberCount = model.NewInt(1)
2424
2425	group2WithMemberCount := *group2
2426	group2WithMemberCount.MemberCount = model.NewInt(0)
2427
2428	group1WSA := &model.GroupWithSchemeAdmin{Group: *group1, SchemeAdmin: model.NewBool(false)}
2429	group2WSA := &model.GroupWithSchemeAdmin{Group: *group2, SchemeAdmin: model.NewBool(false)}
2430	group3WSA := &model.GroupWithSchemeAdmin{Group: *group3, SchemeAdmin: model.NewBool(false)}
2431
2432	testCases := []struct {
2433		Name       string
2434		ChannelId  string
2435		Page       int
2436		PerPage    int
2437		Result     []*model.GroupWithSchemeAdmin
2438		Opts       model.GroupSearchOpts
2439		TotalCount *int64
2440	}{
2441		{
2442			Name:       "Get the two Groups for Channel1",
2443			ChannelId:  channel1.Id,
2444			Opts:       model.GroupSearchOpts{},
2445			Page:       0,
2446			PerPage:    60,
2447			Result:     []*model.GroupWithSchemeAdmin{group1WSA, group2WSA},
2448			TotalCount: model.NewInt64(2),
2449		},
2450		{
2451			Name:      "Get first Group for Channel1 with page 0 with 1 element",
2452			ChannelId: channel1.Id,
2453			Opts:      model.GroupSearchOpts{},
2454			Page:      0,
2455			PerPage:   1,
2456			Result:    []*model.GroupWithSchemeAdmin{group1WSA},
2457		},
2458		{
2459			Name:      "Get second Group for Channel1 with page 1 with 1 element",
2460			ChannelId: channel1.Id,
2461			Opts:      model.GroupSearchOpts{},
2462			Page:      1,
2463			PerPage:   1,
2464			Result:    []*model.GroupWithSchemeAdmin{group2WSA},
2465		},
2466		{
2467			Name:      "Get third Group for Channel2",
2468			ChannelId: channel2.Id,
2469			Opts:      model.GroupSearchOpts{},
2470			Page:      0,
2471			PerPage:   60,
2472			Result:    []*model.GroupWithSchemeAdmin{group3WSA},
2473		},
2474		{
2475			Name:       "Get empty Groups for a fake id",
2476			ChannelId:  model.NewId(),
2477			Opts:       model.GroupSearchOpts{},
2478			Page:       0,
2479			PerPage:    60,
2480			Result:     []*model.GroupWithSchemeAdmin{},
2481			TotalCount: model.NewInt64(0),
2482		},
2483		{
2484			Name:       "Get group matching name",
2485			ChannelId:  channel1.Id,
2486			Opts:       model.GroupSearchOpts{Q: string([]rune(*group1.Name)[2:10])}, // very low change of a name collision
2487			Page:       0,
2488			PerPage:    100,
2489			Result:     []*model.GroupWithSchemeAdmin{group1WSA},
2490			TotalCount: model.NewInt64(1),
2491		},
2492		{
2493			Name:       "Get group matching display name",
2494			ChannelId:  channel1.Id,
2495			Opts:       model.GroupSearchOpts{Q: "rouP-1"},
2496			Page:       0,
2497			PerPage:    100,
2498			Result:     []*model.GroupWithSchemeAdmin{group1WSA},
2499			TotalCount: model.NewInt64(1),
2500		},
2501		{
2502			Name:       "Get group matching multiple display names",
2503			ChannelId:  channel1.Id,
2504			Opts:       model.GroupSearchOpts{Q: "roUp-"},
2505			Page:       0,
2506			PerPage:    100,
2507			Result:     []*model.GroupWithSchemeAdmin{group1WSA, group2WSA},
2508			TotalCount: model.NewInt64(2),
2509		},
2510		{
2511			Name:      "Include member counts",
2512			ChannelId: channel1.Id,
2513			Opts:      model.GroupSearchOpts{IncludeMemberCount: true},
2514			Page:      0,
2515			PerPage:   2,
2516			Result: []*model.GroupWithSchemeAdmin{
2517				{Group: group1WithMemberCount, SchemeAdmin: model.NewBool(false)},
2518				{Group: group2WithMemberCount, SchemeAdmin: model.NewBool(false)},
2519			},
2520		},
2521		{
2522			Name:      "Include allow reference",
2523			ChannelId: channel1.Id,
2524			Opts:      model.GroupSearchOpts{FilterAllowReference: true},
2525			Page:      0,
2526			PerPage:   100,
2527			Result:    []*model.GroupWithSchemeAdmin{group1WSA},
2528		},
2529	}
2530
2531	for _, tc := range testCases {
2532		t.Run(tc.Name, func(t *testing.T) {
2533			if tc.Opts.PageOpts == nil {
2534				tc.Opts.PageOpts = &model.PageOpts{}
2535			}
2536			tc.Opts.PageOpts.Page = tc.Page
2537			tc.Opts.PageOpts.PerPage = tc.PerPage
2538			groups, err := ss.Group().GetGroupsByChannel(tc.ChannelId, tc.Opts)
2539			require.NoError(t, err)
2540			require.ElementsMatch(t, tc.Result, groups)
2541			if tc.TotalCount != nil {
2542				var count int64
2543				count, err = ss.Group().CountGroupsByChannel(tc.ChannelId, tc.Opts)
2544				require.NoError(t, err)
2545				require.Equal(t, *tc.TotalCount, count)
2546			}
2547		})
2548	}
2549}
2550
2551func testGetGroupsAssociatedToChannelsByTeam(t *testing.T, ss store.Store) {
2552	// Create Team1
2553	team1 := &model.Team{
2554		DisplayName:     "Team1",
2555		Description:     model.NewId(),
2556		CompanyName:     model.NewId(),
2557		AllowOpenInvite: false,
2558		InviteId:        model.NewId(),
2559		Name:            "zz" + model.NewId(),
2560		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
2561		Type:            model.TeamOpen,
2562	}
2563	team1, errt := ss.Team().Save(team1)
2564	require.NoError(t, errt)
2565
2566	// Create Channel1
2567	channel1 := &model.Channel{
2568		TeamId:      team1.Id,
2569		DisplayName: "Channel1",
2570		Name:        model.NewId(),
2571		Type:        model.ChannelTypeOpen,
2572	}
2573	channel1, err := ss.Channel().Save(channel1, 9999)
2574	require.NoError(t, err)
2575
2576	// Create Groups 1, 2 and a deleted group
2577	group1, err := ss.Group().Create(&model.Group{
2578		Name:           model.NewString(model.NewId()),
2579		DisplayName:    "group-1",
2580		RemoteId:       model.NewId(),
2581		Source:         model.GroupSourceLdap,
2582		AllowReference: false,
2583	})
2584	require.NoError(t, err)
2585
2586	group2, err := ss.Group().Create(&model.Group{
2587		Name:           model.NewString(model.NewId()),
2588		DisplayName:    "group-2",
2589		RemoteId:       model.NewId(),
2590		Source:         model.GroupSourceLdap,
2591		AllowReference: true,
2592	})
2593	require.NoError(t, err)
2594
2595	deletedGroup, err := ss.Group().Create(&model.Group{
2596		Name:           model.NewString(model.NewId()),
2597		DisplayName:    "group-deleted",
2598		RemoteId:       model.NewId(),
2599		Source:         model.GroupSourceLdap,
2600		AllowReference: true,
2601		DeleteAt:       1,
2602	})
2603	require.NoError(t, err)
2604
2605	// And associate them with Channel1
2606	for _, g := range []*model.Group{group1, group2, deletedGroup} {
2607		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
2608			AutoAdd:    true,
2609			SyncableId: channel1.Id,
2610			Type:       model.GroupSyncableTypeChannel,
2611			GroupId:    g.Id,
2612		})
2613		require.NoError(t, err)
2614	}
2615
2616	// Create Channel2
2617	channel2 := &model.Channel{
2618		TeamId:      team1.Id,
2619		DisplayName: "Channel2",
2620		Name:        model.NewId(),
2621		Type:        model.ChannelTypeOpen,
2622	}
2623	channel2, err = ss.Channel().Save(channel2, 9999)
2624	require.NoError(t, err)
2625
2626	// Create Group3
2627	group3, err := ss.Group().Create(&model.Group{
2628		Name:           model.NewString(model.NewId()),
2629		DisplayName:    "group-3",
2630		RemoteId:       model.NewId(),
2631		Source:         model.GroupSourceLdap,
2632		AllowReference: true,
2633	})
2634	require.NoError(t, err)
2635
2636	// And associate it to Channel2
2637	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
2638		AutoAdd:    true,
2639		SyncableId: channel2.Id,
2640		Type:       model.GroupSyncableTypeChannel,
2641		GroupId:    group3.Id,
2642	})
2643	require.NoError(t, err)
2644
2645	// add members
2646	u1 := &model.User{
2647		Email:    MakeEmail(),
2648		Username: model.NewId(),
2649	}
2650	user1, err := ss.User().Save(u1)
2651	require.NoError(t, err)
2652
2653	u2 := &model.User{
2654		Email:    MakeEmail(),
2655		Username: model.NewId(),
2656	}
2657	user2, err := ss.User().Save(u2)
2658	require.NoError(t, err)
2659
2660	_, err = ss.Group().UpsertMember(group1.Id, user1.Id)
2661	require.NoError(t, err)
2662
2663	_, err = ss.Group().UpsertMember(group1.Id, user2.Id)
2664	require.NoError(t, err)
2665
2666	user2.DeleteAt = 1
2667	_, err = ss.User().Update(user2, true)
2668	require.NoError(t, err)
2669
2670	group1WithMemberCount := *group1
2671	group1WithMemberCount.MemberCount = model.NewInt(1)
2672
2673	group2WithMemberCount := *group2
2674	group2WithMemberCount.MemberCount = model.NewInt(0)
2675
2676	group3WithMemberCount := *group3
2677	group3WithMemberCount.MemberCount = model.NewInt(0)
2678
2679	group1WSA := &model.GroupWithSchemeAdmin{Group: *group1, SchemeAdmin: model.NewBool(false)}
2680	group2WSA := &model.GroupWithSchemeAdmin{Group: *group2, SchemeAdmin: model.NewBool(false)}
2681	group3WSA := &model.GroupWithSchemeAdmin{Group: *group3, SchemeAdmin: model.NewBool(false)}
2682
2683	testCases := []struct {
2684		Name    string
2685		TeamId  string
2686		Page    int
2687		PerPage int
2688		Result  map[string][]*model.GroupWithSchemeAdmin
2689		Opts    model.GroupSearchOpts
2690	}{
2691		{
2692			Name:    "Get the groups for Channel1 and Channel2",
2693			TeamId:  team1.Id,
2694			Opts:    model.GroupSearchOpts{},
2695			Page:    0,
2696			PerPage: 60,
2697			Result:  map[string][]*model.GroupWithSchemeAdmin{channel1.Id: {group1WSA, group2WSA}, channel2.Id: {group3WSA}},
2698		},
2699		{
2700			Name:    "Get first Group for Channel1 with page 0 with 1 element",
2701			TeamId:  team1.Id,
2702			Opts:    model.GroupSearchOpts{},
2703			Page:    0,
2704			PerPage: 1,
2705			Result:  map[string][]*model.GroupWithSchemeAdmin{channel1.Id: {group1WSA}},
2706		},
2707		{
2708			Name:    "Get second Group for Channel1 with page 1 with 1 element",
2709			TeamId:  team1.Id,
2710			Opts:    model.GroupSearchOpts{},
2711			Page:    1,
2712			PerPage: 1,
2713			Result:  map[string][]*model.GroupWithSchemeAdmin{channel1.Id: {group2WSA}},
2714		},
2715		{
2716			Name:    "Get empty Groups for a fake id",
2717			TeamId:  model.NewId(),
2718			Opts:    model.GroupSearchOpts{},
2719			Page:    0,
2720			PerPage: 60,
2721			Result:  map[string][]*model.GroupWithSchemeAdmin{},
2722		},
2723		{
2724			Name:    "Get group matching name",
2725			TeamId:  team1.Id,
2726			Opts:    model.GroupSearchOpts{Q: string([]rune(*group1.Name)[2:10])}, // very low chance of a name collision
2727			Page:    0,
2728			PerPage: 100,
2729			Result:  map[string][]*model.GroupWithSchemeAdmin{channel1.Id: {group1WSA}},
2730		},
2731		{
2732			Name:    "Get group matching display name",
2733			TeamId:  team1.Id,
2734			Opts:    model.GroupSearchOpts{Q: "rouP-1"},
2735			Page:    0,
2736			PerPage: 100,
2737			Result:  map[string][]*model.GroupWithSchemeAdmin{channel1.Id: {group1WSA}},
2738		},
2739		{
2740			Name:    "Get group matching multiple display names",
2741			TeamId:  team1.Id,
2742			Opts:    model.GroupSearchOpts{Q: "roUp-"},
2743			Page:    0,
2744			PerPage: 100,
2745			Result:  map[string][]*model.GroupWithSchemeAdmin{channel1.Id: {group1WSA, group2WSA}, channel2.Id: {group3WSA}},
2746		},
2747		{
2748			Name:    "Include member counts",
2749			TeamId:  team1.Id,
2750			Opts:    model.GroupSearchOpts{IncludeMemberCount: true},
2751			Page:    0,
2752			PerPage: 10,
2753			Result: map[string][]*model.GroupWithSchemeAdmin{
2754				channel1.Id: {
2755					{Group: group1WithMemberCount, SchemeAdmin: model.NewBool(false)},
2756					{Group: group2WithMemberCount, SchemeAdmin: model.NewBool(false)},
2757				},
2758				channel2.Id: {
2759					{Group: group3WithMemberCount, SchemeAdmin: model.NewBool(false)},
2760				},
2761			},
2762		},
2763		{
2764			Name:    "Include allow reference",
2765			TeamId:  team1.Id,
2766			Opts:    model.GroupSearchOpts{FilterAllowReference: true},
2767			Page:    0,
2768			PerPage: 2,
2769			Result: map[string][]*model.GroupWithSchemeAdmin{
2770				channel1.Id: {
2771					group2WSA,
2772				},
2773				channel2.Id: {
2774					group3WSA,
2775				},
2776			},
2777		},
2778	}
2779
2780	for _, tc := range testCases {
2781		t.Run(tc.Name, func(t *testing.T) {
2782			if tc.Opts.PageOpts == nil {
2783				tc.Opts.PageOpts = &model.PageOpts{}
2784			}
2785			tc.Opts.PageOpts.Page = tc.Page
2786			tc.Opts.PageOpts.PerPage = tc.PerPage
2787			groups, err := ss.Group().GetGroupsAssociatedToChannelsByTeam(tc.TeamId, tc.Opts)
2788			require.NoError(t, err)
2789			assert.Equal(t, tc.Result, groups)
2790		})
2791	}
2792}
2793
2794func testGetGroupsByTeam(t *testing.T, ss store.Store) {
2795	// Create Team1
2796	team1 := &model.Team{
2797		DisplayName:     "Team1",
2798		Description:     model.NewId(),
2799		CompanyName:     model.NewId(),
2800		AllowOpenInvite: false,
2801		InviteId:        model.NewId(),
2802		Name:            "zz" + model.NewId(),
2803		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
2804		Type:            model.TeamOpen,
2805	}
2806	team1, err := ss.Team().Save(team1)
2807	require.NoError(t, err)
2808
2809	// Create Groups 1, 2 and a deleted group
2810	group1, err := ss.Group().Create(&model.Group{
2811		Name:           model.NewString(model.NewId()),
2812		DisplayName:    "group-1",
2813		RemoteId:       model.NewId(),
2814		Source:         model.GroupSourceLdap,
2815		AllowReference: false,
2816	})
2817	require.NoError(t, err)
2818
2819	group2, err := ss.Group().Create(&model.Group{
2820		Name:           model.NewString(model.NewId()),
2821		DisplayName:    "group-2",
2822		RemoteId:       model.NewId(),
2823		Source:         model.GroupSourceLdap,
2824		AllowReference: true,
2825	})
2826	require.NoError(t, err)
2827
2828	deletedGroup, err := ss.Group().Create(&model.Group{
2829		Name:           model.NewString(model.NewId()),
2830		DisplayName:    "group-deleted",
2831		RemoteId:       model.NewId(),
2832		Source:         model.GroupSourceLdap,
2833		AllowReference: true,
2834		DeleteAt:       1,
2835	})
2836	require.NoError(t, err)
2837
2838	// And associate them with Team1
2839	for _, g := range []*model.Group{group1, group2, deletedGroup} {
2840		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
2841			AutoAdd:    true,
2842			SyncableId: team1.Id,
2843			Type:       model.GroupSyncableTypeTeam,
2844			GroupId:    g.Id,
2845		})
2846		require.NoError(t, err)
2847	}
2848
2849	// Create Team2
2850	team2 := &model.Team{
2851		DisplayName:     "Team2",
2852		Description:     model.NewId(),
2853		CompanyName:     model.NewId(),
2854		AllowOpenInvite: false,
2855		InviteId:        model.NewId(),
2856		Name:            "zz" + model.NewId(),
2857		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
2858		Type:            model.TeamInvite,
2859	}
2860	team2, err = ss.Team().Save(team2)
2861	require.NoError(t, err)
2862
2863	// Create Group3
2864	group3, err := ss.Group().Create(&model.Group{
2865		Name:           model.NewString(model.NewId()),
2866		DisplayName:    "group-3",
2867		RemoteId:       model.NewId(),
2868		Source:         model.GroupSourceLdap,
2869		AllowReference: true,
2870	})
2871	require.NoError(t, err)
2872
2873	// And associate it to Team2
2874	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
2875		AutoAdd:    true,
2876		SyncableId: team2.Id,
2877		Type:       model.GroupSyncableTypeTeam,
2878		GroupId:    group3.Id,
2879	})
2880	require.NoError(t, err)
2881
2882	// add members
2883	u1 := &model.User{
2884		Email:    MakeEmail(),
2885		Username: model.NewId(),
2886	}
2887	user1, err := ss.User().Save(u1)
2888	require.NoError(t, err)
2889
2890	u2 := &model.User{
2891		Email:    MakeEmail(),
2892		Username: model.NewId(),
2893	}
2894	user2, err := ss.User().Save(u2)
2895	require.NoError(t, err)
2896
2897	_, err = ss.Group().UpsertMember(group1.Id, user1.Id)
2898	require.NoError(t, err)
2899
2900	_, err = ss.Group().UpsertMember(group1.Id, user2.Id)
2901	require.NoError(t, err)
2902
2903	user2.DeleteAt = 1
2904	_, err = ss.User().Update(user2, true)
2905	require.NoError(t, err)
2906
2907	_, err = ss.Group().UpsertMember(deletedGroup.Id, user1.Id)
2908	require.NoError(t, err)
2909
2910	group1WithMemberCount := *group1
2911	group1WithMemberCount.MemberCount = model.NewInt(1)
2912
2913	group2WithMemberCount := *group2
2914	group2WithMemberCount.MemberCount = model.NewInt(0)
2915
2916	group1WSA := &model.GroupWithSchemeAdmin{Group: *group1, SchemeAdmin: model.NewBool(false)}
2917	group2WSA := &model.GroupWithSchemeAdmin{Group: *group2, SchemeAdmin: model.NewBool(false)}
2918	group3WSA := &model.GroupWithSchemeAdmin{Group: *group3, SchemeAdmin: model.NewBool(false)}
2919
2920	testCases := []struct {
2921		Name       string
2922		TeamId     string
2923		Page       int
2924		PerPage    int
2925		Opts       model.GroupSearchOpts
2926		Result     []*model.GroupWithSchemeAdmin
2927		TotalCount *int64
2928	}{
2929		{
2930			Name:       "Get the two Groups for Team1",
2931			TeamId:     team1.Id,
2932			Opts:       model.GroupSearchOpts{},
2933			Page:       0,
2934			PerPage:    60,
2935			Result:     []*model.GroupWithSchemeAdmin{group1WSA, group2WSA},
2936			TotalCount: model.NewInt64(2),
2937		},
2938		{
2939			Name:    "Get first Group for Team1 with page 0 with 1 element",
2940			TeamId:  team1.Id,
2941			Opts:    model.GroupSearchOpts{},
2942			Page:    0,
2943			PerPage: 1,
2944			Result:  []*model.GroupWithSchemeAdmin{group1WSA},
2945		},
2946		{
2947			Name:    "Get second Group for Team1 with page 1 with 1 element",
2948			TeamId:  team1.Id,
2949			Opts:    model.GroupSearchOpts{},
2950			Page:    1,
2951			PerPage: 1,
2952			Result:  []*model.GroupWithSchemeAdmin{group2WSA},
2953		},
2954		{
2955			Name:       "Get third Group for Team2",
2956			TeamId:     team2.Id,
2957			Opts:       model.GroupSearchOpts{},
2958			Page:       0,
2959			PerPage:    60,
2960			Result:     []*model.GroupWithSchemeAdmin{group3WSA},
2961			TotalCount: model.NewInt64(1),
2962		},
2963		{
2964			Name:       "Get empty Groups for a fake id",
2965			TeamId:     model.NewId(),
2966			Opts:       model.GroupSearchOpts{},
2967			Page:       0,
2968			PerPage:    60,
2969			Result:     []*model.GroupWithSchemeAdmin{},
2970			TotalCount: model.NewInt64(0),
2971		},
2972		{
2973			Name:       "Get group matching name",
2974			TeamId:     team1.Id,
2975			Opts:       model.GroupSearchOpts{Q: string([]rune(*group1.Name)[2:10])}, // very low change of a name collision
2976			Page:       0,
2977			PerPage:    100,
2978			Result:     []*model.GroupWithSchemeAdmin{group1WSA},
2979			TotalCount: model.NewInt64(1),
2980		},
2981		{
2982			Name:       "Get group matching display name",
2983			TeamId:     team1.Id,
2984			Opts:       model.GroupSearchOpts{Q: "rouP-1"},
2985			Page:       0,
2986			PerPage:    100,
2987			Result:     []*model.GroupWithSchemeAdmin{group1WSA},
2988			TotalCount: model.NewInt64(1),
2989		},
2990		{
2991			Name:       "Get group matching multiple display names",
2992			TeamId:     team1.Id,
2993			Opts:       model.GroupSearchOpts{Q: "roUp-"},
2994			Page:       0,
2995			PerPage:    100,
2996			Result:     []*model.GroupWithSchemeAdmin{group1WSA, group2WSA},
2997			TotalCount: model.NewInt64(2),
2998		},
2999		{
3000			Name:    "Include member counts",
3001			TeamId:  team1.Id,
3002			Opts:    model.GroupSearchOpts{IncludeMemberCount: true},
3003			Page:    0,
3004			PerPage: 2,
3005			Result: []*model.GroupWithSchemeAdmin{
3006				{Group: group1WithMemberCount, SchemeAdmin: model.NewBool(false)},
3007				{Group: group2WithMemberCount, SchemeAdmin: model.NewBool(false)},
3008			},
3009		},
3010		{
3011			Name:    "Include allow reference",
3012			TeamId:  team1.Id,
3013			Opts:    model.GroupSearchOpts{FilterAllowReference: true},
3014			Page:    0,
3015			PerPage: 100,
3016			Result:  []*model.GroupWithSchemeAdmin{group2WSA},
3017		},
3018	}
3019
3020	for _, tc := range testCases {
3021		t.Run(tc.Name, func(t *testing.T) {
3022			if tc.Opts.PageOpts == nil {
3023				tc.Opts.PageOpts = &model.PageOpts{}
3024			}
3025			tc.Opts.PageOpts.Page = tc.Page
3026			tc.Opts.PageOpts.PerPage = tc.PerPage
3027			groups, err := ss.Group().GetGroupsByTeam(tc.TeamId, tc.Opts)
3028			require.NoError(t, err)
3029			require.ElementsMatch(t, tc.Result, groups)
3030			if tc.TotalCount != nil {
3031				var count int64
3032				count, err = ss.Group().CountGroupsByTeam(tc.TeamId, tc.Opts)
3033				require.NoError(t, err)
3034				require.Equal(t, *tc.TotalCount, count)
3035			}
3036		})
3037	}
3038}
3039
3040func testGetGroups(t *testing.T, ss store.Store) {
3041	// Create Team1
3042	team1 := &model.Team{
3043		DisplayName:      "Team1",
3044		Description:      model.NewId(),
3045		CompanyName:      model.NewId(),
3046		AllowOpenInvite:  false,
3047		InviteId:         model.NewId(),
3048		Name:             "zz" + model.NewId(),
3049		Email:            "success+" + model.NewId() + "@simulator.amazonses.com",
3050		Type:             model.TeamOpen,
3051		GroupConstrained: model.NewBool(true),
3052	}
3053	team1, err := ss.Team().Save(team1)
3054	require.NoError(t, err)
3055
3056	startCreateTime := team1.UpdateAt - 1
3057
3058	// Create Channel1
3059	channel1 := &model.Channel{
3060		TeamId:      model.NewId(),
3061		DisplayName: "Channel1",
3062		Name:        model.NewId(),
3063		Type:        model.ChannelTypePrivate,
3064	}
3065	channel1, nErr := ss.Channel().Save(channel1, 9999)
3066	require.NoError(t, nErr)
3067
3068	// Create Groups 1 and 2
3069	group1, err := ss.Group().Create(&model.Group{
3070		Name:           model.NewString(model.NewId()),
3071		DisplayName:    "group-1",
3072		RemoteId:       model.NewId(),
3073		Source:         model.GroupSourceLdap,
3074		AllowReference: true,
3075	})
3076	require.NoError(t, err)
3077
3078	group2, err := ss.Group().Create(&model.Group{
3079		Name:           model.NewString(model.NewId() + "-group-2"),
3080		DisplayName:    "group-2",
3081		RemoteId:       model.NewId(),
3082		Source:         model.GroupSourceLdap,
3083		AllowReference: false,
3084	})
3085	require.NoError(t, err)
3086
3087	deletedGroup, err := ss.Group().Create(&model.Group{
3088		Name:           model.NewString(model.NewId() + "-group-deleted"),
3089		DisplayName:    "group-deleted",
3090		RemoteId:       model.NewId(),
3091		Source:         model.GroupSourceLdap,
3092		AllowReference: false,
3093		DeleteAt:       1,
3094	})
3095	require.NoError(t, err)
3096
3097	// And associate them with Team1
3098	for _, g := range []*model.Group{group1, group2, deletedGroup} {
3099		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
3100			AutoAdd:    true,
3101			SyncableId: team1.Id,
3102			Type:       model.GroupSyncableTypeTeam,
3103			GroupId:    g.Id,
3104		})
3105		require.NoError(t, err)
3106	}
3107
3108	// Create Team2
3109	team2 := &model.Team{
3110		DisplayName:     "Team2",
3111		Description:     model.NewId(),
3112		CompanyName:     model.NewId(),
3113		AllowOpenInvite: false,
3114		InviteId:        model.NewId(),
3115		Name:            "zz" + model.NewId(),
3116		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
3117		Type:            model.TeamInvite,
3118	}
3119	team2, err = ss.Team().Save(team2)
3120	require.NoError(t, err)
3121
3122	// Create Channel2
3123	channel2 := &model.Channel{
3124		TeamId:      model.NewId(),
3125		DisplayName: "Channel2",
3126		Name:        model.NewId(),
3127		Type:        model.ChannelTypePrivate,
3128	}
3129	channel2, nErr = ss.Channel().Save(channel2, 9999)
3130	require.NoError(t, nErr)
3131
3132	// Create Channel3
3133	channel3 := &model.Channel{
3134		TeamId:      team1.Id,
3135		DisplayName: "Channel3",
3136		Name:        model.NewId(),
3137		Type:        model.ChannelTypePrivate,
3138	}
3139	channel3, nErr = ss.Channel().Save(channel3, 9999)
3140	require.NoError(t, nErr)
3141
3142	// Create Group3
3143	group3, err := ss.Group().Create(&model.Group{
3144		Name:           model.NewString(model.NewId() + "-group-3"),
3145		DisplayName:    "group-3",
3146		RemoteId:       model.NewId(),
3147		Source:         model.GroupSourceLdap,
3148		AllowReference: true,
3149	})
3150	require.NoError(t, err)
3151
3152	// And associate it to Team2
3153	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
3154		AutoAdd:    true,
3155		SyncableId: team2.Id,
3156		Type:       model.GroupSyncableTypeTeam,
3157		GroupId:    group3.Id,
3158	})
3159	require.NoError(t, err)
3160
3161	// And associate Group1 to Channel2
3162	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
3163		AutoAdd:    true,
3164		SyncableId: channel2.Id,
3165		Type:       model.GroupSyncableTypeChannel,
3166		GroupId:    group1.Id,
3167	})
3168	require.NoError(t, err)
3169
3170	// And associate Group2 and Group3 to Channel1
3171	for _, g := range []*model.Group{group2, group3} {
3172		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
3173			AutoAdd:    true,
3174			SyncableId: channel1.Id,
3175			Type:       model.GroupSyncableTypeChannel,
3176			GroupId:    g.Id,
3177		})
3178		require.NoError(t, err)
3179	}
3180
3181	// add members
3182	u1 := &model.User{
3183		Email:    MakeEmail(),
3184		Username: model.NewId(),
3185	}
3186	user1, err := ss.User().Save(u1)
3187	require.NoError(t, err)
3188
3189	u2 := &model.User{
3190		Email:    MakeEmail(),
3191		Username: model.NewId(),
3192	}
3193	user2, err := ss.User().Save(u2)
3194	require.NoError(t, err)
3195
3196	_, err = ss.Group().UpsertMember(group1.Id, user1.Id)
3197	require.NoError(t, err)
3198
3199	_, err = ss.Group().UpsertMember(group1.Id, user2.Id)
3200	require.NoError(t, err)
3201
3202	_, err = ss.Group().UpsertMember(deletedGroup.Id, user1.Id)
3203	require.NoError(t, err)
3204
3205	user2.DeleteAt = 1
3206	u2Update, _ := ss.User().Update(user2, true)
3207
3208	group2NameSubstring := "group-2"
3209
3210	endCreateTime := u2Update.New.UpdateAt + 1
3211
3212	// Create Team3
3213	team3 := &model.Team{
3214		DisplayName:     "Team3",
3215		Description:     model.NewId(),
3216		CompanyName:     model.NewId(),
3217		AllowOpenInvite: false,
3218		InviteId:        model.NewId(),
3219		Name:            "zz" + model.NewId(),
3220		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
3221		Type:            model.TeamInvite,
3222	}
3223	team3, err = ss.Team().Save(team3)
3224	require.NoError(t, err)
3225
3226	channel4 := &model.Channel{
3227		TeamId:      team3.Id,
3228		DisplayName: "Channel4",
3229		Name:        model.NewId(),
3230		Type:        model.ChannelTypePrivate,
3231	}
3232	channel4, nErr = ss.Channel().Save(channel4, 9999)
3233	require.NoError(t, nErr)
3234
3235	testCases := []struct {
3236		Name    string
3237		Page    int
3238		PerPage int
3239		Opts    model.GroupSearchOpts
3240		Resultf func([]*model.Group) bool
3241	}{
3242		{
3243			Name:    "Get all the Groups",
3244			Opts:    model.GroupSearchOpts{},
3245			Page:    0,
3246			PerPage: 3,
3247			Resultf: func(groups []*model.Group) bool { return len(groups) == 3 },
3248		},
3249		{
3250			Name:    "Get first Group with page 0 with 1 element",
3251			Opts:    model.GroupSearchOpts{},
3252			Page:    0,
3253			PerPage: 1,
3254			Resultf: func(groups []*model.Group) bool { return len(groups) == 1 },
3255		},
3256		{
3257			Name:    "Get single result from page 1",
3258			Opts:    model.GroupSearchOpts{},
3259			Page:    1,
3260			PerPage: 1,
3261			Resultf: func(groups []*model.Group) bool { return len(groups) == 1 },
3262		},
3263		{
3264			Name:    "Get multiple results from page 1",
3265			Opts:    model.GroupSearchOpts{},
3266			Page:    1,
3267			PerPage: 2,
3268			Resultf: func(groups []*model.Group) bool { return len(groups) == 2 },
3269		},
3270		{
3271			Name:    "Get group matching name",
3272			Opts:    model.GroupSearchOpts{Q: group2NameSubstring},
3273			Page:    0,
3274			PerPage: 100,
3275			Resultf: func(groups []*model.Group) bool {
3276				for _, g := range groups {
3277					if !strings.Contains(*g.Name, group2NameSubstring) && !strings.Contains(g.DisplayName, group2NameSubstring) {
3278						return false
3279					}
3280				}
3281				return true
3282			},
3283		},
3284		{
3285			Name:    "Get group matching display name",
3286			Opts:    model.GroupSearchOpts{Q: "rouP-3"},
3287			Page:    0,
3288			PerPage: 100,
3289			Resultf: func(groups []*model.Group) bool {
3290				for _, g := range groups {
3291					if !strings.Contains(strings.ToLower(g.DisplayName), "roup-3") {
3292						return false
3293					}
3294				}
3295				return true
3296			},
3297		},
3298		{
3299			Name:    "Get group matching multiple display names",
3300			Opts:    model.GroupSearchOpts{Q: "groUp"},
3301			Page:    0,
3302			PerPage: 100,
3303			Resultf: func(groups []*model.Group) bool {
3304				for _, g := range groups {
3305					if !strings.Contains(strings.ToLower(g.DisplayName), "group") {
3306						return false
3307					}
3308				}
3309				return true
3310			},
3311		},
3312		{
3313			Name:    "Include member counts",
3314			Opts:    model.GroupSearchOpts{IncludeMemberCount: true},
3315			Page:    0,
3316			PerPage: 100,
3317			Resultf: func(groups []*model.Group) bool {
3318				for _, g := range groups {
3319					if g.MemberCount == nil {
3320						return false
3321					}
3322					if g.Id == group1.Id && *g.MemberCount != 1 {
3323						return false
3324					}
3325					if g.DeleteAt != 0 {
3326						return false
3327					}
3328				}
3329				return true
3330			},
3331		},
3332		{
3333			Name:    "Not associated to team",
3334			Opts:    model.GroupSearchOpts{NotAssociatedToTeam: team2.Id},
3335			Page:    0,
3336			PerPage: 100,
3337			Resultf: func(groups []*model.Group) bool {
3338				if len(groups) == 0 {
3339					return false
3340				}
3341				for _, g := range groups {
3342					if g.Id == group3.Id {
3343						return false
3344					}
3345					if g.DeleteAt != 0 {
3346						return false
3347					}
3348				}
3349				return true
3350			},
3351		},
3352		{
3353			Name:    "Not associated to other team",
3354			Opts:    model.GroupSearchOpts{NotAssociatedToTeam: team1.Id},
3355			Page:    0,
3356			PerPage: 100,
3357			Resultf: func(groups []*model.Group) bool {
3358				if len(groups) == 0 {
3359					return false
3360				}
3361				for _, g := range groups {
3362					if g.Id == group1.Id || g.Id == group2.Id {
3363						return false
3364					}
3365					if g.DeleteAt != 0 {
3366						return false
3367					}
3368				}
3369				return true
3370			},
3371		},
3372		{
3373			Name:    "Include allow reference",
3374			Opts:    model.GroupSearchOpts{FilterAllowReference: true},
3375			Page:    0,
3376			PerPage: 100,
3377			Resultf: func(groups []*model.Group) bool {
3378				if len(groups) == 0 {
3379					return false
3380				}
3381				for _, g := range groups {
3382					if !g.AllowReference {
3383						return false
3384					}
3385					if g.DeleteAt != 0 {
3386						return false
3387					}
3388				}
3389				return true
3390			},
3391		},
3392		{
3393			Name:    "Use Since return all",
3394			Opts:    model.GroupSearchOpts{FilterAllowReference: true, Since: startCreateTime},
3395			Page:    0,
3396			PerPage: 100,
3397			Resultf: func(groups []*model.Group) bool {
3398				if len(groups) == 0 {
3399					return false
3400				}
3401				for _, g := range groups {
3402					if g.DeleteAt != 0 {
3403						return false
3404					}
3405				}
3406				return true
3407			},
3408		},
3409		{
3410			Name:    "Use Since return none",
3411			Opts:    model.GroupSearchOpts{FilterAllowReference: true, Since: endCreateTime},
3412			Page:    0,
3413			PerPage: 100,
3414			Resultf: func(groups []*model.Group) bool {
3415				return len(groups) == 0
3416			},
3417		},
3418		{
3419			Name:    "Filter groups from group-constrained teams",
3420			Opts:    model.GroupSearchOpts{NotAssociatedToChannel: channel3.Id, FilterParentTeamPermitted: true},
3421			Page:    0,
3422			PerPage: 100,
3423			Resultf: func(groups []*model.Group) bool {
3424				return len(groups) == 2 && groups[0].Id == group1.Id && groups[1].Id == group2.Id
3425			},
3426		},
3427		{
3428			Name:    "Filter groups from group-constrained page 0",
3429			Opts:    model.GroupSearchOpts{NotAssociatedToChannel: channel3.Id, FilterParentTeamPermitted: true},
3430			Page:    0,
3431			PerPage: 1,
3432			Resultf: func(groups []*model.Group) bool {
3433				return groups[0].Id == group1.Id
3434			},
3435		},
3436		{
3437			Name:    "Filter groups from group-constrained page 1",
3438			Opts:    model.GroupSearchOpts{NotAssociatedToChannel: channel3.Id, FilterParentTeamPermitted: true},
3439			Page:    1,
3440			PerPage: 1,
3441			Resultf: func(groups []*model.Group) bool {
3442				return groups[0].Id == group2.Id
3443			},
3444		},
3445		{
3446			Name:    "Non-group constrained team with no associated groups still returns groups for the child channel",
3447			Opts:    model.GroupSearchOpts{NotAssociatedToChannel: channel4.Id, FilterParentTeamPermitted: true},
3448			Page:    0,
3449			PerPage: 100,
3450			Resultf: func(groups []*model.Group) bool {
3451				return len(groups) > 0
3452			},
3453		},
3454	}
3455
3456	for _, tc := range testCases {
3457		t.Run(tc.Name, func(t *testing.T) {
3458			groups, err := ss.Group().GetGroups(tc.Page, tc.PerPage, tc.Opts)
3459			require.NoError(t, err)
3460			require.True(t, tc.Resultf(groups))
3461		})
3462	}
3463}
3464
3465func testTeamMembersMinusGroupMembers(t *testing.T, ss store.Store) {
3466	const numberOfGroups = 3
3467	const numberOfUsers = 4
3468
3469	groups := []*model.Group{}
3470	users := []*model.User{}
3471
3472	team := &model.Team{
3473		DisplayName:      model.NewId(),
3474		Description:      model.NewId(),
3475		CompanyName:      model.NewId(),
3476		AllowOpenInvite:  false,
3477		InviteId:         model.NewId(),
3478		Name:             "zz" + model.NewId(),
3479		Email:            model.NewId() + "@simulator.amazonses.com",
3480		Type:             model.TeamOpen,
3481		GroupConstrained: model.NewBool(true),
3482	}
3483	team, err := ss.Team().Save(team)
3484	require.NoError(t, err)
3485
3486	for i := 0; i < numberOfUsers; i++ {
3487		user := &model.User{
3488			Email:    MakeEmail(),
3489			Username: fmt.Sprintf("%d_%s", i, model.NewId()),
3490		}
3491		user, err = ss.User().Save(user)
3492		require.NoError(t, err)
3493		users = append(users, user)
3494
3495		trueOrFalse := int(math.Mod(float64(i), 2)) == 0
3496		_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: user.Id, SchemeUser: trueOrFalse, SchemeAdmin: !trueOrFalse}, 999)
3497		require.NoError(t, nErr)
3498	}
3499
3500	// Extra user outside of the group member users.
3501	user := &model.User{
3502		Email:    MakeEmail(),
3503		Username: "99_" + model.NewId(),
3504	}
3505	user, err = ss.User().Save(user)
3506	require.NoError(t, err)
3507	users = append(users, user)
3508	_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: user.Id, SchemeUser: true, SchemeAdmin: false}, 999)
3509	require.NoError(t, nErr)
3510
3511	for i := 0; i < numberOfGroups; i++ {
3512		group := &model.Group{
3513			Name:        model.NewString(fmt.Sprintf("n_%d_%s", i, model.NewId())),
3514			DisplayName: model.NewId(),
3515			Source:      model.GroupSourceLdap,
3516			Description: model.NewId(),
3517			RemoteId:    model.NewId(),
3518		}
3519		group, err := ss.Group().Create(group)
3520		require.NoError(t, err)
3521		groups = append(groups, group)
3522	}
3523
3524	sort.Slice(users, func(i, j int) bool {
3525		return users[i].Username < users[j].Username
3526	})
3527
3528	// Add even users to even group, and the inverse
3529	for i := 0; i < numberOfUsers; i++ {
3530		groupIndex := int(math.Mod(float64(i), 2))
3531		_, err := ss.Group().UpsertMember(groups[groupIndex].Id, users[i].Id)
3532		require.NoError(t, err)
3533
3534		// Add everyone to group 2
3535		_, err = ss.Group().UpsertMember(groups[numberOfGroups-1].Id, users[i].Id)
3536		require.NoError(t, err)
3537	}
3538
3539	testCases := map[string]struct {
3540		expectedUserIDs    []string
3541		expectedTotalCount int64
3542		groupIDs           []string
3543		page               int
3544		perPage            int
3545		setup              func()
3546		teardown           func()
3547	}{
3548		"No group IDs, all members": {
3549			expectedUserIDs:    []string{users[0].Id, users[1].Id, users[2].Id, users[3].Id, user.Id},
3550			expectedTotalCount: numberOfUsers + 1,
3551			groupIDs:           []string{},
3552			page:               0,
3553			perPage:            100,
3554		},
3555		"All members, page 1": {
3556			expectedUserIDs:    []string{users[0].Id, users[1].Id, users[2].Id},
3557			expectedTotalCount: numberOfUsers + 1,
3558			groupIDs:           []string{},
3559			page:               0,
3560			perPage:            3,
3561		},
3562		"All members, page 2": {
3563			expectedUserIDs:    []string{users[3].Id, users[4].Id},
3564			expectedTotalCount: numberOfUsers + 1,
3565			groupIDs:           []string{},
3566			page:               1,
3567			perPage:            3,
3568		},
3569		"Group 1, even users would be removed": {
3570			expectedUserIDs:    []string{users[0].Id, users[2].Id, users[4].Id},
3571			expectedTotalCount: 3,
3572			groupIDs:           []string{groups[1].Id},
3573			page:               0,
3574			perPage:            100,
3575		},
3576		"Group 0, odd users would be removed": {
3577			expectedUserIDs:    []string{users[1].Id, users[3].Id, users[4].Id},
3578			expectedTotalCount: 3,
3579			groupIDs:           []string{groups[0].Id},
3580			page:               0,
3581			perPage:            100,
3582		},
3583		"All groups, no users would be removed": {
3584			expectedUserIDs:    []string{users[4].Id},
3585			expectedTotalCount: 1,
3586			groupIDs:           []string{groups[0].Id, groups[1].Id},
3587			page:               0,
3588			perPage:            100,
3589		},
3590	}
3591
3592	mapUserIDs := func(users []*model.UserWithGroups) []string {
3593		ids := []string{}
3594		for _, user := range users {
3595			ids = append(ids, user.Id)
3596		}
3597		return ids
3598	}
3599
3600	for tcName, tc := range testCases {
3601		t.Run(tcName, func(t *testing.T) {
3602			if tc.setup != nil {
3603				tc.setup()
3604			}
3605
3606			if tc.teardown != nil {
3607				defer tc.teardown()
3608			}
3609
3610			actual, err := ss.Group().TeamMembersMinusGroupMembers(team.Id, tc.groupIDs, tc.page, tc.perPage)
3611			require.NoError(t, err)
3612			require.ElementsMatch(t, tc.expectedUserIDs, mapUserIDs(actual))
3613
3614			actualCount, err := ss.Group().CountTeamMembersMinusGroupMembers(team.Id, tc.groupIDs)
3615			require.NoError(t, err)
3616			require.Equal(t, tc.expectedTotalCount, actualCount)
3617		})
3618	}
3619}
3620
3621func testChannelMembersMinusGroupMembers(t *testing.T, ss store.Store) {
3622	const numberOfGroups = 3
3623	const numberOfUsers = 4
3624
3625	groups := []*model.Group{}
3626	users := []*model.User{}
3627
3628	channel := &model.Channel{
3629		TeamId:           model.NewId(),
3630		DisplayName:      "A Name",
3631		Name:             model.NewId(),
3632		Type:             model.ChannelTypePrivate,
3633		GroupConstrained: model.NewBool(true),
3634	}
3635	channel, err := ss.Channel().Save(channel, 9999)
3636	require.NoError(t, err)
3637
3638	for i := 0; i < numberOfUsers; i++ {
3639		user := &model.User{
3640			Email:    MakeEmail(),
3641			Username: fmt.Sprintf("%d_%s", i, model.NewId()),
3642		}
3643		user, err = ss.User().Save(user)
3644		require.NoError(t, err)
3645		users = append(users, user)
3646
3647		trueOrFalse := int(math.Mod(float64(i), 2)) == 0
3648		_, err = ss.Channel().SaveMember(&model.ChannelMember{
3649			ChannelId:   channel.Id,
3650			UserId:      user.Id,
3651			SchemeUser:  trueOrFalse,
3652			SchemeAdmin: !trueOrFalse,
3653			NotifyProps: model.GetDefaultChannelNotifyProps(),
3654		})
3655		require.NoError(t, err)
3656	}
3657
3658	// Extra user outside of the group member users.
3659	user, err := ss.User().Save(&model.User{
3660		Email:    MakeEmail(),
3661		Username: "99_" + model.NewId(),
3662	})
3663	require.NoError(t, err)
3664	users = append(users, user)
3665	_, err = ss.Channel().SaveMember(&model.ChannelMember{
3666		ChannelId:   channel.Id,
3667		UserId:      user.Id,
3668		SchemeUser:  true,
3669		SchemeAdmin: false,
3670		NotifyProps: model.GetDefaultChannelNotifyProps(),
3671	})
3672	require.NoError(t, err)
3673
3674	for i := 0; i < numberOfGroups; i++ {
3675		group := &model.Group{
3676			Name:        model.NewString(fmt.Sprintf("n_%d_%s", i, model.NewId())),
3677			DisplayName: model.NewId(),
3678			Source:      model.GroupSourceLdap,
3679			Description: model.NewId(),
3680			RemoteId:    model.NewId(),
3681		}
3682		group, err := ss.Group().Create(group)
3683		require.NoError(t, err)
3684		groups = append(groups, group)
3685	}
3686
3687	sort.Slice(users, func(i, j int) bool {
3688		return users[i].Username < users[j].Username
3689	})
3690
3691	// Add even users to even group, and the inverse
3692	for i := 0; i < numberOfUsers; i++ {
3693		groupIndex := int(math.Mod(float64(i), 2))
3694		_, err := ss.Group().UpsertMember(groups[groupIndex].Id, users[i].Id)
3695		require.NoError(t, err)
3696
3697		// Add everyone to group 2
3698		_, err = ss.Group().UpsertMember(groups[numberOfGroups-1].Id, users[i].Id)
3699		require.NoError(t, err)
3700	}
3701
3702	testCases := map[string]struct {
3703		expectedUserIDs    []string
3704		expectedTotalCount int64
3705		groupIDs           []string
3706		page               int
3707		perPage            int
3708		setup              func()
3709		teardown           func()
3710	}{
3711		"No group IDs, all members": {
3712			expectedUserIDs:    []string{users[0].Id, users[1].Id, users[2].Id, users[3].Id, users[4].Id},
3713			expectedTotalCount: numberOfUsers + 1,
3714			groupIDs:           []string{},
3715			page:               0,
3716			perPage:            100,
3717		},
3718		"All members, page 1": {
3719			expectedUserIDs:    []string{users[0].Id, users[1].Id, users[2].Id},
3720			expectedTotalCount: numberOfUsers + 1,
3721			groupIDs:           []string{},
3722			page:               0,
3723			perPage:            3,
3724		},
3725		"All members, page 2": {
3726			expectedUserIDs:    []string{users[3].Id, users[4].Id},
3727			expectedTotalCount: numberOfUsers + 1,
3728			groupIDs:           []string{},
3729			page:               1,
3730			perPage:            3,
3731		},
3732		"Group 1, even users would be removed": {
3733			expectedUserIDs:    []string{users[0].Id, users[2].Id, users[4].Id},
3734			expectedTotalCount: 3,
3735			groupIDs:           []string{groups[1].Id},
3736			page:               0,
3737			perPage:            100,
3738		},
3739		"Group 0, odd users would be removed": {
3740			expectedUserIDs:    []string{users[1].Id, users[3].Id, users[4].Id},
3741			expectedTotalCount: 3,
3742			groupIDs:           []string{groups[0].Id},
3743			page:               0,
3744			perPage:            100,
3745		},
3746		"All groups, no users would be removed": {
3747			expectedUserIDs:    []string{users[4].Id},
3748			expectedTotalCount: 1,
3749			groupIDs:           []string{groups[0].Id, groups[1].Id},
3750			page:               0,
3751			perPage:            100,
3752		},
3753	}
3754
3755	mapUserIDs := func(users []*model.UserWithGroups) []string {
3756		ids := []string{}
3757		for _, user := range users {
3758			ids = append(ids, user.Id)
3759		}
3760		return ids
3761	}
3762
3763	for tcName, tc := range testCases {
3764		t.Run(tcName, func(t *testing.T) {
3765			if tc.setup != nil {
3766				tc.setup()
3767			}
3768
3769			if tc.teardown != nil {
3770				defer tc.teardown()
3771			}
3772
3773			actual, err := ss.Group().ChannelMembersMinusGroupMembers(channel.Id, tc.groupIDs, tc.page, tc.perPage)
3774			require.NoError(t, err)
3775			require.ElementsMatch(t, tc.expectedUserIDs, mapUserIDs(actual))
3776
3777			actualCount, err := ss.Group().CountChannelMembersMinusGroupMembers(channel.Id, tc.groupIDs)
3778			require.NoError(t, err)
3779			require.Equal(t, tc.expectedTotalCount, actualCount)
3780		})
3781	}
3782}
3783
3784func groupTestGetMemberCount(t *testing.T, ss store.Store) {
3785	group := &model.Group{
3786		Name:        model.NewString(model.NewId()),
3787		DisplayName: model.NewId(),
3788		Source:      model.GroupSourceLdap,
3789		Description: model.NewId(),
3790		RemoteId:    model.NewId(),
3791	}
3792	group, err := ss.Group().Create(group)
3793	require.NoError(t, err)
3794
3795	var user *model.User
3796	var nErr error
3797	for i := 0; i < 2; i++ {
3798		user = &model.User{
3799			Email:    MakeEmail(),
3800			Username: fmt.Sprintf("%d_%s", i, model.NewId()),
3801		}
3802		user, nErr = ss.User().Save(user)
3803		require.NoError(t, nErr)
3804
3805		_, err = ss.Group().UpsertMember(group.Id, user.Id)
3806		require.NoError(t, err)
3807	}
3808
3809	count, err := ss.Group().GetMemberCount(group.Id)
3810	require.NoError(t, err)
3811	require.Equal(t, int64(2), count)
3812
3813	user.DeleteAt = 1
3814	_, nErr = ss.User().Update(user, true)
3815	require.NoError(t, nErr)
3816
3817	count, err = ss.Group().GetMemberCount(group.Id)
3818	require.NoError(t, err)
3819	require.Equal(t, int64(1), count)
3820}
3821
3822func groupTestAdminRoleGroupsForSyncableMemberChannel(t *testing.T, ss store.Store) {
3823	user := &model.User{
3824		Email:    MakeEmail(),
3825		Username: model.NewId(),
3826	}
3827	user, err := ss.User().Save(user)
3828	require.NoError(t, err)
3829
3830	group1 := &model.Group{
3831		Name:        model.NewString(model.NewId()),
3832		DisplayName: model.NewId(),
3833		Source:      model.GroupSourceLdap,
3834		Description: model.NewId(),
3835		RemoteId:    model.NewId(),
3836	}
3837	group1, err = ss.Group().Create(group1)
3838	require.NoError(t, err)
3839
3840	_, err = ss.Group().UpsertMember(group1.Id, user.Id)
3841	require.NoError(t, err)
3842
3843	group2 := &model.Group{
3844		Name:        model.NewString(model.NewId()),
3845		DisplayName: model.NewId(),
3846		Source:      model.GroupSourceLdap,
3847		Description: model.NewId(),
3848		RemoteId:    model.NewId(),
3849	}
3850	group2, err = ss.Group().Create(group2)
3851	require.NoError(t, err)
3852
3853	_, err = ss.Group().UpsertMember(group2.Id, user.Id)
3854	require.NoError(t, err)
3855
3856	channel := &model.Channel{
3857		TeamId:      model.NewId(),
3858		DisplayName: "A Name",
3859		Name:        model.NewId(),
3860		Type:        model.ChannelTypeOpen,
3861	}
3862	channel, nErr := ss.Channel().Save(channel, 9999)
3863	require.NoError(t, nErr)
3864
3865	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
3866		AutoAdd:     true,
3867		SyncableId:  channel.Id,
3868		Type:        model.GroupSyncableTypeChannel,
3869		GroupId:     group1.Id,
3870		SchemeAdmin: true,
3871	})
3872	require.NoError(t, err)
3873
3874	groupSyncable2, err := ss.Group().CreateGroupSyncable(&model.GroupSyncable{
3875		AutoAdd:    true,
3876		SyncableId: channel.Id,
3877		Type:       model.GroupSyncableTypeChannel,
3878		GroupId:    group2.Id,
3879	})
3880	require.NoError(t, err)
3881
3882	// User is a member of both groups but only one is SchmeAdmin: true
3883	actualGroupIDs, err := ss.Group().AdminRoleGroupsForSyncableMember(user.Id, channel.Id, model.GroupSyncableTypeChannel)
3884	require.NoError(t, err)
3885	require.ElementsMatch(t, []string{group1.Id}, actualGroupIDs)
3886
3887	// Update the second group syncable to be SchemeAdmin: true and both groups should be returned
3888	groupSyncable2.SchemeAdmin = true
3889	_, err = ss.Group().UpdateGroupSyncable(groupSyncable2)
3890	require.NoError(t, err)
3891	actualGroupIDs, err = ss.Group().AdminRoleGroupsForSyncableMember(user.Id, channel.Id, model.GroupSyncableTypeChannel)
3892	require.NoError(t, err)
3893	require.ElementsMatch(t, []string{group1.Id, group2.Id}, actualGroupIDs)
3894
3895	// Deleting membership from group should stop the group from being returned
3896	_, err = ss.Group().DeleteMember(group1.Id, user.Id)
3897	require.NoError(t, err)
3898	actualGroupIDs, err = ss.Group().AdminRoleGroupsForSyncableMember(user.Id, channel.Id, model.GroupSyncableTypeChannel)
3899	require.NoError(t, err)
3900	require.ElementsMatch(t, []string{group2.Id}, actualGroupIDs)
3901
3902	// Deleting group syncable should stop it being returned
3903	_, err = ss.Group().DeleteGroupSyncable(group2.Id, channel.Id, model.GroupSyncableTypeChannel)
3904	require.NoError(t, err)
3905	actualGroupIDs, err = ss.Group().AdminRoleGroupsForSyncableMember(user.Id, channel.Id, model.GroupSyncableTypeChannel)
3906	require.NoError(t, err)
3907	require.ElementsMatch(t, []string{}, actualGroupIDs)
3908}
3909
3910func groupTestAdminRoleGroupsForSyncableMemberTeam(t *testing.T, ss store.Store) {
3911	user := &model.User{
3912		Email:    MakeEmail(),
3913		Username: model.NewId(),
3914	}
3915	user, err := ss.User().Save(user)
3916	require.NoError(t, err)
3917
3918	group1 := &model.Group{
3919		Name:        model.NewString(model.NewId()),
3920		DisplayName: model.NewId(),
3921		Source:      model.GroupSourceLdap,
3922		Description: model.NewId(),
3923		RemoteId:    model.NewId(),
3924	}
3925	group1, err = ss.Group().Create(group1)
3926	require.NoError(t, err)
3927
3928	_, err = ss.Group().UpsertMember(group1.Id, user.Id)
3929	require.NoError(t, err)
3930
3931	group2 := &model.Group{
3932		Name:        model.NewString(model.NewId()),
3933		DisplayName: model.NewId(),
3934		Source:      model.GroupSourceLdap,
3935		Description: model.NewId(),
3936		RemoteId:    model.NewId(),
3937	}
3938	group2, err = ss.Group().Create(group2)
3939	require.NoError(t, err)
3940
3941	_, err = ss.Group().UpsertMember(group2.Id, user.Id)
3942	require.NoError(t, err)
3943
3944	team := &model.Team{
3945		DisplayName: "A Name",
3946		Name:        "zz" + model.NewId(),
3947		Type:        model.TeamOpen,
3948	}
3949	team, nErr := ss.Team().Save(team)
3950	require.NoError(t, nErr)
3951
3952	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
3953		AutoAdd:     true,
3954		SyncableId:  team.Id,
3955		Type:        model.GroupSyncableTypeTeam,
3956		GroupId:     group1.Id,
3957		SchemeAdmin: true,
3958	})
3959	require.NoError(t, err)
3960
3961	groupSyncable2, err := ss.Group().CreateGroupSyncable(&model.GroupSyncable{
3962		AutoAdd:    true,
3963		SyncableId: team.Id,
3964		Type:       model.GroupSyncableTypeTeam,
3965		GroupId:    group2.Id,
3966	})
3967	require.NoError(t, err)
3968
3969	// User is a member of both groups but only one is SchmeAdmin: true
3970	actualGroupIDs, err := ss.Group().AdminRoleGroupsForSyncableMember(user.Id, team.Id, model.GroupSyncableTypeTeam)
3971	require.NoError(t, err)
3972	require.ElementsMatch(t, []string{group1.Id}, actualGroupIDs)
3973
3974	// Update the second group syncable to be SchemeAdmin: true and both groups should be returned
3975	groupSyncable2.SchemeAdmin = true
3976	_, err = ss.Group().UpdateGroupSyncable(groupSyncable2)
3977	require.NoError(t, err)
3978	actualGroupIDs, err = ss.Group().AdminRoleGroupsForSyncableMember(user.Id, team.Id, model.GroupSyncableTypeTeam)
3979	require.NoError(t, err)
3980	require.ElementsMatch(t, []string{group1.Id, group2.Id}, actualGroupIDs)
3981
3982	// Deleting membership from group should stop the group from being returned
3983	_, err = ss.Group().DeleteMember(group1.Id, user.Id)
3984	require.NoError(t, err)
3985	actualGroupIDs, err = ss.Group().AdminRoleGroupsForSyncableMember(user.Id, team.Id, model.GroupSyncableTypeTeam)
3986	require.NoError(t, err)
3987	require.ElementsMatch(t, []string{group2.Id}, actualGroupIDs)
3988
3989	// Deleting group syncable should stop it being returned
3990	_, err = ss.Group().DeleteGroupSyncable(group2.Id, team.Id, model.GroupSyncableTypeTeam)
3991	require.NoError(t, err)
3992	actualGroupIDs, err = ss.Group().AdminRoleGroupsForSyncableMember(user.Id, team.Id, model.GroupSyncableTypeTeam)
3993	require.NoError(t, err)
3994	require.ElementsMatch(t, []string{}, actualGroupIDs)
3995}
3996
3997func groupTestPermittedSyncableAdminsTeam(t *testing.T, ss store.Store) {
3998	user1 := &model.User{
3999		Email:    MakeEmail(),
4000		Username: model.NewId(),
4001	}
4002	user1, err := ss.User().Save(user1)
4003	require.NoError(t, err)
4004
4005	user2 := &model.User{
4006		Email:    MakeEmail(),
4007		Username: model.NewId(),
4008	}
4009	user2, err = ss.User().Save(user2)
4010	require.NoError(t, err)
4011
4012	user3 := &model.User{
4013		Email:    MakeEmail(),
4014		Username: model.NewId(),
4015	}
4016	user3, err = ss.User().Save(user3)
4017	require.NoError(t, err)
4018
4019	group1 := &model.Group{
4020		Name:        model.NewString(model.NewId()),
4021		DisplayName: model.NewId(),
4022		Source:      model.GroupSourceLdap,
4023		Description: model.NewId(),
4024		RemoteId:    model.NewId(),
4025	}
4026	group1, err = ss.Group().Create(group1)
4027	require.NoError(t, err)
4028
4029	_, err = ss.Group().UpsertMember(group1.Id, user1.Id)
4030	require.NoError(t, err)
4031	_, err = ss.Group().UpsertMember(group1.Id, user2.Id)
4032	require.NoError(t, err)
4033
4034	group2 := &model.Group{
4035		Name:        model.NewString(model.NewId()),
4036		DisplayName: model.NewId(),
4037		Source:      model.GroupSourceLdap,
4038		Description: model.NewId(),
4039		RemoteId:    model.NewId(),
4040	}
4041	group2, err = ss.Group().Create(group2)
4042	require.NoError(t, err)
4043
4044	_, err = ss.Group().UpsertMember(group2.Id, user3.Id)
4045	require.NoError(t, err)
4046
4047	team := &model.Team{
4048		DisplayName: "A Name",
4049		Name:        "zz" + model.NewId(),
4050		Type:        model.TeamOpen,
4051	}
4052	team, nErr := ss.Team().Save(team)
4053	require.NoError(t, nErr)
4054
4055	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
4056		AutoAdd:     true,
4057		SyncableId:  team.Id,
4058		Type:        model.GroupSyncableTypeTeam,
4059		GroupId:     group1.Id,
4060		SchemeAdmin: true,
4061	})
4062	require.NoError(t, err)
4063
4064	groupSyncable2, err := ss.Group().CreateGroupSyncable(&model.GroupSyncable{
4065		AutoAdd:     true,
4066		SyncableId:  team.Id,
4067		Type:        model.GroupSyncableTypeTeam,
4068		GroupId:     group2.Id,
4069		SchemeAdmin: false,
4070	})
4071	require.NoError(t, err)
4072
4073	// group 1's users are returned because groupsyncable 2 has SchemeAdmin false.
4074	actualUserIDs, err := ss.Group().PermittedSyncableAdmins(team.Id, model.GroupSyncableTypeTeam)
4075	require.NoError(t, err)
4076	require.ElementsMatch(t, []string{user1.Id, user2.Id}, actualUserIDs)
4077
4078	// update groupsyncable 2 to be SchemeAdmin true
4079	groupSyncable2.SchemeAdmin = true
4080	_, err = ss.Group().UpdateGroupSyncable(groupSyncable2)
4081	require.NoError(t, err)
4082
4083	// group 2's users are now included in return value
4084	actualUserIDs, err = ss.Group().PermittedSyncableAdmins(team.Id, model.GroupSyncableTypeTeam)
4085	require.NoError(t, err)
4086	require.ElementsMatch(t, []string{user1.Id, user2.Id, user3.Id}, actualUserIDs)
4087
4088	// deleted group member should not be included
4089	ss.Group().DeleteMember(group1.Id, user2.Id)
4090	require.NoError(t, err)
4091	actualUserIDs, err = ss.Group().PermittedSyncableAdmins(team.Id, model.GroupSyncableTypeTeam)
4092	require.NoError(t, err)
4093	require.ElementsMatch(t, []string{user1.Id, user3.Id}, actualUserIDs)
4094
4095	// deleted group syncable no longer includes group members
4096	_, err = ss.Group().DeleteGroupSyncable(group1.Id, team.Id, model.GroupSyncableTypeTeam)
4097	require.NoError(t, err)
4098	actualUserIDs, err = ss.Group().PermittedSyncableAdmins(team.Id, model.GroupSyncableTypeTeam)
4099	require.NoError(t, err)
4100	require.ElementsMatch(t, []string{user3.Id}, actualUserIDs)
4101}
4102
4103func groupTestPermittedSyncableAdminsChannel(t *testing.T, ss store.Store) {
4104	user1 := &model.User{
4105		Email:    MakeEmail(),
4106		Username: model.NewId(),
4107	}
4108	user1, err := ss.User().Save(user1)
4109	require.NoError(t, err)
4110
4111	user2 := &model.User{
4112		Email:    MakeEmail(),
4113		Username: model.NewId(),
4114	}
4115	user2, err = ss.User().Save(user2)
4116	require.NoError(t, err)
4117
4118	user3 := &model.User{
4119		Email:    MakeEmail(),
4120		Username: model.NewId(),
4121	}
4122	user3, err = ss.User().Save(user3)
4123	require.NoError(t, err)
4124
4125	group1 := &model.Group{
4126		Name:        model.NewString(model.NewId()),
4127		DisplayName: model.NewId(),
4128		Source:      model.GroupSourceLdap,
4129		Description: model.NewId(),
4130		RemoteId:    model.NewId(),
4131	}
4132	group1, err = ss.Group().Create(group1)
4133	require.NoError(t, err)
4134
4135	_, err = ss.Group().UpsertMember(group1.Id, user1.Id)
4136	require.NoError(t, err)
4137	_, err = ss.Group().UpsertMember(group1.Id, user2.Id)
4138	require.NoError(t, err)
4139
4140	group2 := &model.Group{
4141		Name:        model.NewString(model.NewId()),
4142		DisplayName: model.NewId(),
4143		Source:      model.GroupSourceLdap,
4144		Description: model.NewId(),
4145		RemoteId:    model.NewId(),
4146	}
4147	group2, err = ss.Group().Create(group2)
4148	require.NoError(t, err)
4149
4150	_, err = ss.Group().UpsertMember(group2.Id, user3.Id)
4151	require.NoError(t, err)
4152
4153	channel := &model.Channel{
4154		TeamId:      model.NewId(),
4155		DisplayName: "A Name",
4156		Name:        model.NewId(),
4157		Type:        model.ChannelTypeOpen,
4158	}
4159	channel, nErr := ss.Channel().Save(channel, 9999)
4160	require.NoError(t, nErr)
4161
4162	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
4163		AutoAdd:     true,
4164		SyncableId:  channel.Id,
4165		Type:        model.GroupSyncableTypeChannel,
4166		GroupId:     group1.Id,
4167		SchemeAdmin: true,
4168	})
4169	require.NoError(t, err)
4170
4171	groupSyncable2, err := ss.Group().CreateGroupSyncable(&model.GroupSyncable{
4172		AutoAdd:     true,
4173		SyncableId:  channel.Id,
4174		Type:        model.GroupSyncableTypeChannel,
4175		GroupId:     group2.Id,
4176		SchemeAdmin: false,
4177	})
4178	require.NoError(t, err)
4179
4180	// group 1's users are returned because groupsyncable 2 has SchemeAdmin false.
4181	actualUserIDs, err := ss.Group().PermittedSyncableAdmins(channel.Id, model.GroupSyncableTypeChannel)
4182	require.NoError(t, err)
4183	require.ElementsMatch(t, []string{user1.Id, user2.Id}, actualUserIDs)
4184
4185	// update groupsyncable 2 to be SchemeAdmin true
4186	groupSyncable2.SchemeAdmin = true
4187	_, err = ss.Group().UpdateGroupSyncable(groupSyncable2)
4188	require.NoError(t, err)
4189
4190	// group 2's users are now included in return value
4191	actualUserIDs, err = ss.Group().PermittedSyncableAdmins(channel.Id, model.GroupSyncableTypeChannel)
4192	require.NoError(t, err)
4193	require.ElementsMatch(t, []string{user1.Id, user2.Id, user3.Id}, actualUserIDs)
4194
4195	// deleted group member should not be included
4196	ss.Group().DeleteMember(group1.Id, user2.Id)
4197	require.NoError(t, err)
4198	actualUserIDs, err = ss.Group().PermittedSyncableAdmins(channel.Id, model.GroupSyncableTypeChannel)
4199	require.NoError(t, err)
4200	require.ElementsMatch(t, []string{user1.Id, user3.Id}, actualUserIDs)
4201
4202	// deleted group syncable no longer includes group members
4203	_, err = ss.Group().DeleteGroupSyncable(group1.Id, channel.Id, model.GroupSyncableTypeChannel)
4204	require.NoError(t, err)
4205	actualUserIDs, err = ss.Group().PermittedSyncableAdmins(channel.Id, model.GroupSyncableTypeChannel)
4206	require.NoError(t, err)
4207	require.ElementsMatch(t, []string{user3.Id}, actualUserIDs)
4208}
4209
4210func groupTestpUpdateMembersRoleTeam(t *testing.T, ss store.Store) {
4211	team := &model.Team{
4212		DisplayName:     "Name",
4213		Description:     "Some description",
4214		CompanyName:     "Some company name",
4215		AllowOpenInvite: false,
4216		InviteId:        "inviteid0",
4217		Name:            "z-z-" + model.NewId() + "a",
4218		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
4219		Type:            model.TeamOpen,
4220	}
4221	team, err := ss.Team().Save(team)
4222	require.NoError(t, err)
4223
4224	user1 := &model.User{
4225		Email:    MakeEmail(),
4226		Username: model.NewId(),
4227	}
4228	user1, err = ss.User().Save(user1)
4229	require.NoError(t, err)
4230
4231	user2 := &model.User{
4232		Email:    MakeEmail(),
4233		Username: model.NewId(),
4234	}
4235	user2, err = ss.User().Save(user2)
4236	require.NoError(t, err)
4237
4238	user3 := &model.User{
4239		Email:    MakeEmail(),
4240		Username: model.NewId(),
4241	}
4242	user3, err = ss.User().Save(user3)
4243	require.NoError(t, err)
4244
4245	user4 := &model.User{
4246		Email:    MakeEmail(),
4247		Username: model.NewId(),
4248	}
4249	user4, err = ss.User().Save(user4)
4250	require.NoError(t, err)
4251
4252	for _, user := range []*model.User{user1, user2, user3} {
4253		_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: user.Id}, 9999)
4254		require.NoError(t, nErr)
4255	}
4256
4257	_, nErr := ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: user4.Id, SchemeGuest: true}, 9999)
4258	require.NoError(t, nErr)
4259
4260	tests := []struct {
4261		testName               string
4262		inUserIDs              []string
4263		targetSchemeAdminValue bool
4264	}{
4265		{
4266			"Given users are admins",
4267			[]string{user1.Id, user2.Id},
4268			true,
4269		},
4270		{
4271			"Given users are members",
4272			[]string{user2.Id},
4273			false,
4274		},
4275		{
4276			"Non-given users are admins",
4277			[]string{user2.Id},
4278			false,
4279		},
4280		{
4281			"Non-given users are members",
4282			[]string{user2.Id},
4283			false,
4284		},
4285	}
4286
4287	for _, tt := range tests {
4288		t.Run(tt.testName, func(t *testing.T) {
4289			err = ss.Team().UpdateMembersRole(team.Id, tt.inUserIDs)
4290			require.NoError(t, err)
4291
4292			members, err := ss.Team().GetMembers(team.Id, 0, 100, nil)
4293			require.NoError(t, err)
4294			require.GreaterOrEqual(t, len(members), 4) // sanity check for team membership
4295
4296			for _, member := range members {
4297				if utils.StringInSlice(member.UserId, tt.inUserIDs) {
4298					require.True(t, member.SchemeAdmin)
4299				} else {
4300					require.False(t, member.SchemeAdmin)
4301				}
4302
4303				// Ensure guest account never changes.
4304				if member.UserId == user4.Id {
4305					require.False(t, member.SchemeUser)
4306					require.False(t, member.SchemeAdmin)
4307					require.True(t, member.SchemeGuest)
4308				}
4309			}
4310		})
4311	}
4312}
4313
4314func groupTestpUpdateMembersRoleChannel(t *testing.T, ss store.Store) {
4315	channel := &model.Channel{
4316		TeamId:      model.NewId(),
4317		DisplayName: "A Name",
4318		Name:        model.NewId(),
4319		Type:        model.ChannelTypeOpen, // Query does not look at type so this shouldn't matter.
4320	}
4321	channel, err := ss.Channel().Save(channel, 9999)
4322	require.NoError(t, err)
4323
4324	user1 := &model.User{
4325		Email:    MakeEmail(),
4326		Username: model.NewId(),
4327	}
4328	user1, err = ss.User().Save(user1)
4329	require.NoError(t, err)
4330
4331	user2 := &model.User{
4332		Email:    MakeEmail(),
4333		Username: model.NewId(),
4334	}
4335	user2, err = ss.User().Save(user2)
4336	require.NoError(t, err)
4337
4338	user3 := &model.User{
4339		Email:    MakeEmail(),
4340		Username: model.NewId(),
4341	}
4342	user3, err = ss.User().Save(user3)
4343	require.NoError(t, err)
4344
4345	user4 := &model.User{
4346		Email:    MakeEmail(),
4347		Username: model.NewId(),
4348	}
4349	user4, err = ss.User().Save(user4)
4350	require.NoError(t, err)
4351
4352	for _, user := range []*model.User{user1, user2, user3} {
4353		_, err = ss.Channel().SaveMember(&model.ChannelMember{
4354			ChannelId:   channel.Id,
4355			UserId:      user.Id,
4356			NotifyProps: model.GetDefaultChannelNotifyProps(),
4357		})
4358		require.NoError(t, err)
4359	}
4360
4361	_, err = ss.Channel().SaveMember(&model.ChannelMember{
4362		ChannelId:   channel.Id,
4363		UserId:      user4.Id,
4364		NotifyProps: model.GetDefaultChannelNotifyProps(),
4365		SchemeGuest: true,
4366	})
4367	require.NoError(t, err)
4368
4369	tests := []struct {
4370		testName               string
4371		inUserIDs              []string
4372		targetSchemeAdminValue bool
4373	}{
4374		{
4375			"Given users are admins",
4376			[]string{user1.Id, user2.Id},
4377			true,
4378		},
4379		{
4380			"Given users are members",
4381			[]string{user2.Id},
4382			false,
4383		},
4384		{
4385			"Non-given users are admins",
4386			[]string{user2.Id},
4387			false,
4388		},
4389		{
4390			"Non-given users are members",
4391			[]string{user2.Id},
4392			false,
4393		},
4394	}
4395
4396	for _, tt := range tests {
4397		t.Run(tt.testName, func(t *testing.T) {
4398			err = ss.Channel().UpdateMembersRole(channel.Id, tt.inUserIDs)
4399			require.NoError(t, err)
4400
4401			members, err := ss.Channel().GetMembers(channel.Id, 0, 100)
4402			require.NoError(t, err)
4403
4404			require.GreaterOrEqual(t, len(members), 4) // sanity check for channel membership
4405
4406			for _, member := range members {
4407				if utils.StringInSlice(member.UserId, tt.inUserIDs) {
4408					require.True(t, member.SchemeAdmin)
4409				} else {
4410					require.False(t, member.SchemeAdmin)
4411				}
4412
4413				// Ensure guest account never changes.
4414				if member.UserId == user4.Id {
4415					require.False(t, member.SchemeUser)
4416					require.False(t, member.SchemeAdmin)
4417					require.True(t, member.SchemeGuest)
4418				}
4419			}
4420		})
4421	}
4422}
4423
4424func groupTestGroupCount(t *testing.T, ss store.Store) {
4425	group1, err := ss.Group().Create(&model.Group{
4426		Name:        model.NewString(model.NewId()),
4427		DisplayName: model.NewId(),
4428		Source:      model.GroupSourceLdap,
4429		RemoteId:    model.NewId(),
4430	})
4431	require.NoError(t, err)
4432	defer ss.Group().Delete(group1.Id)
4433
4434	count, err := ss.Group().GroupCount()
4435	require.NoError(t, err)
4436	require.GreaterOrEqual(t, count, int64(1))
4437
4438	group2, err := ss.Group().Create(&model.Group{
4439		Name:        model.NewString(model.NewId()),
4440		DisplayName: model.NewId(),
4441		Source:      model.GroupSourceLdap,
4442		RemoteId:    model.NewId(),
4443	})
4444	require.NoError(t, err)
4445	defer ss.Group().Delete(group2.Id)
4446
4447	countAfter, err := ss.Group().GroupCount()
4448	require.NoError(t, err)
4449	require.GreaterOrEqual(t, countAfter, count+1)
4450}
4451
4452func groupTestGroupTeamCount(t *testing.T, ss store.Store) {
4453	team, err := ss.Team().Save(&model.Team{
4454		DisplayName:     model.NewId(),
4455		Description:     model.NewId(),
4456		AllowOpenInvite: false,
4457		InviteId:        model.NewId(),
4458		Name:            "zz" + model.NewId(),
4459		Email:           model.NewId() + "@simulator.amazonses.com",
4460		Type:            model.TeamOpen,
4461	})
4462	require.NoError(t, err)
4463	defer ss.Team().PermanentDelete(team.Id)
4464
4465	group1, err := ss.Group().Create(&model.Group{
4466		Name:        model.NewString(model.NewId()),
4467		DisplayName: model.NewId(),
4468		Source:      model.GroupSourceLdap,
4469		RemoteId:    model.NewId(),
4470	})
4471	require.NoError(t, err)
4472	defer ss.Group().Delete(group1.Id)
4473
4474	group2, err := ss.Group().Create(&model.Group{
4475		Name:        model.NewString(model.NewId()),
4476		DisplayName: model.NewId(),
4477		Source:      model.GroupSourceLdap,
4478		RemoteId:    model.NewId(),
4479	})
4480	require.NoError(t, err)
4481	defer ss.Group().Delete(group2.Id)
4482
4483	groupSyncable1, err := ss.Group().CreateGroupSyncable(model.NewGroupTeam(group1.Id, team.Id, false))
4484	require.NoError(t, err)
4485	defer ss.Group().DeleteGroupSyncable(groupSyncable1.GroupId, groupSyncable1.SyncableId, groupSyncable1.Type)
4486
4487	count, err := ss.Group().GroupTeamCount()
4488	require.NoError(t, err)
4489	require.GreaterOrEqual(t, count, int64(1))
4490
4491	groupSyncable2, err := ss.Group().CreateGroupSyncable(model.NewGroupTeam(group2.Id, team.Id, false))
4492	require.NoError(t, err)
4493	defer ss.Group().DeleteGroupSyncable(groupSyncable2.GroupId, groupSyncable2.SyncableId, groupSyncable2.Type)
4494
4495	countAfter, err := ss.Group().GroupTeamCount()
4496	require.NoError(t, err)
4497	require.GreaterOrEqual(t, countAfter, count+1)
4498}
4499
4500func groupTestGroupChannelCount(t *testing.T, ss store.Store) {
4501	channel, err := ss.Channel().Save(&model.Channel{
4502		TeamId:      model.NewId(),
4503		DisplayName: model.NewId(),
4504		Name:        model.NewId(),
4505		Type:        model.ChannelTypeOpen,
4506	}, 9999)
4507	require.NoError(t, err)
4508	defer ss.Channel().Delete(channel.Id, 0)
4509
4510	group1, err := ss.Group().Create(&model.Group{
4511		Name:        model.NewString(model.NewId()),
4512		DisplayName: model.NewId(),
4513		Source:      model.GroupSourceLdap,
4514		RemoteId:    model.NewId(),
4515	})
4516	require.NoError(t, err)
4517	defer ss.Group().Delete(group1.Id)
4518
4519	group2, err := ss.Group().Create(&model.Group{
4520		Name:        model.NewString(model.NewId()),
4521		DisplayName: model.NewId(),
4522		Source:      model.GroupSourceLdap,
4523		RemoteId:    model.NewId(),
4524	})
4525	require.NoError(t, err)
4526	defer ss.Group().Delete(group2.Id)
4527
4528	groupSyncable1, err := ss.Group().CreateGroupSyncable(model.NewGroupChannel(group1.Id, channel.Id, false))
4529	require.NoError(t, err)
4530	defer ss.Group().DeleteGroupSyncable(groupSyncable1.GroupId, groupSyncable1.SyncableId, groupSyncable1.Type)
4531
4532	count, err := ss.Group().GroupChannelCount()
4533	require.NoError(t, err)
4534	require.GreaterOrEqual(t, count, int64(1))
4535
4536	groupSyncable2, err := ss.Group().CreateGroupSyncable(model.NewGroupChannel(group2.Id, channel.Id, false))
4537	require.NoError(t, err)
4538	defer ss.Group().DeleteGroupSyncable(groupSyncable2.GroupId, groupSyncable2.SyncableId, groupSyncable2.Type)
4539
4540	countAfter, err := ss.Group().GroupChannelCount()
4541	require.NoError(t, err)
4542	require.GreaterOrEqual(t, countAfter, count+1)
4543}
4544
4545func groupTestGroupMemberCount(t *testing.T, ss store.Store) {
4546	group, err := ss.Group().Create(&model.Group{
4547		Name:        model.NewString(model.NewId()),
4548		DisplayName: model.NewId(),
4549		Source:      model.GroupSourceLdap,
4550		RemoteId:    model.NewId(),
4551	})
4552	require.NoError(t, err)
4553	defer ss.Group().Delete(group.Id)
4554
4555	member1, err := ss.Group().UpsertMember(group.Id, model.NewId())
4556	require.NoError(t, err)
4557	defer ss.Group().DeleteMember(group.Id, member1.UserId)
4558
4559	count, err := ss.Group().GroupMemberCount()
4560	require.NoError(t, err)
4561	require.GreaterOrEqual(t, count, int64(1))
4562
4563	member2, err := ss.Group().UpsertMember(group.Id, model.NewId())
4564	require.NoError(t, err)
4565	defer ss.Group().DeleteMember(group.Id, member2.UserId)
4566
4567	countAfter, err := ss.Group().GroupMemberCount()
4568	require.NoError(t, err)
4569	require.GreaterOrEqual(t, countAfter, count+1)
4570}
4571
4572func groupTestDistinctGroupMemberCount(t *testing.T, ss store.Store) {
4573	group1, err := ss.Group().Create(&model.Group{
4574		Name:        model.NewString(model.NewId()),
4575		DisplayName: model.NewId(),
4576		Source:      model.GroupSourceLdap,
4577		RemoteId:    model.NewId(),
4578	})
4579	require.NoError(t, err)
4580	defer ss.Group().Delete(group1.Id)
4581
4582	group2, err := ss.Group().Create(&model.Group{
4583		Name:        model.NewString(model.NewId()),
4584		DisplayName: model.NewId(),
4585		Source:      model.GroupSourceLdap,
4586		RemoteId:    model.NewId(),
4587	})
4588	require.NoError(t, err)
4589	defer ss.Group().Delete(group2.Id)
4590
4591	member1, err := ss.Group().UpsertMember(group1.Id, model.NewId())
4592	require.NoError(t, err)
4593	defer ss.Group().DeleteMember(group1.Id, member1.UserId)
4594
4595	count, err := ss.Group().GroupMemberCount()
4596	require.NoError(t, err)
4597	require.GreaterOrEqual(t, count, int64(1))
4598
4599	member2, err := ss.Group().UpsertMember(group1.Id, model.NewId())
4600	require.NoError(t, err)
4601	defer ss.Group().DeleteMember(group1.Id, member2.UserId)
4602
4603	countAfter1, err := ss.Group().GroupMemberCount()
4604	require.NoError(t, err)
4605	require.GreaterOrEqual(t, countAfter1, count+1)
4606
4607	member3, err := ss.Group().UpsertMember(group1.Id, member1.UserId)
4608	require.NoError(t, err)
4609	defer ss.Group().DeleteMember(group1.Id, member3.UserId)
4610
4611	countAfter2, err := ss.Group().GroupMemberCount()
4612	require.NoError(t, err)
4613	require.GreaterOrEqual(t, countAfter2, countAfter1)
4614}
4615
4616func groupTestGroupCountWithAllowReference(t *testing.T, ss store.Store) {
4617	initialCount, err := ss.Group().GroupCountWithAllowReference()
4618	require.NoError(t, err)
4619
4620	group1, err := ss.Group().Create(&model.Group{
4621		Name:        model.NewString(model.NewId()),
4622		DisplayName: model.NewId(),
4623		Source:      model.GroupSourceLdap,
4624		RemoteId:    model.NewId(),
4625	})
4626	require.NoError(t, err)
4627	defer ss.Group().Delete(group1.Id)
4628
4629	count, err := ss.Group().GroupCountWithAllowReference()
4630	require.NoError(t, err)
4631	require.Equal(t, count, initialCount)
4632
4633	group2, err := ss.Group().Create(&model.Group{
4634		Name:           model.NewString(model.NewId()),
4635		DisplayName:    model.NewId(),
4636		Source:         model.GroupSourceLdap,
4637		RemoteId:       model.NewId(),
4638		AllowReference: true,
4639	})
4640	require.NoError(t, err)
4641	defer ss.Group().Delete(group2.Id)
4642
4643	countAfter, err := ss.Group().GroupCountWithAllowReference()
4644	require.NoError(t, err)
4645	require.Greater(t, countAfter, count)
4646}
4647