github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/config/unmarshal_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package config 5 6 import ( 7 "bytes" 8 "os" 9 "strings" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 15 "github.com/mattermost/mattermost-server/v5/model" 16 "github.com/mattermost/mattermost-server/v5/utils" 17 ) 18 19 func TestGetDefaultsFromStruct(t *testing.T) { 20 s := struct { 21 TestSettings struct { 22 IntValue int 23 BoolValue bool 24 StringValue string 25 } 26 PointerToTestSettings *struct { 27 Value int 28 } 29 }{} 30 31 defaults := getDefaultsFromStruct(s) 32 33 assert.Equal(t, defaults["TestSettings.IntValue"], 0) 34 assert.Equal(t, defaults["TestSettings.BoolValue"], false) 35 assert.Equal(t, defaults["TestSettings.StringValue"], "") 36 assert.Equal(t, defaults["PointerToTestSettings.Value"], 0) 37 assert.NotContains(t, defaults, "PointerToTestSettings") 38 assert.Len(t, defaults, 4) 39 } 40 41 func TestUnmarshalConfig(t *testing.T) { 42 _, _, err := unmarshalConfig(bytes.NewReader([]byte(``)), false) 43 require.EqualError(t, err, "parsing error at line 1, character 1: unexpected end of JSON input") 44 45 _, _, err = unmarshalConfig(bytes.NewReader([]byte(` 46 { 47 malformed 48 `)), false) 49 require.EqualError(t, err, "parsing error at line 3, character 5: invalid character 'm' looking for beginning of object key string") 50 } 51 52 func TestUnmarshalConfig_PluginSettings(t *testing.T) { 53 config, _, err := unmarshalConfig(bytes.NewReader([]byte(`{ 54 "PluginSettings": { 55 "Directory": "/temp/mattermost-plugins", 56 "Plugins": { 57 "com.example.plugin": { 58 "number": 1, 59 "string": "abc", 60 "boolean": false, 61 "abc.def.ghi": { 62 "abc": 123, 63 "def": "456" 64 } 65 }, 66 "jira": { 67 "number": 2, 68 "string": "123", 69 "boolean": true, 70 "abc.def.ghi": { 71 "abc": 456, 72 "def": "123" 73 } 74 } 75 }, 76 "PluginStates": { 77 "com.example.plugin": { 78 "enable": true 79 }, 80 "jira": { 81 "enable": false 82 } 83 } 84 } 85 }`)), false) 86 require.Nil(t, err) 87 88 assert.Equal(t, "/temp/mattermost-plugins", *config.PluginSettings.Directory) 89 90 if assert.Contains(t, config.PluginSettings.Plugins, "com.example.plugin") { 91 assert.Equal(t, map[string]interface{}{ 92 "number": float64(1), 93 "string": "abc", 94 "boolean": false, 95 "abc.def.ghi": map[string]interface{}{ 96 "abc": float64(123), 97 "def": "456", 98 }, 99 }, config.PluginSettings.Plugins["com.example.plugin"]) 100 } 101 if assert.Contains(t, config.PluginSettings.PluginStates, "com.example.plugin") { 102 assert.Equal(t, model.PluginState{ 103 Enable: true, 104 }, *config.PluginSettings.PluginStates["com.example.plugin"]) 105 } 106 107 if assert.Contains(t, config.PluginSettings.Plugins, "jira") { 108 assert.Equal(t, map[string]interface{}{ 109 "number": float64(2), 110 "string": "123", 111 "boolean": true, 112 "abc.def.ghi": map[string]interface{}{ 113 "abc": float64(456), 114 "def": "123", 115 }, 116 }, config.PluginSettings.Plugins["jira"]) 117 } 118 if assert.Contains(t, config.PluginSettings.PluginStates, "jira") { 119 assert.Equal(t, model.PluginState{ 120 Enable: false, 121 }, *config.PluginSettings.PluginStates["jira"]) 122 } 123 } 124 125 func TestConfigFromEnviroVars(t *testing.T) { 126 config := `{ 127 "ServiceSettings": { 128 "EnableCommands": true, 129 "ReadTimeout": 100 130 }, 131 "TeamSettings": { 132 "SiteName": "Mattermost", 133 "CustomBrandText": "" 134 }, 135 "SupportSettings": { 136 "TermsOfServiceLink": "https://about.mattermost.com/default-terms/" 137 }, 138 "PluginSettings": { 139 "Enable": true, 140 "Plugins": { 141 "jira": { 142 "enabled": "true", 143 "secret": "config-secret" 144 } 145 }, 146 "PluginStates": { 147 "jira": { 148 "Enable": true 149 } 150 } 151 } 152 }` 153 154 t.Run("string settings", func(t *testing.T) { 155 os.Setenv("MM_TEAMSETTINGS_SITENAME", "From Environment") 156 os.Setenv("MM_TEAMSETTINGS_CUSTOMBRANDTEXT", "Custom Brand") 157 158 cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true) 159 require.Nil(t, err) 160 161 assert.Equal(t, "From Environment", *cfg.TeamSettings.SiteName) 162 assert.Equal(t, "Custom Brand", *cfg.TeamSettings.CustomBrandText) 163 164 teamSettings, ok := envCfg["TeamSettings"] 165 require.True(t, ok, "TeamSettings is missing from envConfig") 166 167 teamSettingsAsMap, ok := teamSettings.(map[string]interface{}) 168 require.True(t, ok, "TeamSettings is not a map in envConfig") 169 170 siteNameInEnv, ok := teamSettingsAsMap["SiteName"].(bool) 171 require.True(t, ok || siteNameInEnv, "SiteName should be in envConfig") 172 173 customBrandTextInEnv, ok := teamSettingsAsMap["CustomBrandText"].(bool) 174 require.True(t, ok || customBrandTextInEnv, "SiteName should be in envConfig") 175 176 os.Unsetenv("MM_TEAMSETTINGS_SITENAME") 177 os.Unsetenv("MM_TEAMSETTINGS_CUSTOMBRANDTEXT") 178 179 cfg, envCfg, err = unmarshalConfig(strings.NewReader(config), true) 180 require.Nil(t, err) 181 182 assert.Equal(t, "Mattermost", *cfg.TeamSettings.SiteName) 183 184 _, ok = envCfg["TeamSettings"] 185 require.False(t, ok, "TeamSettings should be missing from envConfig") 186 }) 187 188 t.Run("boolean setting", func(t *testing.T) { 189 os.Setenv("MM_SERVICESETTINGS_ENABLECOMMANDS", "false") 190 defer os.Unsetenv("MM_SERVICESETTINGS_ENABLECOMMANDS") 191 192 cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true) 193 require.Nil(t, err) 194 195 require.False(t, *cfg.ServiceSettings.EnableCommands, "Couldn't read config from environment var") 196 197 serviceSettings, ok := envCfg["ServiceSettings"] 198 require.True(t, ok, "ServiceSettings is missing from envConfig") 199 200 serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{}) 201 require.True(t, ok, "ServiceSettings is not a map in envConfig") 202 203 enableCommandsInEnv, ok := serviceSettingsAsMap["EnableCommands"].(bool) 204 require.True(t, ok || enableCommandsInEnv, "EnableCommands should be in envConfig") 205 }) 206 207 t.Run("integer setting", func(t *testing.T) { 208 os.Setenv("MM_SERVICESETTINGS_READTIMEOUT", "400") 209 defer os.Unsetenv("MM_SERVICESETTINGS_READTIMEOUT") 210 211 cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true) 212 require.Nil(t, err) 213 214 assert.Equal(t, 400, *cfg.ServiceSettings.ReadTimeout) 215 216 serviceSettings, ok := envCfg["ServiceSettings"] 217 require.True(t, ok, "ServiceSettings is missing from envConfig") 218 219 serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{}) 220 require.True(t, ok, "ServiceSettings is not a map in envConfig") 221 222 readTimeoutInEnv, ok := serviceSettingsAsMap["ReadTimeout"].(bool) 223 require.True(t, ok || readTimeoutInEnv, "ReadTimeout should be in envConfig") 224 }) 225 226 t.Run("setting missing from config.json", func(t *testing.T) { 227 os.Setenv("MM_SERVICESETTINGS_SITEURL", "https://example.com") 228 defer os.Unsetenv("MM_SERVICESETTINGS_SITEURL") 229 230 cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true) 231 require.Nil(t, err) 232 233 assert.Equal(t, "https://example.com", *cfg.ServiceSettings.SiteURL) 234 235 serviceSettings, ok := envCfg["ServiceSettings"] 236 require.True(t, ok, "ServiceSettings is missing from envConfig") 237 238 serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{}) 239 require.True(t, ok, "ServiceSettings is not a map in envConfig") 240 241 siteURLInEnv, ok := serviceSettingsAsMap["SiteURL"].(bool) 242 require.True(t, ok || siteURLInEnv, "SiteURL should be in envConfig") 243 }) 244 245 t.Run("empty string setting", func(t *testing.T) { 246 os.Setenv("MM_SUPPORTSETTINGS_TERMSOFSERVICELINK", "") 247 defer os.Unsetenv("MM_SUPPORTSETTINGS_TERMSOFSERVICELINK") 248 249 cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true) 250 require.Nil(t, err) 251 252 assert.Empty(t, *cfg.SupportSettings.TermsOfServiceLink) 253 254 supportSettings, ok := envCfg["SupportSettings"] 255 require.True(t, ok, "SupportSettings is missing from envConfig") 256 257 supportSettingsAsMap, ok := supportSettings.(map[string]interface{}) 258 require.True(t, ok, "SupportSettings is not a map in envConfig") 259 260 termsOfServiceLinkInEnv, ok := supportSettingsAsMap["TermsOfServiceLink"].(bool) 261 require.True(t, ok || termsOfServiceLinkInEnv, "TermsOfServiceLink should be in envConfig") 262 }) 263 264 t.Run("plugin directory settings", func(t *testing.T) { 265 os.Setenv("MM_PLUGINSETTINGS_ENABLE", "false") 266 os.Setenv("MM_PLUGINSETTINGS_DIRECTORY", "/temp/plugins") 267 os.Setenv("MM_PLUGINSETTINGS_CLIENTDIRECTORY", "/temp/clientplugins") 268 defer os.Unsetenv("MM_PLUGINSETTINGS_ENABLE") 269 defer os.Unsetenv("MM_PLUGINSETTINGS_DIRECTORY") 270 defer os.Unsetenv("MM_PLUGINSETTINGS_CLIENTDIRECTORY") 271 272 cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true) 273 require.Nil(t, err) 274 275 assert.Equal(t, false, *cfg.PluginSettings.Enable) 276 assert.Equal(t, "/temp/plugins", *cfg.PluginSettings.Directory) 277 assert.Equal(t, "/temp/clientplugins", *cfg.PluginSettings.ClientDirectory) 278 279 pluginSettings, ok := envCfg["PluginSettings"] 280 require.True(t, ok, "PluginSettings is missing from envConfig") 281 282 pluginSettingsAsMap, ok := pluginSettings.(map[string]interface{}) 283 require.True(t, ok, "PluginSettings is not a map in envConfig") 284 285 directory, ok := pluginSettingsAsMap["Directory"].(bool) 286 require.True(t, ok || directory, "Directory should be in envConfig") 287 288 clientDirectory, ok := pluginSettingsAsMap["ClientDirectory"].(bool) 289 require.True(t, ok || clientDirectory, "ClientDirectory should be in envConfig") 290 }) 291 292 t.Run("plugin specific settings cannot be overridden via environment", func(t *testing.T) { 293 os.Setenv("MM_PLUGINSETTINGS_PLUGINS_JIRA_ENABLED", "false") 294 os.Setenv("MM_PLUGINSETTINGS_PLUGINS_JIRA_SECRET", "env-secret") 295 os.Setenv("MM_PLUGINSETTINGS_PLUGINSTATES_JIRA_ENABLE", "false") 296 defer os.Unsetenv("MM_PLUGINSETTINGS_PLUGINS_JIRA_ENABLED") 297 defer os.Unsetenv("MM_PLUGINSETTINGS_PLUGINS_JIRA_SECRET") 298 defer os.Unsetenv("MM_PLUGINSETTINGS_PLUGINSTATES_JIRA_ENABLE") 299 300 cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true) 301 require.Nil(t, err) 302 303 pluginsJira, ok := cfg.PluginSettings.Plugins["jira"] 304 require.True(t, ok, "PluginSettings.Plugins.jira is missing from config") 305 306 enabled, ok := pluginsJira["enabled"] 307 require.True(t, ok, "PluginSettings.Plugins.jira.enabled is missing from config") 308 assert.Equal(t, "true", enabled) 309 310 secret, ok := pluginsJira["secret"] 311 require.True(t, ok, "PluginSettings.Plugins.jira.secret is missing from config") 312 assert.Equal(t, "config-secret", secret) 313 314 pluginStatesJira, ok := cfg.PluginSettings.PluginStates["jira"] 315 require.True(t, ok, "PluginSettings.PluginStates.jira is missing from config") 316 require.Equal(t, true, pluginStatesJira.Enable) 317 318 pluginSettings, ok := envCfg["PluginSettings"] 319 require.True(t, ok, "PluginSettings is missing from envConfig") 320 321 pluginSettingsAsMap, ok := pluginSettings.(map[string]interface{}) 322 require.True(t, ok, "PluginSettings is not a map in envConfig") 323 324 plugins, ok := pluginSettingsAsMap["Plugins"].(map[string]interface{}) 325 require.True(t, ok, "PluginSettings.Plugins is not a map in envConfig") 326 327 _, ok = plugins["jira"].(map[string]interface{}) 328 require.False(t, ok, "PluginSettings.Plugins.jira should not be a map in envConfig") 329 330 pluginStates, ok := pluginSettingsAsMap["PluginStates"].(map[string]interface{}) 331 require.True(t, ok, "PluginSettings.PluginStates is missing from envConfig") 332 333 _, ok = pluginStates["jira"].(map[string]interface{}) 334 require.False(t, ok, "PluginSettings.PluginStates.jira should not be a map in envConfig") 335 }) 336 } 337 338 func TestReadConfig_ImageProxySettings(t *testing.T) { 339 utils.TranslationsPreInit() 340 341 t.Run("deprecated settings should still be read properly", func(t *testing.T) { 342 config, _, err := unmarshalConfig(bytes.NewReader([]byte(`{ 343 "ServiceSettings": { 344 "ImageProxyType": "OldImageProxyType", 345 "ImageProxyURL": "OldImageProxyURL", 346 "ImageProxyOptions": "OldImageProxyOptions" 347 } 348 }`)), false) 349 350 require.Nil(t, err) 351 352 assert.Equal(t, model.NewString("OldImageProxyType"), config.ServiceSettings.DEPRECATED_DO_NOT_USE_ImageProxyType) 353 assert.Equal(t, model.NewString("OldImageProxyURL"), config.ServiceSettings.DEPRECATED_DO_NOT_USE_ImageProxyURL) 354 assert.Equal(t, model.NewString("OldImageProxyOptions"), config.ServiceSettings.DEPRECATED_DO_NOT_USE_ImageProxyOptions) 355 }) 356 }