package config import ( "strings" "testing" ) func TestValidate(t *testing.T) { base := func() map[string]string { return map[string]string{ "TERDUT_PUBLIC_URL": "https://terdut.example.com", "TERDUT_OIDC_ISSUER": "https://auth.example.com/application/o/terdut/", "TERDUT_OIDC_CLIENT_ID": "id", "TERDUT_OIDC_CLIENT_SECRET": "secret", } } tests := []struct { name string env func(map[string]string) wantErr string // substring; empty means valid }{ {"off by default", func(m map[string]string) { clear(m) }, ""}, {"minimal sso", func(m map[string]string) {}, ""}, {"groups without issuer", func(m map[string]string) { clear(m) m["TERDUT_OIDC_ADMIN_GROUP"] = "admins" }, "ISSUER is not"}, {"missing secret", func(m map[string]string) { delete(m, "TERDUT_OIDC_CLIENT_SECRET") }, "CLIENT_SECRET"}, {"missing public url", func(m map[string]string) { delete(m, "TERDUT_PUBLIC_URL") }, "PUBLIC_URL"}, {"bad issuer", func(m map[string]string) { m["TERDUT_OIDC_ISSUER"] = "not a url" }, "not a URL"}, {"password off without sso", func(m map[string]string) { clear(m) m["TERDUT_PASSWORD_LOGIN"] = "false" }, "no way to sign in"}, {"password off with sso but no grants", func(m map[string]string) { m["TERDUT_PASSWORD_LOGIN"] = "false" }, "nobody able"}, {"password off with admin group", func(m map[string]string) { m["TERDUT_PASSWORD_LOGIN"] = "false" m["TERDUT_OIDC_ADMIN_GROUP"] = "admins" }, ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { env := base() tt.env(env) for _, k := range []string{ "TERDUT_PUBLIC_URL", "TERDUT_PASSWORD_LOGIN", "TERDUT_OIDC_ISSUER", "TERDUT_OIDC_CLIENT_ID", "TERDUT_OIDC_CLIENT_SECRET", "TERDUT_OIDC_ADMIN_GROUP", } { t.Setenv(k, env[k]) } err := Load().Validate() switch { case tt.wantErr == "" && err != nil: t.Errorf("unexpected error: %v", err) case tt.wantErr != "" && (err == nil || !strings.Contains(err.Error(), tt.wantErr)): t.Errorf("error %v, want one containing %q", err, tt.wantErr) } }) } } func TestLoad_OIDCDefaults(t *testing.T) { t.Setenv("TERDUT_OIDC_ISSUER", "https://auth.example.com/") o := Load().OIDC if o.UsernameClaim != "preferred_username" || o.EmailClaim != "email" || o.GroupsClaim != "groups" { t.Errorf("claim defaults: %+v", o) } if strings.Join(o.Scopes, " ") != "openid profile email" { t.Errorf("scopes: %v", o.Scopes) } if o.SessionMaxAge.Hours() != 12 { t.Errorf("max age: %v", o.SessionMaxAge) } if Load().DisablePasswordLogin { t.Error("password login should be on by default") } }