github.com/xzl8028/xenia-server@v0.0.0-20190809101854-18450a97da63/store/storetest/group_store.go (about)

     1  // Copyright (c) 2018-present Xenia, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package storetest
     5  
     6  import (
     7  	"fmt"
     8  	"math"
     9  	"sort"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/xzl8028/xenia-server/model"
    14  	"github.com/xzl8028/xenia-server/store"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func TestGroupStore(t *testing.T, ss store.Store) {
    19  	t.Run("Create", func(t *testing.T) { testGroupStoreCreate(t, ss) })
    20  	t.Run("Get", func(t *testing.T) { testGroupStoreGet(t, ss) })
    21  	t.Run("GetByIDs", func(t *testing.T) { testGroupStoreGetByIDs(t, ss) })
    22  	t.Run("GetByRemoteID", func(t *testing.T) { testGroupStoreGetByRemoteID(t, ss) })
    23  	t.Run("GetAllBySource", func(t *testing.T) { testGroupStoreGetAllByType(t, ss) })
    24  	t.Run("Update", func(t *testing.T) { testGroupStoreUpdate(t, ss) })
    25  	t.Run("Delete", func(t *testing.T) { testGroupStoreDelete(t, ss) })
    26  
    27  	t.Run("GetMemberUsers", func(t *testing.T) { testGroupGetMemberUsers(t, ss) })
    28  	t.Run("GetMemberUsersPage", func(t *testing.T) { testGroupGetMemberUsersPage(t, ss) })
    29  	t.Run("UpsertMember", func(t *testing.T) { testGroupCreateOrRestoreMember(t, ss) })
    30  	t.Run("DeleteMember", func(t *testing.T) { testGroupDeleteMember(t, ss) })
    31  
    32  	t.Run("CreateGroupSyncable", func(t *testing.T) { testCreateGroupSyncable(t, ss) })
    33  	t.Run("GetGroupSyncable", func(t *testing.T) { testGetGroupSyncable(t, ss) })
    34  	t.Run("GetAllGroupSyncablesByGroupId", func(t *testing.T) { testGetAllGroupSyncablesByGroup(t, ss) })
    35  	t.Run("UpdateGroupSyncable", func(t *testing.T) { testUpdateGroupSyncable(t, ss) })
    36  	t.Run("DeleteGroupSyncable", func(t *testing.T) { testDeleteGroupSyncable(t, ss) })
    37  
    38  	t.Run("TeamMembersToAdd", func(t *testing.T) { testPendingAutoAddTeamMembers(t, ss) })
    39  	t.Run("ChannelMembersToAdd", func(t *testing.T) { testPendingAutoAddChannelMembers(t, ss) })
    40  
    41  	t.Run("TeamMembersToRemove", func(t *testing.T) { testTeamMemberRemovals(t, ss) })
    42  	t.Run("ChannelMembersToRemove", func(t *testing.T) { testChannelMemberRemovals(t, ss) })
    43  
    44  	t.Run("GetGroupsByChannel", func(t *testing.T) { testGetGroupsByChannel(t, ss) })
    45  	t.Run("GetGroupsByTeam", func(t *testing.T) { testGetGroupsByTeam(t, ss) })
    46  
    47  	t.Run("GetGroups", func(t *testing.T) { testGetGroups(t, ss) })
    48  
    49  	t.Run("TeamMembersMinusGroupMembers", func(t *testing.T) { testTeamMembersMinusGroupMembers(t, ss) })
    50  	t.Run("ChannelMembersMinusGroupMembers", func(t *testing.T) { testChannelMembersMinusGroupMembers(t, ss) })
    51  }
    52  
    53  func testGroupStoreCreate(t *testing.T, ss store.Store) {
    54  	// Save a new group
    55  	g1 := &model.Group{
    56  		Name:        model.NewId(),
    57  		DisplayName: model.NewId(),
    58  		Source:      model.GroupSourceLdap,
    59  		Description: model.NewId(),
    60  		RemoteId:    model.NewId(),
    61  	}
    62  
    63  	// Happy path
    64  	res1 := <-ss.Group().Create(g1)
    65  	require.Nil(t, res1.Err)
    66  	d1 := res1.Data.(*model.Group)
    67  	require.Len(t, d1.Id, 26)
    68  	require.Equal(t, g1.Name, d1.Name)
    69  	require.Equal(t, g1.DisplayName, d1.DisplayName)
    70  	require.Equal(t, g1.Description, d1.Description)
    71  	require.Equal(t, g1.RemoteId, d1.RemoteId)
    72  	require.NotZero(t, d1.CreateAt)
    73  	require.NotZero(t, d1.UpdateAt)
    74  	require.Zero(t, d1.DeleteAt)
    75  
    76  	// Requires name and display name
    77  	g2 := &model.Group{
    78  		Name:        "",
    79  		DisplayName: model.NewId(),
    80  		Source:      model.GroupSourceLdap,
    81  		RemoteId:    model.NewId(),
    82  	}
    83  	res2 := <-ss.Group().Create(g2)
    84  	require.Nil(t, res2.Data)
    85  	require.NotNil(t, res2.Err)
    86  	require.Equal(t, res2.Err.Id, "model.group.name.app_error")
    87  
    88  	g2.Name = model.NewId()
    89  	g2.DisplayName = ""
    90  	res3 := <-ss.Group().Create(g2)
    91  	require.Nil(t, res3.Data)
    92  	require.NotNil(t, res3.Err)
    93  	require.Equal(t, res3.Err.Id, "model.group.display_name.app_error")
    94  
    95  	// Won't accept a duplicate name
    96  	g4 := &model.Group{
    97  		Name:        model.NewId(),
    98  		DisplayName: model.NewId(),
    99  		Source:      model.GroupSourceLdap,
   100  		RemoteId:    model.NewId(),
   101  	}
   102  	res5 := <-ss.Group().Create(g4)
   103  	require.Nil(t, res5.Err)
   104  	g4b := &model.Group{
   105  		Name:        g4.Name,
   106  		DisplayName: model.NewId(),
   107  		Source:      model.GroupSourceLdap,
   108  		RemoteId:    model.NewId(),
   109  	}
   110  	res5b := <-ss.Group().Create(g4b)
   111  	require.Nil(t, res5b.Data)
   112  	require.Equal(t, res5b.Err.Id, "store.sql_group.unique_constraint")
   113  
   114  	// Fields cannot be greater than max values
   115  	g5 := &model.Group{
   116  		Name:        strings.Repeat("x", model.GroupNameMaxLength),
   117  		DisplayName: strings.Repeat("x", model.GroupDisplayNameMaxLength),
   118  		Description: strings.Repeat("x", model.GroupDescriptionMaxLength),
   119  		Source:      model.GroupSourceLdap,
   120  		RemoteId:    model.NewId(),
   121  	}
   122  	require.Nil(t, g5.IsValidForCreate())
   123  
   124  	g5.Name = g5.Name + "x"
   125  	require.Equal(t, g5.IsValidForCreate().Id, "model.group.name.app_error")
   126  	g5.Name = model.NewId()
   127  	require.Nil(t, g5.IsValidForCreate())
   128  
   129  	g5.DisplayName = g5.DisplayName + "x"
   130  	require.Equal(t, g5.IsValidForCreate().Id, "model.group.display_name.app_error")
   131  	g5.DisplayName = model.NewId()
   132  	require.Nil(t, g5.IsValidForCreate())
   133  
   134  	g5.Description = g5.Description + "x"
   135  	require.Equal(t, g5.IsValidForCreate().Id, "model.group.description.app_error")
   136  	g5.Description = model.NewId()
   137  	require.Nil(t, g5.IsValidForCreate())
   138  
   139  	// Must use a valid type
   140  	g6 := &model.Group{
   141  		Name:        model.NewId(),
   142  		DisplayName: model.NewId(),
   143  		Description: model.NewId(),
   144  		Source:      model.GroupSource("fake"),
   145  		RemoteId:    model.NewId(),
   146  	}
   147  	require.Equal(t, g6.IsValidForCreate().Id, "model.group.source.app_error")
   148  }
   149  
   150  func testGroupStoreGet(t *testing.T, ss store.Store) {
   151  	// Create a group
   152  	g1 := &model.Group{
   153  		Name:        model.NewId(),
   154  		DisplayName: model.NewId(),
   155  		Description: model.NewId(),
   156  		Source:      model.GroupSourceLdap,
   157  		RemoteId:    model.NewId(),
   158  	}
   159  	res1 := <-ss.Group().Create(g1)
   160  	require.Nil(t, res1.Err)
   161  	d1 := res1.Data.(*model.Group)
   162  	require.Len(t, d1.Id, 26)
   163  
   164  	// Get the group
   165  	res2 := <-ss.Group().Get(d1.Id)
   166  	require.Nil(t, res2.Err)
   167  	d2 := res2.Data.(*model.Group)
   168  	require.Equal(t, d1.Id, d2.Id)
   169  	require.Equal(t, d1.Name, d2.Name)
   170  	require.Equal(t, d1.DisplayName, d2.DisplayName)
   171  	require.Equal(t, d1.Description, d2.Description)
   172  	require.Equal(t, d1.RemoteId, d2.RemoteId)
   173  	require.Equal(t, d1.CreateAt, d2.CreateAt)
   174  	require.Equal(t, d1.UpdateAt, d2.UpdateAt)
   175  	require.Equal(t, d1.DeleteAt, d2.DeleteAt)
   176  
   177  	// Get an invalid group
   178  	res3 := <-ss.Group().Get(model.NewId())
   179  	require.NotNil(t, res3.Err)
   180  	require.Equal(t, res3.Err.Id, "store.sql_group.no_rows")
   181  }
   182  
   183  func testGroupStoreGetByIDs(t *testing.T, ss store.Store) {
   184  	var group1 *model.Group
   185  	var group2 *model.Group
   186  
   187  	for i := 0; i < 2; i++ {
   188  		group := &model.Group{
   189  			Name:        model.NewId(),
   190  			DisplayName: model.NewId(),
   191  			Description: model.NewId(),
   192  			Source:      model.GroupSourceLdap,
   193  			RemoteId:    model.NewId(),
   194  		}
   195  		res := <-ss.Group().Create(group)
   196  		require.Nil(t, res.Err)
   197  		group = res.Data.(*model.Group)
   198  		switch i {
   199  		case 0:
   200  			group1 = group
   201  		case 1:
   202  			group2 = group
   203  		}
   204  	}
   205  
   206  	groups, err := ss.Group().GetByIDs([]string{group1.Id, group2.Id})
   207  	require.Nil(t, err)
   208  	require.Len(t, groups, 2)
   209  
   210  	for i := 0; i < 2; i++ {
   211  		require.True(t, (groups[i].Id == group1.Id || groups[i].Id == group2.Id))
   212  	}
   213  
   214  	require.True(t, groups[0].Id != groups[1].Id)
   215  }
   216  
   217  func testGroupStoreGetByRemoteID(t *testing.T, ss store.Store) {
   218  	// Create a group
   219  	g1 := &model.Group{
   220  		Name:        model.NewId(),
   221  		DisplayName: model.NewId(),
   222  		Description: model.NewId(),
   223  		Source:      model.GroupSourceLdap,
   224  		RemoteId:    model.NewId(),
   225  	}
   226  	res1 := <-ss.Group().Create(g1)
   227  	require.Nil(t, res1.Err)
   228  	d1 := res1.Data.(*model.Group)
   229  	require.Len(t, d1.Id, 26)
   230  
   231  	// Get the group
   232  	res2 := <-ss.Group().GetByRemoteID(d1.RemoteId, model.GroupSourceLdap)
   233  	require.Nil(t, res2.Err)
   234  	d2 := res2.Data.(*model.Group)
   235  	require.Equal(t, d1.Id, d2.Id)
   236  	require.Equal(t, d1.Name, d2.Name)
   237  	require.Equal(t, d1.DisplayName, d2.DisplayName)
   238  	require.Equal(t, d1.Description, d2.Description)
   239  	require.Equal(t, d1.RemoteId, d2.RemoteId)
   240  	require.Equal(t, d1.CreateAt, d2.CreateAt)
   241  	require.Equal(t, d1.UpdateAt, d2.UpdateAt)
   242  	require.Equal(t, d1.DeleteAt, d2.DeleteAt)
   243  
   244  	// Get an invalid group
   245  	res3 := <-ss.Group().GetByRemoteID(model.NewId(), model.GroupSource("fake"))
   246  	require.NotNil(t, res3.Err)
   247  	require.Equal(t, res3.Err.Id, "store.sql_group.no_rows")
   248  }
   249  
   250  func testGroupStoreGetAllByType(t *testing.T, ss store.Store) {
   251  	numGroups := 10
   252  
   253  	groups := []*model.Group{}
   254  
   255  	// Create groups
   256  	for i := 0; i < numGroups; i++ {
   257  		g := &model.Group{
   258  			Name:        model.NewId(),
   259  			DisplayName: model.NewId(),
   260  			Description: model.NewId(),
   261  			Source:      model.GroupSourceLdap,
   262  			RemoteId:    model.NewId(),
   263  		}
   264  		groups = append(groups, g)
   265  		res := <-ss.Group().Create(g)
   266  		require.Nil(t, res.Err)
   267  	}
   268  
   269  	// Returns all the groups
   270  	res1 := <-ss.Group().GetAllBySource(model.GroupSourceLdap)
   271  	d1 := res1.Data.([]*model.Group)
   272  	require.Condition(t, func() bool { return len(d1) >= numGroups })
   273  	for _, expectedGroup := range groups {
   274  		present := false
   275  		for _, dbGroup := range d1 {
   276  			if dbGroup.Id == expectedGroup.Id {
   277  				present = true
   278  				break
   279  			}
   280  		}
   281  		require.True(t, present)
   282  	}
   283  }
   284  
   285  func testGroupStoreUpdate(t *testing.T, ss store.Store) {
   286  	// Save a new group
   287  	g1 := &model.Group{
   288  		Name:        "g1-test",
   289  		DisplayName: model.NewId(),
   290  		Source:      model.GroupSourceLdap,
   291  		Description: model.NewId(),
   292  		RemoteId:    model.NewId(),
   293  	}
   294  
   295  	// Create a group
   296  	res := <-ss.Group().Create(g1)
   297  	require.Nil(t, res.Err)
   298  	d1 := res.Data.(*model.Group)
   299  
   300  	// Update happy path
   301  	g1Update := &model.Group{}
   302  	*g1Update = *g1
   303  	g1Update.Name = model.NewId()
   304  	g1Update.DisplayName = model.NewId()
   305  	g1Update.Description = model.NewId()
   306  	g1Update.RemoteId = model.NewId()
   307  
   308  	res2 := <-ss.Group().Update(g1Update)
   309  	require.Nil(t, res2.Err)
   310  	ud1 := res2.Data.(*model.Group)
   311  	// Not changed...
   312  	require.Equal(t, d1.Id, ud1.Id)
   313  	require.Equal(t, d1.CreateAt, ud1.CreateAt)
   314  	require.Equal(t, d1.Source, ud1.Source)
   315  	// Still zero...
   316  	require.Zero(t, ud1.DeleteAt)
   317  	// Updated...
   318  	require.Equal(t, g1Update.Name, ud1.Name)
   319  	require.Equal(t, g1Update.DisplayName, ud1.DisplayName)
   320  	require.Equal(t, g1Update.Description, ud1.Description)
   321  	require.Equal(t, g1Update.RemoteId, ud1.RemoteId)
   322  
   323  	// Requires name and display name
   324  	res3 := <-ss.Group().Update(&model.Group{
   325  		Id:          d1.Id,
   326  		Name:        "",
   327  		DisplayName: model.NewId(),
   328  		Source:      model.GroupSourceLdap,
   329  		RemoteId:    model.NewId(),
   330  		Description: model.NewId(),
   331  	})
   332  	require.Nil(t, res3.Data)
   333  	require.NotNil(t, res3.Err)
   334  	require.Equal(t, res3.Err.Id, "model.group.name.app_error")
   335  
   336  	res4 := <-ss.Group().Update(&model.Group{
   337  		Id:          d1.Id,
   338  		Name:        model.NewId(),
   339  		DisplayName: "",
   340  		Source:      model.GroupSourceLdap,
   341  		RemoteId:    model.NewId(),
   342  	})
   343  	require.Nil(t, res4.Data)
   344  	require.NotNil(t, res4.Err)
   345  	require.Equal(t, res4.Err.Id, "model.group.display_name.app_error")
   346  
   347  	// Create another Group
   348  	g2 := &model.Group{
   349  		Name:        model.NewId(),
   350  		DisplayName: model.NewId(),
   351  		Source:      model.GroupSourceLdap,
   352  		Description: model.NewId(),
   353  		RemoteId:    model.NewId(),
   354  	}
   355  	res5 := <-ss.Group().Create(g2)
   356  	require.Nil(t, res5.Err)
   357  	d2 := res5.Data.(*model.Group)
   358  
   359  	// Can't update the name to be a duplicate of an existing group's name
   360  	res6 := <-ss.Group().Update(&model.Group{
   361  		Id:          d2.Id,
   362  		Name:        g1Update.Name,
   363  		DisplayName: model.NewId(),
   364  		Source:      model.GroupSourceLdap,
   365  		Description: model.NewId(),
   366  		RemoteId:    model.NewId(),
   367  	})
   368  	require.Equal(t, res6.Err.Id, "store.update_error")
   369  
   370  	// Cannot update CreateAt
   371  	someVal := model.GetMillis()
   372  	d1.CreateAt = someVal
   373  	res7 := <-ss.Group().Update(d1)
   374  	d3 := res7.Data.(*model.Group)
   375  	require.NotEqual(t, someVal, d3.CreateAt)
   376  
   377  	// Cannot update DeleteAt to non-zero
   378  	d1.DeleteAt = 1
   379  	res9 := <-ss.Group().Update(d1)
   380  	require.Equal(t, "model.group.delete_at.app_error", res9.Err.Id)
   381  
   382  	//...except for 0 for DeleteAt
   383  	d1.DeleteAt = 0
   384  	res8 := <-ss.Group().Update(d1)
   385  	require.Nil(t, res8.Err)
   386  	d4 := res8.Data.(*model.Group)
   387  	require.Zero(t, d4.DeleteAt)
   388  }
   389  
   390  func testGroupStoreDelete(t *testing.T, ss store.Store) {
   391  	// Save a group
   392  	g1 := &model.Group{
   393  		Name:        model.NewId(),
   394  		DisplayName: model.NewId(),
   395  		Description: model.NewId(),
   396  		Source:      model.GroupSourceLdap,
   397  		RemoteId:    model.NewId(),
   398  	}
   399  
   400  	res1 := <-ss.Group().Create(g1)
   401  	require.Nil(t, res1.Err)
   402  	d1 := res1.Data.(*model.Group)
   403  	require.Len(t, d1.Id, 26)
   404  
   405  	// Check the group is retrievable
   406  	res2 := <-ss.Group().Get(d1.Id)
   407  	require.Nil(t, res2.Err)
   408  
   409  	// Get the before count
   410  	res7 := <-ss.Group().GetAllBySource(model.GroupSourceLdap)
   411  	d7 := res7.Data.([]*model.Group)
   412  	beforeCount := len(d7)
   413  
   414  	// Delete the group
   415  	res3 := <-ss.Group().Delete(d1.Id)
   416  	require.Nil(t, res3.Err)
   417  
   418  	// Check the group is deleted
   419  	res4 := <-ss.Group().Get(d1.Id)
   420  	d4 := res4.Data.(*model.Group)
   421  	require.NotZero(t, d4.DeleteAt)
   422  
   423  	// Check the after count
   424  	res5 := <-ss.Group().GetAllBySource(model.GroupSourceLdap)
   425  	d5 := res5.Data.([]*model.Group)
   426  	afterCount := len(d5)
   427  	require.Condition(t, func() bool { return beforeCount == afterCount+1 })
   428  
   429  	// Try and delete a nonexistent group
   430  	res6 := <-ss.Group().Delete(model.NewId())
   431  	require.NotNil(t, res6.Err)
   432  	require.Equal(t, res6.Err.Id, "store.sql_group.no_rows")
   433  
   434  	// Cannot delete again
   435  	res8 := <-ss.Group().Delete(d1.Id)
   436  	require.Equal(t, res8.Err.Id, "store.sql_group.no_rows")
   437  }
   438  
   439  func testGroupGetMemberUsers(t *testing.T, ss store.Store) {
   440  	// Save a group
   441  	g1 := &model.Group{
   442  		Name:        model.NewId(),
   443  		DisplayName: model.NewId(),
   444  		Description: model.NewId(),
   445  		Source:      model.GroupSourceLdap,
   446  		RemoteId:    model.NewId(),
   447  	}
   448  	res := <-ss.Group().Create(g1)
   449  	require.Nil(t, res.Err)
   450  	group := res.Data.(*model.Group)
   451  
   452  	u1 := &model.User{
   453  		Email:    MakeEmail(),
   454  		Username: model.NewId(),
   455  	}
   456  	res = <-ss.User().Save(u1)
   457  	require.Nil(t, res.Err)
   458  	user1 := res.Data.(*model.User)
   459  
   460  	res = <-ss.Group().UpsertMember(group.Id, user1.Id)
   461  	require.Nil(t, res.Err)
   462  
   463  	u2 := &model.User{
   464  		Email:    MakeEmail(),
   465  		Username: model.NewId(),
   466  	}
   467  	res = <-ss.User().Save(u2)
   468  	require.Nil(t, res.Err)
   469  	user2 := res.Data.(*model.User)
   470  
   471  	res = <-ss.Group().UpsertMember(group.Id, user2.Id)
   472  	require.Nil(t, res.Err)
   473  
   474  	// Check returns members
   475  	res = <-ss.Group().GetMemberUsers(group.Id)
   476  	require.Nil(t, res.Err)
   477  	groupMembers := res.Data.([]*model.User)
   478  	require.Equal(t, 2, len(groupMembers))
   479  
   480  	// Check madeup id
   481  	res = <-ss.Group().GetMemberUsers(model.NewId())
   482  	require.Equal(t, 0, len(res.Data.([]*model.User)))
   483  
   484  	// Delete a member
   485  	<-ss.Group().DeleteMember(group.Id, user1.Id)
   486  
   487  	// Should not return deleted members
   488  	res = <-ss.Group().GetMemberUsers(group.Id)
   489  	groupMembers = res.Data.([]*model.User)
   490  	require.Equal(t, 1, len(groupMembers))
   491  }
   492  
   493  func testGroupGetMemberUsersPage(t *testing.T, ss store.Store) {
   494  	// Save a group
   495  	g1 := &model.Group{
   496  		Name:        model.NewId(),
   497  		DisplayName: model.NewId(),
   498  		Description: model.NewId(),
   499  		Source:      model.GroupSourceLdap,
   500  		RemoteId:    model.NewId(),
   501  	}
   502  	res := <-ss.Group().Create(g1)
   503  	require.Nil(t, res.Err)
   504  	group := res.Data.(*model.Group)
   505  
   506  	u1 := &model.User{
   507  		Email:    MakeEmail(),
   508  		Username: model.NewId(),
   509  	}
   510  	res = <-ss.User().Save(u1)
   511  	require.Nil(t, res.Err)
   512  	user1 := res.Data.(*model.User)
   513  
   514  	res = <-ss.Group().UpsertMember(group.Id, user1.Id)
   515  	require.Nil(t, res.Err)
   516  
   517  	u2 := &model.User{
   518  		Email:    MakeEmail(),
   519  		Username: model.NewId(),
   520  	}
   521  	res = <-ss.User().Save(u2)
   522  	require.Nil(t, res.Err)
   523  	user2 := res.Data.(*model.User)
   524  
   525  	res = <-ss.Group().UpsertMember(group.Id, user2.Id)
   526  	require.Nil(t, res.Err)
   527  
   528  	// Check returns members
   529  	res = <-ss.Group().GetMemberUsersPage(group.Id, 0, 100)
   530  	require.Nil(t, res.Err)
   531  	groupMembers := res.Data.([]*model.User)
   532  	require.Equal(t, 2, len(groupMembers))
   533  
   534  	// Check page 1
   535  	res = <-ss.Group().GetMemberUsersPage(group.Id, 0, 1)
   536  	require.Nil(t, res.Err)
   537  	groupMembers = res.Data.([]*model.User)
   538  	require.Equal(t, 1, len(groupMembers))
   539  	require.Equal(t, user2.Id, groupMembers[0].Id)
   540  
   541  	// Check page 2
   542  	res = <-ss.Group().GetMemberUsersPage(group.Id, 1, 1)
   543  	require.Nil(t, res.Err)
   544  	groupMembers = res.Data.([]*model.User)
   545  	require.Equal(t, 1, len(groupMembers))
   546  	require.Equal(t, user1.Id, groupMembers[0].Id)
   547  
   548  	// Check madeup id
   549  	res = <-ss.Group().GetMemberUsersPage(model.NewId(), 0, 100)
   550  	require.Equal(t, 0, len(res.Data.([]*model.User)))
   551  
   552  	// Delete a member
   553  	<-ss.Group().DeleteMember(group.Id, user1.Id)
   554  
   555  	// Should not return deleted members
   556  	res = <-ss.Group().GetMemberUsersPage(group.Id, 0, 100)
   557  	groupMembers = res.Data.([]*model.User)
   558  	require.Equal(t, 1, len(groupMembers))
   559  }
   560  
   561  func testGroupCreateOrRestoreMember(t *testing.T, ss store.Store) {
   562  	// Create group
   563  	g1 := &model.Group{
   564  		Name:        model.NewId(),
   565  		DisplayName: model.NewId(),
   566  		Source:      model.GroupSourceLdap,
   567  		RemoteId:    model.NewId(),
   568  	}
   569  	res1 := <-ss.Group().Create(g1)
   570  	require.Nil(t, res1.Err)
   571  	group := res1.Data.(*model.Group)
   572  
   573  	// Create user
   574  	u1 := &model.User{
   575  		Email:    MakeEmail(),
   576  		Username: model.NewId(),
   577  	}
   578  	res2 := <-ss.User().Save(u1)
   579  	require.Nil(t, res2.Err)
   580  	user := res2.Data.(*model.User)
   581  
   582  	// Happy path
   583  	res3 := <-ss.Group().UpsertMember(group.Id, user.Id)
   584  	require.Nil(t, res3.Err)
   585  	d2 := res3.Data.(*model.GroupMember)
   586  	require.Equal(t, d2.GroupId, group.Id)
   587  	require.Equal(t, d2.UserId, user.Id)
   588  	require.NotZero(t, d2.CreateAt)
   589  	require.Zero(t, d2.DeleteAt)
   590  
   591  	// Duplicate composite key (GroupId, UserId)
   592  	res4 := <-ss.Group().UpsertMember(group.Id, user.Id)
   593  	require.Nil(t, res4.Err)
   594  
   595  	// Invalid GroupId
   596  	res6 := <-ss.Group().UpsertMember(model.NewId(), user.Id)
   597  	require.Equal(t, res6.Err.Id, "store.insert_error")
   598  
   599  	// Restores a deleted member
   600  	res := <-ss.Group().UpsertMember(group.Id, user.Id)
   601  	require.Nil(t, res.Err)
   602  
   603  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
   604  	require.Nil(t, res.Err)
   605  
   606  	res = <-ss.Group().GetMemberUsers(group.Id)
   607  	beforeRestoreCount := len(res.Data.([]*model.User))
   608  
   609  	res = <-ss.Group().UpsertMember(group.Id, user.Id)
   610  	require.Nil(t, res.Err)
   611  
   612  	res = <-ss.Group().GetMemberUsers(group.Id)
   613  	afterRestoreCount := len(res.Data.([]*model.User))
   614  
   615  	require.Equal(t, beforeRestoreCount+1, afterRestoreCount)
   616  }
   617  
   618  func testGroupDeleteMember(t *testing.T, ss store.Store) {
   619  	// Create group
   620  	g1 := &model.Group{
   621  		Name:        model.NewId(),
   622  		DisplayName: model.NewId(),
   623  		Source:      model.GroupSourceLdap,
   624  		RemoteId:    model.NewId(),
   625  	}
   626  	res1 := <-ss.Group().Create(g1)
   627  	require.Nil(t, res1.Err)
   628  	group := res1.Data.(*model.Group)
   629  
   630  	// Create user
   631  	u1 := &model.User{
   632  		Email:    MakeEmail(),
   633  		Username: model.NewId(),
   634  	}
   635  	res2 := <-ss.User().Save(u1)
   636  	require.Nil(t, res2.Err)
   637  	user := res2.Data.(*model.User)
   638  
   639  	// Create member
   640  	res3 := <-ss.Group().UpsertMember(group.Id, user.Id)
   641  	require.Nil(t, res3.Err)
   642  	d1 := res3.Data.(*model.GroupMember)
   643  
   644  	// Happy path
   645  	res4 := <-ss.Group().DeleteMember(group.Id, user.Id)
   646  	require.Nil(t, res4.Err)
   647  	d2 := res4.Data.(*model.GroupMember)
   648  	require.Equal(t, d2.GroupId, group.Id)
   649  	require.Equal(t, d2.UserId, user.Id)
   650  	require.Equal(t, d2.CreateAt, d1.CreateAt)
   651  	require.NotZero(t, d2.DeleteAt)
   652  
   653  	// Delete an already deleted member
   654  	res5 := <-ss.Group().DeleteMember(group.Id, user.Id)
   655  	require.Equal(t, res5.Err.Id, "store.sql_group.no_rows")
   656  
   657  	// Delete with non-existent User
   658  	res8 := <-ss.Group().DeleteMember(group.Id, model.NewId())
   659  	require.Equal(t, res8.Err.Id, "store.sql_group.no_rows")
   660  
   661  	// Delete non-existent Group
   662  	res9 := <-ss.Group().DeleteMember(model.NewId(), group.Id)
   663  	require.Equal(t, res9.Err.Id, "store.sql_group.no_rows")
   664  }
   665  
   666  func testCreateGroupSyncable(t *testing.T, ss store.Store) {
   667  	// Invalid GroupID
   668  	_, err := ss.Group().CreateGroupSyncable(model.NewGroupTeam("x", model.NewId(), false))
   669  	require.Equal(t, err.Id, "model.group_syncable.group_id.app_error")
   670  
   671  	// Create Group
   672  	g1 := &model.Group{
   673  		Name:        model.NewId(),
   674  		DisplayName: model.NewId(),
   675  		Source:      model.GroupSourceLdap,
   676  		RemoteId:    model.NewId(),
   677  	}
   678  	res4 := <-ss.Group().Create(g1)
   679  	require.Nil(t, res4.Err)
   680  	group := res4.Data.(*model.Group)
   681  
   682  	// Create Team
   683  	t1 := &model.Team{
   684  		DisplayName:     "Name",
   685  		Description:     "Some description",
   686  		CompanyName:     "Some company name",
   687  		AllowOpenInvite: false,
   688  		InviteId:        "inviteid0",
   689  		Name:            "z-z-" + model.NewId() + "a",
   690  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   691  		Type:            model.TEAM_OPEN,
   692  	}
   693  	team, err := ss.Team().Save(t1)
   694  	require.Nil(t, err)
   695  
   696  	// New GroupSyncable, happy path
   697  	gt1 := model.NewGroupTeam(group.Id, team.Id, false)
   698  	d1, err := ss.Group().CreateGroupSyncable(gt1)
   699  	require.Nil(t, err)
   700  	require.Equal(t, gt1.SyncableId, d1.SyncableId)
   701  	require.Equal(t, gt1.GroupId, d1.GroupId)
   702  	require.Equal(t, gt1.AutoAdd, d1.AutoAdd)
   703  	require.NotZero(t, d1.CreateAt)
   704  	require.Zero(t, d1.DeleteAt)
   705  }
   706  
   707  func testGetGroupSyncable(t *testing.T, ss store.Store) {
   708  	// Create a group
   709  	g1 := &model.Group{
   710  		Name:        model.NewId(),
   711  		DisplayName: model.NewId(),
   712  		Description: model.NewId(),
   713  		Source:      model.GroupSourceLdap,
   714  		RemoteId:    model.NewId(),
   715  	}
   716  	res1 := <-ss.Group().Create(g1)
   717  	require.Nil(t, res1.Err)
   718  	group := res1.Data.(*model.Group)
   719  
   720  	// Create Team
   721  	t1 := &model.Team{
   722  		DisplayName:     "Name",
   723  		Description:     "Some description",
   724  		CompanyName:     "Some company name",
   725  		AllowOpenInvite: false,
   726  		InviteId:        "inviteid0",
   727  		Name:            "z-z-" + model.NewId() + "a",
   728  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   729  		Type:            model.TEAM_OPEN,
   730  	}
   731  	team, err := ss.Team().Save(t1)
   732  	require.Nil(t, err)
   733  
   734  	// Create GroupSyncable
   735  	gt1 := model.NewGroupTeam(group.Id, team.Id, false)
   736  	groupTeam, err := ss.Group().CreateGroupSyncable(gt1)
   737  	require.Nil(t, err)
   738  
   739  	// Get GroupSyncable
   740  	dgt, err := ss.Group().GetGroupSyncable(groupTeam.GroupId, groupTeam.SyncableId, model.GroupSyncableTypeTeam)
   741  	require.Nil(t, err)
   742  	require.Equal(t, gt1.GroupId, dgt.GroupId)
   743  	require.Equal(t, gt1.SyncableId, dgt.SyncableId)
   744  	require.Equal(t, gt1.AutoAdd, dgt.AutoAdd)
   745  	require.NotZero(t, gt1.CreateAt)
   746  	require.NotZero(t, gt1.UpdateAt)
   747  	require.Zero(t, gt1.DeleteAt)
   748  }
   749  
   750  func testGetAllGroupSyncablesByGroup(t *testing.T, ss store.Store) {
   751  	numGroupSyncables := 10
   752  
   753  	// Create group
   754  	g := &model.Group{
   755  		Name:        model.NewId(),
   756  		DisplayName: model.NewId(),
   757  		Description: model.NewId(),
   758  		Source:      model.GroupSourceLdap,
   759  		RemoteId:    model.NewId(),
   760  	}
   761  	res1 := <-ss.Group().Create(g)
   762  	require.Nil(t, res1.Err)
   763  	group := res1.Data.(*model.Group)
   764  
   765  	groupTeams := []*model.GroupSyncable{}
   766  
   767  	// Create groupTeams
   768  	for i := 0; i < numGroupSyncables; i++ {
   769  		// Create Team
   770  		t1 := &model.Team{
   771  			DisplayName:     "Name",
   772  			Description:     "Some description",
   773  			CompanyName:     "Some company name",
   774  			AllowOpenInvite: false,
   775  			InviteId:        "inviteid0",
   776  			Name:            "z-z-" + model.NewId() + "a",
   777  			Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   778  			Type:            model.TEAM_OPEN,
   779  		}
   780  		team, err := ss.Team().Save(t1)
   781  		require.Nil(t, err)
   782  
   783  		// create groupteam
   784  		groupTeam, err := ss.Group().CreateGroupSyncable(model.NewGroupTeam(group.Id, team.Id, false))
   785  		require.Nil(t, err)
   786  		groupTeams = append(groupTeams, groupTeam)
   787  	}
   788  
   789  	// Returns all the group teams
   790  	d1, err := ss.Group().GetAllGroupSyncablesByGroupId(group.Id, model.GroupSyncableTypeTeam)
   791  	require.Nil(t, err)
   792  	require.Condition(t, func() bool { return len(d1) >= numGroupSyncables })
   793  	for _, expectedGroupTeam := range groupTeams {
   794  		present := false
   795  		for _, dbGroupTeam := range d1 {
   796  			if dbGroupTeam.GroupId == expectedGroupTeam.GroupId && dbGroupTeam.SyncableId == expectedGroupTeam.SyncableId {
   797  				present = true
   798  				break
   799  			}
   800  		}
   801  		require.True(t, present)
   802  	}
   803  }
   804  
   805  func testUpdateGroupSyncable(t *testing.T, ss store.Store) {
   806  	// Create Group
   807  	g1 := &model.Group{
   808  		Name:        model.NewId(),
   809  		DisplayName: model.NewId(),
   810  		Source:      model.GroupSourceLdap,
   811  		RemoteId:    model.NewId(),
   812  	}
   813  	res4 := <-ss.Group().Create(g1)
   814  	require.Nil(t, res4.Err)
   815  	group := res4.Data.(*model.Group)
   816  
   817  	// Create Team
   818  	t1 := &model.Team{
   819  		DisplayName:     "Name",
   820  		Description:     "Some description",
   821  		CompanyName:     "Some company name",
   822  		AllowOpenInvite: false,
   823  		InviteId:        "inviteid0",
   824  		Name:            "z-z-" + model.NewId() + "a",
   825  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   826  		Type:            model.TEAM_OPEN,
   827  	}
   828  	team, err := ss.Team().Save(t1)
   829  	require.Nil(t, err)
   830  
   831  	// New GroupSyncable, happy path
   832  	gt1 := model.NewGroupTeam(group.Id, team.Id, false)
   833  	d1, err := ss.Group().CreateGroupSyncable(gt1)
   834  	require.Nil(t, err)
   835  
   836  	// Update existing group team
   837  	gt1.AutoAdd = true
   838  	d2, err := ss.Group().UpdateGroupSyncable(gt1)
   839  	require.Nil(t, err)
   840  	require.True(t, d2.AutoAdd)
   841  
   842  	// Non-existent Group
   843  	gt2 := model.NewGroupTeam(model.NewId(), team.Id, false)
   844  	_, err = ss.Group().UpdateGroupSyncable(gt2)
   845  	require.Equal(t, err.Id, "store.sql_group.no_rows")
   846  
   847  	// Non-existent Team
   848  	gt3 := model.NewGroupTeam(group.Id, model.NewId(), false)
   849  	_, err = ss.Group().UpdateGroupSyncable(gt3)
   850  	require.Equal(t, err.Id, "store.sql_group.no_rows")
   851  
   852  	// Cannot update CreateAt or DeleteAt
   853  	origCreateAt := d1.CreateAt
   854  	d1.CreateAt = model.GetMillis()
   855  	d1.AutoAdd = true
   856  	d3, err := ss.Group().UpdateGroupSyncable(d1)
   857  	require.Nil(t, err)
   858  	require.Equal(t, origCreateAt, d3.CreateAt)
   859  
   860  	// Cannot update DeleteAt to arbitrary value
   861  	d1.DeleteAt = 1
   862  	_, err = ss.Group().UpdateGroupSyncable(d1)
   863  	require.Equal(t, "model.group.delete_at.app_error", err.Id)
   864  
   865  	// Can update DeleteAt to 0
   866  	d1.DeleteAt = 0
   867  	d4, err := ss.Group().UpdateGroupSyncable(d1)
   868  	require.Nil(t, err)
   869  	require.Zero(t, d4.DeleteAt)
   870  }
   871  
   872  func testDeleteGroupSyncable(t *testing.T, ss store.Store) {
   873  	// Create Group
   874  	g1 := &model.Group{
   875  		Name:        model.NewId(),
   876  		DisplayName: model.NewId(),
   877  		Source:      model.GroupSourceLdap,
   878  		RemoteId:    model.NewId(),
   879  	}
   880  	res1 := <-ss.Group().Create(g1)
   881  	require.Nil(t, res1.Err)
   882  	group := res1.Data.(*model.Group)
   883  
   884  	// Create Team
   885  	t1 := &model.Team{
   886  		DisplayName:     "Name",
   887  		Description:     "Some description",
   888  		CompanyName:     "Some company name",
   889  		AllowOpenInvite: false,
   890  		InviteId:        "inviteid0",
   891  		Name:            "z-z-" + model.NewId() + "a",
   892  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   893  		Type:            model.TEAM_OPEN,
   894  	}
   895  	team, err := ss.Team().Save(t1)
   896  	require.Nil(t, err)
   897  
   898  	// Create GroupSyncable
   899  	gt1 := model.NewGroupTeam(group.Id, team.Id, false)
   900  	groupTeam, err := ss.Group().CreateGroupSyncable(gt1)
   901  	require.Nil(t, err)
   902  
   903  	// Non-existent Group
   904  	_, err = ss.Group().DeleteGroupSyncable(model.NewId(), groupTeam.SyncableId, model.GroupSyncableTypeTeam)
   905  	require.Equal(t, err.Id, "store.sql_group.no_rows")
   906  
   907  	// Non-existent Team
   908  	_, err = ss.Group().DeleteGroupSyncable(groupTeam.GroupId, string(model.NewId()), model.GroupSyncableTypeTeam)
   909  	require.Equal(t, err.Id, "store.sql_group.no_rows")
   910  
   911  	// Happy path...
   912  	d1, err := ss.Group().DeleteGroupSyncable(groupTeam.GroupId, groupTeam.SyncableId, model.GroupSyncableTypeTeam)
   913  	require.Nil(t, err)
   914  	require.NotZero(t, d1.DeleteAt)
   915  	require.Equal(t, d1.GroupId, groupTeam.GroupId)
   916  	require.Equal(t, d1.SyncableId, groupTeam.SyncableId)
   917  	require.Equal(t, d1.AutoAdd, groupTeam.AutoAdd)
   918  	require.Equal(t, d1.CreateAt, groupTeam.CreateAt)
   919  	require.Condition(t, func() bool { return d1.UpdateAt > groupTeam.UpdateAt })
   920  
   921  	// Record already deleted
   922  	_, err = ss.Group().DeleteGroupSyncable(d1.GroupId, d1.SyncableId, d1.Type)
   923  	require.NotNil(t, err)
   924  	require.Equal(t, err.Id, "store.sql_group.group_syncable_already_deleted")
   925  }
   926  
   927  func testPendingAutoAddTeamMembers(t *testing.T, ss store.Store) {
   928  	// Create Group
   929  	res := <-ss.Group().Create(&model.Group{
   930  		Name:        model.NewId(),
   931  		DisplayName: "TeamMembersToAdd Test Group",
   932  		RemoteId:    model.NewId(),
   933  		Source:      model.GroupSourceLdap,
   934  	})
   935  	require.Nil(t, res.Err)
   936  	group := res.Data.(*model.Group)
   937  
   938  	// Create User
   939  	user := &model.User{
   940  		Email:    MakeEmail(),
   941  		Username: model.NewId(),
   942  	}
   943  	res = <-ss.User().Save(user)
   944  	require.Nil(t, res.Err)
   945  	user = res.Data.(*model.User)
   946  
   947  	// Create GroupMember
   948  	res = <-ss.Group().UpsertMember(group.Id, user.Id)
   949  	require.Nil(t, res.Err)
   950  
   951  	// Create Team
   952  	team := &model.Team{
   953  		DisplayName:     "Name",
   954  		Description:     "Some description",
   955  		CompanyName:     "Some company name",
   956  		AllowOpenInvite: false,
   957  		InviteId:        "inviteid0",
   958  		Name:            "z-z-" + model.NewId() + "a",
   959  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   960  		Type:            model.TEAM_OPEN,
   961  	}
   962  	team, err := ss.Team().Save(team)
   963  	require.Nil(t, err)
   964  
   965  	// Create GroupTeam
   966  	syncable, err := ss.Group().CreateGroupSyncable(model.NewGroupTeam(group.Id, team.Id, true))
   967  	require.Nil(t, err)
   968  
   969  	// Time before syncable was created
   970  	teamMembers, err := ss.Group().TeamMembersToAdd(syncable.CreateAt - 1)
   971  	require.Nil(t, err)
   972  	require.Len(t, teamMembers, 1)
   973  	require.Equal(t, user.Id, teamMembers[0].UserID)
   974  	require.Equal(t, team.Id, teamMembers[0].TeamID)
   975  
   976  	// Time after syncable was created
   977  	teamMembers, err = ss.Group().TeamMembersToAdd(syncable.CreateAt + 1)
   978  	require.Nil(t, err)
   979  	require.Len(t, teamMembers, 0)
   980  
   981  	// Delete and restore GroupMember should return result
   982  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
   983  	require.Nil(t, res.Err)
   984  	res = <-ss.Group().UpsertMember(group.Id, user.Id)
   985  	require.Nil(t, res.Err)
   986  	teamMembers, err = ss.Group().TeamMembersToAdd(syncable.CreateAt + 1)
   987  	require.Nil(t, err)
   988  	require.Len(t, teamMembers, 1)
   989  
   990  	pristineSyncable := *syncable
   991  
   992  	_, err = ss.Group().UpdateGroupSyncable(syncable)
   993  	require.Nil(t, err)
   994  
   995  	// Time before syncable was updated
   996  	teamMembers, err = ss.Group().TeamMembersToAdd(syncable.UpdateAt - 1)
   997  	require.Nil(t, err)
   998  	require.Len(t, teamMembers, 1)
   999  	require.Equal(t, user.Id, teamMembers[0].UserID)
  1000  	require.Equal(t, team.Id, teamMembers[0].TeamID)
  1001  
  1002  	// Time after syncable was updated
  1003  	teamMembers, err = ss.Group().TeamMembersToAdd(syncable.UpdateAt + 1)
  1004  	require.Nil(t, err)
  1005  	require.Len(t, teamMembers, 0)
  1006  
  1007  	// Only includes if auto-add
  1008  	syncable.AutoAdd = false
  1009  	_, err = ss.Group().UpdateGroupSyncable(syncable)
  1010  	require.Nil(t, err)
  1011  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1012  	require.Nil(t, err)
  1013  	require.Len(t, teamMembers, 0)
  1014  
  1015  	// reset state of syncable and verify
  1016  	_, err = ss.Group().UpdateGroupSyncable(&pristineSyncable)
  1017  	require.Nil(t, err)
  1018  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1019  	require.Nil(t, err)
  1020  	require.Len(t, teamMembers, 1)
  1021  
  1022  	// No result if Group deleted
  1023  	res = <-ss.Group().Delete(group.Id)
  1024  	require.Nil(t, res.Err)
  1025  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1026  	require.Nil(t, err)
  1027  	require.Len(t, teamMembers, 0)
  1028  
  1029  	// reset state of group and verify
  1030  	group.DeleteAt = 0
  1031  	res = <-ss.Group().Update(group)
  1032  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1033  	require.Nil(t, err)
  1034  	require.Len(t, teamMembers, 1)
  1035  
  1036  	// No result if Team deleted
  1037  	team.DeleteAt = model.GetMillis()
  1038  	team, err = ss.Team().Update(team)
  1039  	require.Nil(t, err)
  1040  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1041  	require.Nil(t, err)
  1042  	require.Len(t, teamMembers, 0)
  1043  
  1044  	// reset state of team and verify
  1045  	team.DeleteAt = 0
  1046  	team, err = ss.Team().Update(team)
  1047  	require.Nil(t, err)
  1048  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1049  	require.Nil(t, err)
  1050  	require.Len(t, teamMembers, 1)
  1051  
  1052  	// No result if GroupTeam deleted
  1053  	_, err = ss.Group().DeleteGroupSyncable(group.Id, team.Id, model.GroupSyncableTypeTeam)
  1054  	require.Nil(t, err)
  1055  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1056  	require.Nil(t, err)
  1057  	require.Len(t, teamMembers, 0)
  1058  
  1059  	// reset GroupTeam and verify
  1060  	_, err = ss.Group().UpdateGroupSyncable(&pristineSyncable)
  1061  	require.Nil(t, err)
  1062  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1063  	require.Nil(t, err)
  1064  	require.Len(t, teamMembers, 1)
  1065  
  1066  	// No result if GroupMember deleted
  1067  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
  1068  	require.Nil(t, res.Err)
  1069  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1070  	require.Nil(t, err)
  1071  	require.Len(t, teamMembers, 0)
  1072  
  1073  	// restore group member and verify
  1074  	res = <-ss.Group().UpsertMember(group.Id, user.Id)
  1075  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1076  	require.Nil(t, err)
  1077  	require.Len(t, teamMembers, 1)
  1078  
  1079  	// adding team membership stops returning result
  1080  	res = <-ss.Team().SaveMember(&model.TeamMember{
  1081  		TeamId: team.Id,
  1082  		UserId: user.Id,
  1083  	}, 999)
  1084  	require.Nil(t, res.Err)
  1085  	teamMembers, err = ss.Group().TeamMembersToAdd(0)
  1086  	require.Nil(t, err)
  1087  	require.Len(t, teamMembers, 0)
  1088  }
  1089  
  1090  func testPendingAutoAddChannelMembers(t *testing.T, ss store.Store) {
  1091  	// Create Group
  1092  	res := <-ss.Group().Create(&model.Group{
  1093  		Name:        model.NewId(),
  1094  		DisplayName: "ChannelMembersToAdd Test Group",
  1095  		RemoteId:    model.NewId(),
  1096  		Source:      model.GroupSourceLdap,
  1097  	})
  1098  	require.Nil(t, res.Err)
  1099  	group := res.Data.(*model.Group)
  1100  
  1101  	// Create User
  1102  	user := &model.User{
  1103  		Email:    MakeEmail(),
  1104  		Username: model.NewId(),
  1105  	}
  1106  	res = <-ss.User().Save(user)
  1107  	require.Nil(t, res.Err)
  1108  	user = res.Data.(*model.User)
  1109  
  1110  	// Create GroupMember
  1111  	res = <-ss.Group().UpsertMember(group.Id, user.Id)
  1112  	require.Nil(t, res.Err)
  1113  
  1114  	// Create Channel
  1115  	channel := &model.Channel{
  1116  		TeamId:      model.NewId(),
  1117  		DisplayName: "A Name",
  1118  		Name:        model.NewId(),
  1119  		Type:        model.CHANNEL_OPEN, // Query does not look at type so this shouldn't matter.
  1120  	}
  1121  	channel, err := ss.Channel().Save(channel, 9999)
  1122  	require.Nil(t, err)
  1123  
  1124  	// Create GroupChannel
  1125  	syncable, err := ss.Group().CreateGroupSyncable(model.NewGroupChannel(group.Id, channel.Id, true))
  1126  	require.Nil(t, err)
  1127  
  1128  	// Time before syncable was created
  1129  	channelMembers, err := ss.Group().ChannelMembersToAdd(syncable.CreateAt - 1)
  1130  	require.Nil(t, err)
  1131  	require.Len(t, channelMembers, 1)
  1132  	require.Equal(t, user.Id, channelMembers[0].UserID)
  1133  	require.Equal(t, channel.Id, channelMembers[0].ChannelID)
  1134  
  1135  	// Time after syncable was created
  1136  	channelMembers, err = ss.Group().ChannelMembersToAdd(syncable.CreateAt + 1)
  1137  	require.Nil(t, err)
  1138  	require.Len(t, channelMembers, 0)
  1139  
  1140  	// Delete and restore GroupMember should return result
  1141  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
  1142  	require.Nil(t, res.Err)
  1143  	res = <-ss.Group().UpsertMember(group.Id, user.Id)
  1144  	require.Nil(t, res.Err)
  1145  	channelMembers, err = ss.Group().ChannelMembersToAdd(syncable.CreateAt + 1)
  1146  	require.Nil(t, err)
  1147  	require.Len(t, channelMembers, 1)
  1148  
  1149  	pristineSyncable := *syncable
  1150  
  1151  	_, err = ss.Group().UpdateGroupSyncable(syncable)
  1152  	require.Nil(t, err)
  1153  
  1154  	// Time before syncable was updated
  1155  	channelMembers, err = ss.Group().ChannelMembersToAdd(syncable.UpdateAt - 1)
  1156  	require.Nil(t, err)
  1157  	require.Len(t, channelMembers, 1)
  1158  	require.Equal(t, user.Id, channelMembers[0].UserID)
  1159  	require.Equal(t, channel.Id, channelMembers[0].ChannelID)
  1160  
  1161  	// Time after syncable was updated
  1162  	channelMembers, err = ss.Group().ChannelMembersToAdd(syncable.UpdateAt + 1)
  1163  	require.Nil(t, err)
  1164  	require.Len(t, channelMembers, 0)
  1165  
  1166  	// Only includes if auto-add
  1167  	syncable.AutoAdd = false
  1168  	_, err = ss.Group().UpdateGroupSyncable(syncable)
  1169  	require.Nil(t, err)
  1170  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1171  	require.Nil(t, err)
  1172  	require.Len(t, channelMembers, 0)
  1173  
  1174  	// reset state of syncable and verify
  1175  	_, err = ss.Group().UpdateGroupSyncable(&pristineSyncable)
  1176  	require.Nil(t, err)
  1177  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1178  	require.Nil(t, err)
  1179  	require.Len(t, channelMembers, 1)
  1180  
  1181  	// No result if Group deleted
  1182  	res = <-ss.Group().Delete(group.Id)
  1183  	require.Nil(t, res.Err)
  1184  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1185  	require.Nil(t, err)
  1186  	require.Len(t, channelMembers, 0)
  1187  
  1188  	// reset state of group and verify
  1189  	group.DeleteAt = 0
  1190  	res = <-ss.Group().Update(group)
  1191  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1192  	require.Nil(t, err)
  1193  	require.Len(t, channelMembers, 1)
  1194  
  1195  	// No result if Channel deleted
  1196  	err = ss.Channel().Delete(channel.Id, model.GetMillis())
  1197  	require.Nil(t, err)
  1198  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1199  	require.Nil(t, err)
  1200  	require.Len(t, channelMembers, 0)
  1201  
  1202  	// reset state of channel and verify
  1203  	channel.DeleteAt = 0
  1204  	_, err = ss.Channel().Update(channel)
  1205  	require.Nil(t, err)
  1206  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1207  	require.Nil(t, err)
  1208  	require.Len(t, channelMembers, 1)
  1209  
  1210  	// No result if GroupChannel deleted
  1211  	_, err = ss.Group().DeleteGroupSyncable(group.Id, channel.Id, model.GroupSyncableTypeChannel)
  1212  	require.Nil(t, err)
  1213  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1214  	require.Nil(t, err)
  1215  	require.Len(t, channelMembers, 0)
  1216  
  1217  	// reset GroupChannel and verify
  1218  	_, err = ss.Group().UpdateGroupSyncable(&pristineSyncable)
  1219  	require.Nil(t, err)
  1220  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1221  	require.Nil(t, err)
  1222  	require.Len(t, channelMembers, 1)
  1223  
  1224  	// No result if GroupMember deleted
  1225  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
  1226  	require.Nil(t, res.Err)
  1227  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1228  	require.Nil(t, err)
  1229  	require.Len(t, channelMembers, 0)
  1230  
  1231  	// restore group member and verify
  1232  	res = <-ss.Group().UpsertMember(group.Id, user.Id)
  1233  	require.Nil(t, res.Err)
  1234  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1235  	require.Nil(t, err)
  1236  	require.Len(t, channelMembers, 1)
  1237  
  1238  	// Adding Channel (ChannelMemberHistory) should stop returning result
  1239  	err = ss.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis())
  1240  	require.Nil(t, err)
  1241  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1242  	require.Nil(t, err)
  1243  	require.Len(t, channelMembers, 0)
  1244  
  1245  	// Leaving Channel (ChannelMemberHistory) should still not return result
  1246  	err = ss.ChannelMemberHistory().LogLeaveEvent(user.Id, channel.Id, model.GetMillis())
  1247  	require.Nil(t, err)
  1248  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1249  	require.Nil(t, err)
  1250  	require.Len(t, channelMembers, 0)
  1251  
  1252  	// Purging ChannelMemberHistory re-returns the result
  1253  	_, err = ss.ChannelMemberHistory().PermanentDeleteBatch(model.GetMillis()+1, 100)
  1254  	require.Nil(t, err)
  1255  	channelMembers, err = ss.Group().ChannelMembersToAdd(0)
  1256  	require.Nil(t, err)
  1257  	require.Len(t, channelMembers, 1)
  1258  }
  1259  
  1260  func testTeamMemberRemovals(t *testing.T, ss store.Store) {
  1261  	data := pendingMemberRemovalsDataSetup(t, ss)
  1262  
  1263  	// one result when both users are in the group (for user C)
  1264  	teamMembers, err := ss.Group().TeamMembersToRemove()
  1265  	require.Nil(t, err)
  1266  	require.Len(t, teamMembers, 1)
  1267  	require.Equal(t, data.UserC.Id, teamMembers[0].UserId)
  1268  
  1269  	res := <-ss.Group().DeleteMember(data.Group.Id, data.UserB.Id)
  1270  	require.Nil(t, res.Err)
  1271  
  1272  	// user b and c should now be returned
  1273  	teamMembers, err = ss.Group().TeamMembersToRemove()
  1274  	require.Nil(t, err)
  1275  	require.Len(t, teamMembers, 2)
  1276  
  1277  	var userIDs []string
  1278  	for _, item := range teamMembers {
  1279  		userIDs = append(userIDs, item.UserId)
  1280  	}
  1281  	require.Contains(t, userIDs, data.UserB.Id)
  1282  	require.Contains(t, userIDs, data.UserC.Id)
  1283  	require.Equal(t, data.ConstrainedTeam.Id, teamMembers[0].TeamId)
  1284  	require.Equal(t, data.ConstrainedTeam.Id, teamMembers[1].TeamId)
  1285  
  1286  	res = <-ss.Group().DeleteMember(data.Group.Id, data.UserA.Id)
  1287  	require.Nil(t, res.Err)
  1288  
  1289  	teamMembers, err = ss.Group().TeamMembersToRemove()
  1290  	require.Nil(t, err)
  1291  	require.Len(t, teamMembers, 3)
  1292  
  1293  	// Make one of them a bot
  1294  	teamMembers, err = ss.Group().TeamMembersToRemove()
  1295  	require.Nil(t, err)
  1296  	teamMember := teamMembers[0]
  1297  	bot := &model.Bot{
  1298  		UserId:      teamMember.UserId,
  1299  		Username:    "un_" + model.NewId(),
  1300  		DisplayName: "dn_" + model.NewId(),
  1301  		OwnerId:     teamMember.UserId,
  1302  	}
  1303  	bot, err = ss.Bot().Save(bot)
  1304  	require.Nil(t, err)
  1305  
  1306  	// verify that bot is not returned in results
  1307  	teamMembers, err = ss.Group().TeamMembersToRemove()
  1308  	require.Nil(t, err)
  1309  	require.Len(t, teamMembers, 2)
  1310  
  1311  	// delete the bot
  1312  	err = ss.Bot().PermanentDelete(bot.UserId)
  1313  	require.Nil(t, err)
  1314  
  1315  	// Should be back to 3 users
  1316  	teamMembers, err = ss.Group().TeamMembersToRemove()
  1317  	require.Nil(t, err)
  1318  	require.Len(t, teamMembers, 3)
  1319  
  1320  	// add users back to groups
  1321  	res = <-ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserA.Id)
  1322  	require.Nil(t, res.Err)
  1323  	res = <-ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserB.Id)
  1324  	require.Nil(t, res.Err)
  1325  	res = <-ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserC.Id)
  1326  	require.Nil(t, res.Err)
  1327  	err = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserA.Id)
  1328  	require.Nil(t, err)
  1329  	err = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserB.Id)
  1330  	require.Nil(t, err)
  1331  	err = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserC.Id)
  1332  	require.Nil(t, err)
  1333  }
  1334  
  1335  func testChannelMemberRemovals(t *testing.T, ss store.Store) {
  1336  	data := pendingMemberRemovalsDataSetup(t, ss)
  1337  
  1338  	// one result when both users are in the group (for user C)
  1339  	channelMembers, err := ss.Group().ChannelMembersToRemove()
  1340  	require.Nil(t, err)
  1341  	require.Len(t, channelMembers, 1)
  1342  	require.Equal(t, data.UserC.Id, channelMembers[0].UserId)
  1343  
  1344  	res := <-ss.Group().DeleteMember(data.Group.Id, data.UserB.Id)
  1345  	require.Nil(t, res.Err)
  1346  
  1347  	// user b and c should now be returned
  1348  	channelMembers, err = ss.Group().ChannelMembersToRemove()
  1349  	require.Nil(t, err)
  1350  	require.Len(t, channelMembers, 2)
  1351  
  1352  	var userIDs []string
  1353  	for _, item := range channelMembers {
  1354  		userIDs = append(userIDs, item.UserId)
  1355  	}
  1356  	require.Contains(t, userIDs, data.UserB.Id)
  1357  	require.Contains(t, userIDs, data.UserC.Id)
  1358  	require.Equal(t, data.ConstrainedChannel.Id, channelMembers[0].ChannelId)
  1359  	require.Equal(t, data.ConstrainedChannel.Id, channelMembers[1].ChannelId)
  1360  
  1361  	res = <-ss.Group().DeleteMember(data.Group.Id, data.UserA.Id)
  1362  	require.Nil(t, res.Err)
  1363  
  1364  	channelMembers, err = ss.Group().ChannelMembersToRemove()
  1365  	require.Nil(t, err)
  1366  	require.Len(t, channelMembers, 3)
  1367  
  1368  	// Make one of them a bot
  1369  	channelMembers, err = ss.Group().ChannelMembersToRemove()
  1370  	require.Nil(t, err)
  1371  	channelMember := channelMembers[0]
  1372  	bot := &model.Bot{
  1373  		UserId:      channelMember.UserId,
  1374  		Username:    "un_" + model.NewId(),
  1375  		DisplayName: "dn_" + model.NewId(),
  1376  		OwnerId:     channelMember.UserId,
  1377  	}
  1378  	bot, err = ss.Bot().Save(bot)
  1379  	require.Nil(t, err)
  1380  
  1381  	// verify that bot is not returned in results
  1382  	channelMembers, err = ss.Group().ChannelMembersToRemove()
  1383  	require.Nil(t, err)
  1384  	require.Len(t, channelMembers, 2)
  1385  
  1386  	// delete the bot
  1387  	err = ss.Bot().PermanentDelete(bot.UserId)
  1388  	require.Nil(t, err)
  1389  
  1390  	// Should be back to 3 users
  1391  	channelMembers, err = ss.Group().ChannelMembersToRemove()
  1392  	require.Nil(t, err)
  1393  	require.Len(t, channelMembers, 3)
  1394  
  1395  	// add users back to groups
  1396  	res = <-ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserA.Id)
  1397  	require.Nil(t, res.Err)
  1398  	res = <-ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserB.Id)
  1399  	require.Nil(t, res.Err)
  1400  	res = <-ss.Team().RemoveMember(data.ConstrainedTeam.Id, data.UserC.Id)
  1401  	require.Nil(t, res.Err)
  1402  	err = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserA.Id)
  1403  	require.Nil(t, err)
  1404  	err = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserB.Id)
  1405  	require.Nil(t, err)
  1406  	err = ss.Channel().RemoveMember(data.ConstrainedChannel.Id, data.UserC.Id)
  1407  	require.Nil(t, err)
  1408  }
  1409  
  1410  type removalsData struct {
  1411  	UserA                *model.User
  1412  	UserB                *model.User
  1413  	UserC                *model.User
  1414  	ConstrainedChannel   *model.Channel
  1415  	UnconstrainedChannel *model.Channel
  1416  	ConstrainedTeam      *model.Team
  1417  	UnconstrainedTeam    *model.Team
  1418  	Group                *model.Group
  1419  }
  1420  
  1421  func pendingMemberRemovalsDataSetup(t *testing.T, ss store.Store) *removalsData {
  1422  	// create group
  1423  	res := <-ss.Group().Create(&model.Group{
  1424  		Name:        model.NewId(),
  1425  		DisplayName: "Pending[Channel|Team]MemberRemovals Test Group",
  1426  		RemoteId:    model.NewId(),
  1427  		Source:      model.GroupSourceLdap,
  1428  	})
  1429  	require.Nil(t, res.Err)
  1430  	group := res.Data.(*model.Group)
  1431  
  1432  	// create users
  1433  	// userA will get removed from the group
  1434  	userA := &model.User{
  1435  		Email:    MakeEmail(),
  1436  		Username: model.NewId(),
  1437  	}
  1438  	res = <-ss.User().Save(userA)
  1439  	require.Nil(t, res.Err)
  1440  	userA = res.Data.(*model.User)
  1441  
  1442  	// userB will not get removed from the group
  1443  	userB := &model.User{
  1444  		Email:    MakeEmail(),
  1445  		Username: model.NewId(),
  1446  	}
  1447  	res = <-ss.User().Save(userB)
  1448  	require.Nil(t, res.Err)
  1449  	userB = res.Data.(*model.User)
  1450  
  1451  	// userC was never in the group
  1452  	userC := &model.User{
  1453  		Email:    MakeEmail(),
  1454  		Username: model.NewId(),
  1455  	}
  1456  	res = <-ss.User().Save(userC)
  1457  	require.Nil(t, res.Err)
  1458  	userC = res.Data.(*model.User)
  1459  
  1460  	// add users to group (but not userC)
  1461  	res = <-ss.Group().UpsertMember(group.Id, userA.Id)
  1462  	require.Nil(t, res.Err)
  1463  
  1464  	res = <-ss.Group().UpsertMember(group.Id, userB.Id)
  1465  	require.Nil(t, res.Err)
  1466  
  1467  	// create channels
  1468  	channelConstrained := &model.Channel{
  1469  		TeamId:           model.NewId(),
  1470  		DisplayName:      "A Name",
  1471  		Name:             model.NewId(),
  1472  		Type:             model.CHANNEL_PRIVATE,
  1473  		GroupConstrained: model.NewBool(true),
  1474  	}
  1475  	channelConstrained, err := ss.Channel().Save(channelConstrained, 9999)
  1476  	require.Nil(t, err)
  1477  
  1478  	channelUnconstrained := &model.Channel{
  1479  		TeamId:      model.NewId(),
  1480  		DisplayName: "A Name",
  1481  		Name:        model.NewId(),
  1482  		Type:        model.CHANNEL_PRIVATE,
  1483  	}
  1484  	channelUnconstrained, err = ss.Channel().Save(channelUnconstrained, 9999)
  1485  	require.Nil(t, err)
  1486  
  1487  	// create teams
  1488  	teamConstrained := &model.Team{
  1489  		DisplayName:      "Name",
  1490  		Description:      "Some description",
  1491  		CompanyName:      "Some company name",
  1492  		AllowOpenInvite:  false,
  1493  		InviteId:         "inviteid0",
  1494  		Name:             "z-z-" + model.NewId() + "a",
  1495  		Email:            "success+" + model.NewId() + "@simulator.amazonses.com",
  1496  		Type:             model.TEAM_INVITE,
  1497  		GroupConstrained: model.NewBool(true),
  1498  	}
  1499  	teamConstrained, err = ss.Team().Save(teamConstrained)
  1500  	require.Nil(t, err)
  1501  
  1502  	teamUnconstrained := &model.Team{
  1503  		DisplayName:     "Name",
  1504  		Description:     "Some description",
  1505  		CompanyName:     "Some company name",
  1506  		AllowOpenInvite: false,
  1507  		InviteId:        "inviteid1",
  1508  		Name:            "z-z-" + model.NewId() + "a",
  1509  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
  1510  		Type:            model.TEAM_INVITE,
  1511  	}
  1512  	teamUnconstrained, err = ss.Team().Save(teamUnconstrained)
  1513  	require.Nil(t, err)
  1514  
  1515  	// create groupteams
  1516  	_, err = ss.Group().CreateGroupSyncable(model.NewGroupTeam(group.Id, teamConstrained.Id, true))
  1517  	require.Nil(t, err)
  1518  
  1519  	_, err = ss.Group().CreateGroupSyncable(model.NewGroupTeam(group.Id, teamUnconstrained.Id, true))
  1520  	require.Nil(t, err)
  1521  
  1522  	// create groupchannels
  1523  	_, err = ss.Group().CreateGroupSyncable(model.NewGroupChannel(group.Id, channelConstrained.Id, true))
  1524  	require.Nil(t, err)
  1525  
  1526  	_, err = ss.Group().CreateGroupSyncable(model.NewGroupChannel(group.Id, channelUnconstrained.Id, true))
  1527  	require.Nil(t, err)
  1528  
  1529  	// add users to teams
  1530  	userIDTeamIDs := [][]string{
  1531  		{userA.Id, teamConstrained.Id},
  1532  		{userB.Id, teamConstrained.Id},
  1533  		{userC.Id, teamConstrained.Id},
  1534  		{userA.Id, teamUnconstrained.Id},
  1535  		{userB.Id, teamUnconstrained.Id},
  1536  		{userC.Id, teamUnconstrained.Id},
  1537  	}
  1538  
  1539  	for _, item := range userIDTeamIDs {
  1540  		res = <-ss.Team().SaveMember(&model.TeamMember{
  1541  			UserId: item[0],
  1542  			TeamId: item[1],
  1543  		}, 99)
  1544  		require.Nil(t, res.Err)
  1545  	}
  1546  
  1547  	// add users to channels
  1548  	userIDChannelIDs := [][]string{
  1549  		{userA.Id, channelConstrained.Id},
  1550  		{userB.Id, channelConstrained.Id},
  1551  		{userC.Id, channelConstrained.Id},
  1552  		{userA.Id, channelUnconstrained.Id},
  1553  		{userB.Id, channelUnconstrained.Id},
  1554  		{userC.Id, channelUnconstrained.Id},
  1555  	}
  1556  
  1557  	for _, item := range userIDChannelIDs {
  1558  		res = <-ss.Channel().SaveMember(&model.ChannelMember{
  1559  			UserId:      item[0],
  1560  			ChannelId:   item[1],
  1561  			NotifyProps: model.GetDefaultChannelNotifyProps(),
  1562  		})
  1563  		require.Nil(t, res.Err)
  1564  	}
  1565  
  1566  	return &removalsData{
  1567  		UserA:                userA,
  1568  		UserB:                userB,
  1569  		UserC:                userC,
  1570  		ConstrainedChannel:   channelConstrained,
  1571  		UnconstrainedChannel: channelUnconstrained,
  1572  		ConstrainedTeam:      teamConstrained,
  1573  		UnconstrainedTeam:    teamUnconstrained,
  1574  		Group:                group,
  1575  	}
  1576  }
  1577  
  1578  func testGetGroupsByChannel(t *testing.T, ss store.Store) {
  1579  	// Create Channel1
  1580  	channel1 := &model.Channel{
  1581  		TeamId:      model.NewId(),
  1582  		DisplayName: "Channel1",
  1583  		Name:        model.NewId(),
  1584  		Type:        model.CHANNEL_OPEN,
  1585  	}
  1586  	channel1, err := ss.Channel().Save(channel1, 9999)
  1587  	require.Nil(t, err)
  1588  
  1589  	// Create Groups 1 and 2
  1590  	res := <-ss.Group().Create(&model.Group{
  1591  		Name:        model.NewId(),
  1592  		DisplayName: "group-1",
  1593  		RemoteId:    model.NewId(),
  1594  		Source:      model.GroupSourceLdap,
  1595  	})
  1596  	require.Nil(t, res.Err)
  1597  	group1 := res.Data.(*model.Group)
  1598  
  1599  	res = <-ss.Group().Create(&model.Group{
  1600  		Name:        model.NewId(),
  1601  		DisplayName: "group-2",
  1602  		RemoteId:    model.NewId(),
  1603  		Source:      model.GroupSourceLdap,
  1604  	})
  1605  	require.Nil(t, res.Err)
  1606  	group2 := res.Data.(*model.Group)
  1607  
  1608  	// And associate them with Channel1
  1609  	for _, g := range []*model.Group{group1, group2} {
  1610  		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  1611  			AutoAdd:    true,
  1612  			SyncableId: channel1.Id,
  1613  			Type:       model.GroupSyncableTypeChannel,
  1614  			GroupId:    g.Id,
  1615  		})
  1616  		require.Nil(t, err)
  1617  	}
  1618  
  1619  	// Create Channel2
  1620  	channel2 := &model.Channel{
  1621  		TeamId:      model.NewId(),
  1622  		DisplayName: "Channel2",
  1623  		Name:        model.NewId(),
  1624  		Type:        model.CHANNEL_OPEN,
  1625  	}
  1626  	channel2, err = ss.Channel().Save(channel2, 9999)
  1627  	require.Nil(t, err)
  1628  
  1629  	// Create Group3
  1630  	res = <-ss.Group().Create(&model.Group{
  1631  		Name:        model.NewId(),
  1632  		DisplayName: "group-3",
  1633  		RemoteId:    model.NewId(),
  1634  		Source:      model.GroupSourceLdap,
  1635  	})
  1636  	require.Nil(t, res.Err)
  1637  	group3 := res.Data.(*model.Group)
  1638  
  1639  	// And associate it to Channel2
  1640  	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  1641  		AutoAdd:    true,
  1642  		SyncableId: channel2.Id,
  1643  		Type:       model.GroupSyncableTypeChannel,
  1644  		GroupId:    group3.Id,
  1645  	})
  1646  	require.Nil(t, err)
  1647  
  1648  	// add members
  1649  	u1 := &model.User{
  1650  		Email:    MakeEmail(),
  1651  		Username: model.NewId(),
  1652  	}
  1653  	res = <-ss.User().Save(u1)
  1654  	require.Nil(t, res.Err)
  1655  	user1 := res.Data.(*model.User)
  1656  	<-ss.Group().UpsertMember(group1.Id, user1.Id)
  1657  
  1658  	group1WithMemberCount := model.Group(*group1)
  1659  	group1WithMemberCount.MemberCount = model.NewInt(1)
  1660  
  1661  	group2WithMemberCount := model.Group(*group2)
  1662  	group2WithMemberCount.MemberCount = model.NewInt(0)
  1663  
  1664  	testCases := []struct {
  1665  		Name       string
  1666  		ChannelId  string
  1667  		Page       int
  1668  		PerPage    int
  1669  		Result     []*model.Group
  1670  		Opts       model.GroupSearchOpts
  1671  		TotalCount *int64
  1672  	}{
  1673  		{
  1674  			Name:       "Get the two Groups for Channel1",
  1675  			ChannelId:  channel1.Id,
  1676  			Opts:       model.GroupSearchOpts{},
  1677  			Page:       0,
  1678  			PerPage:    60,
  1679  			Result:     []*model.Group{group1, group2},
  1680  			TotalCount: model.NewInt64(2),
  1681  		},
  1682  		{
  1683  			Name:      "Get first Group for Channel1 with page 0 with 1 element",
  1684  			ChannelId: channel1.Id,
  1685  			Opts:      model.GroupSearchOpts{},
  1686  			Page:      0,
  1687  			PerPage:   1,
  1688  			Result:    []*model.Group{group1},
  1689  		},
  1690  		{
  1691  			Name:      "Get second Group for Channel1 with page 1 with 1 element",
  1692  			ChannelId: channel1.Id,
  1693  			Opts:      model.GroupSearchOpts{},
  1694  			Page:      1,
  1695  			PerPage:   1,
  1696  			Result:    []*model.Group{group2},
  1697  		},
  1698  		{
  1699  			Name:      "Get third Group for Channel2",
  1700  			ChannelId: channel2.Id,
  1701  			Opts:      model.GroupSearchOpts{},
  1702  			Page:      0,
  1703  			PerPage:   60,
  1704  			Result:    []*model.Group{group3},
  1705  		},
  1706  		{
  1707  			Name:       "Get empty Groups for a fake id",
  1708  			ChannelId:  model.NewId(),
  1709  			Opts:       model.GroupSearchOpts{},
  1710  			Page:       0,
  1711  			PerPage:    60,
  1712  			Result:     []*model.Group{},
  1713  			TotalCount: model.NewInt64(0),
  1714  		},
  1715  		{
  1716  			Name:       "Get group matching name",
  1717  			ChannelId:  channel1.Id,
  1718  			Opts:       model.GroupSearchOpts{Q: string([]rune(group1.Name)[2:10])}, // very low change of a name collision
  1719  			Page:       0,
  1720  			PerPage:    100,
  1721  			Result:     []*model.Group{group1},
  1722  			TotalCount: model.NewInt64(1),
  1723  		},
  1724  		{
  1725  			Name:       "Get group matching display name",
  1726  			ChannelId:  channel1.Id,
  1727  			Opts:       model.GroupSearchOpts{Q: "rouP-1"},
  1728  			Page:       0,
  1729  			PerPage:    100,
  1730  			Result:     []*model.Group{group1},
  1731  			TotalCount: model.NewInt64(1),
  1732  		},
  1733  		{
  1734  			Name:       "Get group matching multiple display names",
  1735  			ChannelId:  channel1.Id,
  1736  			Opts:       model.GroupSearchOpts{Q: "roUp-"},
  1737  			Page:       0,
  1738  			PerPage:    100,
  1739  			Result:     []*model.Group{group1, group2},
  1740  			TotalCount: model.NewInt64(2),
  1741  		},
  1742  		{
  1743  			Name:      "Include member counts",
  1744  			ChannelId: channel1.Id,
  1745  			Opts:      model.GroupSearchOpts{IncludeMemberCount: true},
  1746  			Page:      0,
  1747  			PerPage:   2,
  1748  			Result:    []*model.Group{&group1WithMemberCount, &group2WithMemberCount},
  1749  		},
  1750  	}
  1751  
  1752  	for _, tc := range testCases {
  1753  		t.Run(tc.Name, func(t *testing.T) {
  1754  			if tc.Opts.PageOpts == nil {
  1755  				tc.Opts.PageOpts = &model.PageOpts{}
  1756  			}
  1757  			tc.Opts.PageOpts.Page = tc.Page
  1758  			tc.Opts.PageOpts.PerPage = tc.PerPage
  1759  			groups, err := ss.Group().GetGroupsByChannel(tc.ChannelId, tc.Opts)
  1760  			require.Nil(t, err)
  1761  			require.ElementsMatch(t, tc.Result, groups)
  1762  			if tc.TotalCount != nil {
  1763  				var count int64
  1764  				count, err = ss.Group().CountGroupsByChannel(tc.ChannelId, tc.Opts)
  1765  				require.Equal(t, *tc.TotalCount, count)
  1766  			}
  1767  		})
  1768  	}
  1769  }
  1770  
  1771  func testGetGroupsByTeam(t *testing.T, ss store.Store) {
  1772  	// Create Team1
  1773  	team1 := &model.Team{
  1774  		DisplayName:     "Team1",
  1775  		Description:     model.NewId(),
  1776  		CompanyName:     model.NewId(),
  1777  		AllowOpenInvite: false,
  1778  		InviteId:        model.NewId(),
  1779  		Name:            model.NewId(),
  1780  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
  1781  		Type:            model.TEAM_OPEN,
  1782  	}
  1783  	team1, err := ss.Team().Save(team1)
  1784  	require.Nil(t, err)
  1785  
  1786  	// Create Groups 1 and 2
  1787  	res := <-ss.Group().Create(&model.Group{
  1788  		Name:        model.NewId(),
  1789  		DisplayName: "group-1",
  1790  		RemoteId:    model.NewId(),
  1791  		Source:      model.GroupSourceLdap,
  1792  	})
  1793  	require.Nil(t, res.Err)
  1794  	group1 := res.Data.(*model.Group)
  1795  
  1796  	res = <-ss.Group().Create(&model.Group{
  1797  		Name:        model.NewId(),
  1798  		DisplayName: "group-2",
  1799  		RemoteId:    model.NewId(),
  1800  		Source:      model.GroupSourceLdap,
  1801  	})
  1802  	require.Nil(t, res.Err)
  1803  	group2 := res.Data.(*model.Group)
  1804  
  1805  	// And associate them with Team1
  1806  	for _, g := range []*model.Group{group1, group2} {
  1807  		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  1808  			AutoAdd:    true,
  1809  			SyncableId: team1.Id,
  1810  			Type:       model.GroupSyncableTypeTeam,
  1811  			GroupId:    g.Id,
  1812  		})
  1813  		require.Nil(t, err)
  1814  	}
  1815  
  1816  	// Create Team2
  1817  	team2 := &model.Team{
  1818  		DisplayName:     "Team2",
  1819  		Description:     model.NewId(),
  1820  		CompanyName:     model.NewId(),
  1821  		AllowOpenInvite: false,
  1822  		InviteId:        model.NewId(),
  1823  		Name:            model.NewId(),
  1824  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
  1825  		Type:            model.TEAM_INVITE,
  1826  	}
  1827  	team2, err = ss.Team().Save(team2)
  1828  	require.Nil(t, err)
  1829  
  1830  	// Create Group3
  1831  	res = <-ss.Group().Create(&model.Group{
  1832  		Name:        model.NewId(),
  1833  		DisplayName: "group-3",
  1834  		RemoteId:    model.NewId(),
  1835  		Source:      model.GroupSourceLdap,
  1836  	})
  1837  	require.Nil(t, res.Err)
  1838  	group3 := res.Data.(*model.Group)
  1839  
  1840  	// And associate it to Team2
  1841  	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  1842  		AutoAdd:    true,
  1843  		SyncableId: team2.Id,
  1844  		Type:       model.GroupSyncableTypeTeam,
  1845  		GroupId:    group3.Id,
  1846  	})
  1847  	require.Nil(t, err)
  1848  
  1849  	// add members
  1850  	u1 := &model.User{
  1851  		Email:    MakeEmail(),
  1852  		Username: model.NewId(),
  1853  	}
  1854  	res = <-ss.User().Save(u1)
  1855  	require.Nil(t, res.Err)
  1856  	user1 := res.Data.(*model.User)
  1857  	<-ss.Group().UpsertMember(group1.Id, user1.Id)
  1858  
  1859  	group1WithMemberCount := model.Group(*group1)
  1860  	group1WithMemberCount.MemberCount = model.NewInt(1)
  1861  
  1862  	group2WithMemberCount := model.Group(*group2)
  1863  	group2WithMemberCount.MemberCount = model.NewInt(0)
  1864  
  1865  	testCases := []struct {
  1866  		Name       string
  1867  		TeamId     string
  1868  		Page       int
  1869  		PerPage    int
  1870  		Opts       model.GroupSearchOpts
  1871  		Result     []*model.Group
  1872  		TotalCount *int64
  1873  	}{
  1874  		{
  1875  			Name:       "Get the two Groups for Team1",
  1876  			TeamId:     team1.Id,
  1877  			Opts:       model.GroupSearchOpts{},
  1878  			Page:       0,
  1879  			PerPage:    60,
  1880  			Result:     []*model.Group{group1, group2},
  1881  			TotalCount: model.NewInt64(2),
  1882  		},
  1883  		{
  1884  			Name:    "Get first Group for Team1 with page 0 with 1 element",
  1885  			TeamId:  team1.Id,
  1886  			Opts:    model.GroupSearchOpts{},
  1887  			Page:    0,
  1888  			PerPage: 1,
  1889  			Result:  []*model.Group{group1},
  1890  		},
  1891  		{
  1892  			Name:    "Get second Group for Team1 with page 1 with 1 element",
  1893  			TeamId:  team1.Id,
  1894  			Opts:    model.GroupSearchOpts{},
  1895  			Page:    1,
  1896  			PerPage: 1,
  1897  			Result:  []*model.Group{group2},
  1898  		},
  1899  		{
  1900  			Name:       "Get third Group for Team2",
  1901  			TeamId:     team2.Id,
  1902  			Opts:       model.GroupSearchOpts{},
  1903  			Page:       0,
  1904  			PerPage:    60,
  1905  			Result:     []*model.Group{group3},
  1906  			TotalCount: model.NewInt64(1),
  1907  		},
  1908  		{
  1909  			Name:       "Get empty Groups for a fake id",
  1910  			TeamId:     model.NewId(),
  1911  			Opts:       model.GroupSearchOpts{},
  1912  			Page:       0,
  1913  			PerPage:    60,
  1914  			Result:     []*model.Group{},
  1915  			TotalCount: model.NewInt64(0),
  1916  		},
  1917  		{
  1918  			Name:       "Get group matching name",
  1919  			TeamId:     team1.Id,
  1920  			Opts:       model.GroupSearchOpts{Q: string([]rune(group1.Name)[2:10])}, // very low change of a name collision
  1921  			Page:       0,
  1922  			PerPage:    100,
  1923  			Result:     []*model.Group{group1},
  1924  			TotalCount: model.NewInt64(1),
  1925  		},
  1926  		{
  1927  			Name:       "Get group matching display name",
  1928  			TeamId:     team1.Id,
  1929  			Opts:       model.GroupSearchOpts{Q: "rouP-1"},
  1930  			Page:       0,
  1931  			PerPage:    100,
  1932  			Result:     []*model.Group{group1},
  1933  			TotalCount: model.NewInt64(1),
  1934  		},
  1935  		{
  1936  			Name:       "Get group matching multiple display names",
  1937  			TeamId:     team1.Id,
  1938  			Opts:       model.GroupSearchOpts{Q: "roUp-"},
  1939  			Page:       0,
  1940  			PerPage:    100,
  1941  			Result:     []*model.Group{group1, group2},
  1942  			TotalCount: model.NewInt64(2),
  1943  		},
  1944  		{
  1945  			Name:    "Include member counts",
  1946  			TeamId:  team1.Id,
  1947  			Opts:    model.GroupSearchOpts{IncludeMemberCount: true},
  1948  			Page:    0,
  1949  			PerPage: 2,
  1950  			Result:  []*model.Group{&group1WithMemberCount, &group2WithMemberCount},
  1951  		},
  1952  	}
  1953  
  1954  	for _, tc := range testCases {
  1955  		t.Run(tc.Name, func(t *testing.T) {
  1956  			if tc.Opts.PageOpts == nil {
  1957  				tc.Opts.PageOpts = &model.PageOpts{}
  1958  			}
  1959  			tc.Opts.PageOpts.Page = tc.Page
  1960  			tc.Opts.PageOpts.PerPage = tc.PerPage
  1961  			groups, err := ss.Group().GetGroupsByTeam(tc.TeamId, tc.Opts)
  1962  			require.Nil(t, err)
  1963  			require.ElementsMatch(t, tc.Result, groups)
  1964  			if tc.TotalCount != nil {
  1965  				var count int64
  1966  				count, err = ss.Group().CountGroupsByTeam(tc.TeamId, tc.Opts)
  1967  				require.Equal(t, *tc.TotalCount, count)
  1968  			}
  1969  		})
  1970  	}
  1971  }
  1972  
  1973  func testGetGroups(t *testing.T, ss store.Store) {
  1974  	// Create Team1
  1975  	team1 := &model.Team{
  1976  		DisplayName:     "Team1",
  1977  		Description:     model.NewId(),
  1978  		CompanyName:     model.NewId(),
  1979  		AllowOpenInvite: false,
  1980  		InviteId:        model.NewId(),
  1981  		Name:            model.NewId(),
  1982  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
  1983  		Type:            model.TEAM_OPEN,
  1984  	}
  1985  	team1, err := ss.Team().Save(team1)
  1986  	require.Nil(t, err)
  1987  
  1988  	// Create Channel1
  1989  	channel1 := &model.Channel{
  1990  		TeamId:      model.NewId(),
  1991  		DisplayName: "Channel1",
  1992  		Name:        model.NewId(),
  1993  		Type:        model.CHANNEL_PRIVATE,
  1994  	}
  1995  	channel1, err = ss.Channel().Save(channel1, 9999)
  1996  	require.Nil(t, err)
  1997  
  1998  	// Create Groups 1 and 2
  1999  	res := <-ss.Group().Create(&model.Group{
  2000  		Name:        model.NewId(),
  2001  		DisplayName: "group-1",
  2002  		RemoteId:    model.NewId(),
  2003  		Source:      model.GroupSourceLdap,
  2004  	})
  2005  	require.Nil(t, res.Err)
  2006  	group1 := res.Data.(*model.Group)
  2007  
  2008  	res = <-ss.Group().Create(&model.Group{
  2009  		Name:        model.NewId(),
  2010  		DisplayName: "group-2",
  2011  		RemoteId:    model.NewId(),
  2012  		Source:      model.GroupSourceLdap,
  2013  	})
  2014  	require.Nil(t, res.Err)
  2015  	group2 := res.Data.(*model.Group)
  2016  
  2017  	// And associate them with Team1
  2018  	for _, g := range []*model.Group{group1, group2} {
  2019  		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  2020  			AutoAdd:    true,
  2021  			SyncableId: team1.Id,
  2022  			Type:       model.GroupSyncableTypeTeam,
  2023  			GroupId:    g.Id,
  2024  		})
  2025  		require.Nil(t, err)
  2026  	}
  2027  
  2028  	// Create Team2
  2029  	team2 := &model.Team{
  2030  		DisplayName:     "Team2",
  2031  		Description:     model.NewId(),
  2032  		CompanyName:     model.NewId(),
  2033  		AllowOpenInvite: false,
  2034  		InviteId:        model.NewId(),
  2035  		Name:            model.NewId(),
  2036  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
  2037  		Type:            model.TEAM_INVITE,
  2038  	}
  2039  	team2, err = ss.Team().Save(team2)
  2040  	require.Nil(t, err)
  2041  
  2042  	// Create Channel2
  2043  	channel2 := &model.Channel{
  2044  		TeamId:      model.NewId(),
  2045  		DisplayName: "Channel2",
  2046  		Name:        model.NewId(),
  2047  		Type:        model.CHANNEL_PRIVATE,
  2048  	}
  2049  	channel2, err = ss.Channel().Save(channel2, 9999)
  2050  	require.Nil(t, err)
  2051  
  2052  	// Create Group3
  2053  	res = <-ss.Group().Create(&model.Group{
  2054  		Name:        model.NewId(),
  2055  		DisplayName: "group-3",
  2056  		RemoteId:    model.NewId(),
  2057  		Source:      model.GroupSourceLdap,
  2058  	})
  2059  	require.Nil(t, res.Err)
  2060  	group3 := res.Data.(*model.Group)
  2061  
  2062  	// And associate it to Team2
  2063  	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  2064  		AutoAdd:    true,
  2065  		SyncableId: team2.Id,
  2066  		Type:       model.GroupSyncableTypeTeam,
  2067  		GroupId:    group3.Id,
  2068  	})
  2069  	require.Nil(t, err)
  2070  
  2071  	// And associate Group1 to Channel2
  2072  	_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  2073  		AutoAdd:    true,
  2074  		SyncableId: channel2.Id,
  2075  		Type:       model.GroupSyncableTypeChannel,
  2076  		GroupId:    group1.Id,
  2077  	})
  2078  	require.Nil(t, err)
  2079  
  2080  	// And associate Group2 and Group3 to Channel1
  2081  	for _, g := range []*model.Group{group2, group3} {
  2082  		_, err = ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  2083  			AutoAdd:    true,
  2084  			SyncableId: channel1.Id,
  2085  			Type:       model.GroupSyncableTypeChannel,
  2086  			GroupId:    g.Id,
  2087  		})
  2088  		require.Nil(t, err)
  2089  	}
  2090  
  2091  	// add members
  2092  	u1 := &model.User{
  2093  		Email:    MakeEmail(),
  2094  		Username: model.NewId(),
  2095  	}
  2096  	res = <-ss.User().Save(u1)
  2097  	require.Nil(t, res.Err)
  2098  	user1 := res.Data.(*model.User)
  2099  	<-ss.Group().UpsertMember(group1.Id, user1.Id)
  2100  
  2101  	group1WithMemberCount := model.Group(*group1)
  2102  	group1WithMemberCount.MemberCount = model.NewInt(1)
  2103  
  2104  	group2WithMemberCount := model.Group(*group2)
  2105  	group2WithMemberCount.MemberCount = model.NewInt(0)
  2106  
  2107  	group2NameSubstring := string([]rune(group2.Name)[2:5])
  2108  
  2109  	testCases := []struct {
  2110  		Name    string
  2111  		Page    int
  2112  		PerPage int
  2113  		Opts    model.GroupSearchOpts
  2114  		Resultf func([]*model.Group) bool
  2115  	}{
  2116  		{
  2117  			Name:    "Get all the Groups",
  2118  			Opts:    model.GroupSearchOpts{},
  2119  			Page:    0,
  2120  			PerPage: 3,
  2121  			Resultf: func(groups []*model.Group) bool { return len(groups) == 3 },
  2122  		},
  2123  		{
  2124  			Name:    "Get first Group with page 0 with 1 element",
  2125  			Opts:    model.GroupSearchOpts{},
  2126  			Page:    0,
  2127  			PerPage: 1,
  2128  			Resultf: func(groups []*model.Group) bool { return len(groups) == 1 },
  2129  		},
  2130  		{
  2131  			Name:    "Get single result from page 1",
  2132  			Opts:    model.GroupSearchOpts{},
  2133  			Page:    1,
  2134  			PerPage: 1,
  2135  			Resultf: func(groups []*model.Group) bool { return len(groups) == 1 },
  2136  		},
  2137  		{
  2138  			Name:    "Get multiple results from page 1",
  2139  			Opts:    model.GroupSearchOpts{},
  2140  			Page:    1,
  2141  			PerPage: 2,
  2142  			Resultf: func(groups []*model.Group) bool { return len(groups) == 2 },
  2143  		},
  2144  		{
  2145  			Name:    "Get group matching name",
  2146  			Opts:    model.GroupSearchOpts{Q: group2NameSubstring},
  2147  			Page:    0,
  2148  			PerPage: 100,
  2149  			Resultf: func(groups []*model.Group) bool {
  2150  				for _, g := range groups {
  2151  					if !strings.Contains(g.Name, group2NameSubstring) {
  2152  						return false
  2153  					}
  2154  				}
  2155  				return true
  2156  			},
  2157  		},
  2158  		{
  2159  			Name:    "Get group matching display name",
  2160  			Opts:    model.GroupSearchOpts{Q: "rouP-3"},
  2161  			Page:    0,
  2162  			PerPage: 100,
  2163  			Resultf: func(groups []*model.Group) bool {
  2164  				for _, g := range groups {
  2165  					if !strings.Contains(strings.ToLower(g.DisplayName), "roup-3") {
  2166  						return false
  2167  					}
  2168  				}
  2169  				return true
  2170  			},
  2171  		},
  2172  		{
  2173  			Name:    "Get group matching multiple display names",
  2174  			Opts:    model.GroupSearchOpts{Q: "groUp"},
  2175  			Page:    0,
  2176  			PerPage: 100,
  2177  			Resultf: func(groups []*model.Group) bool {
  2178  				for _, g := range groups {
  2179  					if !strings.Contains(strings.ToLower(g.DisplayName), "group") {
  2180  						return false
  2181  					}
  2182  				}
  2183  				return true
  2184  			},
  2185  		},
  2186  		{
  2187  			Name:    "Include member counts",
  2188  			Opts:    model.GroupSearchOpts{IncludeMemberCount: true},
  2189  			Page:    0,
  2190  			PerPage: 2,
  2191  			Resultf: func(groups []*model.Group) bool {
  2192  				for _, g := range groups {
  2193  					if g.MemberCount == nil {
  2194  						return false
  2195  					}
  2196  				}
  2197  				return true
  2198  			},
  2199  		},
  2200  		{
  2201  			Name:    "Not associated to team",
  2202  			Opts:    model.GroupSearchOpts{NotAssociatedToTeam: team2.Id},
  2203  			Page:    0,
  2204  			PerPage: 100,
  2205  			Resultf: func(groups []*model.Group) bool {
  2206  				if len(groups) == 0 {
  2207  					return false
  2208  				}
  2209  				for _, g := range groups {
  2210  					if g.Id == group3.Id {
  2211  						return false
  2212  					}
  2213  				}
  2214  				return true
  2215  			},
  2216  		},
  2217  		{
  2218  			Name:    "Not associated to other team",
  2219  			Opts:    model.GroupSearchOpts{NotAssociatedToTeam: team1.Id},
  2220  			Page:    0,
  2221  			PerPage: 100,
  2222  			Resultf: func(groups []*model.Group) bool {
  2223  				if len(groups) == 0 {
  2224  					return false
  2225  				}
  2226  				for _, g := range groups {
  2227  					if g.Id == group1.Id || g.Id == group2.Id {
  2228  						return false
  2229  					}
  2230  				}
  2231  				return true
  2232  			},
  2233  		},
  2234  	}
  2235  
  2236  	for _, tc := range testCases {
  2237  		t.Run(tc.Name, func(t *testing.T) {
  2238  			groups, err := ss.Group().GetGroups(tc.Page, tc.PerPage, tc.Opts)
  2239  			require.Nil(t, err)
  2240  			require.True(t, tc.Resultf(groups))
  2241  		})
  2242  	}
  2243  }
  2244  
  2245  func testTeamMembersMinusGroupMembers(t *testing.T, ss store.Store) {
  2246  	const numberOfGroups = 3
  2247  	const numberOfUsers = 4
  2248  
  2249  	groups := []*model.Group{}
  2250  	users := []*model.User{}
  2251  
  2252  	team := &model.Team{
  2253  		DisplayName:      model.NewId(),
  2254  		Description:      model.NewId(),
  2255  		CompanyName:      model.NewId(),
  2256  		AllowOpenInvite:  false,
  2257  		InviteId:         model.NewId(),
  2258  		Name:             model.NewId(),
  2259  		Email:            model.NewId() + "@simulator.amazonses.com",
  2260  		Type:             model.TEAM_OPEN,
  2261  		GroupConstrained: model.NewBool(true),
  2262  	}
  2263  	team, err := ss.Team().Save(team)
  2264  	require.Nil(t, err)
  2265  
  2266  	for i := 0; i < numberOfUsers; i++ {
  2267  		user := &model.User{
  2268  			Email:    MakeEmail(),
  2269  			Username: model.NewId(),
  2270  		}
  2271  		res := <-ss.User().Save(user)
  2272  		require.Nil(t, res.Err)
  2273  		user = res.Data.(*model.User)
  2274  		users = append(users, user)
  2275  
  2276  		trueOrFalse := int(math.Mod(float64(i), 2)) == 0
  2277  		res = <-ss.Team().SaveMember(&model.TeamMember{TeamId: team.Id, UserId: user.Id, SchemeUser: trueOrFalse, SchemeAdmin: !trueOrFalse}, 999)
  2278  		require.Nil(t, res.Err)
  2279  	}
  2280  
  2281  	for i := 0; i < numberOfGroups; i++ {
  2282  		group := &model.Group{
  2283  			Name:        fmt.Sprintf("n_%d_%s", i, model.NewId()),
  2284  			DisplayName: model.NewId(),
  2285  			Source:      model.GroupSourceLdap,
  2286  			Description: model.NewId(),
  2287  			RemoteId:    model.NewId(),
  2288  		}
  2289  		res := <-ss.Group().Create(group)
  2290  		require.Nil(t, res.Err)
  2291  		group = res.Data.(*model.Group)
  2292  		groups = append(groups, group)
  2293  	}
  2294  
  2295  	sort.Slice(users, func(i, j int) bool {
  2296  		return users[i].Id < users[j].Id
  2297  	})
  2298  
  2299  	// Add even users to even group, and the inverse
  2300  	for i := 0; i < numberOfUsers; i++ {
  2301  		groupIndex := int(math.Mod(float64(i), 2))
  2302  		res := <-ss.Group().UpsertMember(groups[groupIndex].Id, users[i].Id)
  2303  		require.Nil(t, res.Err)
  2304  
  2305  		// Add everyone to group 2
  2306  		res = <-ss.Group().UpsertMember(groups[numberOfGroups-1].Id, users[i].Id)
  2307  		require.Nil(t, res.Err)
  2308  	}
  2309  
  2310  	testCases := map[string]struct {
  2311  		expectedUserIDs    []string
  2312  		expectedTotalCount int64
  2313  		groupIDs           []string
  2314  		page               int
  2315  		perPage            int
  2316  		setup              func()
  2317  		teardown           func()
  2318  	}{
  2319  		"No group IDs, all members": {
  2320  			expectedUserIDs:    []string{users[0].Id, users[1].Id, users[2].Id, users[3].Id},
  2321  			expectedTotalCount: numberOfUsers,
  2322  			groupIDs:           []string{},
  2323  			page:               0,
  2324  			perPage:            100,
  2325  		},
  2326  		"All members, page 1": {
  2327  			expectedUserIDs:    []string{users[0].Id, users[1].Id},
  2328  			expectedTotalCount: numberOfUsers,
  2329  			groupIDs:           []string{},
  2330  			page:               0,
  2331  			perPage:            2,
  2332  		},
  2333  		"All members, page 2": {
  2334  			expectedUserIDs:    []string{users[2].Id, users[3].Id},
  2335  			expectedTotalCount: numberOfUsers,
  2336  			groupIDs:           []string{},
  2337  			page:               1,
  2338  			perPage:            2,
  2339  		},
  2340  		"Group 1, even users would be removed": {
  2341  			expectedUserIDs:    []string{users[0].Id, users[2].Id},
  2342  			expectedTotalCount: 2,
  2343  			groupIDs:           []string{groups[1].Id},
  2344  			page:               0,
  2345  			perPage:            100,
  2346  		},
  2347  		"Group 0, odd users would be removed": {
  2348  			expectedUserIDs:    []string{users[1].Id, users[3].Id},
  2349  			expectedTotalCount: 2,
  2350  			groupIDs:           []string{groups[0].Id},
  2351  			page:               0,
  2352  			perPage:            100,
  2353  		},
  2354  		"All groups, no users would be removed": {
  2355  			expectedUserIDs:    []string{},
  2356  			expectedTotalCount: 0,
  2357  			groupIDs:           []string{groups[0].Id, groups[1].Id},
  2358  			page:               0,
  2359  			perPage:            100,
  2360  		},
  2361  	}
  2362  
  2363  	mapUserIDs := func(users []*model.UserWithGroups) []string {
  2364  		ids := []string{}
  2365  		for _, user := range users {
  2366  			ids = append(ids, user.Id)
  2367  		}
  2368  		return ids
  2369  	}
  2370  
  2371  	for tcName, tc := range testCases {
  2372  		t.Run(tcName, func(t *testing.T) {
  2373  			if tc.setup != nil {
  2374  				tc.setup()
  2375  			}
  2376  
  2377  			if tc.teardown != nil {
  2378  				defer tc.teardown()
  2379  			}
  2380  
  2381  			actual, err := ss.Group().TeamMembersMinusGroupMembers(team.Id, tc.groupIDs, tc.page, tc.perPage)
  2382  			require.Nil(t, err)
  2383  			require.ElementsMatch(t, tc.expectedUserIDs, mapUserIDs(actual))
  2384  
  2385  			for _, user := range actual {
  2386  				require.NotNil(t, user.GroupIDs)
  2387  				require.True(t, (user.SchemeAdmin || user.SchemeUser))
  2388  			}
  2389  
  2390  			actualCount, err := ss.Group().CountTeamMembersMinusGroupMembers(team.Id, tc.groupIDs)
  2391  			require.Nil(t, err)
  2392  			require.Equal(t, tc.expectedTotalCount, actualCount)
  2393  		})
  2394  	}
  2395  }
  2396  
  2397  func testChannelMembersMinusGroupMembers(t *testing.T, ss store.Store) {
  2398  	const numberOfGroups = 3
  2399  	const numberOfUsers = 4
  2400  
  2401  	groups := []*model.Group{}
  2402  	users := []*model.User{}
  2403  
  2404  	channel := &model.Channel{
  2405  		TeamId:           model.NewId(),
  2406  		DisplayName:      "A Name",
  2407  		Name:             model.NewId(),
  2408  		Type:             model.CHANNEL_PRIVATE,
  2409  		GroupConstrained: model.NewBool(true),
  2410  	}
  2411  	channel, err := ss.Channel().Save(channel, 9999)
  2412  	require.Nil(t, err)
  2413  
  2414  	for i := 0; i < numberOfUsers; i++ {
  2415  		user := &model.User{
  2416  			Email:    MakeEmail(),
  2417  			Username: model.NewId(),
  2418  		}
  2419  		res := <-ss.User().Save(user)
  2420  		require.Nil(t, res.Err)
  2421  		user = res.Data.(*model.User)
  2422  		users = append(users, user)
  2423  
  2424  		trueOrFalse := int(math.Mod(float64(i), 2)) == 0
  2425  		res = <-ss.Channel().SaveMember(&model.ChannelMember{
  2426  			ChannelId:   channel.Id,
  2427  			UserId:      user.Id,
  2428  			SchemeUser:  trueOrFalse,
  2429  			SchemeAdmin: !trueOrFalse,
  2430  			NotifyProps: model.GetDefaultChannelNotifyProps(),
  2431  		})
  2432  		require.Nil(t, res.Err)
  2433  	}
  2434  
  2435  	for i := 0; i < numberOfGroups; i++ {
  2436  		group := &model.Group{
  2437  			Name:        fmt.Sprintf("n_%d_%s", i, model.NewId()),
  2438  			DisplayName: model.NewId(),
  2439  			Source:      model.GroupSourceLdap,
  2440  			Description: model.NewId(),
  2441  			RemoteId:    model.NewId(),
  2442  		}
  2443  		res := <-ss.Group().Create(group)
  2444  		require.Nil(t, res.Err)
  2445  		group = res.Data.(*model.Group)
  2446  		groups = append(groups, group)
  2447  	}
  2448  
  2449  	sort.Slice(users, func(i, j int) bool {
  2450  		return users[i].Id < users[j].Id
  2451  	})
  2452  
  2453  	// Add even users to even group, and the inverse
  2454  	for i := 0; i < numberOfUsers; i++ {
  2455  		groupIndex := int(math.Mod(float64(i), 2))
  2456  		res := <-ss.Group().UpsertMember(groups[groupIndex].Id, users[i].Id)
  2457  		require.Nil(t, res.Err)
  2458  
  2459  		// Add everyone to group 2
  2460  		res = <-ss.Group().UpsertMember(groups[numberOfGroups-1].Id, users[i].Id)
  2461  		require.Nil(t, res.Err)
  2462  	}
  2463  
  2464  	testCases := map[string]struct {
  2465  		expectedUserIDs    []string
  2466  		expectedTotalCount int64
  2467  		groupIDs           []string
  2468  		page               int
  2469  		perPage            int
  2470  		setup              func()
  2471  		teardown           func()
  2472  	}{
  2473  		"No group IDs, all members": {
  2474  			expectedUserIDs:    []string{users[0].Id, users[1].Id, users[2].Id, users[3].Id},
  2475  			expectedTotalCount: numberOfUsers,
  2476  			groupIDs:           []string{},
  2477  			page:               0,
  2478  			perPage:            100,
  2479  		},
  2480  		"All members, page 1": {
  2481  			expectedUserIDs:    []string{users[0].Id, users[1].Id},
  2482  			expectedTotalCount: numberOfUsers,
  2483  			groupIDs:           []string{},
  2484  			page:               0,
  2485  			perPage:            2,
  2486  		},
  2487  		"All members, page 2": {
  2488  			expectedUserIDs:    []string{users[2].Id, users[3].Id},
  2489  			expectedTotalCount: numberOfUsers,
  2490  			groupIDs:           []string{},
  2491  			page:               1,
  2492  			perPage:            2,
  2493  		},
  2494  		"Group 1, even users would be removed": {
  2495  			expectedUserIDs:    []string{users[0].Id, users[2].Id},
  2496  			expectedTotalCount: 2,
  2497  			groupIDs:           []string{groups[1].Id},
  2498  			page:               0,
  2499  			perPage:            100,
  2500  		},
  2501  		"Group 0, odd users would be removed": {
  2502  			expectedUserIDs:    []string{users[1].Id, users[3].Id},
  2503  			expectedTotalCount: 2,
  2504  			groupIDs:           []string{groups[0].Id},
  2505  			page:               0,
  2506  			perPage:            100,
  2507  		},
  2508  		"All groups, no users would be removed": {
  2509  			expectedUserIDs:    []string{},
  2510  			expectedTotalCount: 0,
  2511  			groupIDs:           []string{groups[0].Id, groups[1].Id},
  2512  			page:               0,
  2513  			perPage:            100,
  2514  		},
  2515  	}
  2516  
  2517  	mapUserIDs := func(users []*model.UserWithGroups) []string {
  2518  		ids := []string{}
  2519  		for _, user := range users {
  2520  			ids = append(ids, user.Id)
  2521  		}
  2522  		return ids
  2523  	}
  2524  
  2525  	for tcName, tc := range testCases {
  2526  		t.Run(tcName, func(t *testing.T) {
  2527  			if tc.setup != nil {
  2528  				tc.setup()
  2529  			}
  2530  
  2531  			if tc.teardown != nil {
  2532  				defer tc.teardown()
  2533  			}
  2534  
  2535  			actual, err := ss.Group().ChannelMembersMinusGroupMembers(channel.Id, tc.groupIDs, tc.page, tc.perPage)
  2536  			require.Nil(t, err)
  2537  			require.ElementsMatch(t, tc.expectedUserIDs, mapUserIDs(actual))
  2538  
  2539  			for _, user := range actual {
  2540  				require.NotNil(t, user.GroupIDs)
  2541  				require.True(t, (user.SchemeAdmin || user.SchemeUser))
  2542  			}
  2543  
  2544  			actualCount, err := ss.Group().CountChannelMembersMinusGroupMembers(channel.Id, tc.groupIDs)
  2545  			require.Nil(t, err)
  2546  			require.Equal(t, tc.expectedTotalCount, actualCount)
  2547  		})
  2548  	}
  2549  }