diff options
Diffstat (limited to 'config_test.go')
| -rw-r--r-- | config_test.go | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/config_test.go b/config_test.go new file mode 100644 index 0000000..fe7406d --- /dev/null +++ b/config_test.go @@ -0,0 +1,120 @@ +package main + +import ( + "strings" + "testing" +) + +// Startup refuses an incoherent file rather than guessing, and reports +// everything wrong at once. What each rule catches matters most for the ones +// that would otherwise fail silently much later: an allow entry that can never +// match is a lockout, and a bad issuer is a login that never works. +func TestConfigValidate(t *testing.T) { + provider := OIDCProvider{Key: "sso", Label: "SSO", Issuer: "https://id.example", ClientID: "forge"} + cases := []struct { + what string + spoil func(*Config) + want string + }{ + {"a good file", func(*Config) {}, ""}, + {"no listener", func(c *Config) { c.Listen = "" }, "listen"}, + {"no name", func(c *Config) { c.SiteName = "" }, "site_name"}, + {"a quote in the name", func(c *Config) { c.SiteName = `a"b` }, "site_name"}, + {"a header name with a colon", func(c *Config) { c.ClientIPHeader = "X-Real-IP:" }, "client_ip_header"}, + {"a base url with a path", func(c *Config) { c.BaseURL = "https://git.example/forge" }, "base_url"}, + {"a base url with no scheme", func(c *Config) { c.BaseURL = "git.example" }, "base_url"}, + {"an oidc key that prefixes nothing usable", func(c *Config) { + p := provider + p.Key = "SSO" + c.OIDC = []OIDCProvider{p} + }, "key"}, + {"two providers under one key", func(c *Config) { c.OIDC = []OIDCProvider{provider, provider} }, "duplicate"}, + {"a provider with no label", func(c *Config) { + p := provider + p.Label = "" + c.OIDC = []OIDCProvider{p} + }, "label"}, + {"an issuer that is not https", func(c *Config) { + p := provider + p.Issuer = "http://id.example" + c.OIDC = []OIDCProvider{p} + }, "issuer"}, + {"an issuer with a trailing slash", func(c *Config) { + p := provider + p.Issuer = "https://id.example/" + c.OIDC = []OIDCProvider{p} + }, "trailing slash"}, + {"an allow entry that is neither", func(c *Config) { + p := provider + p.Allow = []string{"everyone"} + c.OIDC = []OIDCProvider{p} + }, "allow[0]"}, + {"an allow entry that is a bare at", func(c *Config) { + p := provider + p.Allow = []string{"@"} + c.OIDC = []OIDCProvider{p} + }, "allow[0]"}, + {"an allow entry padded with spaces", func(c *Config) { + p := provider + p.Allow = []string{" carol@example.com"} + c.OIDC = []OIDCProvider{p} + }, "allow[0]"}, + {"a good provider", func(c *Config) { + p := provider + p.Allow = []string{"carol@example.com", "@example.com"} + c.OIDC = []OIDCProvider{p} + }, ""}, + {"no sender", func(c *Config) { c.Mail.From = "" }, "mail.from"}, + {"a driver that is neither", func(c *Config) { c.Mail.Driver = "sendmail" }, "mail.driver"}, + {"mailgun with no domain", func(c *Config) { c.Mail.Driver = "mailgun" }, "mailgun.domain"}, + {"mailgun with no key in the environment", func(c *Config) { + c.Mail.Driver = "mailgun" + c.Mail.Mailgun.Domain = "mg.example" + }, "MAILGUN_API_KEY"}, + } + for _, c := range cases { + cfg := defaultConfig() + c.spoil(cfg) + err := cfg.validate() + switch { + case c.want == "" && err != nil: + t.Errorf("%s was refused: %v", c.what, err) + case c.want != "" && err == nil: + t.Errorf("%s was accepted", c.what) + case c.want != "" && !strings.Contains(err.Error(), c.want): + t.Errorf("%s was refused for the wrong reason: %v", c.what, err) + } + } +} + +// Everything wrong at once, because fixing a config one restart at a time is +// miserable. +func TestConfigReportsEveryFault(t *testing.T) { + cfg := defaultConfig() + cfg.Listen, cfg.SiteName, cfg.BaseURL, cfg.Mail.From = "", "", "ftp://x", "" + err := cfg.validate() + if err == nil { + t.Fatal("a file with four faults in it was accepted") + } + for _, want := range []string{"listen", "site_name", "base_url", "mail.from"} { + if !strings.Contains(err.Error(), want) { + t.Errorf("%q is not in the report:\n%v", want, err) + } + } +} + +// The host is what generated addresses are built from, so the port has to come +// off and a trailing slash must not survive into it. +func TestConfigBaseURLIsNormalised(t *testing.T) { + cfg := defaultConfig() + cfg.BaseURL = "https://git.example.com:8443/" + if err := cfg.validate(); err != nil { + t.Fatal(err) + } + if cfg.BaseURL != "https://git.example.com:8443" { + t.Errorf("base_url is %q", cfg.BaseURL) + } + if cfg.host != "git.example.com" { + t.Errorf("addresses would be built from %q", cfg.host) + } +} |