summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2018-06-21 12:02:35 +0100
committerGitHub <noreply@github.com>2018-06-21 12:02:35 +0100
commit1f65f0e3d6d142b859f8dda52da99cb3d4a01c9c (patch)
tree57c552d90a67dc0e5a97efeb6e9f265ddecdfa4e
parent8e24dd78fb868cb01dd626bca3e3d756b67fddc8 (diff)
downloadchat-1f65f0e3d6d142b859f8dda52da99cb3d4a01c9c.tar.gz
chat-1f65f0e3d6d142b859f8dda52da99cb3d4a01c9c.tar.bz2
chat-1f65f0e3d6d142b859f8dda52da99cb3d4a01c9c.zip
MM-10233: Add scheme importing to bulk importer. (#8928)
-rw-r--r--app/apptestlib.go49
-rw-r--r--app/import.go270
-rw-r--r--app/import_test.go721
-rw-r--r--app/role.go15
-rw-r--r--app/scheme.go12
-rw-r--r--app/team.go13
-rw-r--r--i18n/en.json72
-rw-r--r--model/scheme.go2
-rw-r--r--store/layered_store.go6
-rw-r--r--store/layered_store_supplier.go1
-rw-r--r--store/local_cache_supplier_schemes.go4
-rw-r--r--store/redis_supplier_schemes.go5
-rw-r--r--store/sqlstore/scheme_supplier.go20
-rw-r--r--store/store.go1
-rw-r--r--store/storetest/mocks/AuditStore.go2
-rw-r--r--store/storetest/mocks/ChannelMemberHistoryStore.go2
-rw-r--r--store/storetest/mocks/ChannelStore.go2
-rw-r--r--store/storetest/mocks/ClusterDiscoveryStore.go2
-rw-r--r--store/storetest/mocks/CommandStore.go2
-rw-r--r--store/storetest/mocks/CommandWebhookStore.go2
-rw-r--r--store/storetest/mocks/ComplianceStore.go2
-rw-r--r--store/storetest/mocks/EmojiStore.go2
-rw-r--r--store/storetest/mocks/FileInfoStore.go2
-rw-r--r--store/storetest/mocks/JobStore.go2
-rw-r--r--store/storetest/mocks/LayeredStoreDatabaseLayer.go25
-rw-r--r--store/storetest/mocks/LayeredStoreSupplier.go25
-rw-r--r--store/storetest/mocks/LicenseStore.go2
-rw-r--r--store/storetest/mocks/OAuthStore.go2
-rw-r--r--store/storetest/mocks/PluginStore.go2
-rw-r--r--store/storetest/mocks/PostStore.go6
-rw-r--r--store/storetest/mocks/PreferenceStore.go2
-rw-r--r--store/storetest/mocks/ReactionStore.go2
-rw-r--r--store/storetest/mocks/RoleStore.go2
-rw-r--r--store/storetest/mocks/SchemeStore.go16
-rw-r--r--store/storetest/mocks/SessionStore.go2
-rw-r--r--store/storetest/mocks/SqlStore.go2
-rw-r--r--store/storetest/mocks/StatusStore.go2
-rw-r--r--store/storetest/mocks/Store.go2
-rw-r--r--store/storetest/mocks/SystemStore.go2
-rw-r--r--store/storetest/mocks/TeamStore.go2
-rw-r--r--store/storetest/mocks/TokenStore.go2
-rw-r--r--store/storetest/mocks/UserAccessTokenStore.go2
-rw-r--r--store/storetest/mocks/UserStore.go2
-rw-r--r--store/storetest/mocks/WebhookStore.go2
-rw-r--r--store/storetest/scheme_store.go36
45 files changed, 1224 insertions, 127 deletions
diff --git a/app/apptestlib.go b/app/apptestlib.go
index 39e05a16e..818b21183 100644
--- a/app/apptestlib.go
+++ b/app/apptestlib.go
@@ -20,6 +20,7 @@ import (
"github.com/mattermost/mattermost-server/store/sqlstore"
"github.com/mattermost/mattermost-server/store/storetest"
"github.com/mattermost/mattermost-server/utils"
+ "testing"
)
type TestHelper struct {
@@ -446,6 +447,54 @@ func (me *TestHelper) ResetEmojisMigration() {
}
}
+func (me *TestHelper) CheckTeamCount(t *testing.T, expected int64) {
+ if r := <-me.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil {
+ if r.Data.(int64) != expected {
+ t.Fatalf("Unexpected number of teams. Expected: %v, found: %v", expected, r.Data.(int64))
+ }
+ } else {
+ t.Fatalf("Failed to get team count.")
+ }
+}
+
+func (me *TestHelper) CheckChannelsCount(t *testing.T, expected int64) {
+ if r := <-me.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
+ if r.Data.(int64) != expected {
+ t.Fatalf("Unexpected number of channels. Expected: %v, found: %v", expected, r.Data.(int64))
+ }
+ } else {
+ t.Fatalf("Failed to get channel count.")
+ }
+}
+
+func (me *TestHelper) SetupTeamScheme() *model.Scheme {
+ scheme := model.Scheme{
+ Name: model.NewId(),
+ DisplayName: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+
+ if scheme, err := me.App.CreateScheme(&scheme); err == nil {
+ return scheme
+ } else {
+ panic(err)
+ }
+}
+
+func (me *TestHelper) SetupChannelScheme() *model.Scheme {
+ scheme := model.Scheme{
+ Name: model.NewId(),
+ DisplayName: model.NewId(),
+ Scope: model.SCHEME_SCOPE_CHANNEL,
+ }
+
+ if scheme, err := me.App.CreateScheme(&scheme); err == nil {
+ return scheme
+ } else {
+ panic(err)
+ }
+}
+
type FakeClusterInterface struct {
clusterMessageHandler einterfaces.ClusterMessageHandler
}
diff --git a/app/import.go b/app/import.go
index 5364b1026..04e71b64c 100644
--- a/app/import.go
+++ b/app/import.go
@@ -26,6 +26,7 @@ import (
type LineImportData struct {
Type string `json:"type"`
+ Scheme *SchemeImportData `json:"scheme"`
Team *TeamImportData `json:"team"`
Channel *ChannelImportData `json:"channel"`
User *UserImportData `json:"user"`
@@ -41,6 +42,7 @@ type TeamImportData struct {
Type *string `json:"type"`
Description *string `json:"description"`
AllowOpenInvite *bool `json:"allow_open_invite"`
+ Scheme *string `json:"scheme"`
}
type ChannelImportData struct {
@@ -50,6 +52,7 @@ type ChannelImportData struct {
Type *string `json:"type"`
Header *string `json:"header"`
Purpose *string `json:"purpose"`
+ Scheme *string `json:"scheme"`
}
type UserImportData struct {
@@ -159,6 +162,24 @@ type DirectPostImportData struct {
Replies *[]ReplyImportData `json:"replies"`
}
+type SchemeImportData struct {
+ Name *string `json:"name"`
+ DisplayName *string `json:"display_name"`
+ Description *string `json:"description"`
+ Scope *string `json:"scope"`
+ DefaultTeamAdminRole *RoleImportData `json:"default_team_admin_role"`
+ DefaultTeamUserRole *RoleImportData `json:"default_team_user_role"`
+ DefaultChannelAdminRole *RoleImportData `json:"default_channel_admin_role"`
+ DefaultChannelUserRole *RoleImportData `json:"default_channel_user_role"`
+}
+
+type RoleImportData struct {
+ Name *string `json:"name"`
+ DisplayName *string `json:"display_name"`
+ Description *string `json:"description"`
+ Permissions *[]string `json:"permissions"`
+}
+
type LineImportWorkerData struct {
LineImportData
LineNumber int
@@ -271,6 +292,12 @@ func processImportDataFileVersionLine(line LineImportData) (int, *model.AppError
func (a *App) ImportLine(line LineImportData, dryRun bool) *model.AppError {
switch {
+ case line.Type == "scheme":
+ if line.Scheme == nil {
+ return model.NewAppError("BulkImport", "app.import.import_line.null_scheme.error", nil, "", http.StatusBadRequest)
+ } else {
+ return a.ImportScheme(line.Scheme, dryRun)
+ }
case line.Type == "team":
if line.Team == nil {
return model.NewAppError("BulkImport", "app.import.import_line.null_team.error", nil, "", http.StatusBadRequest)
@@ -312,6 +339,205 @@ func (a *App) ImportLine(line LineImportData, dryRun bool) *model.AppError {
}
}
+func (a *App) ImportScheme(data *SchemeImportData, dryRun bool) *model.AppError {
+ if err := validateSchemeImportData(data); err != nil {
+ return err
+ }
+
+ // If this is a Dry Run, do not continue any further.
+ if dryRun {
+ return nil
+ }
+
+ scheme, err := a.GetSchemeByName(*data.Name)
+ if err != nil {
+ scheme = new(model.Scheme)
+ } else if scheme.Scope != *data.Scope {
+ return model.NewAppError("BulkImport", "app.import.import_scheme.scope_change.error", map[string]interface{}{"SchemeName": scheme.Name}, "", http.StatusBadRequest)
+ }
+
+ scheme.Name = *data.Name
+ scheme.DisplayName = *data.DisplayName
+ scheme.Scope = *data.Scope
+
+ if data.Description != nil {
+ scheme.Description = *data.Description
+ }
+
+ if len(scheme.Id) == 0 {
+ scheme, err = a.CreateScheme(scheme)
+ } else {
+ scheme, err = a.UpdateScheme(scheme)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ if scheme.Scope == model.SCHEME_SCOPE_TEAM {
+ data.DefaultTeamAdminRole.Name = &scheme.DefaultTeamAdminRole
+ if err := a.ImportRole(data.DefaultTeamAdminRole, dryRun, true); err != nil {
+ return err
+ }
+
+ data.DefaultTeamUserRole.Name = &scheme.DefaultTeamUserRole
+ if err := a.ImportRole(data.DefaultTeamUserRole, dryRun, true); err != nil {
+ return err
+ }
+ }
+
+ if scheme.Scope == model.SCHEME_SCOPE_TEAM || scheme.Scope == model.SCHEME_SCOPE_CHANNEL {
+ data.DefaultChannelAdminRole.Name = &scheme.DefaultChannelAdminRole
+ if err := a.ImportRole(data.DefaultChannelAdminRole, dryRun, true); err != nil {
+ return err
+ }
+
+ data.DefaultChannelUserRole.Name = &scheme.DefaultChannelUserRole
+ if err := a.ImportRole(data.DefaultChannelUserRole, dryRun, true); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (a *App) ImportRole(data *RoleImportData, dryRun bool, isSchemeRole bool) *model.AppError {
+ if !isSchemeRole {
+ if err := validateRoleImportData(data); err != nil {
+ return err
+ }
+ }
+
+ // If this is a Dry Run, do not continue any further.
+ if dryRun {
+ return nil
+ }
+
+ role, err := a.GetRoleByName(*data.Name)
+ if err != nil {
+ role = new(model.Role)
+ }
+
+ role.Name = *data.Name
+
+ if data.DisplayName != nil {
+ role.DisplayName = *data.DisplayName
+ }
+
+ if data.Description != nil {
+ role.Description = *data.Description
+ }
+
+ if data.Permissions != nil {
+ role.Permissions = *data.Permissions
+ }
+
+ if isSchemeRole {
+ role.SchemeManaged = true
+ } else {
+ role.SchemeManaged = false
+ }
+
+ if len(role.Id) == 0 {
+ role, err = a.CreateRole(role)
+ } else {
+ role, err = a.UpdateRole(role)
+ }
+
+ return err
+}
+
+func validateSchemeImportData(data *SchemeImportData) *model.AppError {
+
+ if data.Scope == nil {
+ return model.NewAppError("BulkImport", "app.import.validate_scheme_import_data.null_scope.error", nil, "", http.StatusBadRequest)
+ }
+
+ switch *data.Scope {
+ case model.SCHEME_SCOPE_TEAM:
+ if data.DefaultTeamAdminRole == nil || data.DefaultTeamUserRole == nil || data.DefaultChannelAdminRole == nil || data.DefaultChannelUserRole == nil {
+ return model.NewAppError("BulkImport", "app.import.validate_scheme_import_data.wrong_roles_for_scope.error", nil, "", http.StatusBadRequest)
+ }
+ case model.SCHEME_SCOPE_CHANNEL:
+ if data.DefaultTeamAdminRole != nil || data.DefaultTeamUserRole != nil || data.DefaultChannelAdminRole == nil || data.DefaultChannelUserRole == nil {
+ return model.NewAppError("BulkImport", "app.import.validate_scheme_import_data.wrong_roles_for_scope.error", nil, "", http.StatusBadRequest)
+ }
+ default:
+ return model.NewAppError("BulkImport", "app.import.validate_scheme_import_data.unknown_scheme.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.Name == nil || !model.IsValidSchemeName(*data.Name) {
+ return model.NewAppError("BulkImport", "app.import.validate_scheme_import_data.name_invalid.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.DisplayName == nil || len(*data.DisplayName) == 0 || len(*data.DisplayName) > model.SCHEME_DISPLAY_NAME_MAX_LENGTH {
+ return model.NewAppError("BulkImport", "app.import.validate_scheme_import_data.display_name_invalid.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.Description != nil && len(*data.Description) > model.SCHEME_DESCRIPTION_MAX_LENGTH {
+ return model.NewAppError("BulkImport", "app.import.validate_scheme_import_data.description_invalid.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.DefaultTeamAdminRole != nil {
+ if err := validateRoleImportData(data.DefaultTeamAdminRole); err != nil {
+ return err
+ }
+ }
+
+ if data.DefaultTeamUserRole != nil {
+ if err := validateRoleImportData(data.DefaultTeamUserRole); err != nil {
+ return err
+ }
+ }
+
+ if data.DefaultChannelAdminRole != nil {
+ if err := validateRoleImportData(data.DefaultChannelAdminRole); err != nil {
+ return err
+ }
+ }
+
+ if data.DefaultChannelUserRole != nil {
+ if err := validateRoleImportData(data.DefaultChannelUserRole); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func validateRoleImportData(data *RoleImportData) *model.AppError {
+
+ if data.Name == nil || !model.IsValidRoleName(*data.Name) {
+ return model.NewAppError("BulkImport", "app.import.validate_role_import_data.name_invalid.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.DisplayName == nil || len(*data.DisplayName) == 0 || len(*data.DisplayName) > model.ROLE_DISPLAY_NAME_MAX_LENGTH {
+ return model.NewAppError("BulkImport", "app.import.validate_role_import_data.display_name_invalid.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.Description != nil && len(*data.Description) > model.ROLE_DESCRIPTION_MAX_LENGTH {
+ return model.NewAppError("BulkImport", "app.import.validate_role_import_data.description_invalid.error", nil, "", http.StatusBadRequest)
+ }
+
+ if data.Permissions != nil {
+ for _, permission := range *data.Permissions {
+ permissionValidated := false
+ for _, p := range model.ALL_PERMISSIONS {
+ if permission == p.Id {
+ permissionValidated = true
+ break
+ }
+ }
+
+ if !permissionValidated {
+ return model.NewAppError("BulkImport", "app.import.validate_role_import_data.invalid_permission.error", nil, "permission"+permission, http.StatusBadRequest)
+ }
+ }
+ }
+
+ return nil
+}
+
func (a *App) ImportTeam(data *TeamImportData, dryRun bool) *model.AppError {
if err := validateTeamImportData(data); err != nil {
return err
@@ -341,12 +567,29 @@ func (a *App) ImportTeam(data *TeamImportData, dryRun bool) *model.AppError {
team.AllowOpenInvite = *data.AllowOpenInvite
}
+ if data.Scheme != nil {
+ scheme, err := a.GetSchemeByName(*data.Scheme)
+ if err != nil {
+ return err
+ }
+
+ if scheme.DeleteAt != 0 {
+ return model.NewAppError("BulkImport", "app.import.import_team.scheme_deleted.error", nil, "", http.StatusBadRequest)
+ }
+
+ if scheme.Scope != model.SCHEME_SCOPE_TEAM {
+ return model.NewAppError("BulkImport", "app.import.import_team.scheme_wrong_scope.error", nil, "", http.StatusBadRequest)
+ }
+
+ team.SchemeId = &scheme.Id
+ }
+
if team.Id == "" {
if _, err := a.CreateTeam(team); err != nil {
return err
}
} else {
- if _, err := a.UpdateTeam(team); err != nil {
+ if _, err := a.updateTeamUnsanitized(team); err != nil {
return err
}
}
@@ -382,6 +625,10 @@ func validateTeamImportData(data *TeamImportData) *model.AppError {
return model.NewAppError("BulkImport", "app.import.validate_team_import_data.description_length.error", nil, "", http.StatusBadRequest)
}
+ if data.Scheme != nil && !model.IsValidSchemeName(*data.Scheme) {
+ return model.NewAppError("BulkImport", "app.import.validate_team_import_data.scheme_invalid.error", nil, "", http.StatusBadRequest)
+ }
+
return nil
}
@@ -422,6 +669,23 @@ func (a *App) ImportChannel(data *ChannelImportData, dryRun bool) *model.AppErro
channel.Purpose = *data.Purpose
}
+ if data.Scheme != nil {
+ scheme, err := a.GetSchemeByName(*data.Scheme)
+ if err != nil {
+ return err
+ }
+
+ if scheme.DeleteAt != 0 {
+ return model.NewAppError("BulkImport", "app.import.import_channel.scheme_deleted.error", nil, "", http.StatusBadRequest)
+ }
+
+ if scheme.Scope != model.SCHEME_SCOPE_CHANNEL {
+ return model.NewAppError("BulkImport", "app.import.import_channel.scheme_wrong_scope.error", nil, "", http.StatusBadRequest)
+ }
+
+ channel.SchemeId = &scheme.Id
+ }
+
if channel.Id == "" {
if _, err := a.CreateChannel(channel, false); err != nil {
return err
@@ -469,6 +733,10 @@ func validateChannelImportData(data *ChannelImportData) *model.AppError {
return model.NewAppError("BulkImport", "app.import.validate_channel_import_data.purpose_length.error", nil, "", http.StatusBadRequest)
}
+ if data.Scheme != nil && !model.IsValidSchemeName(*data.Scheme) {
+ return model.NewAppError("BulkImport", "app.import.validate_channel_import_data.scheme_invalid.error", nil, "", http.StatusBadRequest)
+ }
+
return nil
}
diff --git a/app/import_test.go b/app/import_test.go
index a6bc7c467..6a653cc2f 100644
--- a/app/import_test.go
+++ b/app/import_test.go
@@ -9,6 +9,8 @@ import (
"strings"
"testing"
+ "github.com/stretchr/testify/assert"
+
"github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/utils"
@@ -78,6 +80,249 @@ func checkNoError(t *testing.T, err *model.AppError) {
}
}
+func TestImportValidateSchemeImportData(t *testing.T) {
+ // Test with minimum required valid properties and team scope.
+ data := SchemeImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Scope: ptrStr("team"),
+ DefaultTeamAdminRole: &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ },
+ DefaultTeamUserRole: &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ },
+ DefaultChannelAdminRole: &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ },
+ DefaultChannelUserRole: &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ },
+ }
+ if err := validateSchemeImportData(&data); err != nil {
+ t.Fatal("Validation failed but should have been valid.", err)
+ }
+
+ // Test with various invalid names.
+ data.Name = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid name.")
+ }
+
+ data.Name = ptrStr("")
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid name.")
+ }
+
+ data.Name = ptrStr(strings.Repeat("1234567890", 100))
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid name.")
+ }
+
+ data.Name = ptrStr("name")
+ // Test with invalid display name.
+ data.DisplayName = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid display name.")
+ }
+
+ data.DisplayName = ptrStr("")
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid display name.")
+ }
+
+ data.DisplayName = ptrStr(strings.Repeat("1234567890", 100))
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid display name.")
+ }
+
+ data.DisplayName = ptrStr("display name")
+
+ // Test with various missing roles.
+ data.DefaultTeamAdminRole = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to missing role.")
+ }
+
+ data.DefaultTeamAdminRole = &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ }
+ data.DefaultTeamUserRole = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to missing role.")
+ }
+
+ data.DefaultTeamUserRole = &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ }
+ data.DefaultChannelAdminRole = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to missing role.")
+ }
+
+ data.DefaultChannelAdminRole = &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ }
+ data.DefaultChannelUserRole = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to missing role.")
+ }
+
+ data.DefaultChannelUserRole = &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ }
+
+ // Test with various invalid roles.
+ data.DefaultTeamAdminRole.Name = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid role.")
+ }
+
+ data.DefaultTeamAdminRole.Name = ptrStr("name")
+ data.DefaultTeamUserRole.Name = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid role.")
+ }
+
+ data.DefaultTeamUserRole.Name = ptrStr("name")
+ data.DefaultChannelAdminRole.Name = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid role.")
+ }
+
+ data.DefaultChannelAdminRole.Name = ptrStr("name")
+ data.DefaultChannelUserRole.Name = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid role.")
+ }
+
+ data.DefaultChannelUserRole.Name = ptrStr("name")
+
+ // Change to a Channel scope role, and check with missing or extra roles again.
+ data.Scope = ptrStr("channel")
+ data.DefaultTeamAdminRole = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to spurious role.")
+ }
+
+ data.DefaultTeamAdminRole = &RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ Permissions: &[]string{"invite_user"},
+ }
+ data.DefaultTeamUserRole = nil
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to spurious role.")
+ }
+
+ data.DefaultTeamAdminRole = nil
+ if err := validateSchemeImportData(&data); err != nil {
+ t.Fatal("Should have succeeded.")
+ }
+
+ // Test with all combinations of optional parameters.
+ data.Description = ptrStr(strings.Repeat("1234567890", 1024))
+ if err := validateSchemeImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid description.")
+ }
+
+ data.Description = ptrStr("description")
+ if err := validateSchemeImportData(&data); err != nil {
+ t.Fatal("Should have succeeded.")
+ }
+}
+
+func TestImportValidateRoleImportData(t *testing.T) {
+ // Test with minimum required valid properties.
+ data := RoleImportData{
+ Name: ptrStr("name"),
+ DisplayName: ptrStr("display name"),
+ }
+ if err := validateRoleImportData(&data); err != nil {
+ t.Fatal("Validation failed but should have been valid.", err)
+ }
+
+ // Test with various invalid names.
+ data.Name = nil
+ if err := validateRoleImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid name.")
+ }
+
+ data.Name = ptrStr("")
+ if err := validateRoleImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid name.")
+ }
+
+ data.Name = ptrStr(strings.Repeat("1234567890", 100))
+ if err := validateRoleImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid name.")
+ }
+
+ data.Name = ptrStr("name")
+ // Test with invalid display name.
+ data.DisplayName = nil
+ if err := validateRoleImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid display name.")
+ }
+
+ data.DisplayName = ptrStr("")
+ if err := validateRoleImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid display name.")
+ }
+
+ data.DisplayName = ptrStr(strings.Repeat("1234567890", 100))
+ if err := validateRoleImportData(&data); err == nil {
+ t.Fatal("Should have failed due to invalid display name.")
+ }
+
+ data.DisplayName = ptrStr("display name")
+
+ // Test with various valid/invalid permissions.
+ data.Permissions = &[]string{}
+ if err := validateRoleImportData(&data); err != nil {
+ t.Fatal("Validation failed but should have been valid.", err)
+ }
+
+ data.Permissions = &[]string{"invite_user", "add_user_to_team"}
+ if err := validateRoleImportData(&data); err != nil {
+ t.Fatal("Validation failed but should have been valid.", err)
+ }
+
+ data.Permissions = &[]string{"invite_user", "add_user_to_team", "derp"}
+ if err := validateRoleImportData(&data); err == nil {
+ t.Fatal("Validation should have failed due to invalid permission.", err)
+ }
+
+ data.Permissions = &[]string{"invite_user", "add_user_to_team"}
+
+ // Test with various valid/invalid descriptions.
+ data.Description = ptrStr(strings.Repeat("1234567890", 1024))
+ if err := validateRoleImportData(&data); err == nil {
+ t.Fatal("Validation should have failed due to invalid description.", err)
+ }
+
+ data.Description = ptrStr("description")
+ if err := validateRoleImportData(&data); err != nil {
+ t.Fatal("Validation failed but should have been valid.", err)
+ }
+}
+
func TestImportValidateTeamImportData(t *testing.T) {
// Test with minimum required valid properties.
@@ -178,6 +423,19 @@ func TestImportValidateTeamImportData(t *testing.T) {
if err := validateTeamImportData(&data); err == nil {
t.Fatal("Should have failed due to too long description.")
}
+
+ // Test with an empty scheme name.
+ data.Description = ptrStr("abcdefg")
+ data.Scheme = ptrStr("")
+ if err := validateTeamImportData(&data); err == nil {
+ t.Fatal("Should have failed due to empty scheme name.")
+ }
+
+ // Test with a valid scheme name.
+ data.Scheme = ptrStr("abcdefg")
+ if err := validateTeamImportData(&data); err != nil {
+ t.Fatal("Should have succeeded with valid scheme name.")
+ }
}
func TestImportValidateChannelImportData(t *testing.T) {
@@ -291,6 +549,19 @@ func TestImportValidateChannelImportData(t *testing.T) {
if err := validateChannelImportData(&data); err == nil {
t.Fatal("Should have failed due to too long purpose.")
}
+
+ // Test with an empty scheme name.
+ data.Purpose = ptrStr("abcdefg")
+ data.Scheme = ptrStr("")
+ if err := validateChannelImportData(&data); err == nil {
+ t.Fatal("Should have failed due to empty scheme name.")
+ }
+
+ // Test with a valid scheme name.
+ data.Scheme = ptrStr("abcdefg")
+ if err := validateChannelImportData(&data); err != nil {
+ t.Fatal("Should have succeeded with valid scheme name.")
+ }
}
func TestImportValidateUserImportData(t *testing.T) {
@@ -1134,10 +1405,314 @@ func TestImportValidateDirectPostImportData(t *testing.T) {
}
}
+func TestImportImportScheme(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ // Mark the phase 2 permissions migration as completed.
+ <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
+
+ defer func() {
+ <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
+ }()
+
+ // Try importing an invalid scheme in dryRun mode.
+ data := SchemeImportData{
+ Name: ptrStr(model.NewId()),
+ Scope: ptrStr("team"),
+ DefaultTeamUserRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultTeamAdminRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultChannelUserRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ DefaultChannelAdminRole: &RoleImportData{
+ Name: ptrStr(model.NewId()),
+ DisplayName: ptrStr(model.NewId()),
+ },
+ Description: ptrStr("description"),
+ }
+
+ if err := th.App.ImportScheme(&data, true); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil {
+ t.Fatalf("Scheme should not have imported.")
+ }
+
+ // Try importing a valid scheme in dryRun mode.
+ data.DisplayName = ptrStr("display name")
+
+ if err := th.App.ImportScheme(&data, true); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil {
+ t.Fatalf("Scheme should not have imported.")
+ }
+
+ // Try importing an invalid scheme.
+ data.DisplayName = nil
+
+ if err := th.App.ImportScheme(&data, false); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err == nil {
+ t.Fatalf("Scheme should not have imported.")
+ }
+
+ // Try importing a valid scheme with all params set.
+ data.DisplayName = ptrStr("display name")
+
+ if err := th.App.ImportScheme(&data, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil {
+ t.Fatalf("Failed to import scheme: %v", res.Err)
+ } else {
+ scheme := res.Data.(*model.Scheme)
+ assert.Equal(t, *data.Name, scheme.Name)
+ assert.Equal(t, *data.DisplayName, scheme.DisplayName)
+ assert.Equal(t, *data.Description, scheme.Description)
+ assert.Equal(t, *data.Scope, scheme.Scope)
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamAdminRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamUserRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelAdminRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelUserRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+ }
+
+ // Try modifying all the fields and re-importing.
+ data.DisplayName = ptrStr("new display name")
+ data.Description = ptrStr("new description")
+
+ if err := th.App.ImportScheme(&data, false); err != nil {
+ t.Fatalf("Should have succeeded: %v", err)
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil {
+ t.Fatalf("Failed to import scheme: %v", res.Err)
+ } else {
+ scheme := res.Data.(*model.Scheme)
+ assert.Equal(t, *data.Name, scheme.Name)
+ assert.Equal(t, *data.DisplayName, scheme.DisplayName)
+ assert.Equal(t, *data.Description, scheme.Description)
+ assert.Equal(t, *data.Scope, scheme.Scope)
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamAdminRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultTeamAdminRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultTeamUserRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultTeamUserRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelAdminRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultChannelAdminRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(scheme.DefaultChannelUserRole); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.DefaultChannelUserRole.DisplayName, role.DisplayName)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+ }
+
+ // Try changing the scope of the scheme and reimporting.
+ data.Scope = ptrStr("channel")
+
+ if err := th.App.ImportScheme(&data, false); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Scheme().GetByName(*data.Name); res.Err != nil {
+ t.Fatalf("Failed to import scheme: %v", res.Err)
+ } else {
+ scheme := res.Data.(*model.Scheme)
+ assert.Equal(t, *data.Name, scheme.Name)
+ assert.Equal(t, *data.DisplayName, scheme.DisplayName)
+ assert.Equal(t, *data.Description, scheme.Description)
+ assert.Equal(t, "team", scheme.Scope)
+ }
+}
+
+func TestImportImportRole(t *testing.T) {
+ th := Setup()
+ defer th.TearDown()
+
+ // Try importing an invalid role in dryRun mode.
+ rid1 := model.NewId()
+ data := RoleImportData{
+ Name: &rid1,
+ }
+
+ if err := th.App.ImportRole(&data, true, false); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil {
+ t.Fatalf("Role should not have imported.")
+ }
+
+ // Try importing the valid role in dryRun mode.
+ data.DisplayName = ptrStr("display name")
+
+ if err := th.App.ImportRole(&data, true, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil {
+ t.Fatalf("Role should not have imported as we are in dry run mode.")
+ }
+
+ // Try importing an invalid role.
+ data.DisplayName = nil
+
+ if err := th.App.ImportRole(&data, false, false); err == nil {
+ t.Fatalf("Should have failed to import.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err == nil {
+ t.Fatalf("Role should not have imported.")
+ }
+
+ // Try importing a valid role with all params set.
+ data.DisplayName = ptrStr("display name")
+ data.Description = ptrStr("description")
+ data.Permissions = &[]string{"invite_user", "add_user_to_team"}
+
+ if err := th.App.ImportRole(&data, false, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.Name, role.Name)
+ assert.Equal(t, *data.DisplayName, role.DisplayName)
+ assert.Equal(t, *data.Description, role.Description)
+ assert.Equal(t, *data.Permissions, role.Permissions)
+ assert.False(t, role.BuiltIn)
+ assert.False(t, role.SchemeManaged)
+ }
+
+ // Try changing all the params and reimporting.
+ data.DisplayName = ptrStr("new display name")
+ data.Description = ptrStr("description")
+ data.Permissions = &[]string{"use_slash_commands"}
+
+ if err := th.App.ImportRole(&data, false, true); err != nil {
+ t.Fatalf("Should have succeeded. %v", err)
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data.Name, role.Name)
+ assert.Equal(t, *data.DisplayName, role.DisplayName)
+ assert.Equal(t, *data.Description, role.Description)
+ assert.Equal(t, *data.Permissions, role.Permissions)
+ assert.False(t, role.BuiltIn)
+ assert.True(t, role.SchemeManaged)
+ }
+
+ // Check that re-importing with only required fields doesn't update the others.
+ data2 := RoleImportData{
+ Name: &rid1,
+ DisplayName: ptrStr("new display name again"),
+ }
+
+ if err := th.App.ImportRole(&data2, false, false); err != nil {
+ t.Fatalf("Should have succeeded.")
+ }
+
+ if res := <-th.App.Srv.Store.Role().GetByName(rid1); res.Err != nil {
+ t.Fatalf("Should have found the imported role.")
+ } else {
+ role := res.Data.(*model.Role)
+ assert.Equal(t, *data2.Name, role.Name)
+ assert.Equal(t, *data2.DisplayName, role.DisplayName)
+ assert.Equal(t, *data.Description, role.Description)
+ assert.Equal(t, *data.Permissions, role.Permissions)
+ assert.False(t, role.BuiltIn)
+ assert.False(t, role.SchemeManaged)
+ }
+}
+
func TestImportImportTeam(t *testing.T) {
th := Setup()
defer th.TearDown()
+ // Mark the phase 2 permissions migration as completed.
+ <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
+
+ defer func() {
+ <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
+ }()
+
+ scheme1 := th.SetupTeamScheme()
+ scheme2 := th.SetupTeamScheme()
+
// Check how many teams are in the database.
var teamsCount int64
if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil {
@@ -1152,6 +1727,7 @@ func TestImportImportTeam(t *testing.T) {
Type: ptrStr("XYZ"),
Description: ptrStr("The team description."),
AllowOpenInvite: ptrBool(true),
+ Scheme: &scheme1.Name,
}
// Try importing an invalid team in dryRun mode.
@@ -1166,13 +1742,7 @@ func TestImportImportTeam(t *testing.T) {
}
// Check that no more teams are in the DB.
- if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil {
- if r.Data.(int64) != teamsCount {
- t.Fatalf("Teams got persisted in dry run mode.")
- }
- } else {
- t.Fatalf("Failed to get team count.")
- }
+ th.CheckTeamCount(t, teamsCount)
// Do an invalid team in apply mode, check db changes.
data.Type = ptrStr("XYZ")
@@ -1181,36 +1751,26 @@ func TestImportImportTeam(t *testing.T) {
}
// Check that no more teams are in the DB.
- if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil {
- if r.Data.(int64) != teamsCount {
- t.Fatalf("Invalid team got persisted.")
- }
- } else {
- t.Fatalf("Failed to get team count.")
- }
+ th.CheckTeamCount(t, teamsCount)
// Do a valid team in apply mode, check db changes.
data.Type = ptrStr("O")
if err := th.App.ImportTeam(&data, false); err != nil {
- t.Fatalf("Received an error importing valid team.")
+ t.Fatalf("Received an error importing valid team: %v", err)
}
// Check that one more team is in the DB.
- if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil {
- if r.Data.(int64)-1 != teamsCount {
- t.Fatalf("Team did not get saved in apply run mode. analytics=%v teamcount=%v", r.Data.(int64), teamsCount)
- }
- } else {
- t.Fatalf("Failed to get team count.")
- }
+ th.CheckTeamCount(t, teamsCount+1)
// Get the team and check that all the fields are correct.
if team, err := th.App.GetTeamByName(*data.Name); err != nil {
t.Fatalf("Failed to get team from database.")
} else {
- if team.DisplayName != *data.DisplayName || team.Type != *data.Type || team.Description != *data.Description || team.AllowOpenInvite != *data.AllowOpenInvite {
- t.Fatalf("Imported team properties do not match import data.")
- }
+ assert.Equal(t, *data.DisplayName, team.DisplayName)
+ assert.Equal(t, *data.Type, team.Type)
+ assert.Equal(t, *data.Description, team.Description)
+ assert.Equal(t, *data.AllowOpenInvite, team.AllowOpenInvite)
+ assert.Equal(t, scheme1.Id, *team.SchemeId)
}
// Alter all the fields of that team (apart from unique identifier) and import again.
@@ -1218,6 +1778,7 @@ func TestImportImportTeam(t *testing.T) {
data.Type = ptrStr("P")
data.Description = ptrStr("The new description")
data.AllowOpenInvite = ptrBool(false)
+ data.Scheme = &scheme2.Name
// Check that the original number of teams are again in the DB (because this query doesn't include deleted).
data.Type = ptrStr("O")
@@ -1225,21 +1786,17 @@ func TestImportImportTeam(t *testing.T) {
t.Fatalf("Received an error importing updated valid team.")
}
- if r := <-th.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil {
- if r.Data.(int64)-1 != teamsCount {
- t.Fatalf("Team alterations did not get saved in apply run mode. analytics=%v teamcount=%v", r.Data.(int64), teamsCount)
- }
- } else {
- t.Fatalf("Failed to get team count.")
- }
+ th.CheckTeamCount(t, teamsCount+1)
// Get the team and check that all fields are correct.
if team, err := th.App.GetTeamByName(*data.Name); err != nil {
t.Fatalf("Failed to get team from database.")
} else {
- if team.DisplayName != *data.DisplayName || team.Type != *data.Type || team.Description != *data.Description || team.AllowOpenInvite != *data.AllowOpenInvite {
- t.Fatalf("Updated team properties do not match import data.")
- }
+ assert.Equal(t, *data.DisplayName, team.DisplayName)
+ assert.Equal(t, *data.Type, team.Type)
+ assert.Equal(t, *data.Description, team.Description)
+ assert.Equal(t, *data.AllowOpenInvite, team.AllowOpenInvite)
+ assert.Equal(t, scheme2.Id, *team.SchemeId)
}
}
@@ -1247,6 +1804,16 @@ func TestImportImportChannel(t *testing.T) {
th := Setup()
defer th.TearDown()
+ // Mark the phase 2 permissions migration as completed.
+ <-th.App.Srv.Store.System().Save(&model.System{Name: model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2, Value: "true"})
+
+ defer func() {
+ <-th.App.Srv.Store.System().PermanentDeleteByName(model.MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2)
+ }()
+
+ scheme1 := th.SetupChannelScheme()
+ scheme2 := th.SetupChannelScheme()
+
// Import a Team.
teamName := model.NewId()
th.App.ImportTeam(&TeamImportData{
@@ -1274,19 +1841,14 @@ func TestImportImportChannel(t *testing.T) {
Type: ptrStr("O"),
Header: ptrStr("Channe Header"),
Purpose: ptrStr("Channel Purpose"),
+ Scheme: &scheme1.Name,
}
if err := th.App.ImportChannel(&data, true); err == nil {
t.Fatalf("Expected error due to invalid name.")
}
// Check that no more channels are in the DB.
- if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
- if r.Data.(int64) != channelCount {
- t.Fatalf("Channels got persisted in dry run mode.")
- }
- } else {
- t.Fatalf("Failed to get channel count.")
- }
+ th.CheckChannelsCount(t, channelCount)
// Do a valid channel with a nonexistent team in dry-run mode.
data.Name = ptrStr("channelname")
@@ -1296,13 +1858,7 @@ func TestImportImportChannel(t *testing.T) {
}
// Check that no more channels are in the DB.
- if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
- if r.Data.(int64) != channelCount {
- t.Fatalf("Channels got persisted in dry run mode.")
- }
- } else {
- t.Fatalf("Failed to get channel count.")
- }
+ th.CheckChannelsCount(t, channelCount)
// Do a valid channel in dry-run mode.
data.Team = &teamName
@@ -1311,13 +1867,7 @@ func TestImportImportChannel(t *testing.T) {
}
// Check that no more channels are in the DB.
- if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
- if r.Data.(int64) != channelCount {
- t.Fatalf("Channels got persisted in dry run mode.")
- }
- } else {
- t.Fatalf("Failed to get channel count.")
- }
+ th.CheckChannelsCount(t, channelCount)
// Do an invalid channel in apply mode.
data.Name = nil
@@ -1326,13 +1876,7 @@ func TestImportImportChannel(t *testing.T) {
}
// Check that no more channels are in the DB.
- if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
- if r.Data.(int64) != channelCount {
- t.Fatalf("Invalid channel got persisted in apply mode.")
- }
- } else {
- t.Fatalf("Failed to get channel count.")
- }
+ th.CheckChannelsCount(t, channelCount)
// Do a valid channel in apply mode with a non-existent team.
data.Name = ptrStr("channelname")
@@ -1342,13 +1886,7 @@ func TestImportImportChannel(t *testing.T) {
}
// Check that no more channels are in the DB.
- if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
- if r.Data.(int64) != channelCount {
- t.Fatalf("Invalid team channel got persisted in apply mode.")
- }
- } else {
- t.Fatalf("Failed to get channel count.")
- }
+ th.CheckChannelsCount(t, channelCount)
// Do a valid channel in apply mode.
data.Team = &teamName
@@ -1356,22 +1894,19 @@ func TestImportImportChannel(t *testing.T) {
t.Fatalf("Expected success in apply mode: %v", err.Error())
}
- // Check that no more channels are in the DB.
- if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
- if r.Data.(int64) != channelCount+1 {
- t.Fatalf("Channels did not get persisted in apply mode: found %v expected %v + 1", r.Data.(int64), channelCount)
- }
- } else {
- t.Fatalf("Failed to get channel count.")
- }
+ // Check that 1 more channel is in the DB.
+ th.CheckChannelsCount(t, channelCount+1)
// Get the Channel and check all the fields are correct.
if channel, err := th.App.GetChannelByName(*data.Name, team.Id); err != nil {
t.Fatalf("Failed to get channel from database.")
} else {
- if channel.Name != *data.Name || channel.DisplayName != *data.DisplayName || channel.Type != *data.Type || channel.Header != *data.Header || channel.Purpose != *data.Purpose {
- t.Fatalf("Imported team properties do not match Import Data.")
- }
+ assert.Equal(t, *data.Name, channel.Name)
+ assert.Equal(t, *data.DisplayName, channel.DisplayName)
+ assert.Equal(t, *data.Type, channel.Type)
+ assert.Equal(t, *data.Header, channel.Header)
+ assert.Equal(t, *data.Purpose, channel.Purpose)
+ assert.Equal(t, scheme1.Id, *channel.SchemeId)
}
// Alter all the fields of that channel.
@@ -1379,26 +1914,24 @@ func TestImportImportChannel(t *testing.T) {
data.Type = ptrStr(model.CHANNEL_PRIVATE)
data.Header = ptrStr("New Header")
data.Purpose = ptrStr("New Purpose")
+ data.Scheme = &scheme2.Name
if err := th.App.ImportChannel(&data, false); err != nil {
t.Fatalf("Expected success in apply mode: %v", err.Error())
}
// Check channel count the same.
- if r := <-th.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
- if r.Data.(int64) != channelCount {
- t.Fatalf("Updated channel did not get correctly persisted in apply mode.")
- }
- } else {
- t.Fatalf("Failed to get channel count.")
- }
+ th.CheckChannelsCount(t, channelCount)
// Get the Channel and check all the fields are correct.
if channel, err := th.App.GetChannelByName(*data.Name, team.Id); err != nil {
t.Fatalf("Failed to get channel from database.")
} else {
- if channel.Name != *data.Name || channel.DisplayName != *data.DisplayName || channel.Type != *data.Type || channel.Header != *data.Header || channel.Purpose != *data.Purpose {
- t.Fatalf("Updated team properties do not match Import Data.")
- }
+ assert.Equal(t, *data.Name, channel.Name)
+ assert.Equal(t, *data.DisplayName, channel.DisplayName)
+ assert.Equal(t, *data.Type, channel.Type)
+ assert.Equal(t, *data.Header, channel.Header)
+ assert.Equal(t, *data.Purpose, channel.Purpose)
+ assert.Equal(t, scheme2.Id, *channel.SchemeId)
}
}
@@ -3109,6 +3642,12 @@ func TestImportImportLine(t *testing.T) {
if err := th.App.ImportLine(line, false); err == nil {
t.Fatalf("Expected an error when importing a line with type direct_post with a nil direct_post.")
}
+
+ // Try import line with scheme type but nil scheme.
+ line.Type = "scheme"
+ if err := th.App.ImportLine(line, false); err == nil {
+ t.Fatalf("Expected an error when importing a line with type scheme with a nil scheme.")
+ }
}
func TestImportBulkImport(t *testing.T) {
diff --git a/app/role.go b/app/role.go
index 72cf43fe7..3ffe88423 100644
--- a/app/role.go
+++ b/app/role.go
@@ -50,6 +50,21 @@ func (a *App) PatchRole(role *model.Role, patch *model.RolePatch) (*model.Role,
return role, err
}
+func (a *App) CreateRole(role *model.Role) (*model.Role, *model.AppError) {
+ role.Id = ""
+ role.CreateAt = 0
+ role.UpdateAt = 0
+ role.DeleteAt = 0
+ role.BuiltIn = false
+ role.SchemeManaged = false
+
+ if result := <-a.Srv.Store.Role().Save(role); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.Role), nil
+ }
+}
+
func (a *App) UpdateRole(role *model.Role) (*model.Role, *model.AppError) {
if result := <-a.Srv.Store.Role().Save(role); result.Err != nil {
return nil, result.Err
diff --git a/app/scheme.go b/app/scheme.go
index f070e36f8..1d7ddf28a 100644
--- a/app/scheme.go
+++ b/app/scheme.go
@@ -22,6 +22,18 @@ func (a *App) GetScheme(id string) (*model.Scheme, *model.AppError) {
}
}
+func (a *App) GetSchemeByName(name string) (*model.Scheme, *model.AppError) {
+ if err := a.IsPhase2MigrationCompleted(); err != nil {
+ return nil, err
+ }
+
+ if result := <-a.Srv.Store.Scheme().GetByName(name); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.Scheme), nil
+ }
+}
+
func (a *App) GetSchemesPage(scope string, page int, perPage int) ([]*model.Scheme, *model.AppError) {
if err := a.IsPhase2MigrationCompleted(); err != nil {
return nil, err
diff --git a/app/team.go b/app/team.go
index d6245b6df..beb4b1449 100644
--- a/app/team.go
+++ b/app/team.go
@@ -105,8 +105,9 @@ func (a *App) UpdateTeam(team *model.Team) (*model.Team, *model.AppError) {
oldTeam.AllowedDomains = team.AllowedDomains
oldTeam.LastTeamIconUpdate = team.LastTeamIconUpdate
- if result := <-a.Srv.Store.Team().Update(oldTeam); result.Err != nil {
- return nil, result.Err
+ oldTeam, err = a.updateTeamUnsanitized(oldTeam)
+ if err != nil {
+ return team, err
}
a.sendTeamEvent(oldTeam, model.WEBSOCKET_EVENT_UPDATE_TEAM)
@@ -114,6 +115,14 @@ func (a *App) UpdateTeam(team *model.Team) (*model.Team, *model.AppError) {
return oldTeam, nil
}
+func (a *App) updateTeamUnsanitized(team *model.Team) (*model.Team, *model.AppError) {
+ if result := <-a.Srv.Store.Team().Update(team); result.Err != nil {
+ return nil, result.Err
+ } else {
+ return result.Data.(*model.Team), nil
+ }
+}
+
func (a *App) UpdateTeamScheme(team *model.Team) (*model.Team, *model.AppError) {
var oldTeam *model.Team
var err *model.AppError
diff --git a/i18n/en.json b/i18n/en.json
index 543c308bd..7e880b3c4 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -3447,6 +3447,14 @@
"translation": "Import data line has type \"channel\" but the channel object is null."
},
{
+ "id": "app.import.import_line.null_scheme.error",
+ "translation": "Import data line has type \"scheme\" but the scheme object is null."
+ },
+ {
+ "id": "app.import.import_scheme.scope_change.error",
+ "translation": "The bulk importer cannot change the scope of an already-existing scheme."
+ },
+ {
"id": "app.import.import_line.null_direct_channel.error",
"translation": "Import data line has type \"direct_channel\" but the direct_channel object is null."
},
@@ -3467,6 +3475,70 @@
"translation": "Import data line has type \"user\" but the user object is null."
},
{
+ "id": "app.import.validate_scheme_import_data.null_scope.error",
+ "translation": "Scheme scope is required."
+ },
+ {
+ "id": "app.import.validate_scheme_import_data.wrong_roles_for_scope.error",
+ "translation": "The wrong roles were provided for a scheme with this scope."
+ },
+ {
+ "id": "app.import.validate_scheme_import_data.unknown_scheme.error",
+ "translation": "Unknown scheme scope."
+ },
+ {
+ "id": "app.import.validate_scheme_import_data.name_invalid.error",
+ "translation": "Invalid scheme name."
+ },
+ {
+ "id": "app.import.validate_scheme_import_data.display_name_invalid.error",
+ "translation": "Invalid scheme display name."
+ },
+ {
+ "id": "app.import.validate_scheme_import_data.description_invalid.error",
+ "translation": "Invalid scheme description."
+ },
+ {
+ "id": "app.import.validate_role_import_data.name_invalid.error",
+ "translation": "Invalid role name."
+ },
+ {
+ "id": "app.import.validate_role_import_data.display_name_invalid.error",
+ "translation": "Invalid role display name."
+ },
+ {
+ "id": "app.import.validate_role_import_data.description_invalid.error",
+ "translation": "Invalid role description."
+ },
+ {
+ "id": "app.import.validate_role_import_data.invalid_permission.error",
+ "translation": "Invalid permission on role."
+ },
+ {
+ "id": "app.import.validate_team_import_data.scheme_invalid.error",
+ "translation": "Invalid scheme name for team."
+ },
+ {
+ "id": "app.import.validate_channel_import_data.scheme_invalid.error",
+ "translation": "Invalid scheme name for channel."
+ },
+ {
+ "id": "app.import.import_team.scheme_deleted.error",
+ "translation": "Cannot set a team to use a deleted scheme."
+ },
+ {
+ "id": "app.import.import_team.scheme_wrong_scope.error",
+ "translation": "Team must be assigned to a Team-scoped scheme."
+ },
+ {
+ "id": "app.import.import_channel.scheme_deleted.error",
+ "translation": "Cannot set a channel to use a deleted scheme."
+ },
+ {
+ "id": "app.import.import_channel.scheme_wrong_scope.error",
+ "translation": "Channel must be assigned to a Channel-scoped scheme."
+ },
+ {
"id": "app.import.import_line.unknown_line_type.error",
"translation": "Import data line has unknown type \"{{.Type}}\"."
},
diff --git a/model/scheme.go b/model/scheme.go
index 2247717eb..0c38b560f 100644
--- a/model/scheme.go
+++ b/model/scheme.go
@@ -192,7 +192,7 @@ func (p *SchemeIDPatch) ToJson() string {
}
func IsValidSchemeName(name string) bool {
- re := regexp.MustCompile(fmt.Sprintf("^[a-z0-9_]{0,%d}$", SCHEME_NAME_MAX_LENGTH))
+ re := regexp.MustCompile(fmt.Sprintf("^[a-z0-9_]{2,%d}$", SCHEME_NAME_MAX_LENGTH))
return re.MatchString(name)
}
diff --git a/store/layered_store.go b/store/layered_store.go
index 69513febf..851d7536c 100644
--- a/store/layered_store.go
+++ b/store/layered_store.go
@@ -287,6 +287,12 @@ func (s *LayeredSchemeStore) Get(schemeId string) StoreChannel {
})
}
+func (s *LayeredSchemeStore) GetByName(schemeName string) StoreChannel {
+ return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
+ return supplier.SchemeGetByName(s.TmpContext, schemeName)
+ })
+}
+
func (s *LayeredSchemeStore) Delete(schemeId string) StoreChannel {
return s.RunQuery(func(supplier LayeredStoreSupplier) *LayeredStoreSupplierResult {
return supplier.SchemeDelete(s.TmpContext, schemeId)
diff --git a/store/layered_store_supplier.go b/store/layered_store_supplier.go
index 6bf4a0310..971859007 100644
--- a/store/layered_store_supplier.go
+++ b/store/layered_store_supplier.go
@@ -41,6 +41,7 @@ type LayeredStoreSupplier interface {
// Schemes
SchemeSave(ctx context.Context, scheme *model.Scheme, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
SchemeGet(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
+ SchemeGetByName(ctx context.Context, schemeName string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
SchemeDelete(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
SchemeGetAllPage(ctx context.Context, scope string, offset int, limit int, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
SchemePermanentDeleteAll(ctx context.Context, hints ...LayeredStoreHint) *LayeredStoreSupplierResult
diff --git a/store/local_cache_supplier_schemes.go b/store/local_cache_supplier_schemes.go
index b6cde0fc4..2f201c17b 100644
--- a/store/local_cache_supplier_schemes.go
+++ b/store/local_cache_supplier_schemes.go
@@ -36,6 +36,10 @@ func (s *LocalCacheSupplier) SchemeGet(ctx context.Context, schemeId string, hin
return result
}
+func (s *LocalCacheSupplier) SchemeGetByName(ctx context.Context, schemeName string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
+ return s.Next().SchemeGetByName(ctx, schemeName, hints...)
+}
+
func (s *LocalCacheSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
defer s.doInvalidateCacheCluster(s.schemeCache, schemeId)
defer s.doClearCacheCluster(s.roleCache)
diff --git a/store/redis_supplier_schemes.go b/store/redis_supplier_schemes.go
index 1af9dafde..ae3336148 100644
--- a/store/redis_supplier_schemes.go
+++ b/store/redis_supplier_schemes.go
@@ -19,6 +19,11 @@ func (s *RedisSupplier) SchemeGet(ctx context.Context, schemeId string, hints ..
return s.Next().SchemeGet(ctx, schemeId, hints...)
}
+func (s *RedisSupplier) SchemeGetByName(ctx context.Context, schemeName string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
+ // TODO: Redis caching.
+ return s.Next().SchemeGetByName(ctx, schemeName, hints...)
+}
+
func (s *RedisSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...LayeredStoreHint) *LayeredStoreSupplierResult {
// TODO: Redis caching.
return s.Next().SchemeDelete(ctx, schemeId, hints...)
diff --git a/store/sqlstore/scheme_supplier.go b/store/sqlstore/scheme_supplier.go
index 29370f9ae..d58d64792 100644
--- a/store/sqlstore/scheme_supplier.go
+++ b/store/sqlstore/scheme_supplier.go
@@ -48,7 +48,7 @@ func (s *SqlSupplier) SchemeSave(ctx context.Context, scheme *model.Scheme, hint
}
} else {
if !scheme.IsValid() {
- result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "", http.StatusBadRequest)
+ result.Err = model.NewAppError("SqlSchemeStore.Save", "store.sql_scheme.save.invalid_scheme.app_error", nil, "schemeId="+scheme.Id, http.StatusBadRequest)
return result
}
@@ -199,6 +199,24 @@ func (s *SqlSupplier) SchemeGet(ctx context.Context, schemeId string, hints ...s
return result
}
+func (s *SqlSupplier) SchemeGetByName(ctx context.Context, schemeName string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
+ result := store.NewSupplierResult()
+
+ var scheme model.Scheme
+
+ if err := s.GetReplica().SelectOne(&scheme, "SELECT * from Schemes WHERE Name = :Name", map[string]interface{}{"Name": schemeName}); err != nil {
+ if err == sql.ErrNoRows {
+ result.Err = model.NewAppError("SqlSchemeStore.GetByName", "store.sql_scheme.get.app_error", nil, "Name="+schemeName+", "+err.Error(), http.StatusNotFound)
+ } else {
+ result.Err = model.NewAppError("SqlSchemeStore.GetByName", "store.sql_scheme.get.app_error", nil, err.Error(), http.StatusInternalServerError)
+ }
+ }
+
+ result.Data = &scheme
+
+ return result
+}
+
func (s *SqlSupplier) SchemeDelete(ctx context.Context, schemeId string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
result := store.NewSupplierResult()
diff --git a/store/store.go b/store/store.go
index d8b875459..ce5213572 100644
--- a/store/store.go
+++ b/store/store.go
@@ -489,6 +489,7 @@ type RoleStore interface {
type SchemeStore interface {
Save(scheme *model.Scheme) StoreChannel
Get(schemeId string) StoreChannel
+ GetByName(schemeName string) StoreChannel
GetAllPage(scope string, offset int, limit int) StoreChannel
Delete(schemeId string) StoreChannel
PermanentDeleteAll() StoreChannel
diff --git a/store/storetest/mocks/AuditStore.go b/store/storetest/mocks/AuditStore.go
index d1ee9082e..df84545bd 100644
--- a/store/storetest/mocks/AuditStore.go
+++ b/store/storetest/mocks/AuditStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/ChannelMemberHistoryStore.go b/store/storetest/mocks/ChannelMemberHistoryStore.go
index ae8d024d1..16155b982 100644
--- a/store/storetest/mocks/ChannelMemberHistoryStore.go
+++ b/store/storetest/mocks/ChannelMemberHistoryStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/ChannelStore.go b/store/storetest/mocks/ChannelStore.go
index 10ac908e4..114914bb8 100644
--- a/store/storetest/mocks/ChannelStore.go
+++ b/store/storetest/mocks/ChannelStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/ClusterDiscoveryStore.go b/store/storetest/mocks/ClusterDiscoveryStore.go
index 4010006d8..997dcf03f 100644
--- a/store/storetest/mocks/ClusterDiscoveryStore.go
+++ b/store/storetest/mocks/ClusterDiscoveryStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/CommandStore.go b/store/storetest/mocks/CommandStore.go
index 798bbee4d..de4bc4e34 100644
--- a/store/storetest/mocks/CommandStore.go
+++ b/store/storetest/mocks/CommandStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/CommandWebhookStore.go b/store/storetest/mocks/CommandWebhookStore.go
index 5129388ae..cede8cdd2 100644
--- a/store/storetest/mocks/CommandWebhookStore.go
+++ b/store/storetest/mocks/CommandWebhookStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/ComplianceStore.go b/store/storetest/mocks/ComplianceStore.go
index dd75941b3..fb828cd4b 100644
--- a/store/storetest/mocks/ComplianceStore.go
+++ b/store/storetest/mocks/ComplianceStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/EmojiStore.go b/store/storetest/mocks/EmojiStore.go
index b1f0a3217..9871c98aa 100644
--- a/store/storetest/mocks/EmojiStore.go
+++ b/store/storetest/mocks/EmojiStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/FileInfoStore.go b/store/storetest/mocks/FileInfoStore.go
index 67f922146..4dddf0bd7 100644
--- a/store/storetest/mocks/FileInfoStore.go
+++ b/store/storetest/mocks/FileInfoStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/JobStore.go b/store/storetest/mocks/JobStore.go
index a78a3f94e..d3558212e 100644
--- a/store/storetest/mocks/JobStore.go
+++ b/store/storetest/mocks/JobStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/LayeredStoreDatabaseLayer.go b/store/storetest/mocks/LayeredStoreDatabaseLayer.go
index c5b821b05..adbe1068c 100644
--- a/store/storetest/mocks/LayeredStoreDatabaseLayer.go
+++ b/store/storetest/mocks/LayeredStoreDatabaseLayer.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
@@ -655,6 +655,29 @@ func (_m *LayeredStoreDatabaseLayer) SchemeGetAllPage(ctx context.Context, scope
return r0
}
+// SchemeGetByName provides a mock function with given fields: ctx, schemeName, hints
+func (_m *LayeredStoreDatabaseLayer) SchemeGetByName(ctx context.Context, schemeName string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
+ _va := make([]interface{}, len(hints))
+ for _i := range hints {
+ _va[_i] = hints[_i]
+ }
+ var _ca []interface{}
+ _ca = append(_ca, ctx, schemeName)
+ _ca = append(_ca, _va...)
+ ret := _m.Called(_ca...)
+
+ var r0 *store.LayeredStoreSupplierResult
+ if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
+ r0 = rf(ctx, schemeName, hints...)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
+ }
+ }
+
+ return r0
+}
+
// SchemePermanentDeleteAll provides a mock function with given fields: ctx, hints
func (_m *LayeredStoreDatabaseLayer) SchemePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
diff --git a/store/storetest/mocks/LayeredStoreSupplier.go b/store/storetest/mocks/LayeredStoreSupplier.go
index 37a01df14..929f077c7 100644
--- a/store/storetest/mocks/LayeredStoreSupplier.go
+++ b/store/storetest/mocks/LayeredStoreSupplier.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
@@ -352,6 +352,29 @@ func (_m *LayeredStoreSupplier) SchemeGetAllPage(ctx context.Context, scope stri
return r0
}
+// SchemeGetByName provides a mock function with given fields: ctx, schemeName, hints
+func (_m *LayeredStoreSupplier) SchemeGetByName(ctx context.Context, schemeName string, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
+ _va := make([]interface{}, len(hints))
+ for _i := range hints {
+ _va[_i] = hints[_i]
+ }
+ var _ca []interface{}
+ _ca = append(_ca, ctx, schemeName)
+ _ca = append(_ca, _va...)
+ ret := _m.Called(_ca...)
+
+ var r0 *store.LayeredStoreSupplierResult
+ if rf, ok := ret.Get(0).(func(context.Context, string, ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult); ok {
+ r0 = rf(ctx, schemeName, hints...)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(*store.LayeredStoreSupplierResult)
+ }
+ }
+
+ return r0
+}
+
// SchemePermanentDeleteAll provides a mock function with given fields: ctx, hints
func (_m *LayeredStoreSupplier) SchemePermanentDeleteAll(ctx context.Context, hints ...store.LayeredStoreHint) *store.LayeredStoreSupplierResult {
_va := make([]interface{}, len(hints))
diff --git a/store/storetest/mocks/LicenseStore.go b/store/storetest/mocks/LicenseStore.go
index f00ebba78..5c65425ea 100644
--- a/store/storetest/mocks/LicenseStore.go
+++ b/store/storetest/mocks/LicenseStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/OAuthStore.go b/store/storetest/mocks/OAuthStore.go
index a39570b6c..fb49d715d 100644
--- a/store/storetest/mocks/OAuthStore.go
+++ b/store/storetest/mocks/OAuthStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/PluginStore.go b/store/storetest/mocks/PluginStore.go
index b6f161a86..920b0f63c 100644
--- a/store/storetest/mocks/PluginStore.go
+++ b/store/storetest/mocks/PluginStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/PostStore.go b/store/storetest/mocks/PostStore.go
index 8f56bc4b2..f97b8a2f6 100644
--- a/store/storetest/mocks/PostStore.go
+++ b/store/storetest/mocks/PostStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
@@ -66,9 +66,9 @@ func (_m *PostStore) ClearCaches() {
_m.Called()
}
-// Delete provides a mock function with given fields: postId, time
+// Delete provides a mock function with given fields: postId, time, deleteByID
func (_m *PostStore) Delete(postId string, time int64, deleteByID string) store.StoreChannel {
- ret := _m.Called(postId, time)
+ ret := _m.Called(postId, time, deleteByID)
var r0 store.StoreChannel
if rf, ok := ret.Get(0).(func(string, int64, string) store.StoreChannel); ok {
diff --git a/store/storetest/mocks/PreferenceStore.go b/store/storetest/mocks/PreferenceStore.go
index f53ae06d5..5ad56914a 100644
--- a/store/storetest/mocks/PreferenceStore.go
+++ b/store/storetest/mocks/PreferenceStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/ReactionStore.go b/store/storetest/mocks/ReactionStore.go
index b3e81a83b..ce09f3f76 100644
--- a/store/storetest/mocks/ReactionStore.go
+++ b/store/storetest/mocks/ReactionStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/RoleStore.go b/store/storetest/mocks/RoleStore.go
index 95e1914e0..c1b14d5dc 100644
--- a/store/storetest/mocks/RoleStore.go
+++ b/store/storetest/mocks/RoleStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/SchemeStore.go b/store/storetest/mocks/SchemeStore.go
index ffb10f931..ddf24c2c3 100644
--- a/store/storetest/mocks/SchemeStore.go
+++ b/store/storetest/mocks/SchemeStore.go
@@ -61,6 +61,22 @@ func (_m *SchemeStore) GetAllPage(scope string, offset int, limit int) store.Sto
return r0
}
+// GetByName provides a mock function with given fields: schemeName
+func (_m *SchemeStore) GetByName(schemeName string) store.StoreChannel {
+ ret := _m.Called(schemeName)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok {
+ r0 = rf(schemeName)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// PermanentDeleteAll provides a mock function with given fields:
func (_m *SchemeStore) PermanentDeleteAll() store.StoreChannel {
ret := _m.Called()
diff --git a/store/storetest/mocks/SessionStore.go b/store/storetest/mocks/SessionStore.go
index 819ae948d..70b2bd945 100644
--- a/store/storetest/mocks/SessionStore.go
+++ b/store/storetest/mocks/SessionStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/SqlStore.go b/store/storetest/mocks/SqlStore.go
index 6d2c7ec15..021baa7d3 100644
--- a/store/storetest/mocks/SqlStore.go
+++ b/store/storetest/mocks/SqlStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/StatusStore.go b/store/storetest/mocks/StatusStore.go
index 68ccdd4ec..4acb90bdd 100644
--- a/store/storetest/mocks/StatusStore.go
+++ b/store/storetest/mocks/StatusStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/Store.go b/store/storetest/mocks/Store.go
index 5af15d125..dd1967cd5 100644
--- a/store/storetest/mocks/Store.go
+++ b/store/storetest/mocks/Store.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/SystemStore.go b/store/storetest/mocks/SystemStore.go
index e36396fe1..b31e4646d 100644
--- a/store/storetest/mocks/SystemStore.go
+++ b/store/storetest/mocks/SystemStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/TeamStore.go b/store/storetest/mocks/TeamStore.go
index ef5529a1f..ee9999bad 100644
--- a/store/storetest/mocks/TeamStore.go
+++ b/store/storetest/mocks/TeamStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/TokenStore.go b/store/storetest/mocks/TokenStore.go
index 657aeca49..b4baacf03 100644
--- a/store/storetest/mocks/TokenStore.go
+++ b/store/storetest/mocks/TokenStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/UserAccessTokenStore.go b/store/storetest/mocks/UserAccessTokenStore.go
index fd98a8a99..c5ef0fefe 100644
--- a/store/storetest/mocks/UserAccessTokenStore.go
+++ b/store/storetest/mocks/UserAccessTokenStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/UserStore.go b/store/storetest/mocks/UserStore.go
index 347dd2065..6fc787de7 100644
--- a/store/storetest/mocks/UserStore.go
+++ b/store/storetest/mocks/UserStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/mocks/WebhookStore.go b/store/storetest/mocks/WebhookStore.go
index a0b2b0bee..bf5b636eb 100644
--- a/store/storetest/mocks/WebhookStore.go
+++ b/store/storetest/mocks/WebhookStore.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v1.0.0. DO NOT EDIT.
+// Code generated by mockery v1.0.0
// Regenerate this file using `make store-mocks`.
diff --git a/store/storetest/scheme_store.go b/store/storetest/scheme_store.go
index eb4e8efa0..d893f74a0 100644
--- a/store/storetest/scheme_store.go
+++ b/store/storetest/scheme_store.go
@@ -179,6 +179,42 @@ func testSchemeStoreGet(t *testing.T, ss store.Store) {
assert.NotNil(t, res3.Err)
}
+func testSchemeStoreGetByName(t *testing.T, ss store.Store) {
+ // Save a scheme to test with.
+ s1 := &model.Scheme{
+ DisplayName: model.NewId(),
+ Name: model.NewId(),
+ Description: model.NewId(),
+ Scope: model.SCHEME_SCOPE_TEAM,
+ }
+
+ res1 := <-ss.Scheme().Save(s1)
+ assert.Nil(t, res1.Err)
+ d1 := res1.Data.(*model.Scheme)
+ assert.Len(t, d1.Id, 26)
+
+ // Get a valid scheme
+ res2 := <-ss.Scheme().GetByName(d1.Name)
+ assert.Nil(t, res2.Err)
+ d2 := res1.Data.(*model.Scheme)
+ assert.Equal(t, d1.Id, d2.Id)
+ assert.Equal(t, s1.DisplayName, d2.DisplayName)
+ assert.Equal(t, s1.Name, d2.Name)
+ assert.Equal(t, d1.Description, d2.Description)
+ assert.NotZero(t, d2.CreateAt)
+ assert.NotZero(t, d2.UpdateAt)
+ assert.Zero(t, d2.DeleteAt)
+ assert.Equal(t, s1.Scope, d2.Scope)
+ assert.Equal(t, d1.DefaultTeamAdminRole, d2.DefaultTeamAdminRole)
+ assert.Equal(t, d1.DefaultTeamUserRole, d2.DefaultTeamUserRole)
+ assert.Equal(t, d1.DefaultChannelAdminRole, d2.DefaultChannelAdminRole)
+ assert.Equal(t, d1.DefaultChannelUserRole, d2.DefaultChannelUserRole)
+
+ // Get an invalid scheme
+ res3 := <-ss.Scheme().GetByName(model.NewId())
+ assert.NotNil(t, res3.Err)
+}
+
func testSchemeStoreGetAllPage(t *testing.T, ss store.Store) {
// Save a scheme to test with.
schemes := []*model.Scheme{