github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/api/apitestlib.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package api
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"net"
    11  	"os"
    12  	"strings"
    13  	"time"
    14  
    15  	"github.com/mattermost/mattermost-server/api4"
    16  	"github.com/mattermost/mattermost-server/app"
    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/wsapi"
    24  )
    25  
    26  type TestHelper struct {
    27  	App            *app.App
    28  	tempConfigPath string
    29  
    30  	BasicClient  *model.Client
    31  	BasicTeam    *model.Team
    32  	BasicUser    *model.User
    33  	BasicUser2   *model.User
    34  	BasicChannel *model.Channel
    35  	BasicPost    *model.Post
    36  	PinnedPost   *model.Post
    37  
    38  	SystemAdminClient  *model.Client
    39  	SystemAdminTeam    *model.Team
    40  	SystemAdminUser    *model.User
    41  	SystemAdminChannel *model.Channel
    42  }
    43  
    44  type persistentTestStore struct {
    45  	store.Store
    46  }
    47  
    48  func (*persistentTestStore) Close() {}
    49  
    50  var testStoreContainer *storetest.RunningContainer
    51  var testStore *persistentTestStore
    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  	testStoreContainer = container
    57  	testStore = &persistentTestStore{store.NewLayeredStore(sqlstore.NewSqlSupplier(*settings, nil), nil, nil)}
    58  }
    59  
    60  func StopTestStore() {
    61  	if testStoreContainer != nil {
    62  		testStoreContainer.Stop()
    63  		testStoreContainer = nil
    64  	}
    65  }
    66  
    67  func setupTestHelper(enterprise bool) *TestHelper {
    68  	permConfig, err := os.Open(utils.FindConfigFile("config.json"))
    69  	if err != nil {
    70  		panic(err)
    71  	}
    72  	defer permConfig.Close()
    73  	tempConfig, err := ioutil.TempFile("", "")
    74  	if err != nil {
    75  		panic(err)
    76  	}
    77  	_, err = io.Copy(tempConfig, permConfig)
    78  	tempConfig.Close()
    79  	if err != nil {
    80  		panic(err)
    81  	}
    82  
    83  	options := []app.Option{app.ConfigFile(tempConfig.Name()), app.DisableConfigWatch}
    84  	if testStore != nil {
    85  		options = append(options, app.StoreOverride(testStore))
    86  	}
    87  
    88  	a, err := app.New(options...)
    89  	if err != nil {
    90  		panic(err)
    91  	}
    92  
    93  	th := &TestHelper{
    94  		App:            a,
    95  		tempConfigPath: tempConfig.Name(),
    96  	}
    97  
    98  	th.App.UpdateConfig(func(cfg *model.Config) {
    99  		*cfg.TeamSettings.MaxUsersPerTeam = 50
   100  		*cfg.RateLimitSettings.Enable = false
   101  		cfg.EmailSettings.SendEmailNotifications = true
   102  		*cfg.ServiceSettings.EnableAPIv3 = true
   103  	})
   104  	prevListenAddress := *th.App.Config().ServiceSettings.ListenAddress
   105  	if testStore != nil {
   106  		th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
   107  	}
   108  	serverErr := th.App.StartServer()
   109  	if serverErr != nil {
   110  		panic(serverErr)
   111  	}
   112  
   113  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress })
   114  	api4.Init(th.App, th.App.Srv.Router, false)
   115  	Init(th.App, th.App.Srv.Router)
   116  	wsapi.Init(th.App, th.App.Srv.WebSocketRouter)
   117  	th.App.Srv.Store.MarkSystemRanUnitTests()
   118  	th.App.DoAdvancedPermissionsMigration()
   119  
   120  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
   121  
   122  	if enterprise {
   123  		th.App.SetLicense(model.NewTestLicense())
   124  	} else {
   125  		th.App.SetLicense(nil)
   126  	}
   127  
   128  	return th
   129  }
   130  
   131  func SetupEnterprise() *TestHelper {
   132  	return setupTestHelper(true)
   133  }
   134  
   135  func Setup() *TestHelper {
   136  	return setupTestHelper(false)
   137  }
   138  
   139  func (me *TestHelper) InitBasic() *TestHelper {
   140  	me.waitForConnectivity()
   141  
   142  	me.BasicClient = me.CreateClient()
   143  	me.BasicUser = me.CreateUser(me.BasicClient)
   144  	me.App.UpdateUserRoles(me.BasicUser.Id, model.SYSTEM_USER_ROLE_ID, false)
   145  	me.LoginBasic()
   146  	me.BasicTeam = me.CreateTeam(me.BasicClient)
   147  	me.LinkUserToTeam(me.BasicUser, me.BasicTeam)
   148  	me.UpdateUserToNonTeamAdmin(me.BasicUser, me.BasicTeam)
   149  	me.BasicUser2 = me.CreateUser(me.BasicClient)
   150  	me.LinkUserToTeam(me.BasicUser2, me.BasicTeam)
   151  	me.BasicClient.SetTeamId(me.BasicTeam.Id)
   152  	me.BasicChannel = me.CreateChannel(me.BasicClient, me.BasicTeam)
   153  	me.BasicPost = me.CreatePost(me.BasicClient, me.BasicChannel)
   154  
   155  	pinnedPostChannel := me.CreateChannel(me.BasicClient, me.BasicTeam)
   156  	me.PinnedPost = me.CreatePinnedPost(me.BasicClient, pinnedPostChannel)
   157  
   158  	return me
   159  }
   160  
   161  func (me *TestHelper) InitSystemAdmin() *TestHelper {
   162  	me.waitForConnectivity()
   163  
   164  	me.SystemAdminClient = me.CreateClient()
   165  	me.SystemAdminUser = me.CreateUser(me.SystemAdminClient)
   166  	me.SystemAdminUser.Password = "Password1"
   167  	me.LoginSystemAdmin()
   168  	me.SystemAdminTeam = me.CreateTeam(me.SystemAdminClient)
   169  	me.LinkUserToTeam(me.SystemAdminUser, me.SystemAdminTeam)
   170  	me.SystemAdminClient.SetTeamId(me.SystemAdminTeam.Id)
   171  	me.App.UpdateUserRoles(me.SystemAdminUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false)
   172  	me.SystemAdminChannel = me.CreateChannel(me.SystemAdminClient, me.SystemAdminTeam)
   173  
   174  	return me
   175  }
   176  
   177  func (me *TestHelper) waitForConnectivity() {
   178  	for i := 0; i < 1000; i++ {
   179  		conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%v", me.App.Srv.ListenAddr.Port))
   180  		if err == nil {
   181  			conn.Close()
   182  			return
   183  		}
   184  		time.Sleep(time.Millisecond * 20)
   185  	}
   186  	panic("unable to connect")
   187  }
   188  
   189  func (me *TestHelper) CreateClient() *model.Client {
   190  	return model.NewClient(fmt.Sprintf("http://localhost:%v", me.App.Srv.ListenAddr.Port))
   191  }
   192  
   193  func (me *TestHelper) CreateWebSocketClient() (*model.WebSocketClient, *model.AppError) {
   194  	return model.NewWebSocketClient(fmt.Sprintf("ws://localhost:%v", me.App.Srv.ListenAddr.Port), me.BasicClient.AuthToken)
   195  }
   196  
   197  func (me *TestHelper) CreateTeam(client *model.Client) *model.Team {
   198  	id := model.NewId()
   199  	team := &model.Team{
   200  		DisplayName: "dn_" + id,
   201  		Name:        GenerateTestTeamName(),
   202  		Email:       me.GenerateTestEmail(),
   203  		Type:        model.TEAM_OPEN,
   204  	}
   205  
   206  	utils.DisableDebugLogForTest()
   207  	r := client.Must(client.CreateTeam(team)).Data.(*model.Team)
   208  	utils.EnableDebugLogForTest()
   209  	return r
   210  }
   211  
   212  func (me *TestHelper) CreateUser(client *model.Client) *model.User {
   213  	id := model.NewId()
   214  
   215  	user := &model.User{
   216  		Email:    me.GenerateTestEmail(),
   217  		Username: "un_" + id,
   218  		Nickname: "nn_" + id,
   219  		Password: "Password1",
   220  	}
   221  
   222  	utils.DisableDebugLogForTest()
   223  	ruser := client.Must(client.CreateUser(user, "")).Data.(*model.User)
   224  	ruser.Password = "Password1"
   225  	store.Must(me.App.Srv.Store.User().VerifyEmail(ruser.Id))
   226  	utils.EnableDebugLogForTest()
   227  	return ruser
   228  }
   229  
   230  func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) {
   231  	utils.DisableDebugLogForTest()
   232  
   233  	err := me.App.JoinUserToTeam(team, user, "")
   234  	if err != nil {
   235  		mlog.Error(err.Error())
   236  
   237  		time.Sleep(time.Second)
   238  		panic(err)
   239  	}
   240  
   241  	utils.EnableDebugLogForTest()
   242  }
   243  
   244  func (me *TestHelper) UpdateUserToTeamAdmin(user *model.User, team *model.Team) {
   245  	utils.DisableDebugLogForTest()
   246  
   247  	tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.TEAM_USER_ROLE_ID + " " + model.TEAM_ADMIN_ROLE_ID}
   248  	if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
   249  		utils.EnableDebugLogForTest()
   250  		mlog.Error(tmr.Err.Error())
   251  
   252  		time.Sleep(time.Second)
   253  		panic(tmr.Err)
   254  	}
   255  	utils.EnableDebugLogForTest()
   256  }
   257  
   258  func (me *TestHelper) UpdateUserToNonTeamAdmin(user *model.User, team *model.Team) {
   259  	utils.DisableDebugLogForTest()
   260  
   261  	tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.TEAM_USER_ROLE_ID}
   262  	if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil {
   263  		utils.EnableDebugLogForTest()
   264  		mlog.Error(tmr.Err.Error())
   265  
   266  		time.Sleep(time.Second)
   267  		panic(tmr.Err)
   268  	}
   269  	utils.EnableDebugLogForTest()
   270  }
   271  
   272  func (me *TestHelper) MakeUserChannelAdmin(user *model.User, channel *model.Channel) {
   273  	utils.DisableDebugLogForTest()
   274  
   275  	if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
   276  		cm := cmr.Data.(*model.ChannelMember)
   277  		cm.Roles = "channel_admin channel_user"
   278  		if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil {
   279  			utils.EnableDebugLogForTest()
   280  			panic(sr.Err)
   281  		}
   282  	} else {
   283  		utils.EnableDebugLogForTest()
   284  		panic(cmr.Err)
   285  	}
   286  
   287  	utils.EnableDebugLogForTest()
   288  }
   289  
   290  func (me *TestHelper) MakeUserChannelUser(user *model.User, channel *model.Channel) {
   291  	utils.DisableDebugLogForTest()
   292  
   293  	if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil {
   294  		cm := cmr.Data.(*model.ChannelMember)
   295  		cm.Roles = "channel_user"
   296  		if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil {
   297  			utils.EnableDebugLogForTest()
   298  			panic(sr.Err)
   299  		}
   300  	} else {
   301  		utils.EnableDebugLogForTest()
   302  		panic(cmr.Err)
   303  	}
   304  
   305  	utils.EnableDebugLogForTest()
   306  }
   307  
   308  func (me *TestHelper) CreateChannel(client *model.Client, team *model.Team) *model.Channel {
   309  	return me.createChannel(client, team, model.CHANNEL_OPEN)
   310  }
   311  
   312  func (me *TestHelper) CreatePrivateChannel(client *model.Client, team *model.Team) *model.Channel {
   313  	return me.createChannel(client, team, model.CHANNEL_PRIVATE)
   314  }
   315  
   316  func (me *TestHelper) createChannel(client *model.Client, team *model.Team, channelType string) *model.Channel {
   317  	id := model.NewId()
   318  
   319  	channel := &model.Channel{
   320  		DisplayName: "dn_" + id,
   321  		Name:        "name_" + id,
   322  		Type:        channelType,
   323  		TeamId:      team.Id,
   324  	}
   325  
   326  	utils.DisableDebugLogForTest()
   327  	r := client.Must(client.CreateChannel(channel)).Data.(*model.Channel)
   328  	utils.EnableDebugLogForTest()
   329  	return r
   330  }
   331  
   332  func (me *TestHelper) CreatePost(client *model.Client, channel *model.Channel) *model.Post {
   333  	id := model.NewId()
   334  
   335  	post := &model.Post{
   336  		ChannelId: channel.Id,
   337  		Message:   "message_" + id,
   338  	}
   339  
   340  	utils.DisableDebugLogForTest()
   341  	r := client.Must(client.CreatePost(post)).Data.(*model.Post)
   342  	utils.EnableDebugLogForTest()
   343  	return r
   344  }
   345  
   346  func (me *TestHelper) CreatePinnedPost(client *model.Client, channel *model.Channel) *model.Post {
   347  	id := model.NewId()
   348  
   349  	post := &model.Post{
   350  		ChannelId: channel.Id,
   351  		Message:   "message_" + id,
   352  		IsPinned:  true,
   353  	}
   354  
   355  	utils.DisableDebugLogForTest()
   356  	r := client.Must(client.CreatePost(post)).Data.(*model.Post)
   357  	utils.EnableDebugLogForTest()
   358  	return r
   359  }
   360  
   361  func (me *TestHelper) LoginBasic() {
   362  	utils.DisableDebugLogForTest()
   363  	me.BasicClient.Must(me.BasicClient.Login(me.BasicUser.Email, me.BasicUser.Password))
   364  	utils.EnableDebugLogForTest()
   365  }
   366  
   367  func (me *TestHelper) LoginBasic2() {
   368  	utils.DisableDebugLogForTest()
   369  	me.BasicClient.Must(me.BasicClient.Login(me.BasicUser2.Email, me.BasicUser2.Password))
   370  	utils.EnableDebugLogForTest()
   371  }
   372  
   373  func (me *TestHelper) LoginSystemAdmin() {
   374  	utils.DisableDebugLogForTest()
   375  	me.SystemAdminClient.Must(me.SystemAdminClient.Login(me.SystemAdminUser.Email, me.SystemAdminUser.Password))
   376  	utils.EnableDebugLogForTest()
   377  }
   378  
   379  func (me *TestHelper) GenerateTestEmail() string {
   380  	if me.App.Config().EmailSettings.SMTPServer != "dockerhost" && os.Getenv("CI_INBUCKET_PORT") == "" {
   381  		return strings.ToLower("success+" + model.NewId() + "@simulator.amazonses.com")
   382  	}
   383  	return strings.ToLower(model.NewId() + "@dockerhost")
   384  }
   385  
   386  func GenerateTestTeamName() string {
   387  	return "faketeam" + model.NewRandomString(6)
   388  }
   389  
   390  func (me *TestHelper) TearDown() {
   391  	me.App.Shutdown()
   392  	os.Remove(me.tempConfigPath)
   393  	if err := recover(); err != nil {
   394  		StopTestStore()
   395  		panic(err)
   396  	}
   397  }
   398  
   399  func (me *TestHelper) SaveDefaultRolePermissions() map[string][]string {
   400  	utils.DisableDebugLogForTest()
   401  
   402  	results := make(map[string][]string)
   403  
   404  	for _, roleName := range []string{
   405  		"system_user",
   406  		"system_admin",
   407  		"team_user",
   408  		"team_admin",
   409  		"channel_user",
   410  		"channel_admin",
   411  	} {
   412  		role, err1 := me.App.GetRoleByName(roleName)
   413  		if err1 != nil {
   414  			utils.EnableDebugLogForTest()
   415  			panic(err1)
   416  		}
   417  
   418  		results[roleName] = role.Permissions
   419  	}
   420  
   421  	utils.EnableDebugLogForTest()
   422  	return results
   423  }
   424  
   425  func (me *TestHelper) RestoreDefaultRolePermissions(data map[string][]string) {
   426  	utils.DisableDebugLogForTest()
   427  
   428  	for roleName, permissions := range data {
   429  		role, err1 := me.App.GetRoleByName(roleName)
   430  		if err1 != nil {
   431  			utils.EnableDebugLogForTest()
   432  			panic(err1)
   433  		}
   434  
   435  		if strings.Join(role.Permissions, " ") == strings.Join(permissions, " ") {
   436  			continue
   437  		}
   438  
   439  		role.Permissions = permissions
   440  
   441  		_, err2 := me.App.UpdateRole(role)
   442  		if err2 != nil {
   443  			utils.EnableDebugLogForTest()
   444  			panic(err2)
   445  		}
   446  	}
   447  
   448  	utils.EnableDebugLogForTest()
   449  }
   450  
   451  func (me *TestHelper) RemovePermissionFromRole(permission string, roleName string) {
   452  	utils.DisableDebugLogForTest()
   453  
   454  	role, err1 := me.App.GetRoleByName(roleName)
   455  	if err1 != nil {
   456  		utils.EnableDebugLogForTest()
   457  		panic(err1)
   458  	}
   459  
   460  	var newPermissions []string
   461  	for _, p := range role.Permissions {
   462  		if p != permission {
   463  			newPermissions = append(newPermissions, p)
   464  		}
   465  	}
   466  
   467  	if strings.Join(role.Permissions, " ") == strings.Join(newPermissions, " ") {
   468  		utils.EnableDebugLogForTest()
   469  		return
   470  	}
   471  
   472  	role.Permissions = newPermissions
   473  
   474  	_, err2 := me.App.UpdateRole(role)
   475  	if err2 != nil {
   476  		utils.EnableDebugLogForTest()
   477  		panic(err2)
   478  	}
   479  
   480  	utils.EnableDebugLogForTest()
   481  }
   482  
   483  func (me *TestHelper) AddPermissionToRole(permission string, roleName string) {
   484  	utils.DisableDebugLogForTest()
   485  
   486  	role, err1 := me.App.GetRoleByName(roleName)
   487  	if err1 != nil {
   488  		utils.EnableDebugLogForTest()
   489  		panic(err1)
   490  	}
   491  
   492  	for _, existingPermission := range role.Permissions {
   493  		if existingPermission == permission {
   494  			utils.EnableDebugLogForTest()
   495  			return
   496  		}
   497  	}
   498  
   499  	role.Permissions = append(role.Permissions, permission)
   500  
   501  	_, err2 := me.App.UpdateRole(role)
   502  	if err2 != nil {
   503  		utils.EnableDebugLogForTest()
   504  		panic(err2)
   505  	}
   506  
   507  	utils.EnableDebugLogForTest()
   508  }