github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+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/model" 18 "github.com/mattermost/mattermost-server/store" 19 "github.com/mattermost/mattermost-server/store/sqlstore" 20 "github.com/mattermost/mattermost-server/store/storetest" 21 "github.com/mattermost/mattermost-server/utils" 22 "github.com/mattermost/mattermost-server/wsapi" 23 24 l4g "github.com/alecthomas/log4go" 25 ) 26 27 type TestHelper struct { 28 App *app.App 29 tempConfigPath string 30 31 BasicClient *model.Client 32 BasicTeam *model.Team 33 BasicUser *model.User 34 BasicUser2 *model.User 35 BasicChannel *model.Channel 36 BasicPost *model.Post 37 PinnedPost *model.Post 38 39 SystemAdminClient *model.Client 40 SystemAdminTeam *model.Team 41 SystemAdminUser *model.User 42 SystemAdminChannel *model.Channel 43 } 44 45 type persistentTestStore struct { 46 store.Store 47 } 48 49 func (*persistentTestStore) Close() {} 50 51 var testStoreContainer *storetest.RunningContainer 52 var testStore *persistentTestStore 53 54 // UseTestStore sets the container and corresponding settings to use for tests. Once the tests are 55 // complete (e.g. at the end of your TestMain implementation), you should call StopTestStore. 56 func UseTestStore(container *storetest.RunningContainer, settings *model.SqlSettings) { 57 testStoreContainer = container 58 testStore = &persistentTestStore{store.NewLayeredStore(sqlstore.NewSqlSupplier(*settings, nil), nil, nil)} 59 } 60 61 func StopTestStore() { 62 if testStoreContainer != nil { 63 testStoreContainer.Stop() 64 testStoreContainer = nil 65 } 66 } 67 68 func setupTestHelper(enterprise bool) *TestHelper { 69 permConfig, err := os.Open(utils.FindConfigFile("config.json")) 70 if err != nil { 71 panic(err) 72 } 73 defer permConfig.Close() 74 tempConfig, err := ioutil.TempFile("", "") 75 if err != nil { 76 panic(err) 77 } 78 _, err = io.Copy(tempConfig, permConfig) 79 tempConfig.Close() 80 if err != nil { 81 panic(err) 82 } 83 84 options := []app.Option{app.ConfigFile(tempConfig.Name()), app.DisableConfigWatch} 85 if testStore != nil { 86 options = append(options, app.StoreOverride(testStore)) 87 } 88 89 a, err := app.New(options...) 90 if err != nil { 91 panic(err) 92 } 93 94 th := &TestHelper{ 95 App: a, 96 tempConfigPath: tempConfig.Name(), 97 } 98 99 th.App.UpdateConfig(func(cfg *model.Config) { 100 *cfg.TeamSettings.MaxUsersPerTeam = 50 101 *cfg.RateLimitSettings.Enable = false 102 cfg.EmailSettings.SendEmailNotifications = 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 th.App.StartServer() 109 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) 110 api4.Init(th.App, th.App.Srv.Router, false) 111 Init(th.App, th.App.Srv.Router) 112 wsapi.Init(th.App, th.App.Srv.WebSocketRouter) 113 th.App.Srv.Store.MarkSystemRanUnitTests() 114 115 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) 116 117 utils.SetIsLicensed(enterprise) 118 if enterprise { 119 utils.License().Features.SetDefaults() 120 } 121 122 return th 123 } 124 125 func SetupEnterprise() *TestHelper { 126 return setupTestHelper(true) 127 } 128 129 func Setup() *TestHelper { 130 return setupTestHelper(false) 131 } 132 133 func (me *TestHelper) InitBasic() *TestHelper { 134 me.waitForConnectivity() 135 136 me.BasicClient = me.CreateClient() 137 me.BasicUser = me.CreateUser(me.BasicClient) 138 me.App.UpdateUserRoles(me.BasicUser.Id, model.SYSTEM_USER_ROLE_ID, false) 139 me.LoginBasic() 140 me.BasicTeam = me.CreateTeam(me.BasicClient) 141 me.LinkUserToTeam(me.BasicUser, me.BasicTeam) 142 me.UpdateUserToNonTeamAdmin(me.BasicUser, me.BasicTeam) 143 me.BasicUser2 = me.CreateUser(me.BasicClient) 144 me.LinkUserToTeam(me.BasicUser2, me.BasicTeam) 145 me.BasicClient.SetTeamId(me.BasicTeam.Id) 146 me.BasicChannel = me.CreateChannel(me.BasicClient, me.BasicTeam) 147 me.BasicPost = me.CreatePost(me.BasicClient, me.BasicChannel) 148 149 pinnedPostChannel := me.CreateChannel(me.BasicClient, me.BasicTeam) 150 me.PinnedPost = me.CreatePinnedPost(me.BasicClient, pinnedPostChannel) 151 152 return me 153 } 154 155 func (me *TestHelper) InitSystemAdmin() *TestHelper { 156 me.waitForConnectivity() 157 158 me.SystemAdminClient = me.CreateClient() 159 me.SystemAdminUser = me.CreateUser(me.SystemAdminClient) 160 me.SystemAdminUser.Password = "Password1" 161 me.LoginSystemAdmin() 162 me.SystemAdminTeam = me.CreateTeam(me.SystemAdminClient) 163 me.LinkUserToTeam(me.SystemAdminUser, me.SystemAdminTeam) 164 me.SystemAdminClient.SetTeamId(me.SystemAdminTeam.Id) 165 me.App.UpdateUserRoles(me.SystemAdminUser.Id, model.SYSTEM_USER_ROLE_ID+" "+model.SYSTEM_ADMIN_ROLE_ID, false) 166 me.SystemAdminChannel = me.CreateChannel(me.SystemAdminClient, me.SystemAdminTeam) 167 168 return me 169 } 170 171 func (me *TestHelper) waitForConnectivity() { 172 for i := 0; i < 1000; i++ { 173 conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%v", me.App.Srv.ListenAddr.Port)) 174 if err == nil { 175 conn.Close() 176 return 177 } 178 time.Sleep(time.Millisecond * 20) 179 } 180 panic("unable to connect") 181 } 182 183 func (me *TestHelper) CreateClient() *model.Client { 184 return model.NewClient(fmt.Sprintf("http://localhost:%v", me.App.Srv.ListenAddr.Port)) 185 } 186 187 func (me *TestHelper) CreateWebSocketClient() (*model.WebSocketClient, *model.AppError) { 188 return model.NewWebSocketClient(fmt.Sprintf("ws://localhost:%v", me.App.Srv.ListenAddr.Port), me.BasicClient.AuthToken) 189 } 190 191 func (me *TestHelper) CreateTeam(client *model.Client) *model.Team { 192 id := model.NewId() 193 team := &model.Team{ 194 DisplayName: "dn_" + id, 195 Name: GenerateTestTeamName(), 196 Email: me.GenerateTestEmail(), 197 Type: model.TEAM_OPEN, 198 } 199 200 utils.DisableDebugLogForTest() 201 r := client.Must(client.CreateTeam(team)).Data.(*model.Team) 202 utils.EnableDebugLogForTest() 203 return r 204 } 205 206 func (me *TestHelper) CreateUser(client *model.Client) *model.User { 207 id := model.NewId() 208 209 user := &model.User{ 210 Email: me.GenerateTestEmail(), 211 Username: "un_" + id, 212 Nickname: "nn_" + id, 213 Password: "Password1", 214 } 215 216 utils.DisableDebugLogForTest() 217 ruser := client.Must(client.CreateUser(user, "")).Data.(*model.User) 218 ruser.Password = "Password1" 219 store.Must(me.App.Srv.Store.User().VerifyEmail(ruser.Id)) 220 utils.EnableDebugLogForTest() 221 return ruser 222 } 223 224 func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) { 225 utils.DisableDebugLogForTest() 226 227 err := me.App.JoinUserToTeam(team, user, "") 228 if err != nil { 229 l4g.Error(err.Error()) 230 l4g.Close() 231 time.Sleep(time.Second) 232 panic(err) 233 } 234 235 utils.EnableDebugLogForTest() 236 } 237 238 func (me *TestHelper) UpdateUserToTeamAdmin(user *model.User, team *model.Team) { 239 utils.DisableDebugLogForTest() 240 241 tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.TEAM_USER_ROLE_ID + " " + model.TEAM_ADMIN_ROLE_ID} 242 if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil { 243 utils.EnableDebugLogForTest() 244 l4g.Error(tmr.Err.Error()) 245 l4g.Close() 246 time.Sleep(time.Second) 247 panic(tmr.Err) 248 } 249 utils.EnableDebugLogForTest() 250 } 251 252 func (me *TestHelper) UpdateUserToNonTeamAdmin(user *model.User, team *model.Team) { 253 utils.DisableDebugLogForTest() 254 255 tm := &model.TeamMember{TeamId: team.Id, UserId: user.Id, Roles: model.TEAM_USER_ROLE_ID} 256 if tmr := <-me.App.Srv.Store.Team().UpdateMember(tm); tmr.Err != nil { 257 utils.EnableDebugLogForTest() 258 l4g.Error(tmr.Err.Error()) 259 l4g.Close() 260 time.Sleep(time.Second) 261 panic(tmr.Err) 262 } 263 utils.EnableDebugLogForTest() 264 } 265 266 func (me *TestHelper) MakeUserChannelAdmin(user *model.User, channel *model.Channel) { 267 utils.DisableDebugLogForTest() 268 269 if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil { 270 cm := cmr.Data.(*model.ChannelMember) 271 cm.Roles = "channel_admin channel_user" 272 if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil { 273 utils.EnableDebugLogForTest() 274 panic(sr.Err) 275 } 276 } else { 277 utils.EnableDebugLogForTest() 278 panic(cmr.Err) 279 } 280 281 utils.EnableDebugLogForTest() 282 } 283 284 func (me *TestHelper) MakeUserChannelUser(user *model.User, channel *model.Channel) { 285 utils.DisableDebugLogForTest() 286 287 if cmr := <-me.App.Srv.Store.Channel().GetMember(channel.Id, user.Id); cmr.Err == nil { 288 cm := cmr.Data.(*model.ChannelMember) 289 cm.Roles = "channel_user" 290 if sr := <-me.App.Srv.Store.Channel().UpdateMember(cm); sr.Err != nil { 291 utils.EnableDebugLogForTest() 292 panic(sr.Err) 293 } 294 } else { 295 utils.EnableDebugLogForTest() 296 panic(cmr.Err) 297 } 298 299 utils.EnableDebugLogForTest() 300 } 301 302 func (me *TestHelper) CreateChannel(client *model.Client, team *model.Team) *model.Channel { 303 return me.createChannel(client, team, model.CHANNEL_OPEN) 304 } 305 306 func (me *TestHelper) CreatePrivateChannel(client *model.Client, team *model.Team) *model.Channel { 307 return me.createChannel(client, team, model.CHANNEL_PRIVATE) 308 } 309 310 func (me *TestHelper) createChannel(client *model.Client, team *model.Team, channelType string) *model.Channel { 311 id := model.NewId() 312 313 channel := &model.Channel{ 314 DisplayName: "dn_" + id, 315 Name: "name_" + id, 316 Type: channelType, 317 TeamId: team.Id, 318 } 319 320 utils.DisableDebugLogForTest() 321 r := client.Must(client.CreateChannel(channel)).Data.(*model.Channel) 322 utils.EnableDebugLogForTest() 323 return r 324 } 325 326 func (me *TestHelper) CreatePost(client *model.Client, channel *model.Channel) *model.Post { 327 id := model.NewId() 328 329 post := &model.Post{ 330 ChannelId: channel.Id, 331 Message: "message_" + id, 332 } 333 334 utils.DisableDebugLogForTest() 335 r := client.Must(client.CreatePost(post)).Data.(*model.Post) 336 utils.EnableDebugLogForTest() 337 return r 338 } 339 340 func (me *TestHelper) CreatePinnedPost(client *model.Client, channel *model.Channel) *model.Post { 341 id := model.NewId() 342 343 post := &model.Post{ 344 ChannelId: channel.Id, 345 Message: "message_" + id, 346 IsPinned: true, 347 } 348 349 utils.DisableDebugLogForTest() 350 r := client.Must(client.CreatePost(post)).Data.(*model.Post) 351 utils.EnableDebugLogForTest() 352 return r 353 } 354 355 func (me *TestHelper) LoginBasic() { 356 utils.DisableDebugLogForTest() 357 me.BasicClient.Must(me.BasicClient.Login(me.BasicUser.Email, me.BasicUser.Password)) 358 utils.EnableDebugLogForTest() 359 } 360 361 func (me *TestHelper) LoginBasic2() { 362 utils.DisableDebugLogForTest() 363 me.BasicClient.Must(me.BasicClient.Login(me.BasicUser2.Email, me.BasicUser2.Password)) 364 utils.EnableDebugLogForTest() 365 } 366 367 func (me *TestHelper) LoginSystemAdmin() { 368 utils.DisableDebugLogForTest() 369 me.SystemAdminClient.Must(me.SystemAdminClient.Login(me.SystemAdminUser.Email, me.SystemAdminUser.Password)) 370 utils.EnableDebugLogForTest() 371 } 372 373 func (me *TestHelper) GenerateTestEmail() string { 374 if me.App.Config().EmailSettings.SMTPServer != "dockerhost" && os.Getenv("CI_INBUCKET_PORT") == "" { 375 return strings.ToLower("success+" + model.NewId() + "@simulator.amazonses.com") 376 } 377 return strings.ToLower(model.NewId() + "@dockerhost") 378 } 379 380 func GenerateTestTeamName() string { 381 return "faketeam" + model.NewRandomString(6) 382 } 383 384 func (me *TestHelper) TearDown() { 385 me.App.Shutdown() 386 os.Remove(me.tempConfigPath) 387 if err := recover(); err != nil { 388 StopTestStore() 389 panic(err) 390 } 391 }