package config import ( "os" "testing" ) // clearConfigEnv unsets all environment variables that Load() reads, // so tests start from a clean slate. func clearConfigEnv(t *testing.T) { t.Helper() envVars := []string{ "DATABASE_URL", "PUBLIC_ADDR", "ADMIN_ADDR", "BASE_URL", "SESSION_SECRET", "FORGEJO_URL", "FORGEJO_API_TOKEN", "POSTMARK_SERVER_TOKEN", "POSTMARK_FROM_EMAIL", "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_TENANT_ID", "APPLE_CLIENT_ID", "APPLE_TEAM_ID", "APPLE_KEY_ID", "APPLE_KEY_PATH", "TAILSCALE_ALLOWED_USERS", } for _, v := range envVars { os.Unsetenv(v) } } func TestLoad_MissingDatabaseURL(t *testing.T) { clearConfigEnv(t) t.Setenv("SESSION_SECRET", "secret-value") // DATABASE_URL is not set _, err := Load() if err == nil { t.Fatal("expected error when DATABASE_URL is missing, got nil") } expected := "DATABASE_URL is required" if err.Error() != expected { t.Errorf("expected error %q, got %q", expected, err.Error()) } } func TestLoad_MissingSessionSecret(t *testing.T) { clearConfigEnv(t) t.Setenv("DATABASE_URL", "postgres://localhost/test") // SESSION_SECRET is not set _, err := Load() if err == nil { t.Fatal("expected error when SESSION_SECRET is missing, got nil") } expected := "SESSION_SECRET is required" if err.Error() != expected { t.Errorf("expected error %q, got %q", expected, err.Error()) } } func TestLoad_Success(t *testing.T) { clearConfigEnv(t) t.Setenv("DATABASE_URL", "postgres://localhost/test") t.Setenv("SESSION_SECRET", "my-secret") cfg, err := Load() if err != nil { t.Fatalf("expected no error, got: %v", err) } if cfg.DatabaseURL != "postgres://localhost/test" { t.Errorf("expected DatabaseURL %q, got %q", "postgres://localhost/test", cfg.DatabaseURL) } if cfg.SessionSecret != "my-secret" { t.Errorf("expected SessionSecret %q, got %q", "my-secret", cfg.SessionSecret) } } func TestLoad_DefaultValues(t *testing.T) { clearConfigEnv(t) t.Setenv("DATABASE_URL", "postgres://localhost/test") t.Setenv("SESSION_SECRET", "my-secret") cfg, err := Load() if err != nil { t.Fatalf("expected no error, got: %v", err) } if cfg.PublicAddr != ":8080" { t.Errorf("expected default PublicAddr %q, got %q", ":8080", cfg.PublicAddr) } if cfg.AdminAddr != ":8081" { t.Errorf("expected default AdminAddr %q, got %q", ":8081", cfg.AdminAddr) } if cfg.BaseURL != "http://localhost:8080" { t.Errorf("expected default BaseURL %q, got %q", "http://localhost:8080", cfg.BaseURL) } if cfg.MicrosoftTenantID != "common" { t.Errorf("expected default MicrosoftTenantID %q, got %q", "common", cfg.MicrosoftTenantID) } } func TestLoad_OverrideDefaults(t *testing.T) { clearConfigEnv(t) t.Setenv("DATABASE_URL", "postgres://localhost/test") t.Setenv("SESSION_SECRET", "my-secret") t.Setenv("PUBLIC_ADDR", ":9090") t.Setenv("ADMIN_ADDR", ":9091") t.Setenv("BASE_URL", "https://example.com") cfg, err := Load() if err != nil { t.Fatalf("expected no error, got: %v", err) } if cfg.PublicAddr != ":9090" { t.Errorf("expected PublicAddr %q, got %q", ":9090", cfg.PublicAddr) } if cfg.AdminAddr != ":9091" { t.Errorf("expected AdminAddr %q, got %q", ":9091", cfg.AdminAddr) } if cfg.BaseURL != "https://example.com" { t.Errorf("expected BaseURL %q, got %q", "https://example.com", cfg.BaseURL) } } func TestLoad_TailscaleAllowedUsers(t *testing.T) { clearConfigEnv(t) t.Setenv("DATABASE_URL", "postgres://localhost/test") t.Setenv("SESSION_SECRET", "my-secret") t.Setenv("TAILSCALE_ALLOWED_USERS", "alice@example.com, bob@example.com , charlie@example.com") cfg, err := Load() if err != nil { t.Fatalf("expected no error, got: %v", err) } if len(cfg.TailscaleAllowedUsers) != 3 { t.Fatalf("expected 3 tailscale users, got %d", len(cfg.TailscaleAllowedUsers)) } expected := []string{"alice@example.com", "bob@example.com", "charlie@example.com"} for i, want := range expected { if cfg.TailscaleAllowedUsers[i] != want { t.Errorf("TailscaleAllowedUsers[%d]: expected %q, got %q", i, want, cfg.TailscaleAllowedUsers[i]) } } } func TestLoad_EmptyTailscaleAllowedUsers(t *testing.T) { clearConfigEnv(t) t.Setenv("DATABASE_URL", "postgres://localhost/test") t.Setenv("SESSION_SECRET", "my-secret") // TAILSCALE_ALLOWED_USERS not set cfg, err := Load() if err != nil { t.Fatalf("expected no error, got: %v", err) } if cfg.TailscaleAllowedUsers != nil { t.Errorf("expected nil TailscaleAllowedUsers, got %v", cfg.TailscaleAllowedUsers) } }