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 }