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 }