package config import ( "os" "path/filepath" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "nex/backend/internal/config" ) func TestLoadConfig_DefaultValues(t *testing.T) { tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, "config.yaml") cfg, err := config.LoadConfigFromPath(configPath) require.NoError(t, err) assert.Equal(t, 9826, cfg.Server.Port) assert.Equal(t, 30*time.Second, cfg.Server.ReadTimeout) assert.Equal(t, 30*time.Second, cfg.Server.WriteTimeout) assert.Equal(t, 10, cfg.Database.MaxIdleConns) assert.Equal(t, 100, cfg.Database.MaxOpenConns) assert.Equal(t, 1*time.Hour, cfg.Database.ConnMaxLifetime) assert.Equal(t, "info", cfg.Log.Level) assert.Equal(t, 100, cfg.Log.MaxSize) assert.Equal(t, 10, cfg.Log.MaxBackups) assert.Equal(t, 30, cfg.Log.MaxAge) assert.True(t, cfg.Log.Compress) } func TestLoadConfig_EnvOverride(t *testing.T) { tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, "config.yaml") t.Setenv("NEX_SERVER_PORT", "9000") t.Setenv("NEX_LOG_LEVEL", "debug") t.Setenv("NEX_DATABASE_MAX_IDLE_CONNS", "20") cfg, err := config.LoadConfigFromPath(configPath) require.NoError(t, err) assert.Equal(t, 9000, cfg.Server.Port) assert.Equal(t, "debug", cfg.Log.Level) assert.Equal(t, 20, cfg.Database.MaxIdleConns) } func TestLoadConfig_YAMLFile(t *testing.T) { tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, "config.yaml") yamlContent := ` server: port: 8080 read_timeout: 60s write_timeout: 60s database: path: /custom/path.db max_idle_conns: 5 max_open_conns: 50 conn_max_lifetime: 2h log: level: warn path: /custom/log max_size: 200 max_backups: 5 max_age: 7 compress: false ` err := os.WriteFile(configPath, []byte(yamlContent), 0644) require.NoError(t, err) cfg, err := config.LoadConfigFromPath(configPath) require.NoError(t, err) assert.Equal(t, 8080, cfg.Server.Port) assert.Equal(t, 60*time.Second, cfg.Server.ReadTimeout) assert.Equal(t, 60*time.Second, cfg.Server.WriteTimeout) assert.Equal(t, "/custom/path.db", cfg.Database.Path) assert.Equal(t, 5, cfg.Database.MaxIdleConns) assert.Equal(t, 50, cfg.Database.MaxOpenConns) assert.Equal(t, 2*time.Hour, cfg.Database.ConnMaxLifetime) assert.Equal(t, "warn", cfg.Log.Level) assert.Equal(t, "/custom/log", cfg.Log.Path) assert.Equal(t, 200, cfg.Log.MaxSize) assert.Equal(t, 5, cfg.Log.MaxBackups) assert.Equal(t, 7, cfg.Log.MaxAge) assert.False(t, cfg.Log.Compress) } func TestLoadConfig_PriorityChain(t *testing.T) { tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, "config.yaml") yamlContent := ` server: port: 8080 log: level: warn ` err := os.WriteFile(configPath, []byte(yamlContent), 0644) require.NoError(t, err) t.Setenv("NEX_SERVER_PORT", "9000") originalArgs := os.Args defer func() { os.Args = originalArgs }() os.Args = []string{"test", "--server-port", "9999"} cfg, err := config.LoadConfigFromPath(configPath) require.NoError(t, err) assert.Equal(t, 9999, cfg.Server.Port, "CLI should override ENV and YAML") assert.Equal(t, "warn", cfg.Log.Level, "YAML value should be used when no CLI/ENV override") } func TestLoadConfig_AutoCreate(t *testing.T) { tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, "config.yaml") _, err := os.Stat(configPath) assert.True(t, os.IsNotExist(err), "config file should not exist before load") cfg, err := config.LoadConfigFromPath(configPath) require.NoError(t, err) require.NotNil(t, cfg) assert.Equal(t, 9826, cfg.Server.Port, "should load with default values") } func TestSaveAndLoadConfig(t *testing.T) { tmpDir := t.TempDir() homeDir, err := os.UserHomeDir() require.NoError(t, err) nexDir := filepath.Join(homeDir, ".nex") configPath := filepath.Join(nexDir, "config.yaml") originalConfig, err := os.ReadFile(configPath) if err != nil && !os.IsNotExist(err) { require.NoError(t, err) } defer func() { if originalConfig != nil { _ = os.WriteFile(configPath, originalConfig, 0644) } }() cfg := &config.Config{ Server: config.ServerConfig{ Port: 7777, ReadTimeout: 45 * time.Second, WriteTimeout: 45 * time.Second, }, Database: config.DatabaseConfig{ Path: filepath.Join(tmpDir, "test.db"), MaxIdleConns: 15, MaxOpenConns: 150, ConnMaxLifetime: 2 * time.Hour, }, Log: config.LogConfig{ Level: "debug", Path: filepath.Join(tmpDir, "log"), MaxSize: 50, MaxBackups: 3, MaxAge: 14, Compress: false, }, } err = config.SaveConfig(cfg) require.NoError(t, err) loaded, err := config.LoadConfig() require.NoError(t, err) assert.Equal(t, cfg.Server.Port, loaded.Server.Port) assert.Equal(t, cfg.Server.ReadTimeout, loaded.Server.ReadTimeout) assert.Equal(t, cfg.Server.WriteTimeout, loaded.Server.WriteTimeout) assert.Equal(t, cfg.Database.MaxIdleConns, loaded.Database.MaxIdleConns) assert.Equal(t, cfg.Database.MaxOpenConns, loaded.Database.MaxOpenConns) assert.Equal(t, cfg.Database.ConnMaxLifetime, loaded.Database.ConnMaxLifetime) assert.Equal(t, cfg.Log.Level, loaded.Log.Level) assert.Equal(t, cfg.Log.MaxSize, loaded.Log.MaxSize) assert.Equal(t, cfg.Log.MaxBackups, loaded.Log.MaxBackups) assert.Equal(t, cfg.Log.MaxAge, loaded.Log.MaxAge) assert.Equal(t, cfg.Log.Compress, loaded.Log.Compress) }