Team/Channel members bulk save/update/delete (#14053)
* Members Save Multiple * Multiple Channel Members implemented * Working version with member multi save and multi update * Adding tests to the save multiple team members store methods * Tests passing for SaveMember * Adding remove members tests * Working on channel store tests * More work on testing properly SaveMember and SaveMultipleMembers on channels * More work on testing properly SaveMember and SaveMultipleMembers on teams * Adding tests for update multiple members for team * Adding tests for update multiple members for channel * Fixing some tets * Fixing tests * Fixing tests * Fixing i18n * Addressing govet problems * Addressing govet problems * Addressing govet problems * Addressing govet problems * Addressing PR comments (and removing TODO) * Addressing PR comments * Fixed broken test * Removing unnecesary i18n translation string
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
d2848cc167
Коммит
cfe65a33a5
@@ -454,6 +454,11 @@ func (me *TestHelper) AddUserToChannel(user *model.User, channel *model.Channel)
|
||||
return member
|
||||
}
|
||||
|
||||
func (me *TestHelper) CreateRole(roleName string) *model.Role {
|
||||
role, _ := me.App.CreateRole(&model.Role{Name: roleName, DisplayName: roleName, Description: roleName, Permissions: []string{}})
|
||||
return role
|
||||
}
|
||||
|
||||
func (me *TestHelper) CreateScheme() (*model.Scheme, []*model.Role) {
|
||||
utils.DisableDebugLogForTest()
|
||||
|
||||
|
||||
@@ -649,16 +649,39 @@ func (a *App) importUserTeams(user *model.User, data *[]UserTeamImportData) *mod
|
||||
return nil
|
||||
}
|
||||
|
||||
var teamThemePreferences model.Preferences
|
||||
teamNames := []string{}
|
||||
for _, tdata := range *data {
|
||||
team, err := a.GetTeamByName(*tdata.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
teamNames = append(teamNames, *tdata.Name)
|
||||
}
|
||||
allTeams, err := a.getTeamsByNames(teamNames)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
teamThemePreferencesByID := map[string]model.Preferences{}
|
||||
channels := map[string][]UserChannelImportData{}
|
||||
teamsByID := map[string]*model.Team{}
|
||||
teamMemberByTeamID := map[string]*model.TeamMember{}
|
||||
newTeamMembers := []*model.TeamMember{}
|
||||
oldTeamMembers := []*model.TeamMember{}
|
||||
rolesByTeamId := map[string]string{}
|
||||
isGuestByTeamId := map[string]bool{}
|
||||
isUserByTeamId := map[string]bool{}
|
||||
isAdminByTeamId := map[string]bool{}
|
||||
existingMemberships, err := a.Srv().Store.Team().GetTeamsForUser(user.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
existingMembershipsByTeamId := map[string]*model.TeamMember{}
|
||||
for _, teamMembership := range existingMemberships {
|
||||
existingMembershipsByTeamId[teamMembership.TeamId] = teamMembership
|
||||
}
|
||||
for _, tdata := range *data {
|
||||
team := allTeams[*tdata.Name]
|
||||
|
||||
// Team-specific theme Preferences.
|
||||
if tdata.Theme != nil {
|
||||
teamThemePreferences = append(teamThemePreferences, model.Preference{
|
||||
teamThemePreferencesByID[team.Id] = append(teamThemePreferencesByID[team.Id], model.Preference{
|
||||
UserId: user.Id,
|
||||
Category: model.PREFERENCE_CATEGORY_THEME,
|
||||
Name: team.Id,
|
||||
@@ -666,63 +689,95 @@ func (a *App) importUserTeams(user *model.User, data *[]UserTeamImportData) *mod
|
||||
})
|
||||
}
|
||||
|
||||
var roles string
|
||||
isSchemeGuest := false
|
||||
isSchemeUser := true
|
||||
isSchemeAdmin := false
|
||||
isGuestByTeamId[team.Id] = false
|
||||
isUserByTeamId[team.Id] = true
|
||||
isAdminByTeamId[team.Id] = false
|
||||
|
||||
if tdata.Roles == nil {
|
||||
isSchemeUser = true
|
||||
isUserByTeamId[team.Id] = true
|
||||
} else {
|
||||
rawRoles := *tdata.Roles
|
||||
explicitRoles := []string{}
|
||||
for _, role := range strings.Fields(rawRoles) {
|
||||
if role == model.TEAM_GUEST_ROLE_ID {
|
||||
isSchemeGuest = true
|
||||
isSchemeUser = false
|
||||
isGuestByTeamId[team.Id] = true
|
||||
isUserByTeamId[team.Id] = false
|
||||
} else if role == model.TEAM_USER_ROLE_ID {
|
||||
isSchemeUser = true
|
||||
isUserByTeamId[team.Id] = true
|
||||
} else if role == model.TEAM_ADMIN_ROLE_ID {
|
||||
isSchemeAdmin = true
|
||||
isAdminByTeamId[team.Id] = true
|
||||
} else {
|
||||
explicitRoles = append(explicitRoles, role)
|
||||
}
|
||||
}
|
||||
roles = strings.Join(explicitRoles, " ")
|
||||
rolesByTeamId[team.Id] = strings.Join(explicitRoles, " ")
|
||||
}
|
||||
|
||||
var member *model.TeamMember
|
||||
if member, _, err = a.joinUserToTeam(team, user); err != nil {
|
||||
return err
|
||||
member := &model.TeamMember{
|
||||
TeamId: team.Id,
|
||||
UserId: user.Id,
|
||||
SchemeGuest: user.IsGuest(),
|
||||
SchemeUser: !user.IsGuest(),
|
||||
SchemeAdmin: team.Email == user.Email && !user.IsGuest(),
|
||||
}
|
||||
|
||||
if member.ExplicitRoles != roles {
|
||||
if _, err = a.UpdateTeamMemberRoles(team.Id, user.Id, roles); err != nil {
|
||||
if !user.IsGuest() {
|
||||
var userShouldBeAdmin bool
|
||||
userShouldBeAdmin, err = a.UserIsInAdminRoleGroup(user.Id, team.Id, model.GroupSyncableTypeTeam)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
member.SchemeAdmin = userShouldBeAdmin
|
||||
}
|
||||
|
||||
if member.SchemeAdmin != isSchemeAdmin || member.SchemeUser != isSchemeUser || member.SchemeGuest != isSchemeGuest {
|
||||
a.UpdateTeamMemberSchemeRoles(team.Id, user.Id, isSchemeGuest, isSchemeUser, isSchemeAdmin)
|
||||
if tdata.Channels != nil {
|
||||
channels[team.Id] = append(channels[team.Id], *tdata.Channels...)
|
||||
}
|
||||
if !user.IsGuest() {
|
||||
channels[team.Id] = append(channels[team.Id], UserChannelImportData{Name: model.NewString(model.DEFAULT_CHANNEL)})
|
||||
}
|
||||
|
||||
defaultChannel, err := a.GetChannelByName(model.DEFAULT_CHANNEL, team.Id, true)
|
||||
teamsByID[team.Id] = team
|
||||
teamMemberByTeamID[team.Id] = member
|
||||
if _, ok := existingMembershipsByTeamId[team.Id]; !ok {
|
||||
newTeamMembers = append(newTeamMembers, member)
|
||||
} else {
|
||||
oldTeamMembers = append(oldTeamMembers, member)
|
||||
}
|
||||
}
|
||||
|
||||
oldMembers, err := a.Srv().Store.Team().UpdateMultipleMembers(oldTeamMembers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newMembers := []*model.TeamMember{}
|
||||
if len(newTeamMembers) > 0 {
|
||||
newMembers, err = a.Srv().Store.Team().SaveMultipleMembers(newTeamMembers, *a.Config().TeamSettings.MaxUsersPerTeam)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = a.addUserToChannel(user, defaultChannel, member); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := a.importUserChannels(user, team, member, tdata.Channels); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(teamThemePreferences) > 0 {
|
||||
if err := a.Srv().Store.Preference().Save(&teamThemePreferences); err != nil {
|
||||
return model.NewAppError("BulkImport", "app.import.import_user_teams.save_preferences.error", nil, err.Error(), http.StatusInternalServerError)
|
||||
for _, member := range append(newMembers, oldMembers...) {
|
||||
if member.ExplicitRoles != rolesByTeamId[member.TeamId] {
|
||||
if _, err = a.UpdateTeamMemberRoles(member.TeamId, user.Id, rolesByTeamId[member.TeamId]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
a.UpdateTeamMemberSchemeRoles(member.TeamId, user.Id, isGuestByTeamId[member.TeamId], isUserByTeamId[member.TeamId], isAdminByTeamId[member.TeamId])
|
||||
}
|
||||
|
||||
for _, team := range allTeams {
|
||||
if len(teamThemePreferencesByID[team.Id]) > 0 {
|
||||
pref := teamThemePreferencesByID[team.Id]
|
||||
if err := a.Srv().Store.Preference().Save(&pref); err != nil {
|
||||
return model.NewAppError("BulkImport", "app.import.import_user_teams.save_preferences.error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
channelsToImport := channels[team.Id]
|
||||
if err := a.importUserChannels(user, team, teamMemberByTeamID[team.Id], &channelsToImport); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -734,92 +789,144 @@ func (a *App) importUserChannels(user *model.User, team *model.Team, teamMember
|
||||
return nil
|
||||
}
|
||||
|
||||
var preferences model.Preferences
|
||||
channelNames := []string{}
|
||||
for _, tdata := range *data {
|
||||
channelNames = append(channelNames, *tdata.Name)
|
||||
}
|
||||
allChannels, err := a.getChannelsByNames(channelNames, team.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Loop through all channels.
|
||||
channelsByID := map[string]*model.Channel{}
|
||||
channelMemberByChannelID := map[string]*model.ChannelMember{}
|
||||
newChannelMembers := []*model.ChannelMember{}
|
||||
oldChannelMembers := []*model.ChannelMember{}
|
||||
rolesByChannelId := map[string]string{}
|
||||
channelPreferencesByID := map[string]model.Preferences{}
|
||||
isGuestByChannelId := map[string]bool{}
|
||||
isUserByChannelId := map[string]bool{}
|
||||
isAdminByChannelId := map[string]bool{}
|
||||
existingMemberships, err := a.Srv().Store.Channel().GetMembersForUser(team.Id, user.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
existingMembershipsByChannelId := map[string]model.ChannelMember{}
|
||||
for _, channelMembership := range *existingMemberships {
|
||||
existingMembershipsByChannelId[channelMembership.ChannelId] = channelMembership
|
||||
}
|
||||
for _, cdata := range *data {
|
||||
channel, err := a.GetChannelByName(*cdata.Name, team.Id, true)
|
||||
if err != nil {
|
||||
return err
|
||||
channel, ok := allChannels[*cdata.Name]
|
||||
if !ok {
|
||||
return model.NewAppError("BulkImport", "app.import.import_user_channels.channel_not_found.error", nil, "", http.StatusInternalServerError)
|
||||
}
|
||||
if _, ok = channelsByID[channel.Id]; ok && *cdata.Name == model.DEFAULT_CHANNEL {
|
||||
// town-square membership was in the import and added by the importer (skip the added by the importer)
|
||||
continue
|
||||
}
|
||||
|
||||
var roles string
|
||||
isSchemeGuest := false
|
||||
isSchemeUser := true
|
||||
isSchemeAdmin := false
|
||||
isGuestByChannelId[channel.Id] = false
|
||||
isUserByChannelId[channel.Id] = true
|
||||
isAdminByChannelId[channel.Id] = false
|
||||
|
||||
if cdata.Roles == nil {
|
||||
isSchemeUser = true
|
||||
isUserByChannelId[channel.Id] = true
|
||||
} else {
|
||||
rawRoles := *cdata.Roles
|
||||
explicitRoles := []string{}
|
||||
for _, role := range strings.Fields(rawRoles) {
|
||||
if role == model.CHANNEL_GUEST_ROLE_ID {
|
||||
isSchemeGuest = true
|
||||
isSchemeUser = false
|
||||
isGuestByChannelId[channel.Id] = true
|
||||
isUserByChannelId[channel.Id] = false
|
||||
} else if role == model.CHANNEL_USER_ROLE_ID {
|
||||
isSchemeUser = true
|
||||
isUserByChannelId[channel.Id] = true
|
||||
} else if role == model.CHANNEL_ADMIN_ROLE_ID {
|
||||
isSchemeAdmin = true
|
||||
isAdminByChannelId[channel.Id] = true
|
||||
} else {
|
||||
explicitRoles = append(explicitRoles, role)
|
||||
}
|
||||
}
|
||||
roles = strings.Join(explicitRoles, " ")
|
||||
}
|
||||
|
||||
var member *model.ChannelMember
|
||||
member, err = a.GetChannelMember(channel.Id, user.Id)
|
||||
if err != nil {
|
||||
member, err = a.addUserToChannel(user, channel, teamMember)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if member.ExplicitRoles != roles {
|
||||
if _, err := a.UpdateChannelMemberRoles(channel.Id, user.Id, roles); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if member.SchemeAdmin != isSchemeAdmin || member.SchemeUser != isSchemeUser || member.SchemeGuest != isSchemeGuest {
|
||||
a.UpdateChannelMemberSchemeRoles(channel.Id, user.Id, isSchemeGuest, isSchemeUser, isSchemeAdmin)
|
||||
}
|
||||
|
||||
if cdata.NotifyProps != nil {
|
||||
notifyProps := member.NotifyProps
|
||||
|
||||
if cdata.NotifyProps.Desktop != nil {
|
||||
notifyProps[model.DESKTOP_NOTIFY_PROP] = *cdata.NotifyProps.Desktop
|
||||
}
|
||||
|
||||
if cdata.NotifyProps.Mobile != nil {
|
||||
notifyProps[model.PUSH_NOTIFY_PROP] = *cdata.NotifyProps.Mobile
|
||||
}
|
||||
|
||||
if cdata.NotifyProps.MarkUnread != nil {
|
||||
notifyProps[model.MARK_UNREAD_NOTIFY_PROP] = *cdata.NotifyProps.MarkUnread
|
||||
}
|
||||
|
||||
if _, err := a.UpdateChannelMemberNotifyProps(notifyProps, channel.Id, user.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
rolesByChannelId[channel.Id] = strings.Join(explicitRoles, " ")
|
||||
}
|
||||
|
||||
if cdata.Favorite != nil && *cdata.Favorite {
|
||||
preferences = append(preferences, model.Preference{
|
||||
channelPreferencesByID[channel.Id] = append(channelPreferencesByID[channel.Id], model.Preference{
|
||||
UserId: user.Id,
|
||||
Category: model.PREFERENCE_CATEGORY_FAVORITE_CHANNEL,
|
||||
Name: channel.Id,
|
||||
Value: "true",
|
||||
})
|
||||
}
|
||||
|
||||
member := &model.ChannelMember{
|
||||
ChannelId: channel.Id,
|
||||
UserId: user.Id,
|
||||
NotifyProps: model.GetDefaultChannelNotifyProps(),
|
||||
SchemeGuest: user.IsGuest(),
|
||||
SchemeUser: !user.IsGuest(),
|
||||
SchemeAdmin: false,
|
||||
}
|
||||
if !user.IsGuest() {
|
||||
var userShouldBeAdmin bool
|
||||
userShouldBeAdmin, err = a.UserIsInAdminRoleGroup(user.Id, team.Id, model.GroupSyncableTypeTeam)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
member.SchemeAdmin = userShouldBeAdmin
|
||||
}
|
||||
|
||||
if cdata.NotifyProps != nil {
|
||||
if cdata.NotifyProps.Desktop != nil {
|
||||
member.NotifyProps[model.DESKTOP_NOTIFY_PROP] = *cdata.NotifyProps.Desktop
|
||||
}
|
||||
|
||||
if cdata.NotifyProps.Mobile != nil {
|
||||
member.NotifyProps[model.PUSH_NOTIFY_PROP] = *cdata.NotifyProps.Mobile
|
||||
}
|
||||
|
||||
if cdata.NotifyProps.MarkUnread != nil {
|
||||
member.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] = *cdata.NotifyProps.MarkUnread
|
||||
}
|
||||
}
|
||||
|
||||
channelsByID[channel.Id] = channel
|
||||
channelMemberByChannelID[channel.Id] = member
|
||||
if _, ok := existingMembershipsByChannelId[channel.Id]; !ok {
|
||||
newChannelMembers = append(newChannelMembers, member)
|
||||
} else {
|
||||
oldChannelMembers = append(oldChannelMembers, member)
|
||||
}
|
||||
}
|
||||
|
||||
if len(preferences) > 0 {
|
||||
if err := a.Srv().Store.Preference().Save(&preferences); err != nil {
|
||||
return model.NewAppError("BulkImport", "app.import.import_user_channels.save_preferences.error", nil, err.Error(), http.StatusInternalServerError)
|
||||
oldMembers, err := a.Srv().Store.Channel().UpdateMultipleMembers(oldChannelMembers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newMembers := []*model.ChannelMember{}
|
||||
if len(newChannelMembers) > 0 {
|
||||
newMembers, err = a.Srv().Store.Channel().SaveMultipleMembers(newChannelMembers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, member := range append(newMembers, oldMembers...) {
|
||||
if member.ExplicitRoles != rolesByChannelId[member.ChannelId] {
|
||||
if _, err = a.UpdateChannelMemberRoles(member.ChannelId, user.Id, rolesByChannelId[member.ChannelId]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
a.UpdateChannelMemberSchemeRoles(member.ChannelId, user.Id, isGuestByChannelId[member.ChannelId], isUserByChannelId[member.ChannelId], isAdminByChannelId[member.ChannelId])
|
||||
}
|
||||
|
||||
for _, channel := range allChannels {
|
||||
if len(channelPreferencesByID[channel.Id]) > 0 {
|
||||
pref := channelPreferencesByID[channel.Id]
|
||||
if err := a.Srv().Store.Preference().Save(&pref); err != nil {
|
||||
return model.NewAppError("BulkImport", "app.import.import_user_channels.save_preferences.error", nil, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1022,6 +1129,19 @@ func (a *App) getTeamsByNames(names []string) (map[string]*model.Team, *model.Ap
|
||||
return teams, nil
|
||||
}
|
||||
|
||||
func (a *App) getChannelsByNames(names []string, teamId string) (map[string]*model.Channel, *model.AppError) {
|
||||
allChannels, err := a.Srv().Store.Channel().GetByNames(teamId, names, true)
|
||||
if err != nil {
|
||||
return nil, model.NewAppError("BulkImport", "app.import.get_teams_by_names.some_teams_not_found.error", nil, err.Error(), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
channels := make(map[string]*model.Channel)
|
||||
for _, channel := range allChannels {
|
||||
channels[channel.Name] = channel
|
||||
}
|
||||
return channels, nil
|
||||
}
|
||||
|
||||
func (a *App) getChannelsForPosts(teams map[string]*model.Team, data []*PostImportData) (map[string]*model.Channel, *model.AppError) {
|
||||
channels := make(map[string]*model.Channel)
|
||||
for _, postData := range data {
|
||||
|
||||
@@ -1526,6 +1526,363 @@ func TestImportImportUser(t *testing.T) {
|
||||
assert.Equal(t, "", channelMember.ExplicitRoles)
|
||||
}
|
||||
|
||||
func TestImportUserTeams(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
team2 := th.CreateTeam()
|
||||
channel2 := th.CreateChannel(th.BasicTeam)
|
||||
channel3 := th.CreateChannel(team2)
|
||||
customRole := th.CreateRole("test_custom_role")
|
||||
sampleTheme := "{\"test\":\"#abcdef\"}"
|
||||
|
||||
tt := []struct {
|
||||
name string
|
||||
data *[]UserTeamImportData
|
||||
expectedError bool
|
||||
expectedUserTeams int
|
||||
expectedUserChannels int
|
||||
expectedExplicitRoles string
|
||||
expectedRoles string
|
||||
expectedTheme string
|
||||
}{
|
||||
{
|
||||
name: "Not existing team should fail",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: model.NewString("not-existing-team-name"),
|
||||
},
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "nil data shouldn't do anything",
|
||||
expectedError: false,
|
||||
expectedUserTeams: 0,
|
||||
expectedUserChannels: 0,
|
||||
},
|
||||
{
|
||||
name: "Should fail if one of the roles doesn't exists",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
Roles: model.NewString("not-existing-role"),
|
||||
},
|
||||
},
|
||||
expectedError: true,
|
||||
expectedUserTeams: 1,
|
||||
expectedUserChannels: 0,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "team_user",
|
||||
},
|
||||
{
|
||||
name: "Should success to import explicit role",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
Roles: &customRole.Name,
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserTeams: 1,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: customRole.Name,
|
||||
expectedRoles: customRole.Name + " team_user",
|
||||
},
|
||||
{
|
||||
name: "Should success to import admin role",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
Roles: model.NewString(model.TEAM_ADMIN_ROLE_ID),
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserTeams: 1,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "team_user team_admin",
|
||||
},
|
||||
{
|
||||
name: "Should success to import with theme",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
Theme: &sampleTheme,
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserTeams: 1,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "team_user",
|
||||
expectedTheme: sampleTheme,
|
||||
},
|
||||
{
|
||||
name: "Team without channels must add the default channel",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserTeams: 1,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "team_user",
|
||||
},
|
||||
{
|
||||
name: "Team with default channel must add only the default channel",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
Channels: &[]UserChannelImportData{
|
||||
{
|
||||
Name: ptrStr(model.DEFAULT_CHANNEL),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserTeams: 1,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "team_user",
|
||||
},
|
||||
{
|
||||
name: "Team with non default channel must add default channel and the other channel",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
Channels: &[]UserChannelImportData{
|
||||
{
|
||||
Name: &th.BasicChannel.Name,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserTeams: 1,
|
||||
expectedUserChannels: 2,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "team_user",
|
||||
},
|
||||
{
|
||||
name: "Multiple teams with multiple channels each",
|
||||
data: &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
Channels: &[]UserChannelImportData{
|
||||
{
|
||||
Name: &th.BasicChannel.Name,
|
||||
},
|
||||
{
|
||||
Name: &channel2.Name,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: &team2.Name,
|
||||
Channels: &[]UserChannelImportData{
|
||||
{
|
||||
Name: &channel3.Name,
|
||||
},
|
||||
{
|
||||
Name: model.NewString("town-square"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserTeams: 2,
|
||||
expectedUserChannels: 5,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
user := th.CreateUser()
|
||||
|
||||
// Two times import must end with the same results
|
||||
for x := 0; x < 2; x++ {
|
||||
err := th.App.importUserTeams(user, tc.data)
|
||||
if tc.expectedError {
|
||||
require.NotNil(t, err)
|
||||
} else {
|
||||
require.Nil(t, err)
|
||||
}
|
||||
teamMembers, err := th.App.Srv().Store.Team().GetTeamsForUser(user.Id)
|
||||
require.Nil(t, err)
|
||||
require.Len(t, teamMembers, tc.expectedUserTeams)
|
||||
if tc.expectedUserTeams == 1 {
|
||||
require.Equal(t, tc.expectedExplicitRoles, teamMembers[0].ExplicitRoles, "Not matching expected explicit roles")
|
||||
require.Equal(t, tc.expectedRoles, teamMembers[0].Roles, "not matching expected roles")
|
||||
if tc.expectedTheme != "" {
|
||||
pref, prefErr := th.App.Srv().Store.Preference().Get(user.Id, model.PREFERENCE_CATEGORY_THEME, teamMembers[0].TeamId)
|
||||
require.Nil(t, prefErr)
|
||||
require.Equal(t, tc.expectedTheme, pref.Value)
|
||||
}
|
||||
}
|
||||
|
||||
totalMembers := 0
|
||||
for _, teamMember := range teamMembers {
|
||||
channelMembers, err := th.App.Srv().Store.Channel().GetMembersForUser(teamMember.TeamId, user.Id)
|
||||
require.Nil(t, err)
|
||||
totalMembers += len(*channelMembers)
|
||||
}
|
||||
require.Equal(t, tc.expectedUserChannels, totalMembers)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("Should fail if the MaxUserPerTeam is reached", func(t *testing.T) {
|
||||
user := th.CreateUser()
|
||||
data := &[]UserTeamImportData{
|
||||
{
|
||||
Name: &th.BasicTeam.Name,
|
||||
},
|
||||
}
|
||||
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 1 })
|
||||
defer th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 100 })
|
||||
err := th.App.importUserTeams(user, data)
|
||||
require.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestImportUserChannels(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
channel2 := th.CreateChannel(th.BasicTeam)
|
||||
customRole := th.CreateRole("test_custom_role")
|
||||
sampleNotifyProps := UserChannelNotifyPropsImportData{
|
||||
Desktop: model.NewString("all"),
|
||||
Mobile: model.NewString("none"),
|
||||
MarkUnread: model.NewString("all"),
|
||||
}
|
||||
|
||||
tt := []struct {
|
||||
name string
|
||||
data *[]UserChannelImportData
|
||||
expectedError bool
|
||||
expectedUserChannels int
|
||||
expectedExplicitRoles string
|
||||
expectedRoles string
|
||||
expectedNotifyProps *UserChannelNotifyPropsImportData
|
||||
}{
|
||||
{
|
||||
name: "Not existing channel should fail",
|
||||
data: &[]UserChannelImportData{
|
||||
{
|
||||
Name: model.NewString("not-existing-channel-name"),
|
||||
},
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "nil data shouldn't do anything",
|
||||
expectedError: false,
|
||||
expectedUserChannels: 0,
|
||||
},
|
||||
{
|
||||
name: "Should fail if one of the roles doesn't exists",
|
||||
data: &[]UserChannelImportData{
|
||||
{
|
||||
Name: &th.BasicChannel.Name,
|
||||
Roles: model.NewString("not-existing-role"),
|
||||
},
|
||||
},
|
||||
expectedError: true,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "channel_user",
|
||||
},
|
||||
{
|
||||
name: "Should success to import explicit role",
|
||||
data: &[]UserChannelImportData{
|
||||
{
|
||||
Name: &th.BasicChannel.Name,
|
||||
Roles: &customRole.Name,
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: customRole.Name,
|
||||
expectedRoles: customRole.Name + " channel_user",
|
||||
},
|
||||
{
|
||||
name: "Should success to import admin role",
|
||||
data: &[]UserChannelImportData{
|
||||
{
|
||||
Name: &th.BasicChannel.Name,
|
||||
Roles: model.NewString(model.CHANNEL_ADMIN_ROLE_ID),
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "channel_user channel_admin",
|
||||
},
|
||||
{
|
||||
name: "Should success to import with notifyProps",
|
||||
data: &[]UserChannelImportData{
|
||||
{
|
||||
Name: &th.BasicChannel.Name,
|
||||
NotifyProps: &sampleNotifyProps,
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserChannels: 1,
|
||||
expectedExplicitRoles: "",
|
||||
expectedRoles: "channel_user",
|
||||
expectedNotifyProps: &sampleNotifyProps,
|
||||
},
|
||||
{
|
||||
name: "Should import properly multiple channels",
|
||||
data: &[]UserChannelImportData{
|
||||
{
|
||||
Name: &th.BasicChannel.Name,
|
||||
},
|
||||
{
|
||||
Name: &channel2.Name,
|
||||
},
|
||||
},
|
||||
expectedError: false,
|
||||
expectedUserChannels: 2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tt {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
user := th.CreateUser()
|
||||
th.App.joinUserToTeam(th.BasicTeam, user)
|
||||
teamMember, err := th.App.GetTeamMember(th.BasicTeam.Id, user.Id)
|
||||
require.Nil(t, err)
|
||||
|
||||
// Two times import must end with the same results
|
||||
for x := 0; x < 2; x++ {
|
||||
err = th.App.importUserChannels(user, th.BasicTeam, teamMember, tc.data)
|
||||
if tc.expectedError {
|
||||
require.NotNil(t, err)
|
||||
} else {
|
||||
require.Nil(t, err)
|
||||
}
|
||||
channelMembers, err := th.App.Srv().Store.Channel().GetMembersForUser(th.BasicTeam.Id, user.Id)
|
||||
require.Nil(t, err)
|
||||
require.Len(t, *channelMembers, tc.expectedUserChannels)
|
||||
if tc.expectedUserChannels == 1 {
|
||||
channelMember := (*channelMembers)[0]
|
||||
require.Equal(t, tc.expectedExplicitRoles, channelMember.ExplicitRoles, "Not matching expected explicit roles")
|
||||
require.Equal(t, tc.expectedRoles, channelMember.Roles, "not matching expected roles")
|
||||
if tc.expectedNotifyProps != nil {
|
||||
require.Equal(t, *tc.expectedNotifyProps.Desktop, channelMember.NotifyProps[model.DESKTOP_NOTIFY_PROP])
|
||||
require.Equal(t, *tc.expectedNotifyProps.Mobile, channelMember.NotifyProps[model.PUSH_NOTIFY_PROP])
|
||||
require.Equal(t, *tc.expectedNotifyProps.MarkUnread, channelMember.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP])
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportUserDefaultNotifyProps(t *testing.T) {
|
||||
th := Setup(t)
|
||||
defer th.TearDown()
|
||||
|
||||
Ссылка в новой задаче
Block a user