diff --git a/Makefile b/Makefile index 9a3d8d3494..396cf146ad 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: build package run stop run-client run-server stop-client stop-server restart restart-server restart-client start-docker clean-dist clean nuke check-style check-client-style check-server-style check-unit-tests test dist prepare-enteprise run-client-tests setup-run-client-tests cleanup-run-client-tests test-client build-linux build-osx build-windows internal-test-web-client vet run-server-for-web-client-tests diff-config prepackaged-plugins prepackaged-binaries +.PHONY: build package run stop run-client run-server stop-client stop-server restart restart-server restart-client start-docker clean-dist clean nuke check-style check-client-style check-server-style check-unit-tests test dist prepare-enteprise run-client-tests setup-run-client-tests cleanup-run-client-tests test-client build-linux build-osx build-windows internal-test-web-client vet run-server-for-web-client-tests diff-config prepackaged-plugins prepackaged-binaries test-server test-server-quick test-server-race ROOT := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) @@ -81,9 +81,6 @@ DIST_PATH=$(DIST_ROOT)/mattermost # Tests TESTS=. -TESTFLAGS ?= -short -TESTFLAGSEE ?= -short - # Packages lists TE_PACKAGES=$(shell $(GO) list ./...) @@ -312,6 +309,15 @@ else endif ./scripts/test.sh "$(GO)" "$(GOFLAGS)" "$(ALL_PACKAGES)" "$(TESTS)" "$(TESTFLAGS)" "$(GOBIN)" +test-server-quick: ## Runs only quick tests. +ifeq ($(BUILD_ENTERPRISE_READY),true) + @echo Running all tests + $(GO) test $(GOFLAGS) -short $(ALL_PACKAGES) +else + @echo Running only TE tests + $(GO) test $(GOFLAGS) -short $(TE_PACKAGES) +endif + internal-test-web-client: ## Runs web client tests. $(GO) run $(GOFLAGS) $(PLATFORM_FILES) test web_client_tests diff --git a/api4/apitestlib.go b/api4/apitestlib.go index fc035f75b8..2b99dbf878 100644 --- a/api4/apitestlib.go +++ b/api4/apitestlib.go @@ -19,6 +19,8 @@ import ( "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/store" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" + "github.com/mattermost/mattermost-server/v5/testlib" "github.com/mattermost/mattermost-server/v5/utils" "github.com/mattermost/mattermost-server/v5/web" "github.com/mattermost/mattermost-server/v5/wsapi" @@ -51,19 +53,9 @@ type TestHelper struct { tempWorkspace string } -// testStore tracks the active test store. -// This is a bridge between the new testlib ownership of the test store and the existing usage -// of the api4 test helper by many packages. In the future, this test helper would ideally belong -// to the testlib altogether. -var testStore store.Store - -func UseTestStore(store store.Store) { - testStore = store -} - -func setupTestHelper(enterprise bool, updateConfig func(*model.Config)) *TestHelper { - testStore.DropAllTables() +var mainHelper *testlib.MainHelper +func setupTestHelper(dbStore store.Store, enterprise bool, updateConfig func(*model.Config)) *TestHelper { tempWorkspace, err := ioutil.TempDir("", "apptest") if err != nil { panic(err) @@ -84,7 +76,7 @@ func setupTestHelper(enterprise bool, updateConfig func(*model.Config)) *TestHel var options []app.Option options = append(options, app.ConfigStore(memoryStore)) - options = append(options, app.StoreOverride(testStore)) + options = append(options, app.StoreOverride(dbStore)) s, err := app.NewServer(options...) if err != nil { @@ -117,7 +109,6 @@ func setupTestHelper(enterprise bool, updateConfig func(*model.Config)) *TestHel Init(th.Server, th.Server.AppOptions, th.App.Srv().Router) web.New(th.Server, th.Server.AppOptions, th.App.Srv().Router) wsapi.Init(th.App, th.App.Srv().WebSocketRouter) - th.App.Srv().Store.MarkSystemRanUnitTests() th.App.DoAppMigrations() th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) @@ -148,15 +139,72 @@ func setupTestHelper(enterprise bool, updateConfig func(*model.Config)) *TestHel } func SetupEnterprise(tb testing.TB) *TestHelper { - return setupTestHelper(true, nil) + if testing.Short() { + tb.SkipNow() + } + + if mainHelper == nil { + tb.SkipNow() + } + + dbStore := mainHelper.GetStore() + dbStore.DropAllTables() + dbStore.MarkSystemRanUnitTests() + return setupTestHelper(dbStore, true, nil) } func Setup(tb testing.TB) *TestHelper { - return setupTestHelper(false, nil) + if testing.Short() { + tb.SkipNow() + } + + if mainHelper == nil { + tb.SkipNow() + } + + dbStore := mainHelper.GetStore() + dbStore.DropAllTables() + dbStore.MarkSystemRanUnitTests() + return setupTestHelper(dbStore, false, nil) } func SetupConfig(tb testing.TB, updateConfig func(cfg *model.Config)) *TestHelper { - return setupTestHelper(false, updateConfig) + if testing.Short() { + tb.SkipNow() + } + + if mainHelper == nil { + tb.SkipNow() + } + + dbStore := mainHelper.GetStore() + dbStore.DropAllTables() + dbStore.MarkSystemRanUnitTests() + return setupTestHelper(dbStore, false, updateConfig) +} + +func SetupConfigWithStoreMock(tb testing.TB, updateConfig func(cfg *model.Config)) *TestHelper { + th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), false, updateConfig) + emptyMockStore := mocks.Store{} + emptyMockStore.On("Close").Return(nil) + th.App.Srv().Store = &emptyMockStore + return th +} + +func SetupWithStoreMock(tb testing.TB) *TestHelper { + th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), false, nil) + emptyMockStore := mocks.Store{} + emptyMockStore.On("Close").Return(nil) + th.App.Srv().Store = &emptyMockStore + return th +} + +func SetupEnterpriseWithStoreMock(tb testing.TB) *TestHelper { + th := setupTestHelper(testlib.GetMockStoreForSetupFunctions(), true, nil) + emptyMockStore := mocks.Store{} + emptyMockStore.On("Close").Return(nil) + th.App.Srv().Store = &emptyMockStore + return th } func (me *TestHelper) ShutdownApp() { diff --git a/api4/cors_test.go b/api4/cors_test.go index 7f64714486..b71b0fba12 100644 --- a/api4/cors_test.go +++ b/api4/cors_test.go @@ -119,7 +119,7 @@ func TestCORSRequestHandling(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - th := SetupConfig(t, func(cfg *model.Config) { + th := SetupConfigWithStoreMock(t, func(cfg *model.Config) { *cfg.ServiceSettings.AllowCorsFrom = testcase.AllowCorsFrom *cfg.ServiceSettings.CorsExposedHeaders = testcase.CorsExposedHeaders *cfg.ServiceSettings.CorsAllowCredentials = testcase.CorsAllowCredentials diff --git a/api4/main_test.go b/api4/main_test.go index 7adb34e618..e136f23931 100644 --- a/api4/main_test.go +++ b/api4/main_test.go @@ -9,8 +9,6 @@ import ( "github.com/mattermost/mattermost-server/v5/testlib" ) -var mainHelper *testlib.MainHelper - func TestMain(m *testing.M) { var options = testlib.HelperOptions{ EnableStore: true, @@ -20,6 +18,5 @@ func TestMain(m *testing.M) { mainHelper = testlib.NewMainHelperWithOptions(&options) defer mainHelper.Close() - UseTestStore(mainHelper.GetStore()) mainHelper.Main(m) } diff --git a/app/app_test.go b/app/app_test.go index b0f0f65d24..a7943542d6 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -9,8 +9,10 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" ) /* Temporarily comment out until MM-11108 @@ -26,10 +28,21 @@ func TestAppRace(t *testing.T) { } */ -func TestUpdateConfig(t *testing.T) { - th := Setup(t) +func TestUnitUpdateConfig(t *testing.T) { + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*mocks.Store) + mockUserStore := mocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := mocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := mocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + prev := *th.App.Config().ServiceSettings.SiteURL th.App.AddConfigListener(func(old, current *model.Config) { diff --git a/app/config_test.go b/app/config_test.go index 13a0b73a43..637885a973 100644 --- a/app/config_test.go +++ b/app/config_test.go @@ -9,9 +9,11 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/store/sqlstore" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" "github.com/mattermost/mattermost-server/v5/utils" ) @@ -51,22 +53,33 @@ func TestConfigListener(t *testing.T) { } func TestAsymmetricSigningKey(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() assert.NotNil(t, th.App.AsymmetricSigningKey()) assert.NotEmpty(t, th.App.ClientConfig()["AsymmetricSigningPublicKey"]) } func TestPostActionCookieSecret(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() assert.Equal(t, 32, len(th.App.PostActionCookieSecret())) } func TestClientConfigWithComputed(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*mocks.Store) + mockUserStore := mocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := mocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := mocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + config := th.App.ClientConfigWithComputed() _, ok := config["NoAccounts"] assert.True(t, ok, "expected NoAccounts in returned config") diff --git a/app/email_batching_test.go b/app/email_batching_test.go index ca385d10bd..4f6cdf96d8 100644 --- a/app/email_batching_test.go +++ b/app/email_batching_test.go @@ -14,7 +14,7 @@ import ( ) func TestHandleNewNotifications(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() id1 := model.NewId() @@ -265,7 +265,7 @@ func TestCheckPendingNotificationsCantParseInterval(t *testing.T) { * Ensures that post contents are not included in notification email when email notification content type is set to generic */ func TestRenderBatchedPostGeneric(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() var post = &model.Post{} @@ -290,7 +290,7 @@ func TestRenderBatchedPostGeneric(t *testing.T) { * Ensures that post contents included in notification email when email notification content type is set to full */ func TestRenderBatchedPostFull(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() var post = &model.Post{} diff --git a/app/enterprise_test.go b/app/enterprise_test.go index 06093abf44..9c770d0645 100644 --- a/app/enterprise_test.go +++ b/app/enterprise_test.go @@ -9,7 +9,9 @@ import ( "github.com/mattermost/mattermost-server/v5/einterfaces" "github.com/mattermost/mattermost-server/v5/einterfaces/mocks" "github.com/mattermost/mattermost-server/v5/model" + storemocks "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" ) func TestSAMLSettings(t *testing.T) { @@ -93,9 +95,20 @@ func TestSAMLSettings(t *testing.T) { RegisterNewSamlInterface(nil) } - th := SetupEnterprise(t) + th := SetupEnterpriseWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*storemocks.Store) + mockUserStore := storemocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := storemocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := storemocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + if tc.useNewSAMLLibrary { th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ExperimentalSettings.UseNewSAMLLibrary = tc.useNewSAMLLibrary diff --git a/app/export_test.go b/app/export_test.go index f0b2d9131e..eae5a91738 100644 --- a/app/export_test.go +++ b/app/export_test.go @@ -44,7 +44,7 @@ func TestReactionsOfPost(t *testing.T) { } func TestExportUserNotifyProps(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() userNotifyProps := model.StringMap{ @@ -112,7 +112,7 @@ func TestExportUserChannels(t *testing.T) { } func TestDirCreationForEmoji(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() pathToDir := th.App.createDirForEmoji("test.json", "exported_emoji_test") @@ -122,7 +122,7 @@ func TestDirCreationForEmoji(t *testing.T) { } func TestCopyEmojiImages(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() emoji := &model.Emoji{ diff --git a/app/helper_test.go b/app/helper_test.go index 7e986fa1d0..e26e438b92 100644 --- a/app/helper_test.go +++ b/app/helper_test.go @@ -15,6 +15,9 @@ import ( "github.com/mattermost/mattermost-server/v5/config" "github.com/mattermost/mattermost-server/v5/mlog" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/store" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" + "github.com/mattermost/mattermost-server/v5/testlib" "github.com/mattermost/mattermost-server/v5/utils" "github.com/stretchr/testify/require" ) @@ -33,10 +36,7 @@ type TestHelper struct { tempWorkspace string } -func setupTestHelper(enterprise bool, tb testing.TB, configSet func(*model.Config)) *TestHelper { - store := mainHelper.GetStore() - store.DropAllTables() - +func setupTestHelper(dbStore store.Store, enterprise bool, tb testing.TB, configSet func(*model.Config)) *TestHelper { tempWorkspace, err := ioutil.TempDir("", "apptest") if err != nil { panic(err) @@ -57,7 +57,7 @@ func setupTestHelper(enterprise bool, tb testing.TB, configSet func(*model.Confi var options []Option options = append(options, ConfigStore(memoryStore)) - options = append(options, StoreOverride(mainHelper.Store)) + options = append(options, StoreOverride(dbStore)) options = append(options, SetLogger(mlog.NewTestingLogger(tb))) s, err := NewServer(options...) @@ -80,9 +80,6 @@ func setupTestHelper(enterprise bool, tb testing.TB, configSet func(*model.Confi } th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) - - th.App.Srv().Store.MarkSystemRanUnitTests() - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) // Disable strict password requirements for test @@ -108,15 +105,54 @@ func setupTestHelper(enterprise bool, tb testing.TB, configSet func(*model.Confi } func SetupEnterprise(tb testing.TB) *TestHelper { - return setupTestHelper(true, tb, nil) + if testing.Short() { + tb.SkipNow() + } + dbStore := mainHelper.GetStore() + dbStore.DropAllTables() + dbStore.MarkSystemRanUnitTests() + + return setupTestHelper(dbStore, true, tb, nil) } func Setup(tb testing.TB) *TestHelper { - return setupTestHelper(false, tb, nil) + if testing.Short() { + tb.SkipNow() + } + dbStore := mainHelper.GetStore() + dbStore.DropAllTables() + dbStore.MarkSystemRanUnitTests() + + return setupTestHelper(dbStore, false, tb, nil) +} + +func SetupWithStoreMock(tb testing.TB) *TestHelper { + mockStore := testlib.GetMockStoreForSetupFunctions() + th := setupTestHelper(mockStore, false, tb, nil) + emptyMockStore := mocks.Store{} + emptyMockStore.On("Close").Return(nil) + th.App.Srv().Store = &emptyMockStore + return th +} + +func SetupEnterpriseWithStoreMock(tb testing.TB) *TestHelper { + mockStore := testlib.GetMockStoreForSetupFunctions() + th := setupTestHelper(mockStore, true, tb, nil) + emptyMockStore := mocks.Store{} + emptyMockStore.On("Close").Return(nil) + th.App.Srv().Store = &emptyMockStore + return th } func SetupWithCustomConfig(tb testing.TB, configSet func(*model.Config)) *TestHelper { - return setupTestHelper(false, tb, configSet) + if testing.Short() { + tb.SkipNow() + } + dbStore := mainHelper.GetStore() + dbStore.DropAllTables() + dbStore.MarkSystemRanUnitTests() + + return setupTestHelper(dbStore, false, tb, configSet) } func (me *TestHelper) InitBasic() *TestHelper { diff --git a/app/notification_email_test.go b/app/notification_email_test.go index aa578658b9..957379baea 100644 --- a/app/notification_email_test.go +++ b/app/notification_email_test.go @@ -15,13 +15,11 @@ import ( "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/services/timezones" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" "github.com/mattermost/mattermost-server/v5/utils" ) func TestGetDirectMessageNotificationEmailSubject(t *testing.T) { - th := Setup(t) - defer th.TearDown() - expectedPrefix := "[http://localhost:8065] New Direct Message from @sender on" user := &model.User{} post := &model.Post{ @@ -33,9 +31,6 @@ func TestGetDirectMessageNotificationEmailSubject(t *testing.T) { } func TestGetGroupMessageNotificationEmailSubjectFull(t *testing.T) { - th := Setup(t) - defer th.TearDown() - expectedPrefix := "[http://localhost:8065] New Group Message in sender on" user := &model.User{} post := &model.Post{ @@ -48,9 +43,6 @@ func TestGetGroupMessageNotificationEmailSubjectFull(t *testing.T) { } func TestGetGroupMessageNotificationEmailSubjectGeneric(t *testing.T) { - th := Setup(t) - defer th.TearDown() - expectedPrefix := "[http://localhost:8065] New Group Message on" user := &model.User{} post := &model.Post{ @@ -63,9 +55,6 @@ func TestGetGroupMessageNotificationEmailSubjectGeneric(t *testing.T) { } func TestGetNotificationEmailSubject(t *testing.T) { - th := Setup(t) - defer th.TearDown() - expectedPrefix := "[http://localhost:8065] Notification in team on" user := &model.User{} post := &model.Post{ @@ -77,7 +66,7 @@ func TestGetNotificationEmailSubject(t *testing.T) { } func TestGetNotificationEmailBodyFullNotificationPublicChannel(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -90,11 +79,16 @@ func TestGetNotificationEmailBodyFullNotificationPublicChannel(t *testing.T) { } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "You have a new notification.", fmt.Sprintf("Expected email text 'You have a new notification. Got %s", body)) require.Contains(t, body, "Channel: "+channel.DisplayName, "Expected email text 'Channel: %s'. Got %s", channel.DisplayName, body) @@ -104,7 +98,7 @@ func TestGetNotificationEmailBodyFullNotificationPublicChannel(t *testing.T) { } func TestGetNotificationEmailBodyFullNotificationGroupChannel(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -117,11 +111,16 @@ func TestGetNotificationEmailBodyFullNotificationGroupChannel(t *testing.T) { } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "You have a new Group Message.", fmt.Sprintf("Expected email text 'You have a new Group Message. Got "+body)) require.Contains(t, body, "Channel: ChannelName", fmt.Sprintf("Expected email text 'Channel: ChannelName'. Got %s", body)) @@ -131,7 +130,7 @@ func TestGetNotificationEmailBodyFullNotificationGroupChannel(t *testing.T) { } func TestGetNotificationEmailBodyFullNotificationPrivateChannel(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -144,11 +143,16 @@ func TestGetNotificationEmailBodyFullNotificationPrivateChannel(t *testing.T) { } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "You have a new notification.", fmt.Sprintf("Expected email text 'You have a new notification. Got "+body)) require.Contains(t, body, "Channel: "+channel.DisplayName, fmt.Sprintf("Expected email text 'Channel: "+channel.DisplayName+"'. Got "+body)) @@ -158,7 +162,7 @@ func TestGetNotificationEmailBodyFullNotificationPrivateChannel(t *testing.T) { } func TestGetNotificationEmailBodyFullNotificationDirectChannel(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -171,11 +175,16 @@ func TestGetNotificationEmailBodyFullNotificationDirectChannel(t *testing.T) { } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "You have a new Direct Message.", fmt.Sprintf("Expected email text 'You have a new Direct Message. Got "+body)) require.Contains(t, body, senderName+" - ", fmt.Sprintf("Expected email text '%s - '. Got %s", senderName, body)) @@ -184,7 +193,7 @@ func TestGetNotificationEmailBodyFullNotificationDirectChannel(t *testing.T) { } func TestGetNotificationEmailBodyFullNotificationLocaleTimeWithTimezone(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{ @@ -201,11 +210,16 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTimeWithTimezone(t *testi } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, false, translateFunc) r, _ := regexp.Compile("E([S|D]+)T") zone := r.FindString(body) @@ -213,7 +227,7 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTimeWithTimezone(t *testi } func TestGetNotificationEmailBodyFullNotificationLocaleTimeNoTimezone(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{ @@ -229,11 +243,16 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTimeNoTimezone(t *testing } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + tm := time.Unix(post.CreateAt/1000, 0) zone, _ := tm.Zone() @@ -253,7 +272,7 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTimeNoTimezone(t *testing } func TestGetNotificationEmailBodyFullNotificationLocaleTime12Hour(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{ @@ -270,18 +289,23 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTime12Hour(t *testing.T) } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, false, translateFunc) require.Contains(t, body, "sender - 2:30 PM", fmt.Sprintf("Expected email text 'sender - 2:30 PM'. Got %s", body)) require.Contains(t, body, "April 25", fmt.Sprintf("Expected email text 'April 25'. Got %s", body)) } func TestGetNotificationEmailBodyFullNotificationLocaleTime24Hour(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{ @@ -298,11 +322,16 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTime24Hour(t *testing.T) } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "sender - 14:30", fmt.Sprintf("Expected email text 'sender - 14:30'. Got %s", body)) require.Contains(t, body, "April 25", fmt.Sprintf("Expected email text 'April 25'. Got %s", body)) @@ -310,7 +339,7 @@ func TestGetNotificationEmailBodyFullNotificationLocaleTime24Hour(t *testing.T) // from here func TestGetNotificationEmailBodyGenericNotificationPublicChannel(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -323,11 +352,16 @@ func TestGetNotificationEmailBodyGenericNotificationPublicChannel(t *testing.T) } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "You have a new notification from "+senderName, fmt.Sprintf("Expected email text 'You have a new notification from %s'. Got %s", senderName, body)) require.False(t, strings.Contains(body, "Channel: "+channel.DisplayName), fmt.Sprintf("Did not expect email text 'CHANNEL: %s'. Got %s", channel.DisplayName, body)) @@ -336,7 +370,7 @@ func TestGetNotificationEmailBodyGenericNotificationPublicChannel(t *testing.T) } func TestGetNotificationEmailBodyGenericNotificationGroupChannel(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -349,11 +383,16 @@ func TestGetNotificationEmailBodyGenericNotificationGroupChannel(t *testing.T) { } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "You have a new Group Message from "+senderName, fmt.Sprintf("Expected email text 'You have a new Group Message from %s'. Got %s", senderName, body)) require.False(t, strings.Contains(body, "CHANNEL: "+channel.DisplayName), fmt.Sprintf("Did not expect email text 'CHANNEL: %s'. Got %s", channel.DisplayName, body)) @@ -362,7 +401,7 @@ func TestGetNotificationEmailBodyGenericNotificationGroupChannel(t *testing.T) { } func TestGetNotificationEmailBodyGenericNotificationPrivateChannel(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -375,11 +414,16 @@ func TestGetNotificationEmailBodyGenericNotificationPrivateChannel(t *testing.T) } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "You have a new notification from "+senderName, fmt.Sprintf("Expected email text 'You have a new notification from %s'. Got %s", senderName, body)) require.False(t, strings.Contains(body, "CHANNEL: "+channel.DisplayName), fmt.Sprintf("Did not expect email text 'CHANNEL: %s'. Got %s", channel.DisplayName, body)) @@ -388,7 +432,7 @@ func TestGetNotificationEmailBodyGenericNotificationPrivateChannel(t *testing.T) } func TestGetNotificationEmailBodyGenericNotificationDirectChannel(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -401,11 +445,16 @@ func TestGetNotificationEmailBodyGenericNotificationDirectChannel(t *testing.T) } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_GENERIC translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, "You have a new Direct Message from "+senderName, fmt.Sprintf("Expected email text 'You have a new Direct Message from "+senderName+"'. Got "+body)) require.False(t, strings.Contains(body, "CHANNEL: "+channel.DisplayName), fmt.Sprintf("Did not expect email text 'CHANNEL: %s'. Got %s", channel.DisplayName, body)) @@ -414,7 +463,7 @@ func TestGetNotificationEmailBodyGenericNotificationDirectChannel(t *testing.T) } func TestGetNotificationEmailEscapingChars(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() ch := &model.Channel{ @@ -429,35 +478,59 @@ func TestGetNotificationEmailEscapingChars(t *testing.T) { } senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, ch, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) - fmt.Println(body) assert.NotContains(t, body, message) } func TestGetNotificationEmailBodyPublicChannelMention(t *testing.T) { - th := Setup(t).InitBasic() + th := SetupWithStoreMock(t) defer th.TearDown() - ch := th.BasicChannel - recipient := th.BasicUser2 + ch := &model.Channel{ + Name: "channelname", + DisplayName: "ChannelName", + Type: model.CHANNEL_OPEN, + } + id := model.NewId() + recipient := &model.User{ + Email: "success+" + id + "@simulator.amazonses.com", + Username: "un_" + id, + Nickname: "nn_" + id, + Password: "Password1", + EmailVerified: true, + } post := &model.Post{ Message: "This is the message ~" + ch.Name, } - senderName := th.BasicUser.Username - teamName := th.BasicTeam.Name - teamURL := "http://localhost:8065/" + teamName + senderName := "user1" + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Id: "test", Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + + channelStoreMock := mocks.ChannelStore{} + channelStoreMock.On("GetByNames", "test", []string{ch.Name}, true).Return([]*model.Channel{ch}, nil) + storeMock.On("Channel").Return(&channelStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, ch, ch.Name, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) @@ -467,31 +540,62 @@ func TestGetNotificationEmailBodyPublicChannelMention(t *testing.T) { } func TestGetNotificationEmailBodyMultiPublicChannelMention(t *testing.T) { - th := Setup(t).InitBasic() + th := SetupWithStoreMock(t) defer th.TearDown() - ch := th.BasicChannel + ch := &model.Channel{ + Id: model.NewId(), + Name: "channelnameone", + DisplayName: "ChannelName", + Type: model.CHANNEL_OPEN, + } mention := "~" + ch.Name - ch2 := th.CreateChannel(th.BasicTeam) + ch2 := &model.Channel{ + Id: model.NewId(), + Name: "channelnametwo", + DisplayName: "ChannelName2", + Type: model.CHANNEL_OPEN, + } mention2 := "~" + ch2.Name - ch3 := th.CreateChannel(th.BasicTeam) + ch3 := &model.Channel{ + Id: model.NewId(), + Name: "channelnamethree", + DisplayName: "ChannelName3", + Type: model.CHANNEL_OPEN, + } mention3 := "~" + ch3.Name message := fmt.Sprintf("This is the message Channel1: %s; Channel2: %s;"+ " Channel3: %s", mention, mention2, mention3) - recipient := th.BasicUser2 + id := model.NewId() + recipient := &model.User{ + Email: "success+" + id + "@simulator.amazonses.com", + Username: "un_" + id, + Nickname: "nn_" + id, + Password: "Password1", + EmailVerified: true, + } post := &model.Post{ Message: message, } - senderName := th.BasicUser.Username - teamName := th.BasicTeam.Name - teamURL := "http://localhost:8065/" + teamName + senderName := "user1" + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Id: "test", Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + + channelStoreMock := mocks.ChannelStore{} + channelStoreMock.On("GetByNames", "test", []string{ch.Name, ch2.Name, ch3.Name}, true).Return([]*model.Channel{ch, ch2, ch3}, nil) + storeMock.On("Channel").Return(&channelStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, ch, ch.Name, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) @@ -505,21 +609,41 @@ func TestGetNotificationEmailBodyMultiPublicChannelMention(t *testing.T) { } func TestGetNotificationEmailBodyPrivateChannelMention(t *testing.T) { - th := Setup(t).InitBasic() + th := SetupWithStoreMock(t) defer th.TearDown() - ch := th.CreatePrivateChannel(th.BasicTeam) - recipient := th.BasicUser2 + ch := &model.Channel{ + Name: "channelname", + DisplayName: "ChannelName", + Type: model.CHANNEL_PRIVATE, + } + id := model.NewId() + recipient := &model.User{ + Email: "success+" + id + "@simulator.amazonses.com", + Username: "un_" + id, + Nickname: "nn_" + id, + Password: "Password1", + EmailVerified: true, + } post := &model.Post{ Message: "This is the message ~" + ch.Name, } - senderName := th.BasicUser.Username - teamName := ch.Name - teamURL := "http://localhost:8065/" + teamName + senderName := "user1" + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Id: "test", Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + + channelStoreMock := mocks.ChannelStore{} + channelStoreMock.On("GetByNames", "test", []string{ch.Name}, true).Return([]*model.Channel{ch}, nil) + storeMock.On("Channel").Return(&channelStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, ch, ch.Name, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) @@ -529,15 +653,28 @@ func TestGetNotificationEmailBodyPrivateChannelMention(t *testing.T) { } func TestGenerateHyperlinkForChannelsPublic(t *testing.T) { - th := Setup(t).InitBasic() + th := SetupWithStoreMock(t) defer th.TearDown() - ch := th.BasicChannel + ch := &model.Channel{ + Name: "channelname", + DisplayName: "ChannelName", + Type: model.CHANNEL_OPEN, + } message := "This is the message " mention := "~" + ch.Name - teamName := th.BasicTeam.Name - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" + + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Id: "test", Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + + channelStoreMock := mocks.ChannelStore{} + channelStoreMock.On("GetByNames", "test", []string{ch.Name}, true).Return([]*model.Channel{ch}, nil) + storeMock.On("Channel").Return(&channelStoreMock) outMessage := th.App.generateHyperlinkForChannels(message+mention, teamName, teamURL) channelURL := teamURL + "/channels/" + ch.Name @@ -545,23 +682,48 @@ func TestGenerateHyperlinkForChannelsPublic(t *testing.T) { } func TestGenerateHyperlinkForChannelsMultiPublic(t *testing.T) { - th := Setup(t).InitBasic() + th := SetupWithStoreMock(t) defer th.TearDown() - ch := th.BasicChannel + // TODO: Fix the case where the first channel name contains the other channel names (for example here channelnameone)" + ch := &model.Channel{ + Id: model.NewId(), + Name: "channelnameone", + DisplayName: "ChannelName", + Type: model.CHANNEL_OPEN, + } mention := "~" + ch.Name - ch2 := th.CreateChannel(th.BasicTeam) + ch2 := &model.Channel{ + Id: model.NewId(), + Name: "channelnametwo", + DisplayName: "ChannelName2", + Type: model.CHANNEL_OPEN, + } mention2 := "~" + ch2.Name - ch3 := th.CreateChannel(th.BasicTeam) + ch3 := &model.Channel{ + Id: model.NewId(), + Name: "channelnamethree", + DisplayName: "ChannelName3", + Type: model.CHANNEL_OPEN, + } mention3 := "~" + ch3.Name message := fmt.Sprintf("This is the message Channel1: %s; Channel2: %s;"+ " Channel3: %s", mention, mention2, mention3) - teamName := th.BasicTeam.Name - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" + + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Id: "test", Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + + channelStoreMock := mocks.ChannelStore{} + channelStoreMock.On("GetByNames", "test", []string{ch.Name, ch2.Name, ch3.Name}, true).Return([]*model.Channel{ch, ch2, ch3}, nil) + storeMock.On("Channel").Return(&channelStoreMock) outMessage := th.App.generateHyperlinkForChannels(message, teamName, teamURL) channelURL := teamURL + "/channels/" + ch.Name @@ -574,21 +736,34 @@ func TestGenerateHyperlinkForChannelsMultiPublic(t *testing.T) { } func TestGenerateHyperlinkForChannelsPrivate(t *testing.T) { - th := Setup(t).InitBasic() + th := SetupWithStoreMock(t) defer th.TearDown() - ch := th.CreatePrivateChannel(th.BasicTeam) + ch := &model.Channel{ + Name: "channelname", + DisplayName: "ChannelName", + Type: model.CHANNEL_PRIVATE, + } message := "This is the message ~" + ch.Name - teamName := th.BasicTeam.Name - teamURL := "http://localhost:8065/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/testteam" + + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Id: "test", Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + + channelStoreMock := mocks.ChannelStore{} + channelStoreMock.On("GetByNames", "test", []string{ch.Name}, true).Return([]*model.Channel{ch}, nil) + storeMock.On("Channel").Return(&channelStoreMock) outMessage := th.App.generateHyperlinkForChannels(message, teamName, teamURL) assert.Equal(t, message, outMessage) } func TestLandingLink(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -601,17 +776,22 @@ func TestLandingLink(t *testing.T) { } channelName := "ChannelName" senderName := "sender" - teamName := "select_team" - teamURL := "http://localhost:8065/landing#/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/landing#/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, teamURL, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body)) } func TestLandingLinkPermalink(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() recipient := &model.User{} @@ -625,11 +805,16 @@ func TestLandingLinkPermalink(t *testing.T) { } channelName := "ChannelName" senderName := "sender" - teamName := "team" - teamURL := "http://localhost:8065/landing#/" + teamName + teamName := "testteam" + teamURL := "http://localhost:8065/landing#/testteam" emailNotificationContentsType := model.EMAIL_NOTIFICATION_CONTENTS_FULL translateFunc := utils.GetUserTranslations("en") + storeMock := th.App.Srv().Store.(*mocks.Store) + teamStoreMock := mocks.TeamStore{} + teamStoreMock.On("GetByName", "testteam").Return(&model.Team{Name: "testteam"}, nil) + storeMock.On("Team").Return(&teamStoreMock) + body := th.App.getNotificationEmailBody(recipient, post, channel, channelName, senderName, teamName, teamURL, emailNotificationContentsType, true, translateFunc) require.Contains(t, body, teamURL+"/pl/"+post.Id, fmt.Sprintf("Expected email text '%s'. Got %s", teamURL, body)) } diff --git a/app/notification_push_test.go b/app/notification_push_test.go index b400f466ad..394991ee35 100644 --- a/app/notification_push_test.go +++ b/app/notification_push_test.go @@ -8,8 +8,10 @@ import ( "testing" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" "github.com/mattermost/mattermost-server/v5/utils" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -539,9 +541,20 @@ func TestDoesStatusAllowPushNotification(t *testing.T) { } func TestGetPushNotificationMessage(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*mocks.Store) + mockUserStore := mocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := mocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := mocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + for name, tc := range map[string]struct { Message string explicitMention bool diff --git a/app/permissions_migrations.go b/app/permissions_migrations.go index ddff93c676..dcf10ec97f 100644 --- a/app/permissions_migrations.go +++ b/app/permissions_migrations.go @@ -15,17 +15,6 @@ type permissionTransformation struct { type permissionsMap []permissionTransformation const ( - MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split" - MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT = "webhook_permissions_split" - MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS = "list_join_public_private_teams" - MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER = "remove_permanent_delete_user" - MIGRATION_KEY_ADD_BOT_PERMISSIONS = "add_bot_permissions" - MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER = "apply_channel_manage_delete_to_channel_user" - MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER = "remove_channel_manage_delete_from_team_user" - MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION = "view_members_new_permission" - MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS = "add_manage_guests_permissions" - MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION = "add_use_channel_mentions_permission" - PERMISSION_MANAGE_SYSTEM = "manage_system" PERMISSION_MANAGE_EMOJIS = "manage_emojis" PERMISSION_MANAGE_OTHERS_EMOJIS = "manage_others_emojis" @@ -306,16 +295,16 @@ func (a *App) DoPermissionsMigrations() *model.AppError { Key string Migration func() permissionsMap }{ - {Key: MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Migration: getEmojisPermissionsSplitMigration}, - {Key: MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Migration: getWebhooksPermissionsSplitMigration}, - {Key: MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS, Migration: getListJoinPublicPrivateTeamsPermissionsMigration}, - {Key: MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER, Migration: removePermanentDeleteUserMigration}, - {Key: MIGRATION_KEY_ADD_BOT_PERMISSIONS, Migration: getAddBotPermissionsMigration}, - {Key: MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER, Migration: applyChannelManageDeleteToChannelUser}, - {Key: MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER, Migration: removeChannelManageDeleteFromTeamUser}, - {Key: MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION, Migration: getViewMembersPermissionMigration}, - {Key: MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS, Migration: getAddManageGuestsPermissionsMigration}, - {Key: MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION, Migration: getAddUseMentionChannelsPermissionMigration}, + {Key: model.MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Migration: getEmojisPermissionsSplitMigration}, + {Key: model.MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Migration: getWebhooksPermissionsSplitMigration}, + {Key: model.MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS, Migration: getListJoinPublicPrivateTeamsPermissionsMigration}, + {Key: model.MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER, Migration: removePermanentDeleteUserMigration}, + {Key: model.MIGRATION_KEY_ADD_BOT_PERMISSIONS, Migration: getAddBotPermissionsMigration}, + {Key: model.MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER, Migration: applyChannelManageDeleteToChannelUser}, + {Key: model.MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER, Migration: removeChannelManageDeleteFromTeamUser}, + {Key: model.MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION, Migration: getViewMembersPermissionMigration}, + {Key: model.MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS, Migration: getAddManageGuestsPermissionsMigration}, + {Key: model.MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION, Migration: getAddUseMentionChannelsPermissionMigration}, } for _, migration := range PermissionsMigrations { diff --git a/app/plugin_signature_test.go b/app/plugin_signature_test.go index c9a59f82ed..9eb5806253 100644 --- a/app/plugin_signature_test.go +++ b/app/plugin_signature_test.go @@ -9,14 +9,28 @@ import ( "path/filepath" "testing" + "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" "github.com/mattermost/mattermost-server/v5/utils/fileutils" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) func TestPluginPublicKeys(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*mocks.Store) + mockUserStore := mocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := mocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := mocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + path, _ := fileutils.FindDir("tests") publicKeyFilename := "test-public-key.plugin.gpg" publicKey, err := ioutil.ReadFile(filepath.Join(path, publicKeyFilename)) diff --git a/app/post_test.go b/app/post_test.go index 72cffa820f..b2c2c78d15 100644 --- a/app/post_test.go +++ b/app/post_test.go @@ -17,6 +17,7 @@ import ( "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/plugin/plugintest/mock" "github.com/mattermost/mattermost-server/v5/store/storetest" + storemocks "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" ) func TestCreatePostDeduplicate(t *testing.T) { @@ -445,9 +446,20 @@ func TestPostChannelMentions(t *testing.T) { } func TestImageProxy(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*storemocks.Store) + mockUserStore := storemocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := storemocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := storemocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.SiteURL = "http://mymattermost.com" }) diff --git a/cmd/mattermost/commands/cmdtestlib.go b/cmd/mattermost/commands/cmdtestlib.go index 71087ba786..e019f9fd54 100644 --- a/cmd/mattermost/commands/cmdtestlib.go +++ b/cmd/mattermost/commands/cmdtestlib.go @@ -57,6 +57,28 @@ func Setup(t testing.TB) *testHelper { return testHelper } +// Setup creates an instance of testHelper. +func SetupWithStoreMock(t testing.TB) *testHelper { + dir, err := ioutil.TempDir("", "testHelper") + if err != nil { + panic("failed to create temporary directory: " + err.Error()) + } + + api4TestHelper := api4.SetupWithStoreMock(t) + + testHelper := &testHelper{ + TestHelper: api4TestHelper, + tempDir: dir, + configFilePath: filepath.Join(dir, "config-helper.json"), + } + + config := &model.Config{} + config.SetDefaults() + testHelper.SetConfig(config) + + return testHelper +} + // InitBasic simply proxies to api4.InitBasic, while still returning a testHelper. func (h *testHelper) InitBasic() *testHelper { h.TestHelper.InitBasic() @@ -80,7 +102,9 @@ func (h *testHelper) ConfigPath() string { // SetConfig replaces the configuration passed to a running command. func (h *testHelper) SetConfig(config *model.Config) { - config.SqlSettings = *mainHelper.GetSQLSettings() + if !testing.Short() { + config.SqlSettings = *mainHelper.GetSQLSettings() + } // Disable strict password requirements for test *config.PasswordSettings.MinimumLength = 5 diff --git a/cmd/mattermost/commands/main_test.go b/cmd/mattermost/commands/main_test.go index c187c733c3..cb1be3f385 100644 --- a/cmd/mattermost/commands/main_test.go +++ b/cmd/mattermost/commands/main_test.go @@ -8,7 +8,6 @@ import ( "os" "testing" - "github.com/mattermost/mattermost-server/v5/api4" "github.com/mattermost/mattermost-server/v5/testlib" ) @@ -30,7 +29,5 @@ func TestMain(m *testing.M) { mainHelper = testlib.NewMainHelperWithOptions(&options) defer mainHelper.Close() - api4.UseTestStore(mainHelper.GetStore()) - mainHelper.Main(m) } diff --git a/cmd/mattermost/commands/server_test.go b/cmd/mattermost/commands/server_test.go index 4cb1ce7c3f..3f92a43762 100644 --- a/cmd/mattermost/commands/server_test.go +++ b/cmd/mattermost/commands/server_test.go @@ -22,6 +22,9 @@ type ServerTestHelper struct { } func SetupServerTest(t testing.TB) *ServerTestHelper { + if testing.Short() { + t.SkipNow() + } // Build a channel that will be used by the server to receive system signals... interruptChan := make(chan os.Signal, 1) // ...and sent it immediately a SIGINT value. diff --git a/cmd/mattermost/commands/version_test.go b/cmd/mattermost/commands/version_test.go index c58844edab..ba55e3bf47 100644 --- a/cmd/mattermost/commands/version_test.go +++ b/cmd/mattermost/commands/version_test.go @@ -8,7 +8,7 @@ import ( ) func TestVersion(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() th.CheckCommand(t, "version") diff --git a/config/database_test.go b/config/database_test.go index 0eda063157..3ff1dddc32 100644 --- a/config/database_test.go +++ b/config/database_test.go @@ -27,6 +27,9 @@ func getDsn(driver string, source string) string { } func setupConfigDatabase(t *testing.T, cfg *model.Config, files map[string][]byte) (string, func()) { + if testing.Short() { + t.SkipNow() + } t.Helper() os.Clearenv() truncateTables(t) @@ -112,6 +115,9 @@ func assertDatabaseNotEqualsConfig(t *testing.T, expectedCfg *model.Config) { } func TestDatabaseStoreNew(t *testing.T) { + if testing.Short() { + t.SkipNow() + } sqlSettings := mainHelper.GetSQLSettings() t.Run("no existing configuration - initialization required", func(t *testing.T) { @@ -331,6 +337,9 @@ func TestDatabaseStoreGetEnivironmentOverrides(t *testing.T) { } func TestDatabaseStoreSet(t *testing.T) { + if testing.Short() { + t.SkipNow() + } sqlSettings := mainHelper.GetSQLSettings() t.Run("set same pointer value", func(t *testing.T) { @@ -540,6 +549,9 @@ func TestDatabaseStoreSet(t *testing.T) { } func TestDatabaseStoreLoad(t *testing.T) { + if testing.Short() { + t.SkipNow() + } sqlSettings := mainHelper.GetSQLSettings() t.Run("active configuration no longer exists", func(t *testing.T) { @@ -979,6 +991,9 @@ func TestDatabaseRemoveFile(t *testing.T) { } func TestDatabaseStoreString(t *testing.T) { + if testing.Short() { + t.SkipNow() + } _, tearDown := setupConfigDatabase(t, emptyConfig, nil) defer tearDown() diff --git a/model/migration.go b/model/migration.go index a0113afd84..7b040082af 100644 --- a/model/migration.go +++ b/model/migration.go @@ -5,4 +5,15 @@ package model const ( MIGRATION_KEY_ADVANCED_PERMISSIONS_PHASE_2 = "migration_advanced_permissions_phase_2" + + MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT = "emoji_permissions_split" + MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT = "webhook_permissions_split" + MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS = "list_join_public_private_teams" + MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER = "remove_permanent_delete_user" + MIGRATION_KEY_ADD_BOT_PERMISSIONS = "add_bot_permissions" + MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER = "apply_channel_manage_delete_to_channel_user" + MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER = "remove_channel_manage_delete_from_team_user" + MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION = "view_members_new_permission" + MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS = "add_manage_guests_permissions" + MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION = "add_use_channel_mentions_permission" ) diff --git a/store/localcachelayer/layer_test.go b/store/localcachelayer/layer_test.go index 176bb0c52c..562ec52439 100644 --- a/store/localcachelayer/layer_test.go +++ b/store/localcachelayer/layer_test.go @@ -31,7 +31,12 @@ func StoreTest(t *testing.T, f func(*testing.T, store.Store)) { }() for _, st := range storeTypes { st := st - t.Run(st.Name, func(t *testing.T) { f(t, st.Store) }) + t.Run(st.Name, func(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + f(t, st.Store) + }) } } @@ -44,11 +49,19 @@ func StoreTestWithSqlSupplier(t *testing.T, f func(*testing.T, store.Store, stor }() for _, st := range storeTypes { st := st - t.Run(st.Name, func(t *testing.T) { f(t, st.Store, st.SqlSupplier) }) + t.Run(st.Name, func(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + f(t, st.Store, st.SqlSupplier) + }) } } func initStores() { + if testing.Short() { + return + } storeTypes = append(storeTypes, &storeType{ Name: "LocalCache+MySQL", SqlSettings: storetest.MakeSqlSettings(model.DATABASE_DRIVER_MYSQL), @@ -82,6 +95,9 @@ func initStores() { var tearDownStoresOnce sync.Once func tearDownStores() { + if testing.Short() { + return + } tearDownStoresOnce.Do(func() { var wg sync.WaitGroup wg.Add(len(storeTypes)) diff --git a/store/sqlstore/store_test.go b/store/sqlstore/store_test.go index 459c1611ae..3dff4549f0 100644 --- a/store/sqlstore/store_test.go +++ b/store/sqlstore/store_test.go @@ -30,7 +30,12 @@ func StoreTest(t *testing.T, f func(*testing.T, store.Store)) { }() for _, st := range storeTypes { st := st - t.Run(st.Name, func(t *testing.T) { f(t, st.Store) }) + t.Run(st.Name, func(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + f(t, st.Store) + }) } } @@ -43,11 +48,19 @@ func StoreTestWithSqlSupplier(t *testing.T, f func(*testing.T, store.Store, stor }() for _, st := range storeTypes { st := st - t.Run(st.Name, func(t *testing.T) { f(t, st.Store, st.SqlSupplier) }) + t.Run(st.Name, func(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + f(t, st.Store, st.SqlSupplier) + }) } } func initStores() { + if testing.Short() { + return + } storeTypes = append(storeTypes, &storeType{ Name: "MySQL", SqlSettings: storetest.MakeSqlSettings(model.DATABASE_DRIVER_MYSQL), @@ -81,6 +94,9 @@ func initStores() { var tearDownStoresOnce sync.Once func tearDownStores() { + if testing.Short() { + return + } tearDownStoresOnce.Do(func() { var wg sync.WaitGroup wg.Add(len(storeTypes)) diff --git a/testlib/helper.go b/testlib/helper.go index 47bc79abbd..715e63baf9 100644 --- a/testlib/helper.go +++ b/testlib/helper.go @@ -57,7 +57,7 @@ func NewMainHelperWithOptions(options *HelperOptions) *MainHelper { utils.TranslationsPreInit() if options != nil { - if options.EnableStore { + if options.EnableStore && !testing.Short() { mainHelper.setupStore() } diff --git a/testlib/store.go b/testlib/store.go index 21672ff92f..34f20ac69f 100644 --- a/testlib/store.go +++ b/testlib/store.go @@ -4,7 +4,13 @@ package testlib import ( + "net/http" + "strconv" + + "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/plugin/plugintest/mock" "github.com/mattermost/mattermost-server/v5/store" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" ) type TestStore struct { @@ -14,3 +20,53 @@ type TestStore struct { func (s *TestStore) Close() { // Don't propagate to the underlying store, since this instance is persistent. } + +func GetMockStoreForSetupFunctions() *mocks.Store { + mockStore := mocks.Store{} + systemStore := mocks.SystemStore{} + systemStore.On("GetByName", "AsymmetricSigningKey").Return(nil, model.NewAppError("FakeError", "store.sql_system.get_by_name.app_error", nil, "", http.StatusInternalServerError)) + systemStore.On("GetByName", "PostActionCookieSecret").Return(nil, model.NewAppError("FakeError", "store.sql_system.get_by_name.app_error", nil, "", http.StatusInternalServerError)) + systemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: strconv.FormatInt(model.GetMillis(), 10)}, nil) + systemStore.On("GetByName", "AdvancedPermissionsMigrationComplete").Return(&model.System{Name: "AdvancedPermissionsMigrationComplete", Value: "true"}, nil) + systemStore.On("GetByName", "EmojisPermissionsMigrationComplete").Return(&model.System{Name: "EmojisPermissionsMigrationComplete", Value: "true"}, nil) + systemStore.On("GetByName", "GuestRolesCreationMigrationComplete").Return(&model.System{Name: "GuestRolesCreationMigrationComplete", Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT).Return(&model.System{Name: model.MIGRATION_KEY_EMOJI_PERMISSIONS_SPLIT, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT).Return(&model.System{Name: model.MIGRATION_KEY_WEBHOOK_PERMISSIONS_SPLIT, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS).Return(&model.System{Name: model.MIGRATION_KEY_LIST_JOIN_PUBLIC_PRIVATE_TEAMS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER).Return(&model.System{Name: model.MIGRATION_KEY_REMOVE_PERMANENT_DELETE_USER, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_BOT_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_BOT_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER).Return(&model.System{Name: model.MIGRATION_KEY_APPLY_CHANNEL_MANAGE_DELETE_TO_CHANNEL_USER, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER).Return(&model.System{Name: model.MIGRATION_KEY_REMOVE_CHANNEL_MANAGE_DELETE_FROM_TEAM_USER, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION).Return(&model.System{Name: model.MIGRATION_KEY_VIEW_MEMBERS_NEW_PERMISSION, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS).Return(&model.System{Name: model.MIGRATION_KEY_ADD_MANAGE_GUESTS_PERMISSIONS, Value: "true"}, nil) + systemStore.On("GetByName", model.MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION).Return(&model.System{Name: model.MIGRATION_KEY_ADD_USE_CHANNEL_MENTIONS_PERMISSION, Value: "true"}, nil) + systemStore.On("Get").Return(make(model.StringMap), nil) + systemStore.On("Save", mock.AnythingOfType("*model.System")).Return(nil) + + userStore := mocks.UserStore{} + userStore.On("Count", mock.AnythingOfType("model.UserCountOptions")).Return(int64(1), nil) + userStore.On("DeactivateGuests").Return(nil, nil) + userStore.On("ClearCaches").Return(nil) + + postStore := mocks.PostStore{} + postStore.On("GetMaxPostSize").Return(4000) + + statusStore := mocks.StatusStore{} + statusStore.On("ResetAll").Return(nil) + + channelStore := mocks.ChannelStore{} + channelStore.On("ClearCaches").Return(nil) + + teamStore := mocks.TeamStore{} + + mockStore.On("System").Return(&systemStore) + mockStore.On("User").Return(&userStore) + mockStore.On("Post").Return(&postStore) + mockStore.On("Status").Return(&statusStore) + mockStore.On("Channel").Return(&channelStore) + mockStore.On("Team").Return(&teamStore) + mockStore.On("Close").Return(nil) + mockStore.On("DropAllTables").Return(nil) + mockStore.On("MarkSystemRanUnitTests").Return(nil) + return &mockStore +} diff --git a/web/handlers_test.go b/web/handlers_test.go index e2f1c822f6..aac1244fdc 100644 --- a/web/handlers_test.go +++ b/web/handlers_test.go @@ -10,6 +10,8 @@ import ( "github.com/mattermost/mattermost-server/v5/app" "github.com/mattermost/mattermost-server/v5/model" + "github.com/mattermost/mattermost-server/v5/plugin/plugintest/mock" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -19,7 +21,7 @@ func handlerForHTTPErrors(c *Context, w http.ResponseWriter, r *http.Request) { } func TestHandlerServeHTTPErrors(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() web := New(th.Server, th.Server.AppOptions, th.Server.Router) @@ -59,9 +61,20 @@ func handlerForHTTPSecureTransport(c *Context, w http.ResponseWriter, r *http.Re } func TestHandlerServeHTTPSecureTransport(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*mocks.Store) + mockUserStore := mocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := mocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := mocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + th.App.UpdateConfig(func(config *model.Config) { *config.ServiceSettings.TLSStrictTransport = true *config.ServiceSettings.TLSStrictTransportMaxAge = 6000 @@ -243,7 +256,7 @@ func handlerForCSPHeader(c *Context, w http.ResponseWriter, r *http.Request) { func TestHandlerServeCSPHeader(t *testing.T) { t.Run("non-static", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() web := New(th.Server, th.Server.AppOptions, th.Server.Router) @@ -265,7 +278,7 @@ func TestHandlerServeCSPHeader(t *testing.T) { }) t.Run("static, without subpath", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() web := New(th.Server, th.Server.AppOptions, th.Server.Router) @@ -287,9 +300,20 @@ func TestHandlerServeCSPHeader(t *testing.T) { }) t.Run("static, with subpath", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*mocks.Store) + mockUserStore := mocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := mocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := mocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.SiteURL = *cfg.ServiceSettings.SiteURL + "/subpath" }) @@ -379,7 +403,7 @@ func TestHandlerServeInvalidToken(t *testing.T) { func TestCheckCSRFToken(t *testing.T) { t.Run("should allow a POST request with a valid CSRF token header", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() h := &Handler{ @@ -409,7 +433,7 @@ func TestCheckCSRFToken(t *testing.T) { }) t.Run("should allow a POST request with an X-Requested-With header", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() h := &Handler{ @@ -440,9 +464,20 @@ func TestCheckCSRFToken(t *testing.T) { }) t.Run("should not allow a POST request with an X-Requested-With header with strict CSRF enforcement enabled", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() + mockStore := th.App.Srv().Store.(*mocks.Store) + mockUserStore := mocks.UserStore{} + mockUserStore.On("Count", mock.Anything).Return(int64(10), nil) + mockPostStore := mocks.PostStore{} + mockPostStore.On("GetMaxPostSize").Return(65535, nil) + mockSystemStore := mocks.SystemStore{} + mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil) + mockStore.On("User").Return(&mockUserStore) + mockStore.On("Post").Return(&mockPostStore) + mockStore.On("System").Return(&mockSystemStore) + th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ExperimentalStrictCSRFEnforcement = true }) @@ -475,7 +510,7 @@ func TestCheckCSRFToken(t *testing.T) { }) t.Run("should not allow a POST request without either header", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() h := &Handler{ @@ -504,7 +539,7 @@ func TestCheckCSRFToken(t *testing.T) { }) t.Run("should not check GET requests", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() h := &Handler{ @@ -533,7 +568,7 @@ func TestCheckCSRFToken(t *testing.T) { }) t.Run("should not check a request passing the auth token in a header", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() h := &Handler{ @@ -562,7 +597,7 @@ func TestCheckCSRFToken(t *testing.T) { }) t.Run("should not check a request passing a nil session", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() h := &Handler{ @@ -587,7 +622,7 @@ func TestCheckCSRFToken(t *testing.T) { }) t.Run("should check requests for handlers that don't require a session but have one", func(t *testing.T) { - th := Setup(t) + th := SetupWithStoreMock(t) defer th.TearDown() h := &Handler{ diff --git a/web/web_test.go b/web/web_test.go index 756f1eb814..6fddeb9d13 100644 --- a/web/web_test.go +++ b/web/web_test.go @@ -17,6 +17,9 @@ import ( "github.com/mattermost/mattermost-server/v5/config" "github.com/mattermost/mattermost-server/v5/model" "github.com/mattermost/mattermost-server/v5/plugin" + "github.com/mattermost/mattermost-server/v5/store" + "github.com/mattermost/mattermost-server/v5/store/storetest/mocks" + "github.com/mattermost/mattermost-server/v5/testlib" "github.com/mattermost/mattermost-server/v5/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -39,10 +42,28 @@ type TestHelper struct { tempWorkspace string } +func SetupWithStoreMock(tb testing.TB) *TestHelper { + if testing.Short() { + tb.SkipNow() + } + store := testlib.GetMockStoreForSetupFunctions() + th := setupTestHelper(tb, store) + emptyMockStore := mocks.Store{} + emptyMockStore.On("Close").Return(nil) + th.App.Srv().Store = &emptyMockStore + return th +} + func Setup(tb testing.TB) *TestHelper { + if testing.Short() { + tb.SkipNow() + } store := mainHelper.GetStore() store.DropAllTables() + return setupTestHelper(tb, store) +} +func setupTestHelper(t testing.TB, store store.Store) *TestHelper { memoryStore, err := config.NewMemoryStoreWithOptions(&config.MemoryStoreOptions{IgnoreEnvironmentOverrides: true}) if err != nil { panic("failed to initialize memory store: " + err.Error())