package config import ( "os" "path/filepath" "testing" "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" ) 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: "", envVars: map[string]string{}, expectError: false, isDev: true, isProd: false, }, { name: "explicit dev", envValue: "dev", envVars: map[string]string{}, expectError: false, isDev: true, isProd: false, }, { name: "explicit prod", envValue: "prod", envVars: map[string]string{}, expectError: false, isDev: false, isProd: true, }, { name: "invalid environment", envValue: "staging", envVars: map[string]string{}, expectError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Set environment variable if specified if tt.envValue != "" { os.Setenv("WEBHOOKER_ENVIRONMENT", tt.envValue) defer os.Unsetenv("WEBHOOKER_ENVIRONMENT") } else { 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()) } }) } } func TestDevDataDir(t *testing.T) { t.Run("uses XDG_DATA_HOME when set", func(t *testing.T) { os.Setenv("XDG_DATA_HOME", "/custom/data") defer os.Unsetenv("XDG_DATA_HOME") got := devDataDir() assert.Equal(t, "/custom/data/webhooker", got) }) t.Run("falls back to HOME/.local/share/webhooker", func(t *testing.T) { os.Unsetenv("XDG_DATA_HOME") home, err := os.UserHomeDir() require.NoError(t, err) got := devDataDir() assert.Equal(t, filepath.Join(home, ".local", "share", "webhooker"), got) }) t.Run("result is always absolute", func(t *testing.T) { os.Unsetenv("XDG_DATA_HOME") got := devDataDir() assert.True(t, filepath.IsAbs(got), "devDataDir() returned relative path: %s", got) }) } func TestDevDefaultDataDirIsAbsolute(t *testing.T) { // Verify that when WEBHOOKER_ENVIRONMENT=dev and DATA_DIR is unset, // the resulting DataDir is an absolute path. os.Unsetenv("WEBHOOKER_ENVIRONMENT") os.Unsetenv("DATA_DIR") 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.True(t, filepath.IsAbs(cfg.DataDir), "dev default DataDir should be absolute, got: %s", cfg.DataDir) }