github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+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 th.App.StartServer() 100 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.ServiceSettings.ListenAddress = prevListenAddress }) 101 th.App.Srv.Store.MarkSystemRanUnitTests() 102 103 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.EnableOpenServer = true }) 104 105 utils.SetIsLicensed(enterprise) 106 if enterprise { 107 utils.License().Features.SetDefaults() 108 } 109 110 return th 111 } 112 113 func SetupEnterprise() *TestHelper { 114 return setupTestHelper(true) 115 } 116 117 func Setup() *TestHelper { 118 return setupTestHelper(false) 119 } 120 121 func (me *TestHelper) InitBasic() *TestHelper { 122 me.BasicTeam = me.CreateTeam() 123 me.BasicUser = me.CreateUser() 124 me.LinkUserToTeam(me.BasicUser, me.BasicTeam) 125 me.BasicUser2 = me.CreateUser() 126 me.LinkUserToTeam(me.BasicUser2, me.BasicTeam) 127 me.BasicChannel = me.CreateChannel(me.BasicTeam) 128 me.BasicPost = me.CreatePost(me.BasicChannel) 129 130 return me 131 } 132 133 func (me *TestHelper) MakeUsername() string { 134 return "un_" + model.NewId() 135 } 136 137 func (me *TestHelper) MakeEmail() string { 138 return "success_" + model.NewId() + "@simulator.amazonses.com" 139 } 140 141 func (me *TestHelper) CreateTeam() *model.Team { 142 id := model.NewId() 143 team := &model.Team{ 144 DisplayName: "dn_" + id, 145 Name: "name" + id, 146 Email: "success+" + id + "@simulator.amazonses.com", 147 Type: model.TEAM_OPEN, 148 } 149 150 utils.DisableDebugLogForTest() 151 var err *model.AppError 152 if team, err = me.App.CreateTeam(team); err != nil { 153 l4g.Error(err.Error()) 154 l4g.Close() 155 time.Sleep(time.Second) 156 panic(err) 157 } 158 utils.EnableDebugLogForTest() 159 return team 160 } 161 162 func (me *TestHelper) CreateUser() *model.User { 163 id := model.NewId() 164 165 user := &model.User{ 166 Email: "success+" + id + "@simulator.amazonses.com", 167 Username: "un_" + id, 168 Nickname: "nn_" + id, 169 Password: "Password1", 170 EmailVerified: true, 171 } 172 173 utils.DisableDebugLogForTest() 174 var err *model.AppError 175 if user, err = me.App.CreateUser(user); err != nil { 176 l4g.Error(err.Error()) 177 l4g.Close() 178 time.Sleep(time.Second) 179 panic(err) 180 } 181 utils.EnableDebugLogForTest() 182 return user 183 } 184 185 func (me *TestHelper) CreateChannel(team *model.Team) *model.Channel { 186 return me.createChannel(team, model.CHANNEL_OPEN) 187 } 188 189 func (me *TestHelper) CreatePrivateChannel(team *model.Team) *model.Channel { 190 return me.createChannel(team, model.CHANNEL_PRIVATE) 191 } 192 193 func (me *TestHelper) createChannel(team *model.Team, channelType string) *model.Channel { 194 id := model.NewId() 195 196 channel := &model.Channel{ 197 DisplayName: "dn_" + id, 198 Name: "name_" + id, 199 Type: channelType, 200 TeamId: team.Id, 201 CreatorId: me.BasicUser.Id, 202 } 203 204 utils.DisableDebugLogForTest() 205 var err *model.AppError 206 if channel, err = me.App.CreateChannel(channel, true); err != nil { 207 l4g.Error(err.Error()) 208 l4g.Close() 209 time.Sleep(time.Second) 210 panic(err) 211 } 212 utils.EnableDebugLogForTest() 213 return channel 214 } 215 216 func (me *TestHelper) CreatePost(channel *model.Channel) *model.Post { 217 id := model.NewId() 218 219 post := &model.Post{ 220 UserId: me.BasicUser.Id, 221 ChannelId: channel.Id, 222 Message: "message_" + id, 223 } 224 225 utils.DisableDebugLogForTest() 226 var err *model.AppError 227 if post, err = me.App.CreatePost(post, channel, false); err != nil { 228 l4g.Error(err.Error()) 229 l4g.Close() 230 time.Sleep(time.Second) 231 panic(err) 232 } 233 utils.EnableDebugLogForTest() 234 return post 235 } 236 237 func (me *TestHelper) LinkUserToTeam(user *model.User, team *model.Team) { 238 utils.DisableDebugLogForTest() 239 240 err := me.App.JoinUserToTeam(team, user, "") 241 if err != nil { 242 l4g.Error(err.Error()) 243 l4g.Close() 244 time.Sleep(time.Second) 245 panic(err) 246 } 247 248 utils.EnableDebugLogForTest() 249 } 250 251 func (me *TestHelper) TearDown() { 252 me.App.Shutdown() 253 os.Remove(me.tempConfigPath) 254 if err := recover(); err != nil { 255 StopTestStore() 256 panic(err) 257 } 258 if me.tempWorkspace != "" { 259 os.RemoveAll(me.tempWorkspace) 260 } 261 } 262 263 type mockPluginSupervisor struct { 264 hooks plugin.Hooks 265 } 266 267 func (s *mockPluginSupervisor) Start(api plugin.API) error { 268 return s.hooks.OnActivate(api) 269 } 270 271 func (s *mockPluginSupervisor) Stop() error { 272 return nil 273 } 274 275 func (s *mockPluginSupervisor) Hooks() plugin.Hooks { 276 return s.hooks 277 } 278 279 func (me *TestHelper) InstallPlugin(manifest *model.Manifest, hooks plugin.Hooks) { 280 if me.tempWorkspace == "" { 281 dir, err := ioutil.TempDir("", "apptest") 282 if err != nil { 283 panic(err) 284 } 285 me.tempWorkspace = dir 286 } 287 288 pluginDir := filepath.Join(me.tempWorkspace, "plugins") 289 webappDir := filepath.Join(me.tempWorkspace, "webapp") 290 me.App.InitPlugins(pluginDir, webappDir, func(bundle *model.BundleInfo) (plugin.Supervisor, error) { 291 if hooks, ok := me.pluginHooks[bundle.Manifest.Id]; ok { 292 return &mockPluginSupervisor{hooks}, nil 293 } 294 return pluginenv.DefaultSupervisorProvider(bundle) 295 }) 296 297 me.pluginHooks[manifest.Id] = hooks 298 299 manifestCopy := *manifest 300 if manifestCopy.Backend == nil { 301 manifestCopy.Backend = &model.ManifestBackend{} 302 } 303 manifestBytes, err := json.Marshal(&manifestCopy) 304 if err != nil { 305 panic(err) 306 } 307 308 if err := os.MkdirAll(filepath.Join(pluginDir, manifest.Id), 0700); err != nil { 309 panic(err) 310 } 311 312 if err := ioutil.WriteFile(filepath.Join(pluginDir, manifest.Id, "plugin.json"), manifestBytes, 0600); err != nil { 313 panic(err) 314 } 315 }