185 lines
5 KiB
Go
185 lines
5 KiB
Go
|
|
package internal
|
||
|
|
|
||
|
|
import (
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
"testing"
|
||
|
|
|
||
|
|
"github.com/stretchr/testify/assert"
|
||
|
|
"github.com/stretchr/testify/require"
|
||
|
|
)
|
||
|
|
|
||
|
|
// setupTestEnv creates a temporary home directory for testing and ensures a clean environment.
|
||
|
|
func setupTestEnv(t *testing.T) (string, func()) {
|
||
|
|
tempHomeDir, err := os.MkdirTemp("", "test_home_*")
|
||
|
|
require.NoError(t, err, "Failed to create temp home directory")
|
||
|
|
|
||
|
|
oldHome := os.Getenv("HOME")
|
||
|
|
os.Setenv("HOME", tempHomeDir)
|
||
|
|
|
||
|
|
// Unset XDG vars to ensure HOME is used for path resolution, creating a hermetic test.
|
||
|
|
oldXdgData, hadXdgData := os.LookupEnv("XDG_DATA_HOME")
|
||
|
|
oldXdgCache, hadXdgCache := os.LookupEnv("XDG_CACHE_HOME")
|
||
|
|
require.NoError(t, os.Unsetenv("XDG_DATA_HOME"))
|
||
|
|
require.NoError(t, os.Unsetenv("XDG_CACHE_HOME"))
|
||
|
|
|
||
|
|
cleanup := func() {
|
||
|
|
os.Setenv("HOME", oldHome)
|
||
|
|
if hadXdgData {
|
||
|
|
os.Setenv("XDG_DATA_HOME", oldXdgData)
|
||
|
|
} else {
|
||
|
|
os.Unsetenv("XDG_DATA_HOME")
|
||
|
|
}
|
||
|
|
if hadXdgCache {
|
||
|
|
os.Setenv("XDG_CACHE_HOME", oldXdgCache)
|
||
|
|
} else {
|
||
|
|
os.Unsetenv("XDG_CACHE_HOME")
|
||
|
|
}
|
||
|
|
os.RemoveAll(tempHomeDir)
|
||
|
|
}
|
||
|
|
|
||
|
|
return tempHomeDir, cleanup
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestConfigService(t *testing.T) {
|
||
|
|
t.Run("New service creates default config", func(t *testing.T) {
|
||
|
|
_, cleanup := setupTestEnv(t)
|
||
|
|
defer cleanup()
|
||
|
|
|
||
|
|
serviceInstance, err := New()
|
||
|
|
require.NoError(t, err, "New() failed")
|
||
|
|
|
||
|
|
// Check that the config file was created
|
||
|
|
assert.FileExists(t, serviceInstance.ConfigPath, "config.json was not created")
|
||
|
|
|
||
|
|
// Check default values
|
||
|
|
assert.Equal(t, "en", serviceInstance.Language, "Expected default language 'en'")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("New service loads existing config", func(t *testing.T) {
|
||
|
|
tempHomeDir, cleanup := setupTestEnv(t)
|
||
|
|
defer cleanup()
|
||
|
|
|
||
|
|
// Manually create a config file with non-default values
|
||
|
|
configDir := filepath.Join(tempHomeDir, appName, "config")
|
||
|
|
require.NoError(t, os.MkdirAll(configDir, os.ModePerm), "Failed to create test config dir")
|
||
|
|
configPath := filepath.Join(configDir, configFileName)
|
||
|
|
|
||
|
|
customConfig := `{"language": "fr", "features": ["beta-testing"]}`
|
||
|
|
require.NoError(t, os.WriteFile(configPath, []byte(customConfig), 0644), "Failed to write custom config file")
|
||
|
|
|
||
|
|
serviceInstance, err := New()
|
||
|
|
require.NoError(t, err, "New() failed while loading existing config")
|
||
|
|
|
||
|
|
assert.Equal(t, "fr", serviceInstance.Language, "Expected language 'fr'")
|
||
|
|
assert.True(t, serviceInstance.IsFeatureEnabled("beta-testing"), "Expected 'beta-testing' feature to be enabled")
|
||
|
|
assert.False(t, serviceInstance.IsFeatureEnabled("alpha-testing"), "Did not expect 'alpha-testing' to be enabled")
|
||
|
|
})
|
||
|
|
|
||
|
|
t.Run("Set and Get", func(t *testing.T) {
|
||
|
|
_, cleanup := setupTestEnv(t)
|
||
|
|
defer cleanup()
|
||
|
|
|
||
|
|
s, err := New()
|
||
|
|
require.NoError(t, err, "New() failed")
|
||
|
|
|
||
|
|
key := "language"
|
||
|
|
expectedValue := "de"
|
||
|
|
require.NoError(t, s.Set(key, expectedValue), "Set() failed")
|
||
|
|
|
||
|
|
var actualValue string
|
||
|
|
require.NoError(t, s.Get(key, &actualValue), "Get() failed")
|
||
|
|
assert.Equal(t, expectedValue, actualValue, "Get() returned unexpected value")
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestIsFeatureEnabled(t *testing.T) {
|
||
|
|
_, cleanup := setupTestEnv(t)
|
||
|
|
defer cleanup()
|
||
|
|
|
||
|
|
s, err := New()
|
||
|
|
require.NoError(t, err)
|
||
|
|
|
||
|
|
// Test with no features enabled
|
||
|
|
assert.False(t, s.IsFeatureEnabled("beta-feature"))
|
||
|
|
|
||
|
|
// Enable a feature
|
||
|
|
s.Features = []string{"beta-feature", "alpha-testing"}
|
||
|
|
|
||
|
|
// Test for an enabled feature
|
||
|
|
assert.True(t, s.IsFeatureEnabled("beta-feature"))
|
||
|
|
|
||
|
|
// Test for another enabled feature
|
||
|
|
assert.True(t, s.IsFeatureEnabled("alpha-testing"))
|
||
|
|
|
||
|
|
// Test for a disabled feature
|
||
|
|
assert.False(t, s.IsFeatureEnabled("gamma-feature"))
|
||
|
|
|
||
|
|
// Test with an empty string
|
||
|
|
assert.False(t, s.IsFeatureEnabled(""))
|
||
|
|
|
||
|
|
// Test with a nil slice
|
||
|
|
s.Features = nil
|
||
|
|
assert.False(t, s.IsFeatureEnabled("beta-feature"))
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSet_Good(t *testing.T) {
|
||
|
|
_, cleanup := setupTestEnv(t)
|
||
|
|
defer cleanup()
|
||
|
|
|
||
|
|
s, err := New()
|
||
|
|
require.NoError(t, err, "New() failed")
|
||
|
|
|
||
|
|
// Test setting a string value
|
||
|
|
err = s.Set("language", "de")
|
||
|
|
assert.NoError(t, err)
|
||
|
|
var lang string
|
||
|
|
err = s.Get("language", &lang)
|
||
|
|
assert.NoError(t, err)
|
||
|
|
assert.Equal(t, "de", lang)
|
||
|
|
|
||
|
|
// Test setting a slice value
|
||
|
|
err = s.Set("features", []string{"new-feature"})
|
||
|
|
assert.NoError(t, err)
|
||
|
|
var features []string
|
||
|
|
err = s.Get("features", &features)
|
||
|
|
assert.NoError(t, err)
|
||
|
|
assert.Equal(t, []string{"new-feature"}, features)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSet_Bad(t *testing.T) {
|
||
|
|
_, cleanup := setupTestEnv(t)
|
||
|
|
defer cleanup()
|
||
|
|
|
||
|
|
s, err := New()
|
||
|
|
require.NoError(t, err, "New() failed")
|
||
|
|
|
||
|
|
// Test setting a value with the wrong type
|
||
|
|
err = s.Set("language", 123)
|
||
|
|
assert.Error(t, err)
|
||
|
|
|
||
|
|
// Test setting a non-existent key
|
||
|
|
err = s.Set("nonExistentKey", "value")
|
||
|
|
assert.Error(t, err)
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestSet_Ugly(t *testing.T) {
|
||
|
|
_, cleanup := setupTestEnv(t)
|
||
|
|
defer cleanup()
|
||
|
|
|
||
|
|
s, err := New()
|
||
|
|
require.NoError(t, err, "New() failed")
|
||
|
|
|
||
|
|
// This should not panic
|
||
|
|
assert.NotPanics(t, func() {
|
||
|
|
err = s.Set("features", nil)
|
||
|
|
})
|
||
|
|
assert.NoError(t, err)
|
||
|
|
|
||
|
|
// Verify the slice is now nil
|
||
|
|
var features []string
|
||
|
|
err = s.Get("features", &features)
|
||
|
|
assert.NoError(t, err)
|
||
|
|
assert.Nil(t, features)
|
||
|
|
}
|