package config import ( "testing" "github.com/stretchr/testify/assert" "go.uber.org/zap" ) func TestConfigDefaults_Build(t *testing.T) { defaults := NewConfigDefaults(). WithPort(9000). WithEnv("test"). WithJWTSecret("test-secret"). WithDatabaseURL("postgres://test"). WithLogLevel("DEBUG") config := defaults.Build() assert.Equal(t, 9000, config.AppPort) assert.Equal(t, "test-secret", config.JWTSecret) assert.Equal(t, "postgres://test", config.DatabaseURL) assert.Equal(t, "DEBUG", config.LogLevel) } func TestConfigDefaults_Merge(t *testing.T) { existingConfig := &Config{ AppPort: 8080, LogLevel: "INFO", } defaults := NewConfigDefaults(). WithPort(9000). WithLogLevel("DEBUG") merged := defaults.Merge(existingConfig) assert.Equal(t, 9000, merged.AppPort) // Override assert.Equal(t, "DEBUG", merged.LogLevel) // Override assert.Same(t, existingConfig, merged) // Même instance } func TestConfigDefaults_WithPort(t *testing.T) { defaults := NewConfigDefaults().WithPort(3000) config := defaults.Build() assert.Equal(t, 3000, config.AppPort) } func TestConfigDefaults_WithJWTSecret(t *testing.T) { defaults := NewConfigDefaults().WithJWTSecret("my-secret-key") config := defaults.Build() assert.Equal(t, "my-secret-key", config.JWTSecret) } func TestConfigDefaults_WithDatabaseURL(t *testing.T) { defaults := NewConfigDefaults().WithDatabaseURL("postgresql://localhost/db") config := defaults.Build() assert.Equal(t, "postgresql://localhost/db", config.DatabaseURL) } func TestConfigDefaults_WithRedisURL(t *testing.T) { defaults := NewConfigDefaults().WithRedisURL("redis://localhost:6379") config := defaults.Build() assert.Equal(t, "redis://localhost:6379", config.RedisURL) } func TestConfigDefaults_WithCORSOrigins(t *testing.T) { origins := []string{"http://localhost:3000", "https://example.com"} defaults := NewConfigDefaults().WithCORSOrigins(origins) config := defaults.Build() assert.Equal(t, origins, config.CORSOrigins) } func TestConfigDefaults_WithRateLimit(t *testing.T) { defaults := NewConfigDefaults().WithRateLimit(200, 120) config := defaults.Build() assert.Equal(t, 200, config.RateLimitLimit) assert.Equal(t, 120, config.RateLimitWindow) } func TestConfigDefaults_WithLogLevel(t *testing.T) { defaults := NewConfigDefaults().WithLogLevel("ERROR") config := defaults.Build() assert.Equal(t, "ERROR", config.LogLevel) } func TestConfigDefaults_WithLogger(t *testing.T) { logger, _ := zap.NewDevelopment() defaults := NewConfigDefaults().WithLogger(logger) config := defaults.Build() assert.Same(t, logger, config.Logger) } func TestConfigDefaults_Build_Empty(t *testing.T) { defaults := NewConfigDefaults() config := defaults.Build() assert.NotNil(t, config) assert.Equal(t, 0, config.AppPort) assert.Empty(t, config.JWTSecret) assert.Empty(t, config.DatabaseURL) assert.Empty(t, config.RedisURL) assert.Nil(t, config.CORSOrigins) assert.Equal(t, 0, config.RateLimitLimit) assert.Equal(t, 0, config.RateLimitWindow) assert.Empty(t, config.LogLevel) assert.Nil(t, config.Logger) } func TestConfigDefaults_FluentChaining(t *testing.T) { config := NewConfigDefaults(). WithPort(8080). WithJWTSecret("secret"). WithDatabaseURL("postgres://db"). WithRedisURL("redis://redis"). WithCORSOrigins([]string{"*"}). WithRateLimit(100, 60). WithLogLevel("INFO"). Build() assert.Equal(t, 8080, config.AppPort) assert.Equal(t, "secret", config.JWTSecret) assert.Equal(t, "postgres://db", config.DatabaseURL) assert.Equal(t, "redis://redis", config.RedisURL) assert.Equal(t, []string{"*"}, config.CORSOrigins) assert.Equal(t, 100, config.RateLimitLimit) assert.Equal(t, 60, config.RateLimitWindow) assert.Equal(t, "INFO", config.LogLevel) } func TestConfigDefaults_Merge_Partial(t *testing.T) { existingConfig := &Config{ AppPort: 8080, JWTSecret: "original-secret", DatabaseURL: "postgres://original", LogLevel: "INFO", } defaults := NewConfigDefaults(). WithPort(9000). WithDatabaseURL("postgres://new") merged := defaults.Merge(existingConfig) assert.Equal(t, 9000, merged.AppPort) // Override assert.Equal(t, "original-secret", merged.JWTSecret) // Pas override assert.Equal(t, "postgres://new", merged.DatabaseURL) // Override assert.Equal(t, "INFO", merged.LogLevel) // Pas override } func TestConfigDefaults_Merge_AllFields(t *testing.T) { existingConfig := &Config{ AppPort: 8080, JWTSecret: "old-secret", DatabaseURL: "postgres://old", RedisURL: "redis://old", CORSOrigins: []string{"old-origin"}, RateLimitLimit: 50, RateLimitWindow: 30, LogLevel: "WARN", } logger, _ := zap.NewDevelopment() newOrigins := []string{"new-origin1", "new-origin2"} defaults := NewConfigDefaults(). WithPort(9000). WithJWTSecret("new-secret"). WithDatabaseURL("postgres://new"). WithRedisURL("redis://new"). WithCORSOrigins(newOrigins). WithRateLimit(200, 120). WithLogLevel("DEBUG"). WithLogger(logger) merged := defaults.Merge(existingConfig) assert.Equal(t, 9000, merged.AppPort) assert.Equal(t, "new-secret", merged.JWTSecret) assert.Equal(t, "postgres://new", merged.DatabaseURL) assert.Equal(t, "redis://new", merged.RedisURL) assert.Equal(t, newOrigins, merged.CORSOrigins) assert.Equal(t, 200, merged.RateLimitLimit) assert.Equal(t, 120, merged.RateLimitWindow) assert.Equal(t, "DEBUG", merged.LogLevel) assert.Same(t, logger, merged.Logger) } func TestConfigDefaults_WithEnv(t *testing.T) { defaults := NewConfigDefaults().WithEnv("production") // Env n'est pas stocké dans Config, mais le builder l'accepte // Ceci permet d'utiliser l'env pour d'autres choses si nécessaire config := defaults.Build() assert.NotNil(t, config) } func TestConfigDefaults_MultipleCalls(t *testing.T) { defaults := NewConfigDefaults(). WithPort(1000). WithPort(2000). // Override WithLogLevel("INFO"). WithLogLevel("DEBUG") // Override config := defaults.Build() assert.Equal(t, 2000, config.AppPort) // Dernière valeur assert.Equal(t, "DEBUG", config.LogLevel) // Dernière valeur } func TestNewConfigDefaults(t *testing.T) { defaults := NewConfigDefaults() assert.NotNil(t, defaults) config := defaults.Build() assert.NotNil(t, config) }