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