package application_test import ( "encoding/json" "os" "testing" "git.nianxx.cn/wangxuming/NianAIGC/backend/internal/application" ) func TestParseAuthConfigMatchesCurrentSessionContract(t *testing.T) { type expectedConfig struct { Required bool `json:"required"` Configured bool `json:"configured"` SessionSecret *string `json:"sessionSecret"` } var fixture struct { AuthConfigurationCases []struct { Name string `json:"name"` Environment map[string]string `json:"environment"` Expected expectedConfig `json:"expected"` } `json:"authConfigurationCases"` } data, err := os.ReadFile("../../../contracts/auth/current-session-v1.json") if err != nil { t.Fatalf("read current-session contract: %v", err) } if err := json.Unmarshal(data, &fixture); err != nil { t.Fatalf("decode current-session contract: %v", err) } if len(fixture.AuthConfigurationCases) == 0 { t.Fatal("current-session contract has no authConfigurationCases") } for _, testCase := range fixture.AuthConfigurationCases { t.Run(testCase.Name, func(t *testing.T) { config, err := application.ParseAuthConfig(authEnv(testCase.Environment)) if err != nil { t.Fatalf("ParseAuthConfig() error = %v", err) } wantSecret := "" if testCase.Expected.SessionSecret != nil { wantSecret = *testCase.Expected.SessionSecret } want := application.AuthConfig{ Required: testCase.Expected.Required, Configured: testCase.Expected.Configured, SessionSecret: wantSecret, } if config != want { t.Fatalf("config = %+v, want %+v", config, want) } }) } } func TestParseAuthConfigRejectsNilGetenv(t *testing.T) { _, err := application.ParseAuthConfig(nil) if err == nil { t.Fatal("ParseAuthConfig(nil) error = nil, want error") } } func TestParseAuthConfigDefaultsToDisabledAndUnconfigured(t *testing.T) { config, err := application.ParseAuthConfig(authEnv(nil)) if err != nil { t.Fatalf("ParseAuthConfig() error = %v", err) } want := application.AuthConfig{} if config != want { t.Fatalf("config = %+v, want %+v", config, want) } } func TestParseAuthConfigUsesFirstTrimmedSessionSecret(t *testing.T) { config, err := application.ParseAuthConfig(authEnv(map[string]string{ "ZHINIAN_AUTH_SESSION_SECRET": " ", "AUTH_SESSION_SECRET": " auth-secret ", "NEXTAUTH_SECRET": "next-secret", })) if err != nil { t.Fatalf("ParseAuthConfig() error = %v", err) } want := application.AuthConfig{Required: true, Configured: true, SessionSecret: "auth-secret"} if config != want { t.Fatalf("config = %+v, want %+v", config, want) } } func TestParseAuthConfigRequiredPolicy(t *testing.T) { tests := []struct { name string values map[string]string want application.AuthConfig }{ { name: "all accepted true values require auth", values: map[string]string{ "ZHINIAN_AUTH_REQUIRED": " YeS ", }, want: application.AuthConfig{Required: true}, }, { name: "all accepted false values disable auth", values: map[string]string{ "ZHINIAN_AUTH_REQUIRED": " oFf ", "ZHINIAN_AUTH_SESSION_SECRET": "secret", }, want: application.AuthConfig{Configured: true, SessionSecret: "secret"}, }, { name: "disabled true overrides explicit required true", values: map[string]string{ "ZHINIAN_AUTH_DISABLED": "ON", "ZHINIAN_AUTH_REQUIRED": "1", "NEXTAUTH_SECRET": "secret", }, want: application.AuthConfig{Configured: true, SessionSecret: "secret"}, }, { name: "disabled false does not override explicit required", values: map[string]string{ "ZHINIAN_AUTH_DISABLED": "no", "ZHINIAN_AUTH_REQUIRED": "true", }, want: application.AuthConfig{Required: true}, }, { name: "production defaults to required", values: map[string]string{ "NODE_ENV": "production", }, want: application.AuthConfig{Required: true}, }, { name: "secret defaults to required and configured", values: map[string]string{ "NEXTAUTH_SECRET": " secret ", }, want: application.AuthConfig{Required: true, Configured: true, SessionSecret: "secret"}, }, { name: "auto and invalid values use defaults", values: map[string]string{ "ZHINIAN_AUTH_REQUIRED": "auto", "ZHINIAN_AUTH_DISABLED": "invalid", }, want: application.AuthConfig{}, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { config, err := application.ParseAuthConfig(authEnv(test.values)) if err != nil { t.Fatalf("ParseAuthConfig() error = %v", err) } if config != test.want { t.Fatalf("config = %+v, want %+v", config, test.want) } }) } } func TestParseAuthConfigRecognizesEveryBooleanSpelling(t *testing.T) { for _, value := range []string{"1", "true", "yes", "on"} { t.Run("true_"+value, func(t *testing.T) { config, err := application.ParseAuthConfig(authEnv(map[string]string{"ZHINIAN_AUTH_REQUIRED": value})) if err != nil { t.Fatalf("ParseAuthConfig() error = %v", err) } if !config.Required { t.Fatalf("Required = false for %q, want true", value) } }) } for _, value := range []string{"0", "false", "no", "off"} { t.Run("false_"+value, func(t *testing.T) { config, err := application.ParseAuthConfig(authEnv(map[string]string{ "ZHINIAN_AUTH_REQUIRED": value, "ZHINIAN_AUTH_SESSION_SECRET": "secret", })) if err != nil { t.Fatalf("ParseAuthConfig() error = %v", err) } if config.Required { t.Fatalf("Required = true for %q, want false", value) } }) } } func authEnv(values map[string]string) func(string) string { return func(name string) string { return values[name] } }