mattermost-community-enterp.../channels/app/syncables_test.go
Claude ec1f89217a Merge: Complete Mattermost Server with Community Enterprise
Full Mattermost server source with integrated Community Enterprise features.
Includes vendor directory for offline/air-gapped builds.

Structure:
- enterprise-impl/: Enterprise feature implementations
- enterprise-community/: Init files that register implementations
- enterprise/: Bridge imports (community_imports.go)
- vendor/: All dependencies for offline builds

Build (online):
  go build ./cmd/mattermost

Build (offline/air-gapped):
  go build -mod=vendor ./cmd/mattermost

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 23:59:07 +09:00

680 lines
22 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package app
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/v8/channels/store"
)
//nolint:govet // The setup code leads to a lot of variable shadowing.
func TestCreateDefaultMemberships(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic()
defer th.TearDown()
singersTeam, err := th.App.CreateTeam(th.Context, &model.Team{
DisplayName: "Singers",
Name: "zz" + model.NewId(),
Email: "singers@test.com",
Type: model.TeamOpen,
})
if err != nil {
t.Errorf("test team not created: %s", err.Error())
}
nerdsTeam, err := th.App.CreateTeam(th.Context, &model.Team{
DisplayName: "Nerds",
Name: "zz" + model.NewId(),
Email: "nerds@test.com",
Type: model.TeamInvite,
})
if err != nil {
t.Errorf("test team not created: %s", err.Error())
}
practiceChannel, err := th.App.CreateChannel(th.Context, &model.Channel{
TeamId: singersTeam.Id,
DisplayName: "Practices",
Name: model.NewId(),
Type: model.ChannelTypeOpen,
}, false)
if err != nil {
t.Errorf("test channel not created: %s", err.Error())
}
experimentsChannel, err := th.App.CreateChannel(th.Context, &model.Channel{
TeamId: singersTeam.Id,
DisplayName: "Experiments",
Name: model.NewId(),
Type: model.ChannelTypePrivate,
}, false)
if err != nil {
t.Errorf("test channel not created: %s", err.Error())
}
gleeGroup, err := th.App.CreateGroup(&model.Group{
Name: model.NewPointer(model.NewId()),
DisplayName: "Glee Club",
RemoteId: model.NewPointer(model.NewId()),
Source: model.GroupSourceLdap,
})
if err != nil {
t.Errorf("test group not created: %s", err.Error())
}
scienceGroup, err := th.App.CreateGroup(&model.Group{
Name: model.NewPointer(model.NewId()),
DisplayName: "Science Club",
RemoteId: model.NewPointer(model.NewId()),
Source: model.GroupSourceLdap,
})
if err != nil {
t.Errorf("test group not created: %s", err.Error())
}
_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(gleeGroup.Id, practiceChannel.Id, true))
if err != nil {
t.Errorf("test groupchannel not created: %s", err.Error())
}
scienceTeamGroupSyncable, err := th.App.UpsertGroupSyncable(model.NewGroupTeam(scienceGroup.Id, nerdsTeam.Id, false))
if err != nil {
t.Errorf("test groupteam not created: %s", err.Error())
}
scienceChannelGroupSyncable, err := th.App.UpsertGroupSyncable(model.NewGroupChannel(scienceGroup.Id, experimentsChannel.Id, false))
if err != nil {
t.Errorf("test groupchannel not created: %s", err.Error())
}
singer1 := th.BasicUser
scientist1 := th.BasicUser2
_, err = th.App.UpsertGroupMember(gleeGroup.Id, singer1.Id)
if err != nil {
t.Errorf("test groupmember not created: %s", err.Error())
}
scientistGroupMember, err := th.App.UpsertGroupMember(scienceGroup.Id, scientist1.Id)
if err != nil {
t.Errorf("test groupmember not created: %s", err.Error())
}
pErr := th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false})
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
// Singer should be in team and channel
_, err = th.App.GetTeamMember(th.Context, singersTeam.Id, singer1.Id)
if err != nil {
t.Errorf("error retrieving team member: %s", err.Error())
}
_, err = th.App.GetChannelMember(th.Context, practiceChannel.Id, singer1.Id)
if err != nil {
t.Errorf("error retrieving channel member: %s", err.Error())
}
tMembers, err := th.App.GetTeamMembers(singersTeam.Id, 0, 999, nil)
if err != nil {
t.Errorf("error retrieving team members: %s", err.Error())
}
expected := 1
actual := len(tMembers)
if actual != expected {
t.Errorf("expected %d team members but got %d", expected, actual)
}
cMembersCount, err := th.App.GetChannelMemberCount(th.Context, practiceChannel.Id)
if err != nil {
t.Errorf("error retrieving team members: %s", err.Error())
}
if cMembersCount != int64(expected) {
t.Errorf("expected %d team member but got %d", expected, cMembersCount)
}
// Scientist should not be in team or channel
_, err = th.App.GetTeamMember(th.Context, nerdsTeam.Id, scientist1.Id)
if err.Id != "app.team.get_member.missing.app_error" {
t.Errorf("wrong error: %s", err.Id)
}
_, err = th.App.GetChannelMember(th.Context, experimentsChannel.Id, scientist1.Id)
if err.Id != "app.channel.get_member.missing.app_error" {
t.Errorf("wrong error: %s", err.Id)
}
tMembers, err = th.App.GetTeamMembers(nerdsTeam.Id, 0, 999, nil)
if err != nil {
t.Errorf("error retrieving team members: %s", err.Error())
}
expected = 0
actual = len(tMembers)
if actual != expected {
t.Errorf("expected %d team members but got %d", expected, actual)
}
cMembersCount, err = th.App.GetChannelMemberCount(th.Context, experimentsChannel.Id)
if err != nil {
t.Errorf("error retrieving team members: %s", err.Error())
}
if cMembersCount != int64(expected) {
t.Errorf("expected %d team members but got %d", expected, cMembersCount)
}
// update AutoAdd to true
scienceTeamGroupSyncable.AutoAdd = true
_, err = th.App.UpdateGroupSyncable(scienceTeamGroupSyncable)
if err != nil {
t.Errorf("error updating group syncable: %s", err.Error())
}
// Sync everything after syncable was created (proving that team updates trigger re-sync)
pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: scientistGroupMember.CreateAt + 1, ReAddRemovedMembers: false})
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
// Scientist should be in team but not the channel
_, err = th.App.GetTeamMember(th.Context, nerdsTeam.Id, scientist1.Id)
if err != nil {
t.Errorf("error retrieving team member: %s", err.Error())
}
_, err = th.App.GetChannelMember(th.Context, experimentsChannel.Id, scientist1.Id)
if err.Id != "app.channel.get_member.missing.app_error" {
t.Errorf("wrong error: %s", err.Id)
}
tMembers, err = th.App.GetTeamMembers(nerdsTeam.Id, 0, 999, nil)
if err != nil {
t.Errorf("error retrieving team members: %s", err.Error())
}
expected = 1
actual = len(tMembers)
if actual != expected {
t.Errorf("expected %d team members but got %d", expected, actual)
}
expected = 0
cMembersCount, err = th.App.GetChannelMemberCount(th.Context, experimentsChannel.Id)
if err != nil {
t.Errorf("error retrieving team members: %s", err.Error())
}
if cMembersCount != int64(expected) {
t.Errorf("expected %d team members but got %d", expected, cMembersCount)
}
// Update the channel syncable
scienceChannelGroupSyncable.AutoAdd = true
scienceChannelGroupSyncable, err = th.App.UpdateGroupSyncable(scienceChannelGroupSyncable)
if err != nil {
t.Errorf("error updating group syncable: %s", err.Error())
}
// Sync everything after syncable was created (proving that channel updates trigger re-sync)
pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: scientistGroupMember.CreateAt + 1, ReAddRemovedMembers: false})
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
expected = 1
cMembersCount, err = th.App.GetChannelMemberCount(th.Context, experimentsChannel.Id)
if err != nil {
t.Errorf("error retrieving team members: %s", err.Error())
}
if cMembersCount != int64(expected) {
t.Errorf("expected %d team members but got %d", expected, cMembersCount)
}
// singer leaves team and channel
err = th.App.LeaveChannel(th.Context, practiceChannel.Id, singer1.Id)
if err != nil {
t.Errorf("error leaving channel: %s", err.Error())
}
err = th.App.LeaveTeam(th.Context, singersTeam, singer1, "")
if err != nil {
t.Errorf("error leaving team: %s", err.Error())
}
// Even re-syncing from the beginning doesn't re-add to channel or team
pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false})
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
// Singer should not be in team or channel
tMember, err := th.App.GetTeamMember(th.Context, singersTeam.Id, singer1.Id)
if err != nil {
t.Errorf("error retrieving team member: %s", err.Error())
}
if tMember.DeleteAt == 0 {
t.Error("expected team member to remain deleted")
}
_, err = th.App.GetChannelMember(th.Context, practiceChannel.Id, singer1.Id)
if err == nil {
t.Error("Expected channel member to remain deleted")
}
// Ensure members are in channel
_, err = th.App.AddChannelMember(th.Context, scientist1.Id, experimentsChannel, ChannelMemberOpts{})
if err != nil {
t.Errorf("unable to add user to channel: %s", err.Error())
}
// Add other user so that user can leave channel
_, err = th.App.AddTeamMember(th.Context, singersTeam.Id, singer1.Id)
if err != nil {
t.Errorf("unable to add user to team: %s", err.Error())
}
_, err = th.App.AddChannelMember(th.Context, singer1.Id, experimentsChannel, ChannelMemberOpts{})
if err != nil {
t.Errorf("unable to add user to channel: %s", err.Error())
}
// the channel syncable is updated
scienceChannelGroupSyncable, err = th.App.UpdateGroupSyncable(scienceChannelGroupSyncable)
if err != nil {
t.Errorf("error updating group syncable: %s", err.Error())
}
pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false})
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
timeBeforeLeaving := model.GetMillis()
// User leaves channel
err = th.App.LeaveChannel(th.Context, experimentsChannel.Id, scientist1.Id)
if err != nil {
t.Errorf("unable to add user to channel: %s", err.Error())
}
timeAfterLeaving := model.GetMillis() + 1
retentionPolicyBatchConfigs := model.RetentionPolicyBatchConfigs{
Now: 0,
GlobalPolicyEndTime: timeBeforeLeaving,
Limit: 1000,
}
// Purging channelmemberhistory doesn't re-add user to channel
deletedCount, _, nErr := th.App.Srv().Store().ChannelMemberHistory().PermanentDeleteBatchForRetentionPolicies(
retentionPolicyBatchConfigs, model.RetentionPolicyCursor{})
if nErr != nil {
t.Errorf("error permanently deleting channelmemberhistory: %s", nErr.Error())
}
require.Equal(t, int64(1), deletedCount)
pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: scienceChannelGroupSyncable.UpdateAt, ReAddRemovedMembers: false})
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
_, err = th.App.GetChannelMember(th.Context, experimentsChannel.Id, scientist1.Id)
if err == nil {
t.Error("Expected channel member to remain deleted")
}
retentionPolicyBatchConfigs = model.RetentionPolicyBatchConfigs{
Now: 0,
GlobalPolicyEndTime: timeAfterLeaving,
Limit: 1000,
}
// Purging channelmemberhistory doesn't re-add user to channel
deletedCount, _, nErr = th.App.Srv().Store().ChannelMemberHistory().PermanentDeleteBatchForRetentionPolicies(
retentionPolicyBatchConfigs, model.RetentionPolicyCursor{})
if nErr != nil {
t.Errorf("error permanently deleting channelmemberhistory: %s", nErr.Error())
}
require.Equal(t, int64(1), deletedCount)
pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: scienceChannelGroupSyncable.UpdateAt, ReAddRemovedMembers: false})
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
// Channel member is re-added.
_, err = th.App.GetChannelMember(th.Context, experimentsChannel.Id, scientist1.Id)
if err != nil {
t.Errorf("expected channel member: %s", err.Error())
}
t.Run("Team with restricted domains skips over members that do not match the allowed domains", func(t *testing.T) {
restrictedUser := th.CreateUser()
restrictedUser.Email = "restricted@mattermost.org"
_, err = th.App.UpdateUser(th.Context, restrictedUser, false)
require.Nil(t, err)
_, err = th.App.UpsertGroupMember(scienceGroup.Id, restrictedUser.Id)
require.Nil(t, err)
restrictedTeam, err := th.App.CreateTeam(th.Context, &model.Team{
DisplayName: "Restricted",
Name: "restricted" + model.NewId(),
Email: "restricted@mattermost.org",
AllowedDomains: "mattermost.org",
Type: model.TeamOpen,
})
require.Nil(t, err)
_, err = th.App.UpsertGroupSyncable(model.NewGroupTeam(scienceGroup.Id, restrictedTeam.Id, true))
require.Nil(t, err)
restrictedChannel, err := th.App.CreateChannel(th.Context, &model.Channel{
TeamId: restrictedTeam.Id,
DisplayName: "Restricted",
Name: "restricted" + model.NewId(),
Type: model.ChannelTypeOpen,
}, false)
require.Nil(t, err)
_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(scienceGroup.Id, restrictedChannel.Id, true))
require.Nil(t, err)
pErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false})
require.NoError(t, pErr)
// Ensure only the restricted user was added to both the team and channel
cMembersCount, err = th.App.GetChannelMemberCount(th.Context, restrictedChannel.Id)
require.Nil(t, err)
require.Equal(t, cMembersCount, int64(1))
tmembers, err := th.App.GetTeamMembers(restrictedTeam.Id, 0, 100, nil)
require.Nil(t, err)
require.Len(t, tmembers, 1)
require.Equal(t, tmembers[0].UserId, restrictedUser.Id)
})
t.Run("scoped to a single user", func(t *testing.T) {
team1, err := th.App.CreateTeam(th.Context, &model.Team{
DisplayName: "Team 1",
Name: "zz" + model.NewId(),
Email: "team1admin@test.com",
Type: model.TeamOpen,
})
if err != nil {
t.Errorf("test team not created: %s", err.Error())
}
team1Channel1, err := th.App.CreateChannel(th.Context, &model.Channel{
TeamId: team1.Id,
DisplayName: "Team 1 Channel 1",
Name: model.NewId(),
Type: model.ChannelTypeOpen,
}, false)
if err != nil {
t.Errorf("test channel not created: %s", err.Error())
}
group1, err := th.App.CreateGroup(&model.Group{
Name: model.NewPointer(model.NewId()),
DisplayName: "Group 1",
RemoteId: model.NewPointer(model.NewId()),
Source: model.GroupSourceLdap,
})
if err != nil {
t.Errorf("test group not created: %s", err.Error())
}
_, err = th.App.UpsertGroupSyncable(model.NewGroupTeam(group1.Id, team1.Id, true))
if err != nil {
t.Errorf("test groupchannel not created: %s", err.Error())
}
_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(group1.Id, team1Channel1.Id, true))
if err != nil {
t.Errorf("test groupchannel not created: %s", err.Error())
}
user1 := th.BasicUser
user2 := th.BasicUser2
_, err = th.App.UpsertGroupMember(group1.Id, user1.Id)
if err != nil {
t.Errorf("test groupmember not created: %s", err.Error())
}
_, err = th.App.UpsertGroupMember(group1.Id, user2.Id)
if err != nil {
t.Errorf("test groupmember not created: %s", err.Error())
}
params := model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false, ScopedUserID: &user1.Id}
pErr = th.App.CreateDefaultMemberships(th.Context, params)
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
// test that only user 1 is successfully added to the team and channel.
team1Members, err := th.App.GetTeamMembers(team1.Id, 0, 100, nil)
if err != nil {
t.Errorf("failed to get team members: %s", err.Error())
}
if len(team1Members) != 1 {
t.Errorf("expected 1 team member on team1, got %d", len(team1Members))
}
if team1Members[0].UserId != user1.Id {
t.Errorf("expected user1 to be a team member on team1, got %s", team1Members[0].UserId)
}
team1Channel1Members, err := th.App.GetChannelMembersPage(th.Context, team1Channel1.Id, 0, 100)
if err != nil {
t.Errorf("failed to get channel members: %s", err.Error())
}
if len(team1Channel1Members) != 1 {
t.Errorf("expected 1 channel member on team1Channel1, got %d", len(team1Channel1Members))
}
if team1Channel1Members[0].UserId != user1.Id {
t.Errorf("expected user1 to be a channel member on team1Channel1, got %s", team1Channel1Members[0].UserId)
}
// unscoped should add user2 to the team and channel
params = model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false}
pErr = th.App.CreateDefaultMemberships(th.Context, params)
if pErr != nil {
t.Errorf("failed to populate syncables: %s", pErr.Error())
}
team1Members, err = th.App.GetTeamMembers(team1.Id, 0, 100, nil)
if err != nil {
t.Errorf("failed to get team members: %s", err.Error())
}
if len(team1Members) != 2 {
t.Errorf("expected 2 team member on team1, got %d", len(team1Members))
}
team1Channel1Members, err = th.App.GetChannelMembersPage(th.Context, team1Channel1.Id, 0, 100)
if err != nil {
t.Errorf("failed to get channel members: %s", err.Error())
}
if len(team1Channel1Members) != 2 {
t.Errorf("expected 2 channel member on team1Channel1, got %d", len(team1Channel1Members))
}
})
t.Run("error should contain a information about all users that failed", func(t *testing.T) {
user1 := th.CreateUser()
_, err = th.App.UpsertGroupMember(scienceGroup.Id, user1.Id)
require.Nil(t, err)
user2 := th.CreateUser()
_, err = th.App.UpsertGroupMember(scienceGroup.Id, user2.Id)
require.Nil(t, err)
store := &mockStore{
Store: th.App.Srv().Store(),
us: &mokeUserStore{
UserStore: th.App.Srv().Store().User(),
},
}
require.Nil(t, err)
th.App.Srv().platform.Store = store
nErr = th.App.CreateDefaultMemberships(th.Context, model.CreateDefaultMembershipParams{Since: 0, ReAddRemovedMembers: false})
require.Error(t, nErr)
assert.ErrorContains(t, nErr, "failed to add team member for default team membership")
assert.ErrorContains(t, nErr, user1.Id)
assert.ErrorContains(t, nErr, user2.Id)
})
}
type mockStore struct {
store.Store
us store.UserStore
}
func (fk *mockStore) User() store.UserStore { return fk.us }
type mokeUserStore struct {
store.UserStore
}
func (us *mokeUserStore) Get(_ context.Context, id string) (*model.User, error) {
return nil, fmt.Errorf("some error for %s", id)
}
func TestDeleteGroupMemberships(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic()
defer th.TearDown()
group := th.CreateGroup()
userIDs := []string{th.BasicUser.Id, th.BasicUser2.Id, th.SystemAdminUser.Id}
var err *model.AppError
// add users to teams and channels
for _, userID := range userIDs {
_, err = th.App.AddTeamMember(th.Context, th.BasicTeam.Id, userID)
require.Nil(t, err)
_, err = th.App.AddChannelMember(th.Context, userID, th.BasicChannel, ChannelMemberOpts{})
require.Nil(t, err)
}
// make team group-constrained
team := th.BasicTeam
team.GroupConstrained = model.NewPointer(true)
team, err = th.App.UpdateTeam(team)
require.Nil(t, err)
require.True(t, *team.GroupConstrained)
// make channel group-constrained
channel := th.BasicChannel
channel.GroupConstrained = model.NewPointer(true)
channel, err = th.App.UpdateChannel(th.Context, channel)
require.Nil(t, err)
require.True(t, *channel.GroupConstrained)
// create groupteam and groupchannel
_, err = th.App.UpsertGroupSyncable(model.NewGroupTeam(group.Id, team.Id, true))
require.Nil(t, err)
_, err = th.App.UpsertGroupSyncable(model.NewGroupChannel(group.Id, channel.Id, true))
require.Nil(t, err)
// verify the member count
tmembers, err := th.App.GetTeamMembers(th.BasicTeam.Id, 0, 100, nil)
require.Nil(t, err)
require.Len(t, tmembers, 3)
cmemberCount, err := th.App.GetChannelMemberCount(th.Context, th.BasicChannel.Id)
require.Nil(t, err)
require.Equal(t, 3, int(cmemberCount))
// add a user to the group
_, err = th.App.UpsertGroupMember(group.Id, th.SystemAdminUser.Id)
require.Nil(t, err)
// run the delete
appErr := th.App.DeleteGroupConstrainedMemberships(th.Context)
require.NoError(t, appErr)
// verify the new member counts
tmembers, err = th.App.GetTeamMembers(th.BasicTeam.Id, 0, 100, nil)
require.Nil(t, err)
require.Len(t, tmembers, 1)
require.Equal(t, th.SystemAdminUser.Id, tmembers[0].UserId)
cmembers, err := th.App.GetChannelMembersPage(th.Context, channel.Id, 0, 99)
require.Nil(t, err)
require.Len(t, cmembers, 1)
require.Equal(t, th.SystemAdminUser.Id, cmembers[0].UserId)
}
func TestSyncSyncableRoles(t *testing.T) {
mainHelper.Parallel(t)
th := Setup(t).InitBasic()
defer th.TearDown()
team := th.CreateTeam()
channel := th.CreateChannel(th.Context, team)
channel.GroupConstrained = model.NewPointer(true)
channel, err := th.App.UpdateChannel(th.Context, channel)
require.Nil(t, err)
user1 := th.CreateUser()
user2 := th.CreateUser()
group := th.CreateGroup()
teamSyncable, err := th.App.UpsertGroupSyncable(&model.GroupSyncable{
SyncableId: team.Id,
Type: model.GroupSyncableTypeTeam,
GroupId: group.Id,
})
require.Nil(t, err)
channelSyncable, err := th.App.UpsertGroupSyncable(&model.GroupSyncable{
SyncableId: channel.Id,
Type: model.GroupSyncableTypeChannel,
GroupId: group.Id,
})
require.Nil(t, err)
for _, user := range []*model.User{user1, user2} {
_, err = th.App.UpsertGroupMember(group.Id, user.Id)
require.Nil(t, err)
var tm *model.TeamMember
tm, err = th.App.AddTeamMember(th.Context, team.Id, user.Id)
require.Nil(t, err)
require.False(t, tm.SchemeAdmin)
cm := th.AddUserToChannel(user, channel)
require.False(t, cm.SchemeAdmin)
}
teamSyncable.SchemeAdmin = true
_, err = th.App.UpdateGroupSyncable(teamSyncable)
require.Nil(t, err)
channelSyncable.SchemeAdmin = true
_, err = th.App.UpdateGroupSyncable(channelSyncable)
require.Nil(t, err)
err = th.App.SyncSyncableRoles(th.Context, channel.Id, model.GroupSyncableTypeChannel)
require.Nil(t, err)
err = th.App.SyncSyncableRoles(th.Context, team.Id, model.GroupSyncableTypeTeam)
require.Nil(t, err)
for _, user := range []*model.User{user1, user2} {
tm, err := th.App.GetTeamMember(th.Context, team.Id, user.Id)
require.Nil(t, err)
require.True(t, tm.SchemeAdmin)
cm, err := th.App.GetChannelMember(th.Context, channel.Id, user.Id)
require.Nil(t, err)
require.True(t, cm.SchemeAdmin)
}
}