github.com/jlevesy/mattermost-server@v5.3.2-0.20181003190404-7468f35cb0c8+incompatible/app/apptestlib.go (about)

     1  // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package app
     5  
     6  import (
     7  	"io"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"os"
    11  	"path/filepath"
    12  	"time"
    13  
    14  	"testing"
    15  
    16  	"github.com/mattermost/mattermost-server/einterfaces"
    17  	"github.com/mattermost/mattermost-server/mlog"
    18  	"github.com/mattermost/mattermost-server/model"
    19  	"github.com/mattermost/mattermost-server/store"
    20  	"github.com/mattermost/mattermost-server/store/sqlstore"
    21  	"github.com/mattermost/mattermost-server/store/storetest"
    22  	"github.com/mattermost/mattermost-server/utils"
    23  	"github.com/mattermost/mattermost-server/utils/testutils"
    24  )
    25  
    26  type TestHelper struct {
    27  	App          *App
    28  	BasicTeam    *model.Team
    29  	BasicUser    *model.User
    30  	BasicUser2   *model.User
    31  	BasicChannel *model.Channel
    32  	BasicPost    *model.Post
    33  
    34  	SystemAdminUser *model.User
    35  
    36  	tempConfigPath string
    37  	tempWorkspace  string
    38  
    39  	MockedHTTPService *testutils.MockedHTTPService
    40  }
    41  
    42  type persistentTestStore struct {
    43  	store.Store
    44  }
    45  
    46  func (*persistentTestStore) Close() {}
    47  
    48  var testStoreContainer *storetest.RunningContainer
    49  var testStore *persistentTestStore
    50  var testStoreSqlSupplier *sqlstore.SqlSupplier
    51  var testClusterInterface *FakeClusterInterface
    52  
    53  // UseTestStore sets the container and corresponding settings to use for tests. Once the tests are
    54  // complete (e.g. at the end of your TestMain implementation), you should call StopTestStore.
    55  func UseTestStore(container *storetest.RunningContainer, settings *model.SqlSettings) {
    56  	testClusterInterface = &FakeClusterInterface{}
    57  	testStoreContainer = container
    58  	testStoreSqlSupplier = sqlstore.NewSqlSupplier(*settings, nil)
    59  	testStore = &persistentTestStore{store.NewLayeredStore(testStoreSqlSupplier, nil, testClusterInterface)}
    60  }
    61  
    62  func StopTestStore() {
    63  	if testStoreContainer != nil {
    64  		testStoreContainer.Stop()
    65  		testStoreContainer = nil
    66  	}
    67  }
    68  
    69  func setupTestHelper(enterprise bool) *TestHelper {
    70  	permConfig, err := os.Open(utils.FindConfigFile("config.json"))
    71  	if err != nil {
    72  		panic(err)
    73  	}
    74  	defer permConfig.Close()
    75  	tempConfig, err := ioutil.TempFile("", "")
    76  	if err != nil {
    77  		panic(err)
    78  	}
    79  	_, err = io.Copy(tempConfig, permConfig)
    80  	tempConfig.Close()
    81  	if err != nil {
    82  		panic(err)
    83  	}
    84  
    85  	options := []Option{ConfigFile(tempConfig.Name()), DisableConfigWatch}
    86  	if testStore != nil {
    87  		options = append(options, StoreOverride(testStore))
    88  	}
    89  
    90  	a, err := New(options...)
    91  	if err != nil {
    92  		panic(err)
    93  	}
    94  
    95  	th := &TestHelper{
    96  		App:            a,
    97  		tempConfigPath: tempConfig.Name(),
    98  	}
    99  
   100  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 })
   101  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.RateLimitSettings.Enable = false })
   102  	prevListenAddress := *th.App.Config().ServiceSettings.ListenAddress
   103  	if testStore != nil {
   104  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
   105  	}
   106  	serverErr := th.App.StartServer()
   107  	if serverErr != nil {
   108  		panic(serverErr)
   109  	}
   110  
   111  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress })
   112  
   113  	th.App.DoAdvancedPermissionsMigration()
   114  	th.App.DoEmojisPermissionsMigration()
   115  
   116  	th.App.Srv.Store.MarkSystemRanUnitTests()
   117  
   118  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
   119  
   120  	if enterprise {
   121  		th.App.SetLicense(model.NewTestLicense())
   122  	} else {
   123  		th.App.SetLicense(nil)
   124  	}
   125  
   126  	if th.tempWorkspace == "" {
   127  		dir, err := ioutil.TempDir("", "apptest")
   128  		if err != nil {
   129  			panic(err)
   130  		}
   131  		th.tempWorkspace = dir
   132  	}
   133  
   134  	pluginDir := filepath.Join(th.tempWorkspace, "plugins")
   135  	webappDir := filepath.Join(th.tempWorkspace, "webapp")
   136  
   137  	th.App.InitPlugins(pluginDir, webappDir)
   138  
   139  	return th
   140  }
   141  
   142  func SetupEnterprise() *TestHelper {
   143  	return setupTestHelper(true)
   144  }
   145  
   146  func Setup() *TestHelper {
   147  	return setupTestHelper(false)
   148  }
   149  
   150  func (me *TestHelper) InitBasic() *TestHelper {
   151  	me.BasicTeam = me.CreateTeam()
   152  	me.BasicUser = me.CreateUser()
   153  	me.LinkUserToTeam(me.BasicUser, me.BasicTeam)
   154  	me.BasicUser2 = me.CreateUser()
   155  	me.LinkUserToTeam(me.BasicUser2, me.BasicTeam)
   156  	me.BasicChannel = me.CreateChannel(me.BasicTeam)
   157  	me.BasicPost = me.CreatePost(me.BasicChannel)
   158  
   159  	return me
   160  }
   161  
   162  func (me *TestHelper) InitSystemAdmin() *TestHelper {
   163  	me.SystemAdminUser = me.CreateUser()
   164  	me.App.UpdateUserRoles(me.SystemAdminUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false)
   165  	me.SystemAdminUser, _ = me.App.GetUser(me.SystemAdminUser.Id)
   166  
   167  	return me
   168  }
   169  
   170  func (me *TestHelper) MockHTTPService(handler http.Handler) *TestHelper {
   171  	me.MockedHTTPService = testutils.MakeMockedHTTPService(handler)
   172  	me.App.HTTPService = me.MockedHTTPService
   173  
   174  	return me
   175  }
   176  
   177  func (me *TestHelper) MakeEmail() string {
   178  	return "success_" + model.NewId() + "@simulator.amazonses.com"
   179  }
   180  
   181  func (me *TestHelper) CreateTeam() *model.Team {
   182  	id := model.NewId()
   183  	team := &model.Team{
   184  		DisplayName: "dn_" + id,
   185  		Name:        "name" + id,
   186  		Email:       "success+" + id + "@simulator.amazonses.com",
   187  		Type:        model.TEAM_OPEN,
   188  	}
   189  
   190  	utils.DisableDebugLogForTest()
   191  	var err *model.AppError
   192  	if team, err = me.App.CreateTeam(team); err != nil {
   193  		mlog.Error(err.Error())
   194  
   195  		time.Sleep(time.Second)
   196  		panic(err)
   197  	}
   198  	utils.EnableDebugLogForTest()
   199  	return team
   200  }
   201  
   202  func (me *TestHelper) CreateUser() *model.User {
   203  	id := model.NewId()
   204  
   205  	user := &model.User{
   206  		Email:         "success+" + id + "@simulator.amazonses.com",
   207  		Username:      "un_" + id,
   208  		Nickname:      "nn_" + id,
   209  		Password:      "Password1",
   210  		EmailVerified: true,
   211  	}
   212  
   213  	utils.DisableDebugLogForTest()
   214  	var err *model.AppError
   215  	if user, err = me.App.CreateUser(user); err != nil {
   216  		mlog.Error(err.Error())
   217  
   218  		time.Sleep(time.Second)
   219  		panic(err)
   220  	}
   221  	utils.EnableDebugLogForTest()
   222  	return user
   223  }
   224  
   225  func (me *TestHelper) CreateChannel(team *model.Team) *model.Channel {
   226  	return me.createChannel(team, model.CHANNEL_OPEN)
   227  }
   228  
   229  func (me *TestHelper) CreatePrivateChannel(team *model.Team) *model.Channel {
   230  	return me.createChannel(team, model.CHANNEL_PRIVATE)
   231  }
   232  
   233  func (me *TestHelper) createChannel(team *model.Team, channelType string) *model.Channel {
   234  	id := model.NewId()
   235  
   236  	channel := &model.Channel{
   237  		DisplayName: "dn_" + id,
   238  		Name:        "name_" + id,
   239  		Type:        channelType,
   240  		TeamId:      team.Id,
   241  		CreatorId:   me.BasicUser.Id,
   242  	}
   243  
   244  	utils.DisableDebugLogForTest()
   245  	var err *model.AppError
   246  	if channel, err = me.App.CreateChannel(channel, true); err != nil {
   247  		mlog.Error(err.Error())
   248  
   249  		time.Sleep(time.Second)
   250  		panic(err)
   251  	}
   252  	utils.EnableDebugLogForTest()
   253  	return channel
   254  }
   255  
   256  func (me *TestHelper) createChannelWithAnotherUser(team *model.Team, channelType, userId string) *model.Channel {
   257  	id := model.NewId()
   258  
   259  	channel := &model.Channel{
   260  		DisplayName: "dn_" + id,
   261  		Name:        "name_" + id,
   262  		Type:        channelType,
   263  		TeamId:      team.Id,
   264  		CreatorId:   userId,
   265  	}
   266  
   267  	utils.DisableDebugLogForTest()
   268  	var err *model.AppError
   269  	if channel, err = me.App.CreateChannel(channel, true); err != nil {
   270  		mlog.Error(err.Error())
   271  
   272  		time.Sleep(time.Second)
   273  		panic(err)
   274  	}
   275  	utils.EnableDebugLogForTest()
   276  	return channel
   277  }
   278  
   279  func (me *TestHelper) CreateDmChannel(user *model.User) *model.Channel {
   280  	utils.DisableDebugLogForTest()
   281  	var err *model.AppError
   282  	var channel *model.Channel
   283  	if channel, err = me.App.CreateDirectChannel(me.BasicUser.Id, user.Id); err != nil {
   284  		mlog.Error(err.Error())
   285  
   286  		time.Sleep(time.Second)
   287  		panic(err)
   288  	}
   289  	utils.EnableDebugLogForTest()
   290  	return channel
   291  }
   292  
   293  func (me *TestHelper) CreateGroupChannel(user1 *model.User, user2 *model.User) *model.Channel {
   294  	utils.DisableDebugLogForTest()
   295  	var err *model.AppError
   296  	var channel *model.Channel
   297  	if channel, err = me.App.CreateGroupChannel([]string{me.BasicUser.Id, user1.Id, user2.Id}, me.BasicUser.Id); err != nil {
   298  		mlog.Error(err.Error())
   299  
   300  		time.Sleep(time.Second)
   301  		panic(err)
   302  	}
   303  	utils.EnableDebugLogForTest()
   304  	return channel
   305  }
   306  
   307  func (me *TestHelper) CreatePost(channel *model.Channel) *model.Post {
   308  	id := model.NewId()
   309  
   310  	post := &model.Post{
   311  		UserId:    me.BasicUser.Id,
   312  		ChannelId: channel.Id,
   313  		Message:   "message_" + id,
   314  		CreateAt:  model.GetMillis() - 10000,
   315  	}
   316  
   317  	utils.DisableDebugLogForTest()
   318  	var err *model.AppError
   319  	if post, err = me.App.CreatePost(post, channel, false); err != nil {
   320  		mlog.Error(err.Error())
   321  
   322  		time.Sleep(time.Second)
   323  		panic(err)
   324  	}
   325  	utils.EnableDebugLogForTest()
   326  	return post
   327  }
   328  
   329  func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) {
   330  	utils.DisableDebugLogForTest()
   331  
   332  	err := me.App.JoinUserToTeam(team, user, "")
   333  	if err != nil {
   334  		mlog.Error(err.Error())
   335  
   336  		time.Sleep(time.Second)
   337  		panic(err)
   338  	}
   339  
   340  	utils.EnableDebugLogForTest()
   341  }
   342  
   343  func (me *TestHelper) AddUserToChannel(user *model.User, channel *model.Channel) *model.ChannelMember {
   344  	utils.DisableDebugLogForTest()
   345  
   346  	member, err := me.App.AddUserToChannel(user, channel)
   347  	if err != nil {
   348  		mlog.Error(err.Error())
   349  
   350  		time.Sleep(time.Second)
   351  		panic(err)
   352  	}
   353  
   354  	utils.EnableDebugLogForTest()
   355  
   356  	return member
   357  }
   358  
   359  func (me *TestHelper) CreateScheme() (*model.Scheme, []*model.Role) {
   360  	utils.DisableDebugLogForTest()
   361  
   362  	scheme, err := me.App.CreateScheme(&model.Scheme{
   363  		DisplayName: "Test Scheme Display Name",
   364  		Name:        model.NewId(),
   365  		Description: "Test scheme description",
   366  		Scope:       model.SCHEME_SCOPE_TEAM,
   367  	})
   368  	if err != nil {
   369  		panic(err)
   370  	}
   371  
   372  	roleNames := []string{
   373  		scheme.DefaultTeamAdminRole,
   374  		scheme.DefaultTeamUserRole,
   375  		scheme.DefaultChannelAdminRole,
   376  		scheme.DefaultChannelUserRole,
   377  	}
   378  
   379  	var roles []*model.Role
   380  	for _, roleName := range roleNames {
   381  		role, err := me.App.GetRoleByName(roleName)
   382  		if err != nil {
   383  			panic(err)
   384  		}
   385  		roles = append(roles, role)
   386  	}
   387  
   388  	utils.EnableDebugLogForTest()
   389  
   390  	return scheme, roles
   391  }
   392  
   393  func (me *TestHelper) TearDown() {
   394  	me.App.Shutdown()
   395  	os.Remove(me.tempConfigPath)
   396  	if err := recover(); err != nil {
   397  		StopTestStore()
   398  		panic(err)
   399  	}
   400  	if me.tempWorkspace != "" {
   401  		os.RemoveAll(me.tempWorkspace)
   402  	}
   403  }
   404  
   405  func (me *TestHelper) ResetRoleMigration() {
   406  	if _, err := testStoreSqlSupplier.GetMaster().Exec("DELETE from Roles"); err != nil {
   407  		panic(err)
   408  	}
   409  
   410  	testClusterInterface.sendClearRoleCacheMessage()
   411  
   412  	if _, err := testStoreSqlSupplier.GetMaster().Exec("DELETE from Systems where Name = :Name", map[string]interface{}{"Name": ADVANCED_PERMISSIONS_MIGRATION_KEY}); err != nil {
   413  		panic(err)
   414  	}
   415  }
   416  
   417  func (me *TestHelper) ResetEmojisMigration() {
   418  	if _, err := testStoreSqlSupplier.GetMaster().Exec("UPDATE Roles SET Permissions=REPLACE(Permissions, ', manage_emojis', '') WHERE builtin=True"); err != nil {
   419  		panic(err)
   420  	}
   421  
   422  	testClusterInterface.sendClearRoleCacheMessage()
   423  
   424  	if _, err := testStoreSqlSupplier.GetMaster().Exec("DELETE from Systems where Name = :Name", map[string]interface{}{"Name": EMOJIS_PERMISSIONS_MIGRATION_KEY}); err != nil {
   425  		panic(err)
   426  	}
   427  }
   428  
   429  func (me *TestHelper) CheckTeamCount(t *testing.T, expected int64) {
   430  	if r := <-me.App.Srv.Store.Team().AnalyticsTeamCount(); r.Err == nil {
   431  		if r.Data.(int64) != expected {
   432  			t.Fatalf("Unexpected number of teams. Expected: %v, found: %v", expected, r.Data.(int64))
   433  		}
   434  	} else {
   435  		t.Fatalf("Failed to get team count.")
   436  	}
   437  }
   438  
   439  func (me *TestHelper) CheckChannelsCount(t *testing.T, expected int64) {
   440  	if r := <-me.App.Srv.Store.Channel().AnalyticsTypeCount("", model.CHANNEL_OPEN); r.Err == nil {
   441  		if r.Data.(int64) != expected {
   442  			t.Fatalf("Unexpected number of channels. Expected: %v, found: %v", expected, r.Data.(int64))
   443  		}
   444  	} else {
   445  		t.Fatalf("Failed to get channel count.")
   446  	}
   447  }
   448  
   449  func (me *TestHelper) SetupTeamScheme() *model.Scheme {
   450  	scheme := model.Scheme{
   451  		Name:        model.NewId(),
   452  		DisplayName: model.NewId(),
   453  		Scope:       model.SCHEME_SCOPE_TEAM,
   454  	}
   455  
   456  	if scheme, err := me.App.CreateScheme(&scheme); err == nil {
   457  		return scheme
   458  	} else {
   459  		panic(err)
   460  	}
   461  }
   462  
   463  func (me *TestHelper) SetupChannelScheme() *model.Scheme {
   464  	scheme := model.Scheme{
   465  		Name:        model.NewId(),
   466  		DisplayName: model.NewId(),
   467  		Scope:       model.SCHEME_SCOPE_CHANNEL,
   468  	}
   469  
   470  	if scheme, err := me.App.CreateScheme(&scheme); err == nil {
   471  		return scheme
   472  	} else {
   473  		panic(err)
   474  	}
   475  }
   476  
   477  func (me *TestHelper) SetupPluginAPI() *PluginAPI {
   478  	manifest := &model.Manifest{
   479  		Id: "pluginid",
   480  	}
   481  
   482  	return NewPluginAPI(me.App, manifest)
   483  }
   484  
   485  type FakeClusterInterface struct {
   486  	clusterMessageHandler einterfaces.ClusterMessageHandler
   487  }
   488  
   489  func (me *FakeClusterInterface) StartInterNodeCommunication() {}
   490  func (me *FakeClusterInterface) StopInterNodeCommunication()  {}
   491  func (me *FakeClusterInterface) RegisterClusterMessageHandler(event string, crm einterfaces.ClusterMessageHandler) {
   492  	me.clusterMessageHandler = crm
   493  }
   494  func (me *FakeClusterInterface) GetClusterId() string                             { return "" }
   495  func (me *FakeClusterInterface) IsLeader() bool                                   { return false }
   496  func (me *FakeClusterInterface) GetMyClusterInfo() *model.ClusterInfo             { return nil }
   497  func (me *FakeClusterInterface) GetClusterInfos() []*model.ClusterInfo            { return nil }
   498  func (me *FakeClusterInterface) SendClusterMessage(cluster *model.ClusterMessage) {}
   499  func (me *FakeClusterInterface) NotifyMsg(buf []byte)                             {}
   500  func (me *FakeClusterInterface) GetClusterStats() ([]*model.ClusterStats, *model.AppError) {
   501  	return nil, nil
   502  }
   503  func (me *FakeClusterInterface) GetLogs(page, perPage int) ([]string, *model.AppError) {
   504  	return []string{}, nil
   505  }
   506  func (me *FakeClusterInterface) GetPluginStatuses() (model.PluginStatuses, *model.AppError) {
   507  	return nil, nil
   508  }
   509  func (me *FakeClusterInterface) ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError {
   510  	return nil
   511  }
   512  func (me *FakeClusterInterface) sendClearRoleCacheMessage() {
   513  	me.clusterMessageHandler(&model.ClusterMessage{
   514  		Event: model.CLUSTER_EVENT_INVALIDATE_CACHE_FOR_ROLES,
   515  	})
   516  }