github.com/adacta-ru/mattermost-server@v5.11.1+incompatible/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/model"
    16  	"github.com/mattermost/mattermost-server/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  		if teamSettings, ok := envCfg["TeamSettings"]; !ok {
   165  			t.Fatal("TeamSettings is missing from envConfig")
   166  		} else if teamSettingsAsMap, ok := teamSettings.(map[string]interface{}); !ok {
   167  			t.Fatal("TeamSettings is not a map in envConfig")
   168  		} else {
   169  			if siteNameInEnv, ok := teamSettingsAsMap["SiteName"].(bool); !ok || !siteNameInEnv {
   170  				t.Fatal("SiteName should be in envConfig")
   171  			}
   172  
   173  			if customBrandTextInEnv, ok := teamSettingsAsMap["CustomBrandText"].(bool); !ok || !customBrandTextInEnv {
   174  				t.Fatal("SiteName should be in envConfig")
   175  			}
   176  		}
   177  
   178  		os.Unsetenv("MM_TEAMSETTINGS_SITENAME")
   179  		os.Unsetenv("MM_TEAMSETTINGS_CUSTOMBRANDTEXT")
   180  
   181  		cfg, envCfg, err = unmarshalConfig(strings.NewReader(config), true)
   182  		require.Nil(t, err)
   183  
   184  		assert.Equal(t, "Mattermost", *cfg.TeamSettings.SiteName)
   185  
   186  		if _, ok := envCfg["TeamSettings"]; ok {
   187  			t.Fatal("TeamSettings should be missing from envConfig")
   188  		}
   189  	})
   190  
   191  	t.Run("boolean setting", func(t *testing.T) {
   192  		os.Setenv("MM_SERVICESETTINGS_ENABLECOMMANDS", "false")
   193  		defer os.Unsetenv("MM_SERVICESETTINGS_ENABLECOMMANDS")
   194  
   195  		cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true)
   196  		require.Nil(t, err)
   197  
   198  		if *cfg.ServiceSettings.EnableCommands {
   199  			t.Fatal("Couldn't read config from environment var")
   200  		}
   201  
   202  		if serviceSettings, ok := envCfg["ServiceSettings"]; !ok {
   203  			t.Fatal("ServiceSettings is missing from envConfig")
   204  		} else if serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{}); !ok {
   205  			t.Fatal("ServiceSettings is not a map in envConfig")
   206  		} else {
   207  			if enableCommandsInEnv, ok := serviceSettingsAsMap["EnableCommands"].(bool); !ok || !enableCommandsInEnv {
   208  				t.Fatal("EnableCommands should be in envConfig")
   209  			}
   210  		}
   211  	})
   212  
   213  	t.Run("integer setting", func(t *testing.T) {
   214  		os.Setenv("MM_SERVICESETTINGS_READTIMEOUT", "400")
   215  		defer os.Unsetenv("MM_SERVICESETTINGS_READTIMEOUT")
   216  
   217  		cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true)
   218  		require.Nil(t, err)
   219  
   220  		assert.Equal(t, 400, *cfg.ServiceSettings.ReadTimeout)
   221  
   222  		if serviceSettings, ok := envCfg["ServiceSettings"]; !ok {
   223  			t.Fatal("ServiceSettings is missing from envConfig")
   224  		} else if serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{}); !ok {
   225  			t.Fatal("ServiceSettings is not a map in envConfig")
   226  		} else {
   227  			if readTimeoutInEnv, ok := serviceSettingsAsMap["ReadTimeout"].(bool); !ok || !readTimeoutInEnv {
   228  				t.Fatal("ReadTimeout should be in envConfig")
   229  			}
   230  		}
   231  	})
   232  
   233  	t.Run("setting missing from config.json", func(t *testing.T) {
   234  		os.Setenv("MM_SERVICESETTINGS_SITEURL", "https://example.com")
   235  		defer os.Unsetenv("MM_SERVICESETTINGS_SITEURL")
   236  
   237  		cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true)
   238  		require.Nil(t, err)
   239  
   240  		assert.Equal(t, "https://example.com", *cfg.ServiceSettings.SiteURL)
   241  
   242  		if serviceSettings, ok := envCfg["ServiceSettings"]; !ok {
   243  			t.Fatal("ServiceSettings is missing from envConfig")
   244  		} else if serviceSettingsAsMap, ok := serviceSettings.(map[string]interface{}); !ok {
   245  			t.Fatal("ServiceSettings is not a map in envConfig")
   246  		} else {
   247  			if siteURLInEnv, ok := serviceSettingsAsMap["SiteURL"].(bool); !ok || !siteURLInEnv {
   248  				t.Fatal("SiteURL should be in envConfig")
   249  			}
   250  		}
   251  	})
   252  
   253  	t.Run("empty string setting", func(t *testing.T) {
   254  		os.Setenv("MM_SUPPORTSETTINGS_TERMSOFSERVICELINK", "")
   255  		defer os.Unsetenv("MM_SUPPORTSETTINGS_TERMSOFSERVICELINK")
   256  
   257  		cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true)
   258  		require.Nil(t, err)
   259  
   260  		assert.Empty(t, *cfg.SupportSettings.TermsOfServiceLink)
   261  
   262  		if supportSettings, ok := envCfg["SupportSettings"]; !ok {
   263  			t.Fatal("SupportSettings is missing from envConfig")
   264  		} else if supportSettingsAsMap, ok := supportSettings.(map[string]interface{}); !ok {
   265  			t.Fatal("SupportSettings is not a map in envConfig")
   266  		} else {
   267  			if termsOfServiceLinkInEnv, ok := supportSettingsAsMap["TermsOfServiceLink"].(bool); !ok || !termsOfServiceLinkInEnv {
   268  				t.Fatal("TermsOfServiceLink should be in envConfig")
   269  			}
   270  		}
   271  	})
   272  
   273  	t.Run("plugin directory settings", func(t *testing.T) {
   274  		os.Setenv("MM_PLUGINSETTINGS_ENABLE", "false")
   275  		os.Setenv("MM_PLUGINSETTINGS_DIRECTORY", "/temp/plugins")
   276  		os.Setenv("MM_PLUGINSETTINGS_CLIENTDIRECTORY", "/temp/clientplugins")
   277  		defer os.Unsetenv("MM_PLUGINSETTINGS_ENABLE")
   278  		defer os.Unsetenv("MM_PLUGINSETTINGS_DIRECTORY")
   279  		defer os.Unsetenv("MM_PLUGINSETTINGS_CLIENTDIRECTORY")
   280  
   281  		cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true)
   282  		require.Nil(t, err)
   283  
   284  		assert.Equal(t, false, *cfg.PluginSettings.Enable)
   285  		assert.Equal(t, "/temp/plugins", *cfg.PluginSettings.Directory)
   286  		assert.Equal(t, "/temp/clientplugins", *cfg.PluginSettings.ClientDirectory)
   287  
   288  		if pluginSettings, ok := envCfg["PluginSettings"]; !ok {
   289  			t.Fatal("PluginSettings is missing from envConfig")
   290  		} else if pluginSettingsAsMap, ok := pluginSettings.(map[string]interface{}); !ok {
   291  			t.Fatal("PluginSettings is not a map in envConfig")
   292  		} else {
   293  			if directory, ok := pluginSettingsAsMap["Directory"].(bool); !ok || !directory {
   294  				t.Fatal("Directory should be in envConfig")
   295  			}
   296  			if clientDirectory, ok := pluginSettingsAsMap["ClientDirectory"].(bool); !ok || !clientDirectory {
   297  				t.Fatal("ClientDirectory should be in envConfig")
   298  			}
   299  		}
   300  	})
   301  
   302  	t.Run("plugin specific settings cannot be overridden via environment", func(t *testing.T) {
   303  		os.Setenv("MM_PLUGINSETTINGS_PLUGINS_JIRA_ENABLED", "false")
   304  		os.Setenv("MM_PLUGINSETTINGS_PLUGINS_JIRA_SECRET", "env-secret")
   305  		os.Setenv("MM_PLUGINSETTINGS_PLUGINSTATES_JIRA_ENABLE", "false")
   306  		defer os.Unsetenv("MM_PLUGINSETTINGS_PLUGINS_JIRA_ENABLED")
   307  		defer os.Unsetenv("MM_PLUGINSETTINGS_PLUGINS_JIRA_SECRET")
   308  		defer os.Unsetenv("MM_PLUGINSETTINGS_PLUGINSTATES_JIRA_ENABLE")
   309  
   310  		cfg, envCfg, err := unmarshalConfig(strings.NewReader(config), true)
   311  		require.Nil(t, err)
   312  
   313  		if pluginsJira, ok := cfg.PluginSettings.Plugins["jira"]; !ok {
   314  			t.Fatal("PluginSettings.Plugins.jira is missing from config")
   315  		} else {
   316  			if enabled, ok := pluginsJira["enabled"]; !ok {
   317  				t.Fatal("PluginSettings.Plugins.jira.enabled is missing from config")
   318  			} else {
   319  				assert.Equal(t, "true", enabled)
   320  			}
   321  
   322  			if secret, ok := pluginsJira["secret"]; !ok {
   323  				t.Fatal("PluginSettings.Plugins.jira.secret is missing from config")
   324  			} else {
   325  				assert.Equal(t, "config-secret", secret)
   326  			}
   327  		}
   328  
   329  		if pluginStatesJira, ok := cfg.PluginSettings.PluginStates["jira"]; !ok {
   330  			t.Fatal("PluginSettings.PluginStates.jira is missing from config")
   331  		} else {
   332  			require.Equal(t, true, pluginStatesJira.Enable)
   333  		}
   334  
   335  		if pluginSettings, ok := envCfg["PluginSettings"]; !ok {
   336  			t.Fatal("PluginSettings is missing from envConfig")
   337  		} else if pluginSettingsAsMap, ok := pluginSettings.(map[string]interface{}); !ok {
   338  			t.Fatal("PluginSettings is not a map in envConfig")
   339  		} else {
   340  			if plugins, ok := pluginSettingsAsMap["Plugins"].(map[string]interface{}); !ok {
   341  				t.Fatal("PluginSettings.Plugins is not a map in envConfig")
   342  			} else if _, ok := plugins["jira"].(map[string]interface{}); ok {
   343  				t.Fatal("PluginSettings.Plugins.jira should not be a map in envConfig")
   344  			}
   345  
   346  			if pluginStates, ok := pluginSettingsAsMap["PluginStates"].(map[string]interface{}); !ok {
   347  				t.Fatal("PluginSettings.PluginStates is missing from envConfig")
   348  			} else if _, ok := pluginStates["jira"].(map[string]interface{}); ok {
   349  				t.Fatal("PluginSettings.PluginStates.jira should not be a map in envConfig")
   350  			}
   351  		}
   352  	})
   353  }
   354  
   355  func TestReadConfig_ImageProxySettings(t *testing.T) {
   356  	utils.TranslationsPreInit()
   357  
   358  	t.Run("deprecated settings should still be read properly", func(t *testing.T) {
   359  		config, _, err := unmarshalConfig(bytes.NewReader([]byte(`{
   360  			"ServiceSettings": {
   361  				"ImageProxyType": "OldImageProxyType",
   362  				"ImageProxyURL": "OldImageProxyURL",
   363  				"ImageProxyOptions": "OldImageProxyOptions"
   364  			}
   365  		}`)), false)
   366  
   367  		require.Nil(t, err)
   368  
   369  		assert.Equal(t, model.NewString("OldImageProxyType"), config.ServiceSettings.DEPRECATED_DO_NOT_USE_ImageProxyType)
   370  		assert.Equal(t, model.NewString("OldImageProxyURL"), config.ServiceSettings.DEPRECATED_DO_NOT_USE_ImageProxyURL)
   371  		assert.Equal(t, model.NewString("OldImageProxyOptions"), config.ServiceSettings.DEPRECATED_DO_NOT_USE_ImageProxyOptions)
   372  	})
   373  }