620 lines
18 KiB
Go
620 lines
18 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func TestLoad(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalDBPassword := os.Getenv("DB_PASSWORD")
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
originalAppPort := os.Getenv("APP_PORT")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalDBPassword != "" {
|
|
os.Setenv("DB_PASSWORD", originalDBPassword)
|
|
} else {
|
|
os.Unsetenv("DB_PASSWORD")
|
|
}
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
if originalAppPort != "" {
|
|
os.Setenv("APP_PORT", originalAppPort)
|
|
} else {
|
|
os.Unsetenv("APP_PORT")
|
|
}
|
|
}()
|
|
|
|
// Définir les variables requises
|
|
os.Setenv("DB_PASSWORD", "test_password")
|
|
os.Setenv("JWT_SECRET", "test_secret")
|
|
|
|
config, err := Load()
|
|
require.NoError(t, err)
|
|
require.NotNil(t, config)
|
|
|
|
// Vérifier les valeurs par défaut
|
|
assert.Equal(t, 8080, config.AppPort)
|
|
assert.Equal(t, "development", config.AppEnv)
|
|
assert.Equal(t, "localhost", config.DBHost)
|
|
assert.Equal(t, 5432, config.DBPort)
|
|
assert.Equal(t, "veza", config.DBUser)
|
|
assert.Equal(t, "veza_db", config.DBName)
|
|
assert.Equal(t, "redis://localhost:6379", config.RedisURL)
|
|
|
|
// Vérifier les valeurs requises
|
|
assert.Equal(t, "test_password", config.DBPassword)
|
|
assert.Equal(t, "test_secret", config.JWTSecret)
|
|
}
|
|
|
|
func TestLoad_WithCustomValues(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalDBPassword := os.Getenv("DB_PASSWORD")
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
originalAppPort := os.Getenv("APP_PORT")
|
|
originalDBHost := os.Getenv("DB_HOST")
|
|
originalDBPort := os.Getenv("DB_PORT")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalDBPassword != "" {
|
|
os.Setenv("DB_PASSWORD", originalDBPassword)
|
|
} else {
|
|
os.Unsetenv("DB_PASSWORD")
|
|
}
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
if originalAppPort != "" {
|
|
os.Setenv("APP_PORT", originalAppPort)
|
|
} else {
|
|
os.Unsetenv("APP_PORT")
|
|
}
|
|
if originalDBHost != "" {
|
|
os.Setenv("DB_HOST", originalDBHost)
|
|
} else {
|
|
os.Unsetenv("DB_HOST")
|
|
}
|
|
if originalDBPort != "" {
|
|
os.Setenv("DB_PORT", originalDBPort)
|
|
} else {
|
|
os.Unsetenv("DB_PORT")
|
|
}
|
|
}()
|
|
|
|
// Définir des valeurs personnalisées
|
|
os.Setenv("DB_PASSWORD", "custom_password")
|
|
os.Setenv("JWT_SECRET", "custom_secret")
|
|
os.Setenv("APP_PORT", "9090")
|
|
os.Setenv("DB_HOST", "custom_host")
|
|
os.Setenv("DB_PORT", "3306")
|
|
|
|
config, err := Load()
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, 9090, config.AppPort)
|
|
assert.Equal(t, "custom_host", config.DBHost)
|
|
assert.Equal(t, 3306, config.DBPort)
|
|
assert.Equal(t, "custom_password", config.DBPassword)
|
|
assert.Equal(t, "custom_secret", config.JWTSecret)
|
|
}
|
|
|
|
func TestLoad_MissingRequiredVariable_DBPassword(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalDBPassword := os.Getenv("DB_PASSWORD")
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalDBPassword != "" {
|
|
os.Setenv("DB_PASSWORD", originalDBPassword)
|
|
} else {
|
|
os.Unsetenv("DB_PASSWORD")
|
|
}
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
}()
|
|
|
|
// Supprimer les variables requises
|
|
os.Unsetenv("DB_PASSWORD")
|
|
os.Setenv("JWT_SECRET", "test_secret")
|
|
|
|
// Devrait paniquer
|
|
assert.Panics(t, func() {
|
|
_, _ = Load()
|
|
}, "Should panic when DB_PASSWORD is missing")
|
|
}
|
|
|
|
func TestLoad_MissingRequiredVariable_JWTSecret(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalDBPassword := os.Getenv("DB_PASSWORD")
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalDBPassword != "" {
|
|
os.Setenv("DB_PASSWORD", originalDBPassword)
|
|
} else {
|
|
os.Unsetenv("DB_PASSWORD")
|
|
}
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
}()
|
|
|
|
// Supprimer les variables requises
|
|
os.Setenv("DB_PASSWORD", "test_password")
|
|
os.Unsetenv("JWT_SECRET")
|
|
|
|
// Devrait paniquer
|
|
assert.Panics(t, func() {
|
|
_, _ = Load()
|
|
}, "Should panic when JWT_SECRET is missing")
|
|
}
|
|
|
|
func TestGetEnv(t *testing.T) {
|
|
// Sauvegarder la valeur originale
|
|
originalValue := os.Getenv("TEST_VAR")
|
|
|
|
defer func() {
|
|
if originalValue != "" {
|
|
os.Setenv("TEST_VAR", originalValue)
|
|
} else {
|
|
os.Unsetenv("TEST_VAR")
|
|
}
|
|
}()
|
|
|
|
// Test avec valeur définie
|
|
os.Setenv("TEST_VAR", "test_value")
|
|
assert.Equal(t, "test_value", getEnv("TEST_VAR", "default"))
|
|
|
|
// Test sans valeur (devrait retourner défaut)
|
|
os.Unsetenv("TEST_VAR")
|
|
assert.Equal(t, "default", getEnv("TEST_VAR", "default"))
|
|
}
|
|
|
|
func TestGetEnvInt(t *testing.T) {
|
|
// Sauvegarder la valeur originale
|
|
originalValue := os.Getenv("TEST_INT")
|
|
|
|
defer func() {
|
|
if originalValue != "" {
|
|
os.Setenv("TEST_INT", originalValue)
|
|
} else {
|
|
os.Unsetenv("TEST_INT")
|
|
}
|
|
}()
|
|
|
|
// Test avec valeur entière valide
|
|
os.Setenv("TEST_INT", "42")
|
|
assert.Equal(t, 42, getEnvInt("TEST_INT", 10))
|
|
|
|
// Test sans valeur (devrait retourner défaut)
|
|
os.Unsetenv("TEST_INT")
|
|
assert.Equal(t, 10, getEnvInt("TEST_INT", 10))
|
|
|
|
// Test avec valeur invalide (devrait retourner défaut)
|
|
os.Setenv("TEST_INT", "not_a_number")
|
|
assert.Equal(t, 10, getEnvInt("TEST_INT", 10))
|
|
}
|
|
|
|
func TestGetEnvRequired(t *testing.T) {
|
|
// Sauvegarder la valeur originale
|
|
originalValue := os.Getenv("TEST_REQUIRED")
|
|
|
|
defer func() {
|
|
if originalValue != "" {
|
|
os.Setenv("TEST_REQUIRED", originalValue)
|
|
} else {
|
|
os.Unsetenv("TEST_REQUIRED")
|
|
}
|
|
}()
|
|
|
|
// Test avec valeur définie
|
|
os.Setenv("TEST_REQUIRED", "required_value")
|
|
assert.Equal(t, "required_value", getEnvRequired("TEST_REQUIRED"))
|
|
|
|
// Test sans valeur (devrait paniquer)
|
|
os.Unsetenv("TEST_REQUIRED")
|
|
assert.Panics(t, func() {
|
|
_ = getEnvRequired("TEST_REQUIRED")
|
|
}, "Should panic when required variable is missing")
|
|
}
|
|
|
|
func TestLoad_DefaultValues(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalDBPassword := os.Getenv("DB_PASSWORD")
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
originalAppEnv := os.Getenv("APP_ENV")
|
|
originalRedisURL := os.Getenv("REDIS_URL")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalDBPassword != "" {
|
|
os.Setenv("DB_PASSWORD", originalDBPassword)
|
|
} else {
|
|
os.Unsetenv("DB_PASSWORD")
|
|
}
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
if originalAppEnv != "" {
|
|
os.Setenv("APP_ENV", originalAppEnv)
|
|
} else {
|
|
os.Unsetenv("APP_ENV")
|
|
}
|
|
if originalRedisURL != "" {
|
|
os.Setenv("REDIS_URL", originalRedisURL)
|
|
} else {
|
|
os.Unsetenv("REDIS_URL")
|
|
}
|
|
}()
|
|
|
|
// Définir seulement les variables requises
|
|
os.Setenv("DB_PASSWORD", "test")
|
|
os.Setenv("JWT_SECRET", "secret")
|
|
|
|
// Supprimer les variables optionnelles pour tester les valeurs par défaut
|
|
os.Unsetenv("APP_ENV")
|
|
os.Unsetenv("REDIS_URL")
|
|
|
|
config, err := Load()
|
|
require.NoError(t, err)
|
|
|
|
// Vérifier que les valeurs par défaut sont utilisées
|
|
assert.Equal(t, "development", config.AppEnv)
|
|
assert.Equal(t, "redis://localhost:6379", config.RedisURL)
|
|
}
|
|
|
|
// TestNewConfig_RequiresJWTSecret vérifie que NewConfig() refuse de démarrer sans JWT_SECRET
|
|
// Ce test valide la correction de sécurité qui empêche l'utilisation d'une valeur par défaut hardcodée
|
|
func TestNewConfig_RequiresJWTSecret(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
originalDatabaseURL := os.Getenv("DATABASE_URL")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
if originalDatabaseURL != "" {
|
|
os.Setenv("DATABASE_URL", originalDatabaseURL)
|
|
} else {
|
|
os.Unsetenv("DATABASE_URL")
|
|
}
|
|
}()
|
|
|
|
// Supprimer JWT_SECRET - devrait causer un panic
|
|
os.Unsetenv("JWT_SECRET")
|
|
// Définir DATABASE_URL pour éviter un panic sur cette variable (on teste seulement JWT_SECRET)
|
|
os.Setenv("DATABASE_URL", "postgresql://test:test@localhost:5432/test_db")
|
|
|
|
// Devrait paniquer car JWT_SECRET est requis
|
|
assert.Panics(t, func() {
|
|
_, _ = NewConfig()
|
|
}, "NewConfig should panic when JWT_SECRET is missing")
|
|
}
|
|
|
|
// TestNewConfig_RequiresDatabaseURL vérifie que NewConfig() refuse de démarrer sans DATABASE_URL
|
|
// Ce test valide la correction de sécurité qui empêche l'utilisation d'une valeur par défaut avec credentials
|
|
func TestNewConfig_RequiresDatabaseURL(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
originalDatabaseURL := os.Getenv("DATABASE_URL")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
if originalDatabaseURL != "" {
|
|
os.Setenv("DATABASE_URL", originalDatabaseURL)
|
|
} else {
|
|
os.Unsetenv("DATABASE_URL")
|
|
}
|
|
}()
|
|
|
|
// Définir JWT_SECRET (minimum 32 caractères pour passer la validation)
|
|
os.Setenv("JWT_SECRET", "test-jwt-secret-key-minimum-32-characters-long")
|
|
// Supprimer DATABASE_URL - devrait causer un panic
|
|
os.Unsetenv("DATABASE_URL")
|
|
|
|
// Devrait paniquer car DATABASE_URL est requis
|
|
assert.Panics(t, func() {
|
|
_, _ = NewConfig()
|
|
}, "NewConfig should panic when DATABASE_URL is missing")
|
|
}
|
|
|
|
// ============================================================================
|
|
// P0-SECURITY: Tests pour la sécurisation de la configuration CORS
|
|
// ============================================================================
|
|
|
|
// TestLoadConfig_DevDefaults vérifie que les defaults dev sont corrects (P0-SECURITY)
|
|
func TestLoadConfig_DevDefaults(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalEnv := os.Getenv("APP_ENV")
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
originalDatabaseURL := os.Getenv("DATABASE_URL")
|
|
originalCORSOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalEnv != "" {
|
|
os.Setenv("APP_ENV", originalEnv)
|
|
} else {
|
|
os.Unsetenv("APP_ENV")
|
|
}
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
if originalDatabaseURL != "" {
|
|
os.Setenv("DATABASE_URL", originalDatabaseURL)
|
|
} else {
|
|
os.Unsetenv("DATABASE_URL")
|
|
}
|
|
if originalCORSOrigins != "" {
|
|
os.Setenv("CORS_ALLOWED_ORIGINS", originalCORSOrigins)
|
|
} else {
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS")
|
|
}
|
|
}()
|
|
|
|
// Configuration pour développement
|
|
os.Setenv("APP_ENV", "development")
|
|
os.Setenv("JWT_SECRET", "test-jwt-secret-key-minimum-32-characters-long")
|
|
os.Setenv("DATABASE_URL", "postgresql://test:test@localhost:5432/test_db")
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS") // Pas défini pour tester les defaults
|
|
|
|
// Note: NewConfig() nécessite Redis et DB, donc on teste seulement getCORSOrigins
|
|
origins := getCORSOrigins("development")
|
|
require.NotEmpty(t, origins, "Development should have default CORS origins")
|
|
assert.Contains(t, origins, "http://localhost:3000", "Should include localhost:3000")
|
|
assert.Contains(t, origins, "http://127.0.0.1:3000", "Should include 127.0.0.1:3000")
|
|
assert.NotContains(t, origins, "*", "Should not contain wildcard")
|
|
}
|
|
|
|
// TestLoadConfig_ProdMissingCritical vérifie que prod refuse si CORS manquant (P0-SECURITY)
|
|
func TestLoadConfig_ProdMissingCritical(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalEnv := os.Getenv("APP_ENV")
|
|
originalJWTSecret := os.Getenv("JWT_SECRET")
|
|
originalDatabaseURL := os.Getenv("DATABASE_URL")
|
|
originalCORSOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalEnv != "" {
|
|
os.Setenv("APP_ENV", originalEnv)
|
|
} else {
|
|
os.Unsetenv("APP_ENV")
|
|
}
|
|
if originalJWTSecret != "" {
|
|
os.Setenv("JWT_SECRET", originalJWTSecret)
|
|
} else {
|
|
os.Unsetenv("JWT_SECRET")
|
|
}
|
|
if originalDatabaseURL != "" {
|
|
os.Setenv("DATABASE_URL", originalDatabaseURL)
|
|
} else {
|
|
os.Unsetenv("DATABASE_URL")
|
|
}
|
|
if originalCORSOrigins != "" {
|
|
os.Setenv("CORS_ALLOWED_ORIGINS", originalCORSOrigins)
|
|
} else {
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS")
|
|
}
|
|
}()
|
|
|
|
// Configuration pour production sans CORS
|
|
os.Setenv("APP_ENV", "production")
|
|
os.Setenv("JWT_SECRET", "test-jwt-secret-key-minimum-32-characters-long")
|
|
os.Setenv("DATABASE_URL", "postgresql://test:test@localhost:5432/test_db")
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS") // Manquant intentionnellement
|
|
|
|
// Créer une config minimale pour tester la validation
|
|
cfg := &Config{
|
|
Env: "production",
|
|
JWTSecret: "test-jwt-secret-key-minimum-32-characters-long",
|
|
DatabaseURL: "postgresql://test:test@localhost:5432/test_db",
|
|
RedisURL: "redis://localhost:6379",
|
|
AppPort: 8080,
|
|
LogLevel: "INFO",
|
|
RateLimitLimit: 100, // Valeur valide pour passer Validate()
|
|
RateLimitWindow: 60, // Valeur valide pour passer Validate()
|
|
CORSOrigins: []string{}, // Vide - devrait échouer en prod
|
|
}
|
|
|
|
// Créer un logger minimal pour la config
|
|
logger, _ := zap.NewDevelopment()
|
|
cfg.Logger = logger
|
|
|
|
// La validation devrait échouer
|
|
err := cfg.ValidateForEnvironment()
|
|
require.Error(t, err, "Production config should fail validation when CORS_ALLOWED_ORIGINS is empty")
|
|
assert.Contains(t, err.Error(), "CORS_ALLOWED_ORIGINS is required", "Error should mention CORS requirement")
|
|
}
|
|
|
|
// TestLoadConfig_ProdWildcard vérifie que prod refuse le wildcard (P0-SECURITY)
|
|
func TestLoadConfig_ProdWildcard(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalEnv := os.Getenv("APP_ENV")
|
|
originalCORSOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalEnv != "" {
|
|
os.Setenv("APP_ENV", originalEnv)
|
|
} else {
|
|
os.Unsetenv("APP_ENV")
|
|
}
|
|
if originalCORSOrigins != "" {
|
|
os.Setenv("CORS_ALLOWED_ORIGINS", originalCORSOrigins)
|
|
} else {
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS")
|
|
}
|
|
}()
|
|
|
|
// Configuration pour production avec wildcard
|
|
os.Setenv("APP_ENV", "production")
|
|
|
|
// Créer une config minimale avec wildcard
|
|
cfg := &Config{
|
|
Env: "production",
|
|
JWTSecret: "test-jwt-secret-key-minimum-32-characters-long",
|
|
DatabaseURL: "postgresql://test:test@localhost:5432/test_db",
|
|
RedisURL: "redis://localhost:6379",
|
|
AppPort: 8080,
|
|
LogLevel: "INFO",
|
|
RateLimitLimit: 100, // Valeur valide pour passer Validate()
|
|
RateLimitWindow: 60, // Valeur valide pour passer Validate()
|
|
CORSOrigins: []string{"*"}, // Wildcard - devrait échouer en prod
|
|
}
|
|
|
|
// Créer un logger minimal pour la config
|
|
logger, _ := zap.NewDevelopment()
|
|
cfg.Logger = logger
|
|
|
|
// La validation devrait échouer
|
|
err := cfg.ValidateForEnvironment()
|
|
require.Error(t, err, "Production config should fail validation when CORS contains wildcard")
|
|
assert.Contains(t, err.Error(), "wildcard", "Error should mention wildcard prohibition")
|
|
}
|
|
|
|
// TestLoadConfig_ProdValid vérifie qu'une config prod valide passe (P0-SECURITY)
|
|
func TestLoadConfig_ProdValid(t *testing.T) {
|
|
// Sauvegarder les valeurs originales
|
|
originalEnv := os.Getenv("APP_ENV")
|
|
originalCORSOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
|
|
|
|
// Nettoyer après le test
|
|
defer func() {
|
|
if originalEnv != "" {
|
|
os.Setenv("APP_ENV", originalEnv)
|
|
} else {
|
|
os.Unsetenv("APP_ENV")
|
|
}
|
|
if originalCORSOrigins != "" {
|
|
os.Setenv("CORS_ALLOWED_ORIGINS", originalCORSOrigins)
|
|
} else {
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS")
|
|
}
|
|
}()
|
|
|
|
// Configuration pour production valide
|
|
os.Setenv("APP_ENV", "production")
|
|
|
|
// Créer une config minimale valide
|
|
cfg := &Config{
|
|
Env: "production",
|
|
JWTSecret: "test-jwt-secret-key-minimum-32-characters-long",
|
|
DatabaseURL: "postgresql://test:test@localhost:5432/test_db",
|
|
RedisURL: "redis://localhost:6379",
|
|
AppPort: 8080,
|
|
LogLevel: "INFO",
|
|
RateLimitLimit: 100, // Valeur valide pour passer Validate()
|
|
RateLimitWindow: 60, // Valeur valide pour passer Validate()
|
|
CORSOrigins: []string{"https://app.veza.com", "https://www.veza.com"}, // Valide - pas de wildcard
|
|
}
|
|
|
|
// Créer un logger minimal pour la config
|
|
logger, _ := zap.NewDevelopment()
|
|
cfg.Logger = logger
|
|
|
|
// La validation devrait passer
|
|
err := cfg.ValidateForEnvironment()
|
|
assert.NoError(t, err, "Valid production config should pass validation")
|
|
}
|
|
|
|
// TestGetCORSOrigins_EnvironmentDefaults teste les defaults selon l'environnement (P0-SECURITY)
|
|
func TestGetCORSOrigins_EnvironmentDefaults(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
env string
|
|
expected []string
|
|
}{
|
|
{
|
|
name: "development defaults",
|
|
env: "development",
|
|
expected: []string{"http://localhost:3000", "http://127.0.0.1:3000", "http://localhost:5173", "http://127.0.0.1:5173"},
|
|
},
|
|
{
|
|
name: "staging defaults",
|
|
env: "staging",
|
|
expected: []string{"http://localhost:3000", "http://127.0.0.1:3000", "http://localhost:5173", "http://127.0.0.1:5173"},
|
|
},
|
|
{
|
|
name: "production no defaults",
|
|
env: "production",
|
|
expected: []string{},
|
|
},
|
|
{
|
|
name: "test no defaults",
|
|
env: "test",
|
|
expected: []string{},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Sauvegarder CORS_ALLOWED_ORIGINS
|
|
originalCORSOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
|
|
defer func() {
|
|
if originalCORSOrigins != "" {
|
|
os.Setenv("CORS_ALLOWED_ORIGINS", originalCORSOrigins)
|
|
} else {
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS")
|
|
}
|
|
}()
|
|
|
|
// S'assurer que CORS_ALLOWED_ORIGINS n'est pas défini
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS")
|
|
|
|
origins := getCORSOrigins(tt.env)
|
|
assert.Equal(t, tt.expected, origins, "CORS origins should match expected defaults for %s", tt.env)
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestGetCORSOrigins_ExplicitValue teste que les valeurs explicites sont utilisées (P0-SECURITY)
|
|
func TestGetCORSOrigins_ExplicitValue(t *testing.T) {
|
|
// Sauvegarder CORS_ALLOWED_ORIGINS
|
|
originalCORSOrigins := os.Getenv("CORS_ALLOWED_ORIGINS")
|
|
defer func() {
|
|
if originalCORSOrigins != "" {
|
|
os.Setenv("CORS_ALLOWED_ORIGINS", originalCORSOrigins)
|
|
} else {
|
|
os.Unsetenv("CORS_ALLOWED_ORIGINS")
|
|
}
|
|
}()
|
|
|
|
// Définir explicitement CORS_ALLOWED_ORIGINS
|
|
os.Setenv("CORS_ALLOWED_ORIGINS", "https://example.com,https://app.example.com")
|
|
|
|
origins := getCORSOrigins("production")
|
|
assert.Equal(t, []string{"https://example.com", "https://app.example.com"}, origins, "Should use explicit CORS_ALLOWED_ORIGINS value")
|
|
}
|