github.com/coincircle/mattermost-server@v4.8.1-0.20180321182714-9d701c704416+incompatible/app/apptestlib.go (about) 1 // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "encoding/json" 8 "io" 9 "io/ioutil" 10 "os" 11 "path/filepath" 12 "time" 13 14 l4g "github.com/alecthomas/log4go" 15 16 "github.com/mattermost/mattermost-server/model" 17 "github.com/mattermost/mattermost-server/plugin" 18 "github.com/mattermost/mattermost-server/plugin/pluginenv" 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 ) 24 25 type TestHelper struct { 26 App *App 27 BasicTeam *model.Team 28 BasicUser *model.User 29 BasicUser2 *model.User 30 BasicChannel *model.Channel 31 BasicPost *model.Post 32 33 tempConfigPath string 34 tempWorkspace string 35 pluginHooks map[string]plugin.Hooks 36 } 37 38 type persistentTestStore struct { 39 store.Store 40 } 41 42 func (*persistentTestStore) Close() {} 43 44 var testStoreContainer *storetest.RunningContainer 45 var testStore *persistentTestStore 46 47 // UseTestStore sets the container and corresponding settings to use for tests. Once the tests are 48 // complete (e.g. at the end of your TestMain implementation), you should call StopTestStore. 49 func UseTestStore(container *storetest.RunningContainer, settings *model.SqlSettings) { 50 testStoreContainer = container 51 testStore = &persistentTestStore{store.NewLayeredStore(sqlstore.NewSqlSupplier(*settings, nil), nil, nil)} 52 } 53 54 func StopTestStore() { 55 if testStoreContainer != nil { 56 testStoreContainer.Stop() 57 testStoreContainer = nil 58 } 59 } 60 61 func setupTestHelper(enterprise bool) *TestHelper { 62 permConfig, err := os.Open(utils.FindConfigFile("config.json")) 63 if err != nil { 64 panic(err) 65 } 66 defer permConfig.Close() 67 tempConfig, err := ioutil.TempFile("", "") 68 if err != nil { 69 panic(err) 70 } 71 _, err = io.Copy(tempConfig, permConfig) 72 tempConfig.Close() 73 if err != nil { 74 panic(err) 75 } 76 77 options := []Option{ConfigFile(tempConfig.Name()), DisableConfigWatch} 78 if testStore != nil { 79 options = append(options, StoreOverride(testStore)) 80 } 81 82 a, err := New(options...) 83 if err != nil { 84 panic(err) 85 } 86 87 th := &TestHelper{ 88 App: a, 89 pluginHooks: make(map[string]plugin.Hooks), 90 tempConfigPath: tempConfig.Name(), 91 } 92 93 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.MaxUsersPerTeam = 50 }) 94 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.RateLimitSettings.Enable = false }) 95 prevListenAddress := *th.App.Config().ServiceSettings.ListenAddress 96 if testStore != nil { 97 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = ":0" }) 98 } 99 serverErr := th.App.StartServer() 100 if serverErr != nil { 101 panic(serverErr) 102 } 103 104 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) 105 th.App.Srv.Store.MarkSystemRanUnitTests() 106 107 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) 108 109 if enterprise { 110 th.App.SetLicense(model.NewTestLicense()) 111 } else { 112 th.App.SetLicense(nil) 113 } 114 115 return th 116 } 117 118 func SetupEnterprise() *TestHelper { 119 return setupTestHelper(true) 120 } 121 122 func Setup() *TestHelper { 123 return setupTestHelper(false) 124 } 125 126 func (me *TestHelper) InitBasic() *TestHelper { 127 me.BasicTeam = me.CreateTeam() 128 me.BasicUser = me.CreateUser() 129 me.LinkUserToTeam(me.BasicUser, me.BasicTeam) 130 me.BasicUser2 = me.CreateUser() 131 me.LinkUserToTeam(me.BasicUser2, me.BasicTeam) 132 me.BasicChannel = me.CreateChannel(me.BasicTeam) 133 me.BasicPost = me.CreatePost(me.BasicChannel) 134 135 return me 136 } 137 138 func (me *TestHelper) MakeEmail() string { 139 return "success_" + model.NewId() + "@simulator.amazonses.com" 140 } 141 142 func (me *TestHelper) CreateTeam() *model.Team { 143 id := model.NewId() 144 team := &model.Team{ 145 DisplayName: "dn_" + id, 146 Name: "name" + id, 147 Email: "success+" + id + "@simulator.amazonses.com", 148 Type: model.TEAM_OPEN, 149 } 150 151 utils.DisableDebugLogForTest() 152 var err *model.AppError 153 if team, err = me.App.CreateTeam(team); err != nil { 154 l4g.Error(err.Error()) 155 l4g.Close() 156 time.Sleep(time.Second) 157 panic(err) 158 } 159 utils.EnableDebugLogForTest() 160 return team 161 } 162 163 func (me *TestHelper) CreateUser() *model.User { 164 id := model.NewId() 165 166 user := &model.User{ 167 Email: "success+" + id + "@simulator.amazonses.com", 168 Username: "un_" + id, 169 Nickname: "nn_" + id, 170 Password: "Password1", 171 EmailVerified: true, 172 } 173 174 utils.DisableDebugLogForTest() 175 var err *model.AppError 176 if user, err = me.App.CreateUser(user); err != nil { 177 l4g.Error(err.Error()) 178 l4g.Close() 179 time.Sleep(time.Second) 180 panic(err) 181 } 182 utils.EnableDebugLogForTest() 183 return user 184 } 185 186 func (me *TestHelper) CreateChannel(team *model.Team) *model.Channel { 187 return me.createChannel(team, model.CHANNEL_OPEN) 188 } 189 190 func (me *TestHelper) createChannel(team *model.Team, channelType string) *model.Channel { 191 id := model.NewId() 192 193 channel := &model.Channel{ 194 DisplayName: "dn_" + id, 195 Name: "name_" + id, 196 Type: channelType, 197 TeamId: team.Id, 198 CreatorId: me.BasicUser.Id, 199 } 200 201 utils.DisableDebugLogForTest() 202 var err *model.AppError 203 if channel, err = me.App.CreateChannel(channel, true); err != nil { 204 l4g.Error(err.Error()) 205 l4g.Close() 206 time.Sleep(time.Second) 207 panic(err) 208 } 209 utils.EnableDebugLogForTest() 210 return channel 211 } 212 213 func (me *TestHelper) CreatePost(channel *model.Channel) *model.Post { 214 id := model.NewId() 215 216 post := &model.Post{ 217 UserId: me.BasicUser.Id, 218 ChannelId: channel.Id, 219 Message: "message_" + id, 220 } 221 222 utils.DisableDebugLogForTest() 223 var err *model.AppError 224 if post, err = me.App.CreatePost(post, channel, false); err != nil { 225 l4g.Error(err.Error()) 226 l4g.Close() 227 time.Sleep(time.Second) 228 panic(err) 229 } 230 utils.EnableDebugLogForTest() 231 return post 232 } 233 234 func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) { 235 utils.DisableDebugLogForTest() 236 237 err := me.App.JoinUserToTeam(team, user, "") 238 if err != nil { 239 l4g.Error(err.Error()) 240 l4g.Close() 241 time.Sleep(time.Second) 242 panic(err) 243 } 244 245 utils.EnableDebugLogForTest() 246 } 247 248 func (me *TestHelper) AddUserToChannel(user *model.User, channel *model.Channel) *model.ChannelMember { 249 utils.DisableDebugLogForTest() 250 251 member, err := me.App.AddUserToChannel(user, channel) 252 if err != nil { 253 l4g.Error(err.Error()) 254 l4g.Close() 255 time.Sleep(time.Second) 256 panic(err) 257 } 258 259 utils.EnableDebugLogForTest() 260 261 return member 262 } 263 264 func (me *TestHelper) TearDown() { 265 me.App.Shutdown() 266 os.Remove(me.tempConfigPath) 267 if err := recover(); err != nil { 268 StopTestStore() 269 panic(err) 270 } 271 if me.tempWorkspace != "" { 272 os.RemoveAll(me.tempWorkspace) 273 } 274 } 275 276 type mockPluginSupervisor struct { 277 hooks plugin.Hooks 278 } 279 280 func (s *mockPluginSupervisor) Start(api plugin.API) error { 281 return s.hooks.OnActivate(api) 282 } 283 284 func (s *mockPluginSupervisor) Stop() error { 285 return nil 286 } 287 288 func (s *mockPluginSupervisor) Hooks() plugin.Hooks { 289 return s.hooks 290 } 291 292 func (me *TestHelper) InstallPlugin(manifest *model.Manifest, hooks plugin.Hooks) { 293 if me.tempWorkspace == "" { 294 dir, err := ioutil.TempDir("", "apptest") 295 if err != nil { 296 panic(err) 297 } 298 me.tempWorkspace = dir 299 } 300 301 pluginDir := filepath.Join(me.tempWorkspace, "plugins") 302 webappDir := filepath.Join(me.tempWorkspace, "webapp") 303 me.App.InitPlugins(pluginDir, webappDir, func(bundle *model.BundleInfo) (plugin.Supervisor, error) { 304 if hooks, ok := me.pluginHooks[bundle.Manifest.Id]; ok { 305 return &mockPluginSupervisor{hooks}, nil 306 } 307 return pluginenv.DefaultSupervisorProvider(bundle) 308 }) 309 310 me.pluginHooks[manifest.Id] = hooks 311 312 manifestCopy := *manifest 313 if manifestCopy.Backend == nil { 314 manifestCopy.Backend = &model.ManifestBackend{} 315 } 316 manifestBytes, err := json.Marshal(&manifestCopy) 317 if err != nil { 318 panic(err) 319 } 320 321 if err := os.MkdirAll(filepath.Join(pluginDir, manifest.Id), 0700); err != nil { 322 panic(err) 323 } 324 325 if err := ioutil.WriteFile(filepath.Join(pluginDir, manifest.Id, "plugin.json"), manifestBytes, 0600); err != nil { 326 panic(err) 327 } 328 }