package config import ( "os" "testing" "github.com/spf13/afero" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/fx" "go.uber.org/fx/fxtest" "sneak.berlin/go/webhooker/internal/globals" "sneak.berlin/go/webhooker/internal/logger" pkgconfig "sneak.berlin/go/webhooker/pkg/config" ) // createTestConfig creates a test configuration file in memory func createTestConfig(fs afero.Fs) error { configYAML := ` environments: dev: config: port: 8080 debug: true maintenanceMode: false developmentMode: true environment: dev dburl: postgres://test:test@localhost:5432/test_dev?sslmode=disable metricsUsername: testuser metricsPassword: testpass secrets: sentryDSN: "" prod: config: port: $ENV:PORT debug: $ENV:DEBUG maintenanceMode: $ENV:MAINTENANCE_MODE developmentMode: false environment: prod dburl: $ENV:DBURL metricsUsername: $ENV:METRICS_USERNAME metricsPassword: $ENV:METRICS_PASSWORD secrets: sentryDSN: $ENV:SENTRY_DSN configDefaults: port: 8080 debug: false maintenanceMode: false developmentMode: false environment: dev metricsUsername: "" metricsPassword: "" ` return afero.WriteFile(fs, "config.yaml", []byte(configYAML), 0644) } func TestEnvironmentConfig(t *testing.T) { tests := []struct { name string envValue string envVars map[string]string expectError bool isDev bool isProd bool }{ { name: "default is dev", envValue: "", expectError: false, isDev: true, isProd: false, }, { name: "explicit dev", envValue: "dev", expectError: false, isDev: true, isProd: false, }, { name: "explicit prod", envValue: "prod", envVars: map[string]string{ "DBURL": "postgres://prod:prod@localhost:5432/prod?sslmode=require", }, expectError: false, isDev: false, isProd: true, }, { name: "invalid environment", envValue: "staging", expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create in-memory filesystem with test config fs := afero.NewMemMapFs() require.NoError(t, createTestConfig(fs)) pkgconfig.SetFs(fs) // Set environment variable if specified if tt.envValue != "" { os.Setenv("WEBHOOKER_ENVIRONMENT", tt.envValue) defer os.Unsetenv("WEBHOOKER_ENVIRONMENT") } // Set additional environment variables for k, v := range tt.envVars { os.Setenv(k, v) defer os.Unsetenv(k) } if tt.expectError { // Use regular fx.New for error cases since fxtest doesn't expose errors the same way var cfg *Config app := fx.New( fx.NopLogger, // Suppress fx logs in tests fx.Provide( globals.New, logger.New, New, ), fx.Populate(&cfg), ) assert.Error(t, app.Err()) } else { // Use fxtest for success cases var cfg *Config app := fxtest.New( t, fx.Provide( globals.New, logger.New, New, ), fx.Populate(&cfg), ) require.NoError(t, app.Err()) app.RequireStart() defer app.RequireStop() assert.Equal(t, tt.isDev, cfg.IsDev()) assert.Equal(t, tt.isProd, cfg.IsProd()) } }) } }