github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/app/slashcommands/helper_test.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package slashcommands
     5  
     6  import (
     7  	"bytes"
     8  	"context"
     9  	"io/ioutil"
    10  	"os"
    11  	"path/filepath"
    12  	"strings"
    13  	"sync"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/masterhung0112/hk_server/v5/app"
    18  	"github.com/masterhung0112/hk_server/v5/app/request"
    19  	"github.com/masterhung0112/hk_server/v5/config"
    20  	"github.com/masterhung0112/hk_server/v5/model"
    21  	"github.com/masterhung0112/hk_server/v5/shared/mlog"
    22  	"github.com/masterhung0112/hk_server/v5/store"
    23  	"github.com/masterhung0112/hk_server/v5/store/localcachelayer"
    24  	"github.com/masterhung0112/hk_server/v5/utils"
    25  )
    26  
    27  type TestHelper struct {
    28  	App          *app.App
    29  	Context      *request.Context
    30  	Server       *app.Server
    31  	BasicTeam    *model.Team
    32  	BasicUser    *model.User
    33  	BasicUser2   *model.User
    34  	BasicChannel *model.Channel
    35  	BasicPost    *model.Post
    36  
    37  	SystemAdminUser   *model.User
    38  	LogBuffer         *bytes.Buffer
    39  	IncludeCacheLayer bool
    40  
    41  	tempWorkspace string
    42  }
    43  
    44  func setupTestHelper(dbStore store.Store, enterprise bool, includeCacheLayer bool, tb testing.TB, configSet func(*model.Config)) *TestHelper {
    45  	tempWorkspace, err := ioutil.TempDir("", "apptest")
    46  	if err != nil {
    47  		panic(err)
    48  	}
    49  
    50  	memoryStore := config.NewTestMemoryStore()
    51  
    52  	config := memoryStore.Get()
    53  	if configSet != nil {
    54  		configSet(config)
    55  	}
    56  	*config.PluginSettings.Directory = filepath.Join(tempWorkspace, "plugins")
    57  	*config.PluginSettings.ClientDirectory = filepath.Join(tempWorkspace, "webapp")
    58  	*config.LogSettings.EnableSentry = false // disable error reporting during tests
    59  	memoryStore.Set(config)
    60  
    61  	buffer := &bytes.Buffer{}
    62  
    63  	var options []app.Option
    64  	options = append(options, app.ConfigStore(memoryStore))
    65  	if includeCacheLayer {
    66  		options = append(options, app.StoreOverride(func(s *app.Server) store.Store {
    67  			lcl, err2 := localcachelayer.NewLocalCacheLayer(dbStore, s.Metrics, s.Cluster, s.CacheProvider)
    68  			if err2 != nil {
    69  				panic(err2)
    70  			}
    71  			return lcl
    72  		}))
    73  	} else {
    74  		options = append(options, app.StoreOverride(dbStore))
    75  	}
    76  	options = append(options, app.SetLogger(mlog.NewTestingLogger(tb, buffer)))
    77  
    78  	s, err := app.NewServer(options...)
    79  	if err != nil {
    80  		panic(err)
    81  	}
    82  
    83  	th := &TestHelper{
    84  		App:               app.New(app.ServerConnector(s)),
    85  		Context:           &request.Context{},
    86  		Server:            s,
    87  		LogBuffer:         buffer,
    88  		IncludeCacheLayer: includeCacheLayer,
    89  	}
    90  
    91  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 })
    92  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.RateLimitSettings.Enable = false })
    93  	prevListenAddress := *th.App.Config().ServiceSettings.ListenAddress
    94  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" })
    95  	serverErr := th.Server.Start()
    96  	if serverErr != nil {
    97  		panic(serverErr)
    98  	}
    99  
   100  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress })
   101  
   102  	th.App.Srv().SearchEngine = mainHelper.SearchEngine
   103  
   104  	th.App.Srv().Store.MarkSystemRanUnitTests()
   105  
   106  	th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true })
   107  
   108  	// Disable strict password requirements for test
   109  	th.App.UpdateConfig(func(cfg *model.Config) {
   110  		*cfg.PasswordSettings.MinimumLength = 5
   111  		*cfg.PasswordSettings.Lowercase = false
   112  		*cfg.PasswordSettings.Uppercase = false
   113  		*cfg.PasswordSettings.Symbol = false
   114  		*cfg.PasswordSettings.Number = false
   115  	})
   116  
   117  	if enterprise {
   118  		th.App.Srv().SetLicense(model.NewTestLicense())
   119  		th.App.Srv().Jobs.InitWorkers()
   120  		th.App.Srv().Jobs.InitSchedulers()
   121  	} else {
   122  		th.App.Srv().SetLicense(nil)
   123  	}
   124  
   125  	if th.tempWorkspace == "" {
   126  		th.tempWorkspace = tempWorkspace
   127  	}
   128  
   129  	return th
   130  }
   131  
   132  func setup(tb testing.TB) *TestHelper {
   133  	if testing.Short() {
   134  		tb.SkipNow()
   135  	}
   136  	tb.Skip("MM-36947")
   137  	dbStore := mainHelper.GetStore()
   138  	dbStore.DropAllTables()
   139  	dbStore.MarkSystemRanUnitTests()
   140  
   141  	return setupTestHelper(dbStore, false, true, tb, nil)
   142  }
   143  
   144  var initBasicOnce sync.Once
   145  var userCache struct {
   146  	SystemAdminUser *model.User
   147  	BasicUser       *model.User
   148  	BasicUser2      *model.User
   149  }
   150  
   151  func (th *TestHelper) initBasic() *TestHelper {
   152  	// create users once and cache them because password hashing is slow
   153  	initBasicOnce.Do(func() {
   154  		th.SystemAdminUser = th.createUser()
   155  		th.App.UpdateUserRoles(th.SystemAdminUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false)
   156  		th.SystemAdminUser, _ = th.App.GetUser(th.SystemAdminUser.Id)
   157  		userCache.SystemAdminUser = th.SystemAdminUser.DeepCopy()
   158  
   159  		th.BasicUser = th.createUser()
   160  		th.BasicUser, _ = th.App.GetUser(th.BasicUser.Id)
   161  		userCache.BasicUser = th.BasicUser.DeepCopy()
   162  
   163  		th.BasicUser2 = th.createUser()
   164  		th.BasicUser2, _ = th.App.GetUser(th.BasicUser2.Id)
   165  		userCache.BasicUser2 = th.BasicUser2.DeepCopy()
   166  	})
   167  	// restore cached users
   168  	th.SystemAdminUser = userCache.SystemAdminUser.DeepCopy()
   169  	th.BasicUser = userCache.BasicUser.DeepCopy()
   170  	th.BasicUser2 = userCache.BasicUser2.DeepCopy()
   171  	mainHelper.GetSQLStore().GetMaster().Insert(th.SystemAdminUser, th.BasicUser, th.BasicUser2)
   172  
   173  	th.BasicTeam = th.createTeam()
   174  
   175  	th.linkUserToTeam(th.BasicUser, th.BasicTeam)
   176  	th.linkUserToTeam(th.BasicUser2, th.BasicTeam)
   177  	th.BasicChannel = th.CreateChannel(th.BasicTeam)
   178  	th.BasicPost = th.createPost(th.BasicChannel)
   179  	return th
   180  }
   181  
   182  func (th *TestHelper) createTeam() *model.Team {
   183  	id := model.NewId()
   184  	team := &model.Team{
   185  		DisplayName: "dn_" + id,
   186  		Name:        "name" + id,
   187  		Email:       "success+" + id + "@simulator.amazonses.com",
   188  		Type:        model.TEAM_OPEN,
   189  	}
   190  
   191  	utils.DisableDebugLogForTest()
   192  	var err *model.AppError
   193  	if team, err = th.App.CreateTeam(th.Context, team); err != nil {
   194  		panic(err)
   195  	}
   196  	utils.EnableDebugLogForTest()
   197  	return team
   198  }
   199  
   200  func (th *TestHelper) createUser() *model.User {
   201  	return th.createUserOrGuest(false)
   202  }
   203  
   204  func (th *TestHelper) createGuest() *model.User {
   205  	return th.createUserOrGuest(true)
   206  }
   207  
   208  func (th *TestHelper) createUserOrGuest(guest bool) *model.User {
   209  	id := model.NewId()
   210  
   211  	user := &model.User{
   212  		Email:         "success+" + id + "@simulator.amazonses.com",
   213  		Username:      "un_" + id,
   214  		Nickname:      "nn_" + id,
   215  		Password:      "Password1",
   216  		EmailVerified: true,
   217  	}
   218  
   219  	utils.DisableDebugLogForTest()
   220  	var err *model.AppError
   221  	if guest {
   222  		if user, err = th.App.CreateGuest(th.Context, user); err != nil {
   223  			panic(err)
   224  		}
   225  	} else {
   226  		if user, err = th.App.CreateUser(th.Context, user); err != nil {
   227  			panic(err)
   228  		}
   229  	}
   230  	utils.EnableDebugLogForTest()
   231  	return user
   232  }
   233  
   234  type ChannelOption func(*model.Channel)
   235  
   236  func WithShared(v bool) ChannelOption {
   237  	return func(channel *model.Channel) {
   238  		channel.Shared = model.NewBool(v)
   239  	}
   240  }
   241  
   242  func (th *TestHelper) CreateChannel(team *model.Team, options ...ChannelOption) *model.Channel {
   243  	return th.createChannel(team, model.CHANNEL_OPEN, options...)
   244  }
   245  
   246  func (th *TestHelper) createPrivateChannel(team *model.Team) *model.Channel {
   247  	return th.createChannel(team, model.CHANNEL_PRIVATE)
   248  }
   249  
   250  func (th *TestHelper) createChannel(team *model.Team, channelType string, options ...ChannelOption) *model.Channel {
   251  	id := model.NewId()
   252  
   253  	channel := &model.Channel{
   254  		DisplayName: "dn_" + id,
   255  		Name:        "name_" + id,
   256  		Type:        channelType,
   257  		TeamId:      team.Id,
   258  		CreatorId:   th.BasicUser.Id,
   259  	}
   260  
   261  	for _, option := range options {
   262  		option(channel)
   263  	}
   264  
   265  	utils.DisableDebugLogForTest()
   266  	var err *model.AppError
   267  	if channel, err = th.App.CreateChannel(th.Context, channel, true); err != nil {
   268  		panic(err)
   269  	}
   270  
   271  	if channel.IsShared() {
   272  		id := model.NewId()
   273  		_, err := th.App.SaveSharedChannel(&model.SharedChannel{
   274  			ChannelId:        channel.Id,
   275  			TeamId:           channel.TeamId,
   276  			Home:             false,
   277  			ReadOnly:         false,
   278  			ShareName:        "shared-" + id,
   279  			ShareDisplayName: "shared-" + id,
   280  			CreatorId:        th.BasicUser.Id,
   281  			RemoteId:         model.NewId(),
   282  		})
   283  		if err != nil {
   284  			panic(err)
   285  		}
   286  	}
   287  	utils.EnableDebugLogForTest()
   288  	return channel
   289  }
   290  
   291  func (th *TestHelper) createChannelWithAnotherUser(team *model.Team, channelType, userID string) *model.Channel {
   292  	id := model.NewId()
   293  
   294  	channel := &model.Channel{
   295  		DisplayName: "dn_" + id,
   296  		Name:        "name_" + id,
   297  		Type:        channelType,
   298  		TeamId:      team.Id,
   299  		CreatorId:   userID,
   300  	}
   301  
   302  	utils.DisableDebugLogForTest()
   303  	var err *model.AppError
   304  	if channel, err = th.App.CreateChannel(th.Context, channel, true); err != nil {
   305  		panic(err)
   306  	}
   307  	utils.EnableDebugLogForTest()
   308  	return channel
   309  }
   310  
   311  func (th *TestHelper) createDmChannel(user *model.User) *model.Channel {
   312  	utils.DisableDebugLogForTest()
   313  	var err *model.AppError
   314  	var channel *model.Channel
   315  	if channel, err = th.App.GetOrCreateDirectChannel(th.Context, th.BasicUser.Id, user.Id); err != nil {
   316  		panic(err)
   317  	}
   318  	utils.EnableDebugLogForTest()
   319  	return channel
   320  }
   321  
   322  func (th *TestHelper) createGroupChannel(user1 *model.User, user2 *model.User) *model.Channel {
   323  	utils.DisableDebugLogForTest()
   324  	var err *model.AppError
   325  	var channel *model.Channel
   326  	if channel, err = th.App.CreateGroupChannel([]string{th.BasicUser.Id, user1.Id, user2.Id}, th.BasicUser.Id); err != nil {
   327  		panic(err)
   328  	}
   329  	utils.EnableDebugLogForTest()
   330  	return channel
   331  }
   332  
   333  func (th *TestHelper) createPost(channel *model.Channel) *model.Post {
   334  	id := model.NewId()
   335  
   336  	post := &model.Post{
   337  		UserId:    th.BasicUser.Id,
   338  		ChannelId: channel.Id,
   339  		Message:   "message_" + id,
   340  		CreateAt:  model.GetMillis() - 10000,
   341  	}
   342  
   343  	utils.DisableDebugLogForTest()
   344  	var err *model.AppError
   345  	if post, err = th.App.CreatePost(th.Context, post, channel, false, true); err != nil {
   346  		panic(err)
   347  	}
   348  	utils.EnableDebugLogForTest()
   349  	return post
   350  }
   351  
   352  func (th *TestHelper) linkUserToTeam(user *model.User, team *model.Team) {
   353  	utils.DisableDebugLogForTest()
   354  
   355  	_, err := th.App.JoinUserToTeam(th.Context, team, user, "")
   356  	if err != nil {
   357  		panic(err)
   358  	}
   359  
   360  	utils.EnableDebugLogForTest()
   361  }
   362  
   363  func (th *TestHelper) addUserToChannel(user *model.User, channel *model.Channel) *model.ChannelMember {
   364  	utils.DisableDebugLogForTest()
   365  
   366  	member, err := th.App.AddUserToChannel(user, channel, false)
   367  	if err != nil {
   368  		panic(err)
   369  	}
   370  
   371  	utils.EnableDebugLogForTest()
   372  
   373  	return member
   374  }
   375  
   376  func (th *TestHelper) shutdownApp() {
   377  	done := make(chan bool)
   378  	go func() {
   379  		th.Server.Shutdown()
   380  		close(done)
   381  	}()
   382  
   383  	select {
   384  	case <-done:
   385  	case <-time.After(30 * time.Second):
   386  		// panic instead of fatal to terminate all tests in this package, otherwise the
   387  		// still running App could spuriously fail subsequent tests.
   388  		panic("failed to shutdown App within 30 seconds")
   389  	}
   390  }
   391  
   392  func (th *TestHelper) tearDown() {
   393  	if th.IncludeCacheLayer {
   394  		// Clean all the caches
   395  		th.App.Srv().InvalidateAllCaches()
   396  	}
   397  	th.shutdownApp()
   398  	if th.tempWorkspace != "" {
   399  		os.RemoveAll(th.tempWorkspace)
   400  	}
   401  }
   402  
   403  func (th *TestHelper) removePermissionFromRole(permission string, roleName string) {
   404  	utils.DisableDebugLogForTest()
   405  
   406  	role, err1 := th.App.GetRoleByName(context.Background(), roleName)
   407  	if err1 != nil {
   408  		utils.EnableDebugLogForTest()
   409  		panic(err1)
   410  	}
   411  
   412  	var newPermissions []string
   413  	for _, p := range role.Permissions {
   414  		if p != permission {
   415  			newPermissions = append(newPermissions, p)
   416  		}
   417  	}
   418  
   419  	if strings.Join(role.Permissions, " ") == strings.Join(newPermissions, " ") {
   420  		utils.EnableDebugLogForTest()
   421  		return
   422  	}
   423  
   424  	role.Permissions = newPermissions
   425  
   426  	_, err2 := th.App.UpdateRole(role)
   427  	if err2 != nil {
   428  		utils.EnableDebugLogForTest()
   429  		panic(err2)
   430  	}
   431  
   432  	utils.EnableDebugLogForTest()
   433  }
   434  
   435  func (th *TestHelper) addPermissionToRole(permission string, roleName string) {
   436  	utils.DisableDebugLogForTest()
   437  
   438  	role, err1 := th.App.GetRoleByName(context.Background(), roleName)
   439  	if err1 != nil {
   440  		utils.EnableDebugLogForTest()
   441  		panic(err1)
   442  	}
   443  
   444  	for _, existingPermission := range role.Permissions {
   445  		if existingPermission == permission {
   446  			utils.EnableDebugLogForTest()
   447  			return
   448  		}
   449  	}
   450  
   451  	role.Permissions = append(role.Permissions, permission)
   452  
   453  	_, err2 := th.App.UpdateRole(role)
   454  	if err2 != nil {
   455  		utils.EnableDebugLogForTest()
   456  		panic(err2)
   457  	}
   458  
   459  	utils.EnableDebugLogForTest()
   460  }