package config import ( "fmt" "os" "testing" "github.com/stretchr/testify/assert" ) func TestDetectEnvironment(t *testing.T) { tests := []struct { name string setupFunc func() expected string }{ { name: "APP_ENV takes priority", setupFunc: func() { os.Setenv("APP_ENV", "production") os.Setenv("NODE_ENV", "development") os.Setenv("GO_ENV", "staging") }, expected: EnvProduction, }, { name: "NODE_ENV fallback", setupFunc: func() { os.Unsetenv("APP_ENV") os.Setenv("NODE_ENV", "staging") os.Unsetenv("GO_ENV") }, expected: EnvStaging, }, { name: "GO_ENV fallback", setupFunc: func() { os.Unsetenv("APP_ENV") os.Unsetenv("NODE_ENV") os.Setenv("GO_ENV", "test") }, expected: EnvTest, }, { name: "default to development", setupFunc: func() { os.Unsetenv("APP_ENV") os.Unsetenv("NODE_ENV") os.Unsetenv("GO_ENV") }, expected: EnvDevelopment, }, { name: "invalid APP_ENV falls back to NODE_ENV", setupFunc: func() { os.Setenv("APP_ENV", "invalid") os.Setenv("NODE_ENV", "production") os.Unsetenv("GO_ENV") }, expected: EnvProduction, }, { name: "case insensitive", setupFunc: func() { os.Setenv("APP_ENV", "PRODUCTION") os.Unsetenv("NODE_ENV") os.Unsetenv("GO_ENV") }, expected: EnvProduction, }, { name: "whitespace trimmed", setupFunc: func() { os.Setenv("APP_ENV", " production ") os.Unsetenv("NODE_ENV") os.Unsetenv("GO_ENV") }, expected: EnvProduction, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.setupFunc() defer func() { os.Unsetenv("APP_ENV") os.Unsetenv("NODE_ENV") os.Unsetenv("GO_ENV") }() result := DetectEnvironment() fmt.Println("TestDetectEnvironment/whitespace_trimmed - Detected Environment:", result) assert.Equal(t, tt.expected, result) }) } } func TestNormalizeEnvironment(t *testing.T) { tests := []struct { input string expected string }{ {"dev", EnvDevelopment}, {"prod", EnvProduction}, {"stage", EnvStaging}, {"stg", EnvStaging}, {"test", EnvTest}, {"local", EnvDevelopment}, {"development", EnvDevelopment}, {"production", EnvProduction}, {"staging", EnvStaging}, {"invalid", EnvDevelopment}, {"", EnvDevelopment}, {" dev ", EnvDevelopment}, {"PROD", EnvProduction}, {"STAGE", EnvStaging}, } for _, tt := range tests { t.Run(tt.input, func(t *testing.T) { result := NormalizeEnvironment(tt.input) assert.Equal(t, tt.expected, result) }) } } func TestIsValidEnvironment(t *testing.T) { tests := []struct { name string env string expected bool }{ {"valid development", EnvDevelopment, true}, {"valid staging", EnvStaging, true}, {"valid production", EnvProduction, true}, {"valid test", EnvTest, true}, {"invalid", "invalid", false}, {"empty", "", false}, {"case insensitive", "PRODUCTION", true}, {"with whitespace", " production ", true}, {"dev alias", "dev", false}, // Dev n'est pas valide directement, doit être normalisé {"prod alias", "prod", false}, // Prod n'est pas valide directement, doit être normalisé } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result := isValidEnvironment(tt.env) assert.Equal(t, tt.expected, result, "Environment %s should be valid: %v", tt.env, tt.expected) }) } } func TestDetectEnvironment_Priority(t *testing.T) { // Test que APP_ENV a la plus haute priorité os.Setenv("APP_ENV", "production") os.Setenv("NODE_ENV", "staging") os.Setenv("GO_ENV", "development") defer func() { os.Unsetenv("APP_ENV") os.Unsetenv("NODE_ENV") os.Unsetenv("GO_ENV") }() result := DetectEnvironment() assert.Equal(t, EnvProduction, result, "APP_ENV should have highest priority") } func TestDetectEnvironment_AllEnvironments(t *testing.T) { environments := []string{EnvDevelopment, EnvStaging, EnvProduction, EnvTest} for _, env := range environments { t.Run(env, func(t *testing.T) { os.Setenv("APP_ENV", env) defer os.Unsetenv("APP_ENV") result := DetectEnvironment() assert.Equal(t, env, result) }) } } func TestNormalizeEnvironment_CanonicalNames(t *testing.T) { // Les noms canoniques doivent rester inchangés canonicalNames := []string{ EnvDevelopment, EnvStaging, EnvProduction, EnvTest, } for _, name := range canonicalNames { t.Run(name, func(t *testing.T) { result := NormalizeEnvironment(name) assert.Equal(t, name, result, "Canonical name should remain unchanged") }) } } func TestNormalizeEnvironment_Aliases(t *testing.T) { aliasTests := []struct { alias string expected string }{ {"dev", EnvDevelopment}, {"local", EnvDevelopment}, {"prod", EnvProduction}, {"stage", EnvStaging}, {"stg", EnvStaging}, {"test", EnvTest}, } for _, tt := range aliasTests { t.Run(tt.alias, func(t *testing.T) { result := NormalizeEnvironment(tt.alias) assert.Equal(t, tt.expected, result, "Alias %s should normalize to %s", tt.alias, tt.expected) }) } } func TestConstants(t *testing.T) { // Vérifier que les constantes sont définies correctement assert.Equal(t, "development", EnvDevelopment) assert.Equal(t, "staging", EnvStaging) assert.Equal(t, "production", EnvProduction) assert.Equal(t, "test", EnvTest) } func TestDetectEnvironment_InvalidEnvFallback(t *testing.T) { // Test que les environnements invalides ne sont pas utilisés os.Setenv("APP_ENV", "invalid_env") os.Setenv("NODE_ENV", "also_invalid") os.Setenv("GO_ENV", "still_invalid") defer func() { os.Unsetenv("APP_ENV") os.Unsetenv("NODE_ENV") os.Unsetenv("GO_ENV") }() result := DetectEnvironment() // Devrait fallback sur hostname ou development assert.Contains(t, []string{EnvDevelopment, EnvStaging, EnvProduction}, result) }