mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-23 23:29:08 +02:00
AGENTS.md asks for a context message on comparison and boolean assertions, and four of the ones added with this test had none, so a failure would have read as a bare Empty/Equal with no hint of which step of the round trip broke. Reported by cubic on the PR.
98 lines
4.2 KiB
Go
98 lines
4.2 KiB
Go
package mobile
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/netbirdio/netbird/client/internal/profilemanager"
|
|
)
|
|
|
|
// loadAsTheMobileSDKsDo replays what the iOS SDK does with a stored profile:
|
|
// read the config, serialize it, and load it back. Client.SetConfigFromJSON
|
|
// stores that document for tvOS, Auth.SetConfigFromJSON authenticates with it,
|
|
// and copyConfig round-trips a Config through the same pair to take an
|
|
// in-memory copy before applying the MDM overlay.
|
|
func loadAsTheMobileSDKsDo(t *testing.T, configPath string) *profilemanager.Config {
|
|
t.Helper()
|
|
|
|
stored, err := profilemanager.GetExistingConfig(configPath)
|
|
require.NoError(t, err, "read the stored profile")
|
|
|
|
document, err := profilemanager.ConfigToJSON(stored)
|
|
require.NoError(t, err, "serialize the stored profile")
|
|
|
|
reloaded, err := profilemanager.ConfigFromJSON(document)
|
|
require.NoError(t, err, "load the profile back")
|
|
return reloaded
|
|
}
|
|
|
|
// A profile survives the whole round its user puts it through: created, logged
|
|
// out, loaded again, and switched away from and back.
|
|
//
|
|
// Logout is the step that makes this worth asserting. It clears the peer's
|
|
// keys in place so the next login registers a new peer rather than bringing
|
|
// the old one back, which leaves a profile that legitimately carries no
|
|
// identity — and both mobile SDKs go on loading that profile through the
|
|
// serialized form. A load that refused it, or a creation that never wrote an
|
|
// identity in the first place, breaks logout and profile switching on iOS and
|
|
// Android without any of it being visible from the desktop client.
|
|
func TestProfileSurvivesLogoutAndReload(t *testing.T) {
|
|
pm := newTestProfileManager(t)
|
|
|
|
created, err := pm.AddProfile("work")
|
|
require.NoError(t, err)
|
|
require.NoError(t, pm.SwitchProfile(profilemanager.DefaultProfileName))
|
|
|
|
// Created: the profile carries the identity it will connect with.
|
|
require.NotEmpty(t, privateKeyOf(t, pm, created.ID), "a new profile was written with no identity")
|
|
|
|
configPath, err := pm.GetConfigPath(created.ID)
|
|
require.NoError(t, err)
|
|
|
|
before := loadAsTheMobileSDKsDo(t, configPath)
|
|
require.NotEmpty(t, before.PrivateKey)
|
|
managementURL := before.ManagementURL.String()
|
|
|
|
// Logged out: the identity is gone, on purpose.
|
|
require.NoError(t, pm.LogoutProfile(created.ID))
|
|
require.Empty(t, privateKeyOf(t, pm, created.ID), "logout left the peer's key behind")
|
|
|
|
// Loaded again: the profile is still readable, and loading it neither
|
|
// fails nor mints a key that nothing would write down.
|
|
after := loadAsTheMobileSDKsDo(t, configPath)
|
|
assert.Empty(t, after.PrivateKey, "loading a logged-out profile minted a key nothing will persist")
|
|
assert.Empty(t, after.SSHKey, "loading a logged-out profile minted an SSH key")
|
|
assert.Equal(t, managementURL, after.ManagementURL.String(), "the rest of the profile did not survive the logout")
|
|
|
|
// Switched away from and back: still the same profile, still loadable.
|
|
require.NoError(t, pm.SwitchProfile(created.ID))
|
|
require.NoError(t, pm.SwitchProfile(profilemanager.DefaultProfileName))
|
|
require.NoError(t, pm.SwitchProfile(created.ID))
|
|
|
|
active, err := pm.GetActiveProfile()
|
|
require.NoError(t, err)
|
|
assert.Equal(t, created.ID, active.ID, "the profile switched to is not the active one")
|
|
|
|
assert.Equal(t, managementURL, loadAsTheMobileSDKsDo(t, configPath).ManagementURL.String(),
|
|
"the profile did not survive the round of switches")
|
|
}
|
|
|
|
// The profile the SDKs fall back to gets the same treatment, since it is the
|
|
// one a mobile client without an explicit profile runs on.
|
|
func TestDefaultProfileSurvivesLogoutAndReload(t *testing.T) {
|
|
pm := newTestProfileManager(t)
|
|
require.NoError(t, pm.SwitchProfile(profilemanager.DefaultProfileName))
|
|
|
|
configPath, err := pm.GetConfigPath(profilemanager.DefaultProfileName)
|
|
require.NoError(t, err)
|
|
require.NotEmpty(t, loadAsTheMobileSDKsDo(t, configPath).PrivateKey)
|
|
|
|
require.NoError(t, pm.LogoutProfile(profilemanager.DefaultProfileName))
|
|
|
|
reloaded := loadAsTheMobileSDKsDo(t, configPath)
|
|
assert.Empty(t, reloaded.PrivateKey, "loading the logged-out default profile minted a key")
|
|
assert.NotNil(t, reloaded.ManagementURL, "the profile lost its management URL")
|
|
}
|