github.com/jfrerich/mattermost-server@v5.8.0-rc2+incompatible/store/storetest/group_supplier.go (about)

     1  // Copyright (c) 2018-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package storetest
     5  
     6  import (
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/mattermost/mattermost-server/model"
    11  	"github.com/mattermost/mattermost-server/store"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestGroupStore(t *testing.T, ss store.Store) {
    16  	t.Run("Create", func(t *testing.T) { testGroupStoreCreate(t, ss) })
    17  	t.Run("Get", func(t *testing.T) { testGroupStoreGet(t, ss) })
    18  	t.Run("GetByRemoteID", func(t *testing.T) { testGroupStoreGetByRemoteID(t, ss) })
    19  	t.Run("GetAllBySource", func(t *testing.T) { testGroupStoreGetAllByType(t, ss) })
    20  	t.Run("Update", func(t *testing.T) { testGroupStoreUpdate(t, ss) })
    21  	t.Run("Delete", func(t *testing.T) { testGroupStoreDelete(t, ss) })
    22  
    23  	t.Run("GetMemberUsers", func(t *testing.T) { testGroupGetMemberUsers(t, ss) })
    24  	t.Run("GetMemberUsersPage", func(t *testing.T) { testGroupGetMemberUsersPage(t, ss) })
    25  	t.Run("CreateOrRestoreMember", func(t *testing.T) { testGroupCreateOrRestoreMember(t, ss) })
    26  	t.Run("DeleteMember", func(t *testing.T) { testGroupDeleteMember(t, ss) })
    27  
    28  	t.Run("CreateGroupSyncable", func(t *testing.T) { testCreateGroupSyncable(t, ss) })
    29  	t.Run("GetGroupSyncable", func(t *testing.T) { testGetGroupSyncable(t, ss) })
    30  	t.Run("GetAllGroupSyncablesByGroupId", func(t *testing.T) { testGetAllGroupSyncablesByGroup(t, ss) })
    31  	t.Run("UpdateGroupSyncable", func(t *testing.T) { testUpdateGroupSyncable(t, ss) })
    32  	t.Run("DeleteGroupSyncable", func(t *testing.T) { testDeleteGroupSyncable(t, ss) })
    33  
    34  	t.Run("PendingAutoAddTeamMembers", func(t *testing.T) { testPendingAutoAddTeamMembers(t, ss) })
    35  	t.Run("PendingAutoAddChannelMembers", func(t *testing.T) { testPendingAutoAddChannelMembers(t, ss) })
    36  }
    37  
    38  func testGroupStoreCreate(t *testing.T, ss store.Store) {
    39  	// Save a new group
    40  	g1 := &model.Group{
    41  		Name:        model.NewId(),
    42  		DisplayName: model.NewId(),
    43  		Source:      model.GroupSourceLdap,
    44  		Description: model.NewId(),
    45  		RemoteId:    model.NewId(),
    46  	}
    47  
    48  	// Happy path
    49  	res1 := <-ss.Group().Create(g1)
    50  	assert.Nil(t, res1.Err)
    51  	d1 := res1.Data.(*model.Group)
    52  	assert.Len(t, d1.Id, 26)
    53  	assert.Equal(t, g1.Name, d1.Name)
    54  	assert.Equal(t, g1.DisplayName, d1.DisplayName)
    55  	assert.Equal(t, g1.Description, d1.Description)
    56  	assert.Equal(t, g1.RemoteId, d1.RemoteId)
    57  	assert.NotZero(t, d1.CreateAt)
    58  	assert.NotZero(t, d1.UpdateAt)
    59  	assert.Zero(t, d1.DeleteAt)
    60  
    61  	// Requires name and display name
    62  	g2 := &model.Group{
    63  		Name:        "",
    64  		DisplayName: model.NewId(),
    65  		Source:      model.GroupSourceLdap,
    66  		RemoteId:    model.NewId(),
    67  	}
    68  	res2 := <-ss.Group().Create(g2)
    69  	assert.Nil(t, res2.Data)
    70  	assert.NotNil(t, res2.Err)
    71  	assert.Equal(t, res2.Err.Id, "model.group.name.app_error")
    72  
    73  	g2.Name = model.NewId()
    74  	g2.DisplayName = ""
    75  	res3 := <-ss.Group().Create(g2)
    76  	assert.Nil(t, res3.Data)
    77  	assert.NotNil(t, res3.Err)
    78  	assert.Equal(t, res3.Err.Id, "model.group.display_name.app_error")
    79  
    80  	// Won't accept a duplicate name
    81  	g4 := &model.Group{
    82  		Name:        model.NewId(),
    83  		DisplayName: model.NewId(),
    84  		Source:      model.GroupSourceLdap,
    85  		RemoteId:    model.NewId(),
    86  	}
    87  	res5 := <-ss.Group().Create(g4)
    88  	assert.Nil(t, res5.Err)
    89  	g4b := &model.Group{
    90  		Name:        g4.Name,
    91  		DisplayName: model.NewId(),
    92  		Source:      model.GroupSourceLdap,
    93  		RemoteId:    model.NewId(),
    94  	}
    95  	res5b := <-ss.Group().Create(g4b)
    96  	assert.Nil(t, res5b.Data)
    97  	assert.Equal(t, res5b.Err.Id, "store.sql_group.unique_constraint")
    98  
    99  	// Fields cannot be greater than max values
   100  	g5 := &model.Group{
   101  		Name:        strings.Repeat("x", model.GroupNameMaxLength),
   102  		DisplayName: strings.Repeat("x", model.GroupDisplayNameMaxLength),
   103  		Description: strings.Repeat("x", model.GroupDescriptionMaxLength),
   104  		Source:      model.GroupSourceLdap,
   105  		RemoteId:    model.NewId(),
   106  	}
   107  	assert.Nil(t, g5.IsValidForCreate())
   108  
   109  	g5.Name = g5.Name + "x"
   110  	assert.Equal(t, g5.IsValidForCreate().Id, "model.group.name.app_error")
   111  	g5.Name = model.NewId()
   112  	assert.Nil(t, g5.IsValidForCreate())
   113  
   114  	g5.DisplayName = g5.DisplayName + "x"
   115  	assert.Equal(t, g5.IsValidForCreate().Id, "model.group.display_name.app_error")
   116  	g5.DisplayName = model.NewId()
   117  	assert.Nil(t, g5.IsValidForCreate())
   118  
   119  	g5.Description = g5.Description + "x"
   120  	assert.Equal(t, g5.IsValidForCreate().Id, "model.group.description.app_error")
   121  	g5.Description = model.NewId()
   122  	assert.Nil(t, g5.IsValidForCreate())
   123  
   124  	// Must use a valid type
   125  	g6 := &model.Group{
   126  		Name:        model.NewId(),
   127  		DisplayName: model.NewId(),
   128  		Description: model.NewId(),
   129  		Source:      model.GroupSource("fake"),
   130  		RemoteId:    model.NewId(),
   131  	}
   132  	assert.Equal(t, g6.IsValidForCreate().Id, "model.group.source.app_error")
   133  }
   134  
   135  func testGroupStoreGet(t *testing.T, ss store.Store) {
   136  	// Create a group
   137  	g1 := &model.Group{
   138  		Name:        model.NewId(),
   139  		DisplayName: model.NewId(),
   140  		Description: model.NewId(),
   141  		Source:      model.GroupSourceLdap,
   142  		RemoteId:    model.NewId(),
   143  	}
   144  	res1 := <-ss.Group().Create(g1)
   145  	assert.Nil(t, res1.Err)
   146  	d1 := res1.Data.(*model.Group)
   147  	assert.Len(t, d1.Id, 26)
   148  
   149  	// Get the group
   150  	res2 := <-ss.Group().Get(d1.Id)
   151  	assert.Nil(t, res2.Err)
   152  	d2 := res2.Data.(*model.Group)
   153  	assert.Equal(t, d1.Id, d2.Id)
   154  	assert.Equal(t, d1.Name, d2.Name)
   155  	assert.Equal(t, d1.DisplayName, d2.DisplayName)
   156  	assert.Equal(t, d1.Description, d2.Description)
   157  	assert.Equal(t, d1.RemoteId, d2.RemoteId)
   158  	assert.Equal(t, d1.CreateAt, d2.CreateAt)
   159  	assert.Equal(t, d1.UpdateAt, d2.UpdateAt)
   160  	assert.Equal(t, d1.DeleteAt, d2.DeleteAt)
   161  
   162  	// Get an invalid group
   163  	res3 := <-ss.Group().Get(model.NewId())
   164  	assert.NotNil(t, res3.Err)
   165  	assert.Equal(t, res3.Err.Id, "store.sql_group.no_rows")
   166  }
   167  
   168  func testGroupStoreGetByRemoteID(t *testing.T, ss store.Store) {
   169  	// Create a group
   170  	g1 := &model.Group{
   171  		Name:        model.NewId(),
   172  		DisplayName: model.NewId(),
   173  		Description: model.NewId(),
   174  		Source:      model.GroupSourceLdap,
   175  		RemoteId:    model.NewId(),
   176  	}
   177  	res1 := <-ss.Group().Create(g1)
   178  	assert.Nil(t, res1.Err)
   179  	d1 := res1.Data.(*model.Group)
   180  	assert.Len(t, d1.Id, 26)
   181  
   182  	// Get the group
   183  	res2 := <-ss.Group().GetByRemoteID(d1.RemoteId, model.GroupSourceLdap)
   184  	assert.Nil(t, res2.Err)
   185  	d2 := res2.Data.(*model.Group)
   186  	assert.Equal(t, d1.Id, d2.Id)
   187  	assert.Equal(t, d1.Name, d2.Name)
   188  	assert.Equal(t, d1.DisplayName, d2.DisplayName)
   189  	assert.Equal(t, d1.Description, d2.Description)
   190  	assert.Equal(t, d1.RemoteId, d2.RemoteId)
   191  	assert.Equal(t, d1.CreateAt, d2.CreateAt)
   192  	assert.Equal(t, d1.UpdateAt, d2.UpdateAt)
   193  	assert.Equal(t, d1.DeleteAt, d2.DeleteAt)
   194  
   195  	// Get an invalid group
   196  	res3 := <-ss.Group().GetByRemoteID(model.NewId(), model.GroupSource("fake"))
   197  	assert.NotNil(t, res3.Err)
   198  	assert.Equal(t, res3.Err.Id, "store.sql_group.no_rows")
   199  }
   200  
   201  func testGroupStoreGetAllByType(t *testing.T, ss store.Store) {
   202  	numGroups := 10
   203  
   204  	groups := []*model.Group{}
   205  
   206  	// Create groups
   207  	for i := 0; i < numGroups; i++ {
   208  		g := &model.Group{
   209  			Name:        model.NewId(),
   210  			DisplayName: model.NewId(),
   211  			Description: model.NewId(),
   212  			Source:      model.GroupSourceLdap,
   213  			RemoteId:    model.NewId(),
   214  		}
   215  		groups = append(groups, g)
   216  		res := <-ss.Group().Create(g)
   217  		assert.Nil(t, res.Err)
   218  	}
   219  
   220  	// Returns all the groups
   221  	res1 := <-ss.Group().GetAllBySource(model.GroupSourceLdap)
   222  	d1 := res1.Data.([]*model.Group)
   223  	assert.Condition(t, func() bool { return len(d1) >= numGroups })
   224  	for _, expectedGroup := range groups {
   225  		present := false
   226  		for _, dbGroup := range d1 {
   227  			if dbGroup.Id == expectedGroup.Id {
   228  				present = true
   229  				break
   230  			}
   231  		}
   232  		assert.True(t, present)
   233  	}
   234  }
   235  
   236  func testGroupStoreUpdate(t *testing.T, ss store.Store) {
   237  	// Save a new group
   238  	g1 := &model.Group{
   239  		Name:        "g1-test",
   240  		DisplayName: model.NewId(),
   241  		Source:      model.GroupSourceLdap,
   242  		Description: model.NewId(),
   243  		RemoteId:    model.NewId(),
   244  	}
   245  
   246  	// Create a group
   247  	res := <-ss.Group().Create(g1)
   248  	assert.Nil(t, res.Err)
   249  	d1 := res.Data.(*model.Group)
   250  
   251  	// Update happy path
   252  	g1Update := &model.Group{}
   253  	*g1Update = *g1
   254  	g1Update.Name = model.NewId()
   255  	g1Update.DisplayName = model.NewId()
   256  	g1Update.Description = model.NewId()
   257  	g1Update.RemoteId = model.NewId()
   258  
   259  	res2 := <-ss.Group().Update(g1Update)
   260  	assert.Nil(t, res2.Err)
   261  	ud1 := res2.Data.(*model.Group)
   262  	// Not changed...
   263  	assert.Equal(t, d1.Id, ud1.Id)
   264  	assert.Equal(t, d1.CreateAt, ud1.CreateAt)
   265  	assert.Equal(t, d1.Source, ud1.Source)
   266  	// Still zero...
   267  	assert.Zero(t, ud1.DeleteAt)
   268  	// Updated...
   269  	assert.Equal(t, g1Update.Name, ud1.Name)
   270  	assert.Equal(t, g1Update.DisplayName, ud1.DisplayName)
   271  	assert.Equal(t, g1Update.Description, ud1.Description)
   272  	assert.Equal(t, g1Update.RemoteId, ud1.RemoteId)
   273  
   274  	// Requires name and display name
   275  	res3 := <-ss.Group().Update(&model.Group{
   276  		Id:          d1.Id,
   277  		Name:        "",
   278  		DisplayName: model.NewId(),
   279  		Source:      model.GroupSourceLdap,
   280  		RemoteId:    model.NewId(),
   281  		Description: model.NewId(),
   282  	})
   283  	assert.Nil(t, res3.Data)
   284  	assert.NotNil(t, res3.Err)
   285  	assert.Equal(t, res3.Err.Id, "model.group.name.app_error")
   286  
   287  	res4 := <-ss.Group().Update(&model.Group{
   288  		Id:          d1.Id,
   289  		Name:        model.NewId(),
   290  		DisplayName: "",
   291  		Source:      model.GroupSourceLdap,
   292  		RemoteId:    model.NewId(),
   293  	})
   294  	assert.Nil(t, res4.Data)
   295  	assert.NotNil(t, res4.Err)
   296  	assert.Equal(t, res4.Err.Id, "model.group.display_name.app_error")
   297  
   298  	// Create another Group
   299  	g2 := &model.Group{
   300  		Name:        model.NewId(),
   301  		DisplayName: model.NewId(),
   302  		Source:      model.GroupSourceLdap,
   303  		Description: model.NewId(),
   304  		RemoteId:    model.NewId(),
   305  	}
   306  	res5 := <-ss.Group().Create(g2)
   307  	assert.Nil(t, res5.Err)
   308  	d2 := res5.Data.(*model.Group)
   309  
   310  	// Can't update the name to be a duplicate of an existing group's name
   311  	res6 := <-ss.Group().Update(&model.Group{
   312  		Id:          d2.Id,
   313  		Name:        g1Update.Name,
   314  		DisplayName: model.NewId(),
   315  		Source:      model.GroupSourceLdap,
   316  		Description: model.NewId(),
   317  		RemoteId:    model.NewId(),
   318  	})
   319  	assert.Equal(t, res6.Err.Id, "store.update_error")
   320  
   321  	// Cannot update CreateAt
   322  	someVal := model.GetMillis()
   323  	d1.CreateAt = someVal
   324  	res7 := <-ss.Group().Update(d1)
   325  	d3 := res7.Data.(*model.Group)
   326  	assert.NotEqual(t, someVal, d3.CreateAt)
   327  
   328  	// Cannot update DeleteAt to non-zero
   329  	d1.DeleteAt = 1
   330  	res9 := <-ss.Group().Update(d1)
   331  	assert.Equal(t, "model.group.delete_at.app_error", res9.Err.Id)
   332  
   333  	//...except for 0 for DeleteAt
   334  	d1.DeleteAt = 0
   335  	res8 := <-ss.Group().Update(d1)
   336  	assert.Nil(t, res8.Err)
   337  	d4 := res8.Data.(*model.Group)
   338  	assert.Zero(t, d4.DeleteAt)
   339  }
   340  
   341  func testGroupStoreDelete(t *testing.T, ss store.Store) {
   342  	// Save a group
   343  	g1 := &model.Group{
   344  		Name:        model.NewId(),
   345  		DisplayName: model.NewId(),
   346  		Description: model.NewId(),
   347  		Source:      model.GroupSourceLdap,
   348  		RemoteId:    model.NewId(),
   349  	}
   350  
   351  	res1 := <-ss.Group().Create(g1)
   352  	assert.Nil(t, res1.Err)
   353  	d1 := res1.Data.(*model.Group)
   354  	assert.Len(t, d1.Id, 26)
   355  
   356  	// Check the group is retrievable
   357  	res2 := <-ss.Group().Get(d1.Id)
   358  	assert.Nil(t, res2.Err)
   359  
   360  	// Get the before count
   361  	res7 := <-ss.Group().GetAllBySource(model.GroupSourceLdap)
   362  	d7 := res7.Data.([]*model.Group)
   363  	beforeCount := len(d7)
   364  
   365  	// Delete the group
   366  	res3 := <-ss.Group().Delete(d1.Id)
   367  	assert.Nil(t, res3.Err)
   368  
   369  	// Check the group is deleted
   370  	res4 := <-ss.Group().Get(d1.Id)
   371  	d4 := res4.Data.(*model.Group)
   372  	assert.NotZero(t, d4.DeleteAt)
   373  
   374  	// Check the after count
   375  	res5 := <-ss.Group().GetAllBySource(model.GroupSourceLdap)
   376  	d5 := res5.Data.([]*model.Group)
   377  	afterCount := len(d5)
   378  	assert.Condition(t, func() bool { return beforeCount == afterCount+1 })
   379  
   380  	// Try and delete a nonexistent group
   381  	res6 := <-ss.Group().Delete(model.NewId())
   382  	assert.NotNil(t, res6.Err)
   383  	assert.Equal(t, res6.Err.Id, "store.sql_group.no_rows")
   384  
   385  	// Cannot delete again
   386  	res8 := <-ss.Group().Delete(d1.Id)
   387  	assert.Equal(t, res8.Err.Id, "store.sql_group.no_rows")
   388  }
   389  
   390  func testGroupGetMemberUsers(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  	res := <-ss.Group().Create(g1)
   400  	assert.Nil(t, res.Err)
   401  	group := res.Data.(*model.Group)
   402  
   403  	u1 := &model.User{
   404  		Email:    MakeEmail(),
   405  		Username: model.NewId(),
   406  	}
   407  	res = <-ss.User().Save(u1)
   408  	assert.Nil(t, res.Err)
   409  	user1 := res.Data.(*model.User)
   410  
   411  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user1.Id)
   412  	assert.Nil(t, res.Err)
   413  
   414  	u2 := &model.User{
   415  		Email:    MakeEmail(),
   416  		Username: model.NewId(),
   417  	}
   418  	res = <-ss.User().Save(u2)
   419  	assert.Nil(t, res.Err)
   420  	user2 := res.Data.(*model.User)
   421  
   422  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user2.Id)
   423  	assert.Nil(t, res.Err)
   424  
   425  	// Check returns members
   426  	res = <-ss.Group().GetMemberUsers(group.Id)
   427  	assert.Nil(t, res.Err)
   428  	groupMembers := res.Data.([]*model.User)
   429  	assert.Equal(t, 2, len(groupMembers))
   430  
   431  	// Check madeup id
   432  	res = <-ss.Group().GetMemberUsers(model.NewId())
   433  	assert.Equal(t, 0, len(res.Data.([]*model.User)))
   434  
   435  	// Delete a member
   436  	<-ss.Group().DeleteMember(group.Id, user1.Id)
   437  
   438  	// Should not return deleted members
   439  	res = <-ss.Group().GetMemberUsers(group.Id)
   440  	groupMembers = res.Data.([]*model.User)
   441  	assert.Equal(t, 1, len(groupMembers))
   442  }
   443  
   444  func testGroupGetMemberUsersPage(t *testing.T, ss store.Store) {
   445  	// Save a group
   446  	g1 := &model.Group{
   447  		Name:        model.NewId(),
   448  		DisplayName: model.NewId(),
   449  		Description: model.NewId(),
   450  		Source:      model.GroupSourceLdap,
   451  		RemoteId:    model.NewId(),
   452  	}
   453  	res := <-ss.Group().Create(g1)
   454  	assert.Nil(t, res.Err)
   455  	group := res.Data.(*model.Group)
   456  
   457  	u1 := &model.User{
   458  		Email:    MakeEmail(),
   459  		Username: model.NewId(),
   460  	}
   461  	res = <-ss.User().Save(u1)
   462  	assert.Nil(t, res.Err)
   463  	user1 := res.Data.(*model.User)
   464  
   465  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user1.Id)
   466  	assert.Nil(t, res.Err)
   467  
   468  	u2 := &model.User{
   469  		Email:    MakeEmail(),
   470  		Username: model.NewId(),
   471  	}
   472  	res = <-ss.User().Save(u2)
   473  	assert.Nil(t, res.Err)
   474  	user2 := res.Data.(*model.User)
   475  
   476  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user2.Id)
   477  	assert.Nil(t, res.Err)
   478  
   479  	// Check returns members
   480  	res = <-ss.Group().GetMemberUsersPage(group.Id, 0, 100)
   481  	assert.Nil(t, res.Err)
   482  	groupMembers := res.Data.([]*model.User)
   483  	assert.Equal(t, 2, len(groupMembers))
   484  
   485  	// Check page 1
   486  	res = <-ss.Group().GetMemberUsersPage(group.Id, 0, 1)
   487  	assert.Nil(t, res.Err)
   488  	groupMembers = res.Data.([]*model.User)
   489  	assert.Equal(t, 1, len(groupMembers))
   490  	assert.Equal(t, user2.Id, groupMembers[0].Id)
   491  
   492  	// Check page 2
   493  	res = <-ss.Group().GetMemberUsersPage(group.Id, 1, 1)
   494  	assert.Nil(t, res.Err)
   495  	groupMembers = res.Data.([]*model.User)
   496  	assert.Equal(t, 1, len(groupMembers))
   497  	assert.Equal(t, user1.Id, groupMembers[0].Id)
   498  
   499  	// Check madeup id
   500  	res = <-ss.Group().GetMemberUsersPage(model.NewId(), 0, 100)
   501  	assert.Equal(t, 0, len(res.Data.([]*model.User)))
   502  
   503  	// Delete a member
   504  	<-ss.Group().DeleteMember(group.Id, user1.Id)
   505  
   506  	// Should not return deleted members
   507  	res = <-ss.Group().GetMemberUsersPage(group.Id, 0, 100)
   508  	groupMembers = res.Data.([]*model.User)
   509  	assert.Equal(t, 1, len(groupMembers))
   510  }
   511  
   512  func testGroupCreateOrRestoreMember(t *testing.T, ss store.Store) {
   513  	// Create group
   514  	g1 := &model.Group{
   515  		Name:        model.NewId(),
   516  		DisplayName: model.NewId(),
   517  		Source:      model.GroupSourceLdap,
   518  		RemoteId:    model.NewId(),
   519  	}
   520  	res1 := <-ss.Group().Create(g1)
   521  	assert.Nil(t, res1.Err)
   522  	group := res1.Data.(*model.Group)
   523  
   524  	// Create user
   525  	u1 := &model.User{
   526  		Email:    MakeEmail(),
   527  		Username: model.NewId(),
   528  	}
   529  	res2 := <-ss.User().Save(u1)
   530  	assert.Nil(t, res2.Err)
   531  	user := res2.Data.(*model.User)
   532  
   533  	// Happy path
   534  	res3 := <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
   535  	assert.Nil(t, res3.Err)
   536  	d2 := res3.Data.(*model.GroupMember)
   537  	assert.Equal(t, d2.GroupId, group.Id)
   538  	assert.Equal(t, d2.UserId, user.Id)
   539  	assert.NotZero(t, d2.CreateAt)
   540  	assert.Zero(t, d2.DeleteAt)
   541  
   542  	// Duplicate composite key (GroupId, UserId)
   543  	res4 := <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
   544  	assert.Equal(t, res4.Err.Id, "store.sql_group.uniqueness_error")
   545  
   546  	// Invalid GroupId
   547  	res6 := <-ss.Group().CreateOrRestoreMember(model.NewId(), user.Id)
   548  	assert.Equal(t, res6.Err.Id, "store.insert_error")
   549  
   550  	// Restores a deleted member
   551  	res := <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
   552  	assert.NotNil(t, res.Err)
   553  
   554  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
   555  	assert.Nil(t, res.Err)
   556  
   557  	res = <-ss.Group().GetMemberUsers(group.Id)
   558  	beforeRestoreCount := len(res.Data.([]*model.User))
   559  
   560  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
   561  	assert.Nil(t, res.Err)
   562  
   563  	res = <-ss.Group().GetMemberUsers(group.Id)
   564  	afterRestoreCount := len(res.Data.([]*model.User))
   565  
   566  	assert.Equal(t, beforeRestoreCount+1, afterRestoreCount)
   567  }
   568  
   569  func testGroupDeleteMember(t *testing.T, ss store.Store) {
   570  	// Create group
   571  	g1 := &model.Group{
   572  		Name:        model.NewId(),
   573  		DisplayName: model.NewId(),
   574  		Source:      model.GroupSourceLdap,
   575  		RemoteId:    model.NewId(),
   576  	}
   577  	res1 := <-ss.Group().Create(g1)
   578  	assert.Nil(t, res1.Err)
   579  	group := res1.Data.(*model.Group)
   580  
   581  	// Create user
   582  	u1 := &model.User{
   583  		Email:    MakeEmail(),
   584  		Username: model.NewId(),
   585  	}
   586  	res2 := <-ss.User().Save(u1)
   587  	assert.Nil(t, res2.Err)
   588  	user := res2.Data.(*model.User)
   589  
   590  	// Create member
   591  	res3 := <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
   592  	assert.Nil(t, res3.Err)
   593  	d1 := res3.Data.(*model.GroupMember)
   594  
   595  	// Happy path
   596  	res4 := <-ss.Group().DeleteMember(group.Id, user.Id)
   597  	assert.Nil(t, res4.Err)
   598  	d2 := res4.Data.(*model.GroupMember)
   599  	assert.Equal(t, d2.GroupId, group.Id)
   600  	assert.Equal(t, d2.UserId, user.Id)
   601  	assert.Equal(t, d2.CreateAt, d1.CreateAt)
   602  	assert.NotZero(t, d2.DeleteAt)
   603  
   604  	// Delete an already deleted member
   605  	res5 := <-ss.Group().DeleteMember(group.Id, user.Id)
   606  	assert.Equal(t, res5.Err.Id, "store.sql_group.no_rows")
   607  
   608  	// Delete with non-existent User
   609  	res8 := <-ss.Group().DeleteMember(group.Id, model.NewId())
   610  	assert.Equal(t, res8.Err.Id, "store.sql_group.no_rows")
   611  
   612  	// Delete non-existent Group
   613  	res9 := <-ss.Group().DeleteMember(model.NewId(), group.Id)
   614  	assert.Equal(t, res9.Err.Id, "store.sql_group.no_rows")
   615  }
   616  
   617  func testCreateGroupSyncable(t *testing.T, ss store.Store) {
   618  	// Invalid GroupID
   619  	res2 := <-ss.Group().CreateGroupSyncable(&model.GroupSyncable{
   620  		GroupId:    "x",
   621  		CanLeave:   true,
   622  		SyncableId: string(model.NewId()),
   623  		Type:       model.GroupSyncableTypeTeam,
   624  	})
   625  	assert.Equal(t, res2.Err.Id, "model.group_syncable.group_id.app_error")
   626  
   627  	// TODO: Add this validation test in phase 2 of LDAP groups sync.
   628  	// Invalid CanLeave/AutoAdd combo (both false)
   629  	// res3 := <-ss.Group().CreateGroupSyncable(&model.GroupSyncable{
   630  	// 	GroupId:    model.NewId(),
   631  	// 	CanLeave:   false,
   632  	// 	AutoAdd:    false,
   633  	// 	SyncableId: string(model.NewId()),
   634  	// 	Type:       model.GroupSyncableTypeTeam,
   635  	// })
   636  	// assert.Equal(t, res3.Err.Id, "model.group_syncable.invalid_state")
   637  
   638  	// Create Group
   639  	g1 := &model.Group{
   640  		Name:        model.NewId(),
   641  		DisplayName: model.NewId(),
   642  		Source:      model.GroupSourceLdap,
   643  		RemoteId:    model.NewId(),
   644  	}
   645  	res4 := <-ss.Group().Create(g1)
   646  	assert.Nil(t, res4.Err)
   647  	group := res4.Data.(*model.Group)
   648  
   649  	// Create Team
   650  	t1 := &model.Team{
   651  		DisplayName:     "Name",
   652  		Description:     "Some description",
   653  		CompanyName:     "Some company name",
   654  		AllowOpenInvite: false,
   655  		InviteId:        "inviteid0",
   656  		Name:            "z-z-" + model.NewId() + "a",
   657  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   658  		Type:            model.TEAM_OPEN,
   659  	}
   660  	res5 := <-ss.Team().Save(t1)
   661  	assert.Nil(t, res5.Err)
   662  	team := res5.Data.(*model.Team)
   663  
   664  	// New GroupSyncable, happy path
   665  	gt1 := &model.GroupSyncable{
   666  		GroupId:    group.Id,
   667  		CanLeave:   true,
   668  		AutoAdd:    false,
   669  		SyncableId: string(team.Id),
   670  		Type:       model.GroupSyncableTypeTeam,
   671  	}
   672  	res6 := <-ss.Group().CreateGroupSyncable(gt1)
   673  	assert.Nil(t, res6.Err)
   674  	d1 := res6.Data.(*model.GroupSyncable)
   675  	assert.Equal(t, gt1.SyncableId, d1.SyncableId)
   676  	assert.Equal(t, gt1.GroupId, d1.GroupId)
   677  	assert.Equal(t, gt1.CanLeave, d1.CanLeave)
   678  	assert.Equal(t, gt1.AutoAdd, d1.AutoAdd)
   679  	assert.NotZero(t, d1.CreateAt)
   680  	assert.Zero(t, d1.DeleteAt)
   681  }
   682  
   683  func testGetGroupSyncable(t *testing.T, ss store.Store) {
   684  	// Create a group
   685  	g1 := &model.Group{
   686  		Name:        model.NewId(),
   687  		DisplayName: model.NewId(),
   688  		Description: model.NewId(),
   689  		Source:      model.GroupSourceLdap,
   690  		RemoteId:    model.NewId(),
   691  	}
   692  	res1 := <-ss.Group().Create(g1)
   693  	assert.Nil(t, res1.Err)
   694  	group := res1.Data.(*model.Group)
   695  
   696  	// Create Team
   697  	t1 := &model.Team{
   698  		DisplayName:     "Name",
   699  		Description:     "Some description",
   700  		CompanyName:     "Some company name",
   701  		AllowOpenInvite: false,
   702  		InviteId:        "inviteid0",
   703  		Name:            "z-z-" + model.NewId() + "a",
   704  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   705  		Type:            model.TEAM_OPEN,
   706  	}
   707  	res2 := <-ss.Team().Save(t1)
   708  	assert.Nil(t, res2.Err)
   709  	team := res2.Data.(*model.Team)
   710  
   711  	// Create GroupSyncable
   712  	gt1 := &model.GroupSyncable{
   713  		GroupId:    group.Id,
   714  		CanLeave:   true,
   715  		AutoAdd:    false,
   716  		SyncableId: string(team.Id),
   717  		Type:       model.GroupSyncableTypeTeam,
   718  	}
   719  	res3 := <-ss.Group().CreateGroupSyncable(gt1)
   720  	assert.Nil(t, res3.Err)
   721  	groupTeam := res3.Data.(*model.GroupSyncable)
   722  
   723  	// Get GroupSyncable
   724  	res4 := <-ss.Group().GetGroupSyncable(groupTeam.GroupId, groupTeam.SyncableId, model.GroupSyncableTypeTeam)
   725  	assert.Nil(t, res4.Err)
   726  	dgt := res4.Data.(*model.GroupSyncable)
   727  	assert.Equal(t, gt1.GroupId, dgt.GroupId)
   728  	assert.Equal(t, gt1.SyncableId, dgt.SyncableId)
   729  	// assert.Equal(t, gt1.CanLeave, dgt.CanLeave) // TODO: Re-add this test in phase 2 of LDAP groups sync.
   730  	assert.Equal(t, gt1.AutoAdd, dgt.AutoAdd)
   731  	assert.NotZero(t, gt1.CreateAt)
   732  	assert.NotZero(t, gt1.UpdateAt)
   733  	assert.Zero(t, gt1.DeleteAt)
   734  }
   735  
   736  func testGetAllGroupSyncablesByGroup(t *testing.T, ss store.Store) {
   737  	numGroupSyncables := 10
   738  
   739  	// Create group
   740  	g := &model.Group{
   741  		Name:        model.NewId(),
   742  		DisplayName: model.NewId(),
   743  		Description: model.NewId(),
   744  		Source:      model.GroupSourceLdap,
   745  		RemoteId:    model.NewId(),
   746  	}
   747  	res1 := <-ss.Group().Create(g)
   748  	assert.Nil(t, res1.Err)
   749  	group := res1.Data.(*model.Group)
   750  
   751  	groupTeams := []*model.GroupSyncable{}
   752  
   753  	// Create groupTeams
   754  	for i := 0; i < numGroupSyncables; i++ {
   755  		// Create Team
   756  		t1 := &model.Team{
   757  			DisplayName:     "Name",
   758  			Description:     "Some description",
   759  			CompanyName:     "Some company name",
   760  			AllowOpenInvite: false,
   761  			InviteId:        "inviteid0",
   762  			Name:            "z-z-" + model.NewId() + "a",
   763  			Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   764  			Type:            model.TEAM_OPEN,
   765  		}
   766  		res2 := <-ss.Team().Save(t1)
   767  		assert.Nil(t, res2.Err)
   768  		team := res2.Data.(*model.Team)
   769  
   770  		// create groupteam
   771  		res3 := <-ss.Group().CreateGroupSyncable(&model.GroupSyncable{
   772  			GroupId:    group.Id,
   773  			CanLeave:   true,
   774  			SyncableId: string(team.Id),
   775  			Type:       model.GroupSyncableTypeTeam,
   776  		})
   777  		assert.Nil(t, res3.Err)
   778  		groupTeam := res3.Data.(*model.GroupSyncable)
   779  		groupTeams = append(groupTeams, groupTeam)
   780  	}
   781  
   782  	// Returns all the group teams
   783  	res4 := <-ss.Group().GetAllGroupSyncablesByGroupId(group.Id, model.GroupSyncableTypeTeam)
   784  	d1 := res4.Data.([]*model.GroupSyncable)
   785  	assert.Condition(t, func() bool { return len(d1) >= numGroupSyncables })
   786  	for _, expectedGroupTeam := range groupTeams {
   787  		present := false
   788  		for _, dbGroupTeam := range d1 {
   789  			if dbGroupTeam.GroupId == expectedGroupTeam.GroupId && dbGroupTeam.SyncableId == expectedGroupTeam.SyncableId {
   790  				present = true
   791  				break
   792  			}
   793  		}
   794  		assert.True(t, present)
   795  	}
   796  }
   797  
   798  func testUpdateGroupSyncable(t *testing.T, ss store.Store) {
   799  	// Create Group
   800  	g1 := &model.Group{
   801  		Name:        model.NewId(),
   802  		DisplayName: model.NewId(),
   803  		Source:      model.GroupSourceLdap,
   804  		RemoteId:    model.NewId(),
   805  	}
   806  	res4 := <-ss.Group().Create(g1)
   807  	assert.Nil(t, res4.Err)
   808  	group := res4.Data.(*model.Group)
   809  
   810  	// Create Team
   811  	t1 := &model.Team{
   812  		DisplayName:     "Name",
   813  		Description:     "Some description",
   814  		CompanyName:     "Some company name",
   815  		AllowOpenInvite: false,
   816  		InviteId:        "inviteid0",
   817  		Name:            "z-z-" + model.NewId() + "a",
   818  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   819  		Type:            model.TEAM_OPEN,
   820  	}
   821  	res5 := <-ss.Team().Save(t1)
   822  	assert.Nil(t, res5.Err)
   823  	team := res5.Data.(*model.Team)
   824  
   825  	// New GroupSyncable, happy path
   826  	gt1 := &model.GroupSyncable{
   827  		GroupId:    group.Id,
   828  		CanLeave:   true,
   829  		AutoAdd:    false,
   830  		SyncableId: string(team.Id),
   831  		Type:       model.GroupSyncableTypeTeam,
   832  	}
   833  	res6 := <-ss.Group().CreateGroupSyncable(gt1)
   834  	assert.Nil(t, res6.Err)
   835  	d1 := res6.Data.(*model.GroupSyncable)
   836  
   837  	// Update existing group team
   838  	gt1.CanLeave = false
   839  	gt1.AutoAdd = true
   840  	res7 := <-ss.Group().UpdateGroupSyncable(gt1)
   841  	assert.Nil(t, res7.Err)
   842  	d2 := res7.Data.(*model.GroupSyncable)
   843  	assert.False(t, d2.CanLeave)
   844  	assert.True(t, d2.AutoAdd)
   845  
   846  	// TODO: Add this validation check test in phase 2 of LDAP groups sync.
   847  	// Update to invalid state
   848  	// gt1.AutoAdd = false
   849  	// gt1.CanLeave = false
   850  	// res8 := <-ss.Group().UpdateGroupSyncable(gt1)
   851  	// assert.Equal(t, res8.Err.Id, "model.group_syncable.invalid_state")
   852  
   853  	// Non-existent Group
   854  	gt2 := &model.GroupSyncable{
   855  		GroupId:    model.NewId(),
   856  		CanLeave:   true,
   857  		AutoAdd:    false,
   858  		SyncableId: string(team.Id),
   859  		Type:       model.GroupSyncableTypeTeam,
   860  	}
   861  	res9 := <-ss.Group().UpdateGroupSyncable(gt2)
   862  	assert.Equal(t, res9.Err.Id, "store.sql_group.no_rows")
   863  
   864  	// Non-existent Team
   865  	gt3 := &model.GroupSyncable{
   866  		GroupId:    group.Id,
   867  		CanLeave:   true,
   868  		AutoAdd:    false,
   869  		SyncableId: string(model.NewId()),
   870  		Type:       model.GroupSyncableTypeTeam,
   871  	}
   872  	res10 := <-ss.Group().UpdateGroupSyncable(gt3)
   873  	assert.Equal(t, res10.Err.Id, "store.sql_group.no_rows")
   874  
   875  	// Cannot update CreateAt or DeleteAt
   876  	origCreateAt := d1.CreateAt
   877  	d1.CreateAt = model.GetMillis()
   878  	d1.AutoAdd = true
   879  	d1.CanLeave = true
   880  	res11 := <-ss.Group().UpdateGroupSyncable(d1)
   881  	assert.Nil(t, res11.Err)
   882  	d3 := res11.Data.(*model.GroupSyncable)
   883  	assert.Equal(t, origCreateAt, d3.CreateAt)
   884  
   885  	// Cannot update DeleteAt to arbitrary value
   886  	d1.DeleteAt = 1
   887  	res12 := <-ss.Group().UpdateGroupSyncable(d1)
   888  	assert.Equal(t, "model.group.delete_at.app_error", res12.Err.Id)
   889  
   890  	// Can update DeleteAt to 0
   891  	d1.DeleteAt = 0
   892  	res13 := <-ss.Group().UpdateGroupSyncable(d1)
   893  	assert.Nil(t, res13.Err)
   894  	d4 := res13.Data.(*model.GroupSyncable)
   895  	assert.Zero(t, d4.DeleteAt)
   896  }
   897  
   898  func testDeleteGroupSyncable(t *testing.T, ss store.Store) {
   899  	// Create Group
   900  	g1 := &model.Group{
   901  		Name:        model.NewId(),
   902  		DisplayName: model.NewId(),
   903  		Source:      model.GroupSourceLdap,
   904  		RemoteId:    model.NewId(),
   905  	}
   906  	res1 := <-ss.Group().Create(g1)
   907  	assert.Nil(t, res1.Err)
   908  	group := res1.Data.(*model.Group)
   909  
   910  	// Create Team
   911  	t1 := &model.Team{
   912  		DisplayName:     "Name",
   913  		Description:     "Some description",
   914  		CompanyName:     "Some company name",
   915  		AllowOpenInvite: false,
   916  		InviteId:        "inviteid0",
   917  		Name:            "z-z-" + model.NewId() + "a",
   918  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   919  		Type:            model.TEAM_OPEN,
   920  	}
   921  	res2 := <-ss.Team().Save(t1)
   922  	assert.Nil(t, res2.Err)
   923  	team := res2.Data.(*model.Team)
   924  
   925  	// Create GroupSyncable
   926  	gt1 := &model.GroupSyncable{
   927  		GroupId:    group.Id,
   928  		CanLeave:   true,
   929  		AutoAdd:    false,
   930  		SyncableId: string(team.Id),
   931  		Type:       model.GroupSyncableTypeTeam,
   932  	}
   933  	res7 := <-ss.Group().CreateGroupSyncable(gt1)
   934  	assert.Nil(t, res7.Err)
   935  	groupTeam := res7.Data.(*model.GroupSyncable)
   936  
   937  	// Non-existent Group
   938  	res5 := <-ss.Group().DeleteGroupSyncable(model.NewId(), groupTeam.SyncableId, model.GroupSyncableTypeTeam)
   939  	assert.Equal(t, res5.Err.Id, "store.sql_group.no_rows")
   940  
   941  	// Non-existent Team
   942  	res6 := <-ss.Group().DeleteGroupSyncable(groupTeam.GroupId, string(model.NewId()), model.GroupSyncableTypeTeam)
   943  	assert.Equal(t, res6.Err.Id, "store.sql_group.no_rows")
   944  
   945  	// Happy path...
   946  	res8 := <-ss.Group().DeleteGroupSyncable(groupTeam.GroupId, groupTeam.SyncableId, model.GroupSyncableTypeTeam)
   947  	assert.Nil(t, res8.Err)
   948  	d1 := res8.Data.(*model.GroupSyncable)
   949  	assert.NotZero(t, d1.DeleteAt)
   950  	assert.Equal(t, d1.GroupId, groupTeam.GroupId)
   951  	assert.Equal(t, d1.SyncableId, groupTeam.SyncableId)
   952  	// assert.Equal(t, d1.CanLeave, groupTeam.CanLeave) // TODO: Re-add this test in phase 2 of LDAP groups sync.
   953  	assert.Equal(t, d1.AutoAdd, groupTeam.AutoAdd)
   954  	assert.Equal(t, d1.CreateAt, groupTeam.CreateAt)
   955  	assert.Condition(t, func() bool { return d1.UpdateAt > groupTeam.UpdateAt })
   956  
   957  	// Record already deleted
   958  	res9 := <-ss.Group().DeleteGroupSyncable(d1.GroupId, d1.SyncableId, d1.Type)
   959  	assert.NotNil(t, res9.Err)
   960  	assert.Equal(t, res9.Err.Id, "store.sql_group.group_syncable_already_deleted")
   961  }
   962  
   963  func testPendingAutoAddTeamMembers(t *testing.T, ss store.Store) {
   964  	// Create Group
   965  	res := <-ss.Group().Create(&model.Group{
   966  		Name:        model.NewId(),
   967  		DisplayName: "PendingAutoAddTeamMembers Test Group",
   968  		RemoteId:    model.NewId(),
   969  		Source:      model.GroupSourceLdap,
   970  	})
   971  	assert.Nil(t, res.Err)
   972  	group := res.Data.(*model.Group)
   973  
   974  	// Create User
   975  	user := &model.User{
   976  		Email:    MakeEmail(),
   977  		Username: model.NewId(),
   978  	}
   979  	res = <-ss.User().Save(user)
   980  	assert.Nil(t, res.Err)
   981  	user = res.Data.(*model.User)
   982  
   983  	// Create GroupMember
   984  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
   985  	assert.Nil(t, res.Err)
   986  
   987  	// Create Team
   988  	team := &model.Team{
   989  		DisplayName:     "Name",
   990  		Description:     "Some description",
   991  		CompanyName:     "Some company name",
   992  		AllowOpenInvite: false,
   993  		InviteId:        "inviteid0",
   994  		Name:            "z-z-" + model.NewId() + "a",
   995  		Email:           "success+" + model.NewId() + "@simulator.amazonses.com",
   996  		Type:            model.TEAM_OPEN,
   997  	}
   998  	res = <-ss.Team().Save(team)
   999  	assert.Nil(t, res.Err)
  1000  	team = res.Data.(*model.Team)
  1001  
  1002  	// Create GroupTeam
  1003  	res = <-ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  1004  		AutoAdd:    true,
  1005  		CanLeave:   true,
  1006  		SyncableId: team.Id,
  1007  		Type:       model.GroupSyncableTypeTeam,
  1008  		GroupId:    group.Id,
  1009  	})
  1010  	assert.Nil(t, res.Err)
  1011  	syncable := res.Data.(*model.GroupSyncable)
  1012  
  1013  	// Time before syncable was created
  1014  	res = <-ss.Group().PendingAutoAddTeamMembers(syncable.CreateAt - 1)
  1015  	assert.Nil(t, res.Err)
  1016  	userTeamIDs := res.Data.([]*model.UserTeamIDPair)
  1017  	assert.Len(t, userTeamIDs, 1)
  1018  	assert.Equal(t, user.Id, userTeamIDs[0].UserID)
  1019  	assert.Equal(t, team.Id, userTeamIDs[0].TeamID)
  1020  
  1021  	// Time after syncable was created
  1022  	res = <-ss.Group().PendingAutoAddTeamMembers(syncable.CreateAt + 1)
  1023  	assert.Nil(t, res.Err)
  1024  	assert.Len(t, res.Data, 0)
  1025  
  1026  	// Delete and restore GroupMember should return result
  1027  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
  1028  	assert.Nil(t, res.Err)
  1029  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
  1030  	assert.Nil(t, res.Err)
  1031  	res = <-ss.Group().PendingAutoAddTeamMembers(syncable.CreateAt + 1)
  1032  	assert.Nil(t, res.Err)
  1033  	assert.Len(t, res.Data, 1)
  1034  
  1035  	pristineSyncable := *syncable
  1036  
  1037  	syncable.CanLeave = false
  1038  	res = <-ss.Group().UpdateGroupSyncable(syncable)
  1039  	assert.Nil(t, res.Err)
  1040  
  1041  	// Time before syncable was updated
  1042  	res = <-ss.Group().PendingAutoAddTeamMembers(syncable.UpdateAt - 1)
  1043  	assert.Nil(t, res.Err)
  1044  	userTeamIDs = res.Data.([]*model.UserTeamIDPair)
  1045  	assert.Len(t, userTeamIDs, 1)
  1046  	assert.Equal(t, user.Id, userTeamIDs[0].UserID)
  1047  	assert.Equal(t, team.Id, userTeamIDs[0].TeamID)
  1048  
  1049  	// Time after syncable was updated
  1050  	res = <-ss.Group().PendingAutoAddTeamMembers(syncable.UpdateAt + 1)
  1051  	assert.Nil(t, res.Err)
  1052  	assert.Len(t, res.Data, 0)
  1053  
  1054  	// Only includes if auto-add
  1055  	syncable.AutoAdd = false
  1056  	syncable.CanLeave = true // have to update this or the model isn't valid
  1057  	res = <-ss.Group().UpdateGroupSyncable(syncable)
  1058  	assert.Nil(t, res.Err)
  1059  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1060  	assert.Nil(t, res.Err)
  1061  	assert.Len(t, res.Data, 0)
  1062  
  1063  	// reset state of syncable and verify
  1064  	res = <-ss.Group().UpdateGroupSyncable(&pristineSyncable)
  1065  	assert.Nil(t, res.Err)
  1066  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1067  	assert.Nil(t, res.Err)
  1068  	assert.Len(t, res.Data, 1)
  1069  
  1070  	// No result if Group deleted
  1071  	res = <-ss.Group().Delete(group.Id)
  1072  	assert.Nil(t, res.Err)
  1073  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1074  	assert.Nil(t, res.Err)
  1075  	assert.Len(t, res.Data, 0)
  1076  
  1077  	// reset state of group and verify
  1078  	group.DeleteAt = 0
  1079  	res = <-ss.Group().Update(group)
  1080  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1081  	assert.Nil(t, res.Err)
  1082  	assert.Len(t, res.Data, 1)
  1083  
  1084  	// No result if Team deleted
  1085  	team.DeleteAt = model.GetMillis()
  1086  	res = <-ss.Team().Update(team)
  1087  	assert.Nil(t, res.Err)
  1088  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1089  	assert.Nil(t, res.Err)
  1090  	assert.Len(t, res.Data, 0)
  1091  
  1092  	// reset state of team and verify
  1093  	team.DeleteAt = 0
  1094  	res = <-ss.Team().Update(team)
  1095  	assert.Nil(t, res.Err)
  1096  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1097  	assert.Nil(t, res.Err)
  1098  	assert.Len(t, res.Data, 1)
  1099  
  1100  	// No result if GroupTeam deleted
  1101  	res = <-ss.Group().DeleteGroupSyncable(group.Id, team.Id, model.GroupSyncableTypeTeam)
  1102  	assert.Nil(t, res.Err)
  1103  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1104  	assert.Nil(t, res.Err)
  1105  	assert.Len(t, res.Data, 0)
  1106  
  1107  	// reset GroupTeam and verify
  1108  	res = <-ss.Group().UpdateGroupSyncable(&pristineSyncable)
  1109  	assert.Nil(t, res.Err)
  1110  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1111  	assert.Nil(t, res.Err)
  1112  	assert.Len(t, res.Data, 1)
  1113  
  1114  	// No result if GroupMember deleted
  1115  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
  1116  	assert.Nil(t, res.Err)
  1117  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1118  	assert.Nil(t, res.Err)
  1119  	assert.Len(t, res.Data, 0)
  1120  
  1121  	// restore group member and verify
  1122  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
  1123  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1124  	assert.Nil(t, res.Err)
  1125  	assert.Len(t, res.Data, 1)
  1126  
  1127  	// adding team membership stops returning result
  1128  	res = <-ss.Team().SaveMember(&model.TeamMember{
  1129  		TeamId: team.Id,
  1130  		UserId: user.Id,
  1131  	}, 999)
  1132  	assert.Nil(t, res.Err)
  1133  	res = <-ss.Group().PendingAutoAddTeamMembers(0)
  1134  	assert.Nil(t, res.Err)
  1135  	assert.Len(t, res.Data, 0)
  1136  }
  1137  
  1138  func testPendingAutoAddChannelMembers(t *testing.T, ss store.Store) {
  1139  	// Create Group
  1140  	res := <-ss.Group().Create(&model.Group{
  1141  		Name:        model.NewId(),
  1142  		DisplayName: "PendingAutoAddChannelMembers Test Group",
  1143  		RemoteId:    model.NewId(),
  1144  		Source:      model.GroupSourceLdap,
  1145  	})
  1146  	assert.Nil(t, res.Err)
  1147  	group := res.Data.(*model.Group)
  1148  
  1149  	// Create User
  1150  	user := &model.User{
  1151  		Email:    MakeEmail(),
  1152  		Username: model.NewId(),
  1153  	}
  1154  	res = <-ss.User().Save(user)
  1155  	assert.Nil(t, res.Err)
  1156  	user = res.Data.(*model.User)
  1157  
  1158  	// Create GroupMember
  1159  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
  1160  	assert.Nil(t, res.Err)
  1161  
  1162  	// Create Channel
  1163  	channel := &model.Channel{
  1164  		TeamId:      model.NewId(),
  1165  		DisplayName: "A Name",
  1166  		Name:        model.NewId(),
  1167  		Type:        model.CHANNEL_OPEN, // Query does not look at type so this shouldn't matter.
  1168  	}
  1169  	res = <-ss.Channel().Save(channel, 9999)
  1170  	assert.Nil(t, res.Err)
  1171  	channel = res.Data.(*model.Channel)
  1172  
  1173  	// Create GroupChannel
  1174  	res = <-ss.Group().CreateGroupSyncable(&model.GroupSyncable{
  1175  		AutoAdd:    true,
  1176  		CanLeave:   true,
  1177  		SyncableId: channel.Id,
  1178  		Type:       model.GroupSyncableTypeChannel,
  1179  		GroupId:    group.Id,
  1180  	})
  1181  	assert.Nil(t, res.Err)
  1182  	syncable := res.Data.(*model.GroupSyncable)
  1183  
  1184  	// Time before syncable was created
  1185  	res = <-ss.Group().PendingAutoAddChannelMembers(syncable.CreateAt - 1)
  1186  	assert.Nil(t, res.Err)
  1187  	userChannelIDs := res.Data.([]*model.UserChannelIDPair)
  1188  	assert.Len(t, userChannelIDs, 1)
  1189  	assert.Equal(t, user.Id, userChannelIDs[0].UserID)
  1190  	assert.Equal(t, channel.Id, userChannelIDs[0].ChannelID)
  1191  
  1192  	// Time after syncable was created
  1193  	res = <-ss.Group().PendingAutoAddChannelMembers(syncable.CreateAt + 1)
  1194  	assert.Nil(t, res.Err)
  1195  	assert.Len(t, res.Data, 0)
  1196  
  1197  	// Delete and restore GroupMember should return result
  1198  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
  1199  	assert.Nil(t, res.Err)
  1200  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
  1201  	assert.Nil(t, res.Err)
  1202  	res = <-ss.Group().PendingAutoAddChannelMembers(syncable.CreateAt + 1)
  1203  	assert.Nil(t, res.Err)
  1204  	assert.Len(t, res.Data, 1)
  1205  
  1206  	pristineSyncable := *syncable
  1207  
  1208  	syncable.CanLeave = false
  1209  	res = <-ss.Group().UpdateGroupSyncable(syncable)
  1210  	assert.Nil(t, res.Err)
  1211  
  1212  	// Time before syncable was updated
  1213  	res = <-ss.Group().PendingAutoAddChannelMembers(syncable.UpdateAt - 1)
  1214  	assert.Nil(t, res.Err)
  1215  	userChannelIDs = res.Data.([]*model.UserChannelIDPair)
  1216  	assert.Len(t, userChannelIDs, 1)
  1217  	assert.Equal(t, user.Id, userChannelIDs[0].UserID)
  1218  	assert.Equal(t, channel.Id, userChannelIDs[0].ChannelID)
  1219  
  1220  	// Time after syncable was updated
  1221  	res = <-ss.Group().PendingAutoAddChannelMembers(syncable.UpdateAt + 1)
  1222  	assert.Nil(t, res.Err)
  1223  	assert.Len(t, res.Data, 0)
  1224  
  1225  	// Only includes if auto-add
  1226  	syncable.AutoAdd = false
  1227  	syncable.CanLeave = true // have to update this or the model isn't valid
  1228  	res = <-ss.Group().UpdateGroupSyncable(syncable)
  1229  	assert.Nil(t, res.Err)
  1230  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1231  	assert.Nil(t, res.Err)
  1232  	assert.Len(t, res.Data, 0)
  1233  
  1234  	// reset state of syncable and verify
  1235  	res = <-ss.Group().UpdateGroupSyncable(&pristineSyncable)
  1236  	assert.Nil(t, res.Err)
  1237  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1238  	assert.Nil(t, res.Err)
  1239  	assert.Len(t, res.Data, 1)
  1240  
  1241  	// No result if Group deleted
  1242  	res = <-ss.Group().Delete(group.Id)
  1243  	assert.Nil(t, res.Err)
  1244  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1245  	assert.Nil(t, res.Err)
  1246  	assert.Len(t, res.Data, 0)
  1247  
  1248  	// reset state of group and verify
  1249  	group.DeleteAt = 0
  1250  	res = <-ss.Group().Update(group)
  1251  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1252  	assert.Nil(t, res.Err)
  1253  	assert.Len(t, res.Data, 1)
  1254  
  1255  	// No result if Channel deleted
  1256  	res = <-ss.Channel().Delete(channel.Id, model.GetMillis())
  1257  	assert.Nil(t, res.Err)
  1258  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1259  	assert.Nil(t, res.Err)
  1260  	assert.Len(t, res.Data, 0)
  1261  
  1262  	// reset state of channel and verify
  1263  	channel.DeleteAt = 0
  1264  	res = <-ss.Channel().Update(channel)
  1265  	assert.Nil(t, res.Err)
  1266  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1267  	assert.Nil(t, res.Err)
  1268  	assert.Len(t, res.Data, 1)
  1269  
  1270  	// No result if GroupChannel deleted
  1271  	res = <-ss.Group().DeleteGroupSyncable(group.Id, channel.Id, model.GroupSyncableTypeChannel)
  1272  	assert.Nil(t, res.Err)
  1273  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1274  	assert.Nil(t, res.Err)
  1275  	assert.Len(t, res.Data, 0)
  1276  
  1277  	// reset GroupChannel and verify
  1278  	res = <-ss.Group().UpdateGroupSyncable(&pristineSyncable)
  1279  	assert.Nil(t, res.Err)
  1280  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1281  	assert.Nil(t, res.Err)
  1282  	assert.Len(t, res.Data, 1)
  1283  
  1284  	// No result if GroupMember deleted
  1285  	res = <-ss.Group().DeleteMember(group.Id, user.Id)
  1286  	assert.Nil(t, res.Err)
  1287  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1288  	assert.Nil(t, res.Err)
  1289  	assert.Len(t, res.Data, 0)
  1290  
  1291  	// restore group member and verify
  1292  	res = <-ss.Group().CreateOrRestoreMember(group.Id, user.Id)
  1293  	assert.Nil(t, res.Err)
  1294  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1295  	assert.Nil(t, res.Err)
  1296  	assert.Len(t, res.Data, 1)
  1297  
  1298  	// Adding Channel (ChannelMemberHistory) should stop returning result
  1299  	res = <-ss.ChannelMemberHistory().LogJoinEvent(user.Id, channel.Id, model.GetMillis())
  1300  	assert.Nil(t, res.Err)
  1301  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1302  	assert.Nil(t, res.Err)
  1303  	assert.Len(t, res.Data, 0)
  1304  
  1305  	// Leaving Channel (ChannelMemberHistory) should still not return result
  1306  	res = <-ss.ChannelMemberHistory().LogLeaveEvent(user.Id, channel.Id, model.GetMillis())
  1307  	assert.Nil(t, res.Err)
  1308  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1309  	assert.Nil(t, res.Err)
  1310  	assert.Len(t, res.Data, 0)
  1311  
  1312  	// Purging ChannelMemberHistory re-returns the result
  1313  	res = <-ss.ChannelMemberHistory().PermanentDeleteBatch(model.GetMillis()+1, 100)
  1314  	assert.Nil(t, res.Err)
  1315  	res = <-ss.Group().PendingAutoAddChannelMembers(0)
  1316  	assert.Nil(t, res.Err)
  1317  	assert.Len(t, res.Data, 1)
  1318  }