mirror of
https://github.com/netbirdio/netbird.git
synced 2025-08-18 02:50:43 +02:00
[client] Feat: Support Multiple Profiles (#3980)
[client] Feat: Support Multiple Profiles (#3980)
This commit is contained in:
151
client/internal/profilemanager/profilemanager_test.go
Normal file
151
client/internal/profilemanager/profilemanager_test.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package profilemanager
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func withTempConfigDir(t *testing.T, testFunc func(configDir string)) {
|
||||
t.Helper()
|
||||
tempDir := t.TempDir()
|
||||
t.Setenv("NETBIRD_CONFIG_DIR", tempDir)
|
||||
defer os.Unsetenv("NETBIRD_CONFIG_DIR")
|
||||
testFunc(tempDir)
|
||||
}
|
||||
|
||||
func withPatchedGlobals(t *testing.T, configDir string, testFunc func()) {
|
||||
origDefaultConfigPathDir := DefaultConfigPathDir
|
||||
origDefaultConfigPath := DefaultConfigPath
|
||||
origActiveProfileStatePath := ActiveProfileStatePath
|
||||
origOldDefaultConfigPath := oldDefaultConfigPath
|
||||
origConfigDirOverride := ConfigDirOverride
|
||||
DefaultConfigPathDir = configDir
|
||||
DefaultConfigPath = filepath.Join(configDir, "default.json")
|
||||
ActiveProfileStatePath = filepath.Join(configDir, "active_profile.json")
|
||||
oldDefaultConfigPath = filepath.Join(configDir, "old_config.json")
|
||||
ConfigDirOverride = configDir
|
||||
// Clean up any files in the config dir to ensure isolation
|
||||
os.RemoveAll(configDir)
|
||||
os.MkdirAll(configDir, 0755) //nolint: errcheck
|
||||
defer func() {
|
||||
DefaultConfigPathDir = origDefaultConfigPathDir
|
||||
DefaultConfigPath = origDefaultConfigPath
|
||||
ActiveProfileStatePath = origActiveProfileStatePath
|
||||
oldDefaultConfigPath = origOldDefaultConfigPath
|
||||
ConfigDirOverride = origConfigDirOverride
|
||||
}()
|
||||
testFunc()
|
||||
}
|
||||
|
||||
func TestServiceManager_CreateAndGetDefaultProfile(t *testing.T) {
|
||||
withTempConfigDir(t, func(configDir string) {
|
||||
withPatchedGlobals(t, configDir, func() {
|
||||
sm := &ServiceManager{}
|
||||
err := sm.CreateDefaultProfile()
|
||||
assert.NoError(t, err)
|
||||
|
||||
state, err := sm.GetActiveProfileState()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, state.Name, defaultProfileName) // No active profile state yet
|
||||
|
||||
err = sm.SetActiveProfileStateToDefault()
|
||||
assert.NoError(t, err)
|
||||
|
||||
active, err := sm.GetActiveProfileState()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "default", active.Name)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceManager_CopyDefaultProfileIfNotExists(t *testing.T) {
|
||||
withTempConfigDir(t, func(configDir string) {
|
||||
withPatchedGlobals(t, configDir, func() {
|
||||
sm := &ServiceManager{}
|
||||
|
||||
// Case: old default config does not exist
|
||||
ok, err := sm.CopyDefaultProfileIfNotExists()
|
||||
assert.False(t, ok)
|
||||
assert.ErrorIs(t, err, ErrorOldDefaultConfigNotFound)
|
||||
|
||||
// Case: old default config exists, should be moved
|
||||
f, err := os.Create(oldDefaultConfigPath)
|
||||
assert.NoError(t, err)
|
||||
f.Close()
|
||||
|
||||
ok, err = sm.CopyDefaultProfileIfNotExists()
|
||||
assert.True(t, ok)
|
||||
assert.NoError(t, err)
|
||||
_, err = os.Stat(DefaultConfigPath)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceManager_SetActiveProfileState(t *testing.T) {
|
||||
withTempConfigDir(t, func(configDir string) {
|
||||
withPatchedGlobals(t, configDir, func() {
|
||||
currUser, err := user.Current()
|
||||
assert.NoError(t, err)
|
||||
sm := &ServiceManager{}
|
||||
state := &ActiveProfileState{Name: "foo", Username: currUser.Username}
|
||||
err = sm.SetActiveProfileState(state)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Should error on nil or incomplete state
|
||||
err = sm.SetActiveProfileState(nil)
|
||||
assert.Error(t, err)
|
||||
err = sm.SetActiveProfileState(&ActiveProfileState{Name: "", Username: ""})
|
||||
assert.Error(t, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestServiceManager_DefaultProfilePath(t *testing.T) {
|
||||
withTempConfigDir(t, func(configDir string) {
|
||||
withPatchedGlobals(t, configDir, func() {
|
||||
sm := &ServiceManager{}
|
||||
assert.Equal(t, DefaultConfigPath, sm.DefaultProfilePath())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestSanitizeProfileName(t *testing.T) {
|
||||
tests := []struct {
|
||||
in, want string
|
||||
}{
|
||||
// unchanged
|
||||
{"Alice", "Alice"},
|
||||
{"bob123", "bob123"},
|
||||
{"under_score", "under_score"},
|
||||
{"dash-name", "dash-name"},
|
||||
|
||||
// spaces and forbidden chars removed
|
||||
{"Alice Smith", "AliceSmith"},
|
||||
{"bad/char\\name", "badcharname"},
|
||||
{"colon:name*?", "colonname"},
|
||||
{"quotes\"<>|", "quotes"},
|
||||
|
||||
// mixed
|
||||
{"User_123-Test!@#", "User_123-Test"},
|
||||
|
||||
// empty and all-bad
|
||||
{"", ""},
|
||||
{"!@#$%^&*()", ""},
|
||||
|
||||
// unicode letters and digits
|
||||
{"ÜserÇ", "ÜserÇ"},
|
||||
{"漢字テスト123", "漢字テスト123"},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
got := sanitizeProfileName(tc.in)
|
||||
if got != tc.want {
|
||||
t.Errorf("sanitizeProfileName(%q) = %q; want %q", tc.in, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user