feat: add portable directory safeguards
This commit is contained in:
@@ -23,7 +23,7 @@ func TestStoreRoundTripAndCreatesPrivateFile(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got.Version != currentVersion || got.Settings != want.Settings || len(got.Instances) != 1 || got.Instances[0].ID != "a" {
|
||||
if got.Version != currentVersion || got.Settings.ChromePath != want.Settings.ChromePath || got.Settings.RemoteDebugStartPort != want.Settings.RemoteDebugStartPort || got.Settings.DefaultDirSource != DirectorySourcePortable || got.Settings.LogDirSource != DirectorySourcePortable || len(got.Instances) != 1 || got.Instances[0].ID != "a" {
|
||||
t.Fatalf("round trip mismatch: %#v", got)
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ func TestStoreAddsDefaultRemoteDebugPortForExistingConfig(t *testing.T) {
|
||||
|
||||
func TestStoreAssignsPreferredPortsForLegacyInstancesInStableOrder(t *testing.T) {
|
||||
path := filepath.Join(t.TempDir(), "config.json")
|
||||
contents := `{"version":1,"settings":{"remoteDebugStartPort":9777},"instances":[{"id":"first","launch":{"Kind":"chrome","UserDataDir":"C:\\profiles\\first"}},{"id":"second","launch":{"Kind":"edge","UserDataDir":"C:\\profiles\\second"}}]}`
|
||||
contents := `{"version":1,"settings":{"remoteDebugStartPort":9777},"instances":[{"id":"first","name":"第一实例","launch":{"Kind":"chrome","UserDataDir":"C:\\profiles\\first"}},{"id":"second","name":"第二实例","launch":{"Kind":"edge","UserDataDir":"C:\\profiles\\second"}}]}`
|
||||
if err := os.WriteFile(path, []byte(contents), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -75,13 +75,13 @@ func TestStoreRejectsInvalidOrDuplicatePreferredPorts(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
duplicate := File{Instances: []Instance{
|
||||
{ID: "one", PreferredRemoteDebugPort: 9666},
|
||||
{ID: "two", PreferredRemoteDebugPort: 9666},
|
||||
{ID: "one", Name: "一号", PreferredRemoteDebugPort: 9666},
|
||||
{ID: "two", Name: "二号", PreferredRemoteDebugPort: 9666},
|
||||
}}
|
||||
if err := store.Save(duplicate); err == nil {
|
||||
t.Fatal("duplicate preferred port was accepted")
|
||||
}
|
||||
invalid := File{Instances: []Instance{{ID: "one", PreferredRemoteDebugPort: domain.MinRemoteDebugPort - 1}}}
|
||||
invalid := File{Instances: []Instance{{ID: "one", Name: "一号", PreferredRemoteDebugPort: domain.MinRemoteDebugPort - 1}}}
|
||||
if err := store.Save(invalid); err == nil {
|
||||
t.Fatal("invalid preferred port was accepted")
|
||||
}
|
||||
@@ -134,6 +134,51 @@ func TestDefaultInstanceUserDataDirectoryUsesExecutableDirectoryAndStableID(t *t
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreMigratesHistoricalDirectoriesToPortableDefaults(t *testing.T) {
|
||||
base := filepath.Join(t.TempDir(), "published")
|
||||
store, err := New(filepath.Join(base, "config.json"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := store.Save(File{Settings: Settings{DefaultDir: legacyDefaultUserDataDir, LogDir: legacyLogDir}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got, err := store.Load()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got.Settings.DefaultDir != filepath.Join(base, "user_data_dirs") || got.Settings.LogDir != filepath.Join(base, "logs") || got.Settings.DefaultDirSource != DirectorySourcePortable || got.Settings.LogDirSource != DirectorySourcePortable {
|
||||
t.Fatalf("portable migration = %#v", got.Settings)
|
||||
}
|
||||
|
||||
custom := filepath.Join(t.TempDir(), "custom-profiles")
|
||||
got.Settings.DefaultDir = custom
|
||||
got.Settings.DefaultDirSource = DirectorySourceCustom
|
||||
if err := store.Save(got); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
reloaded, err := store.Load()
|
||||
if err != nil || reloaded.Settings.DefaultDir != custom || reloaded.Settings.DefaultDirSource != DirectorySourceCustom {
|
||||
t.Fatalf("custom directory = %#v, error = %v", reloaded.Settings, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestStoreRejectsInvalidAndDuplicateInstanceNames(t *testing.T) {
|
||||
store, err := New(filepath.Join(t.TempDir(), "config.json"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, instances := range [][]Instance{
|
||||
{{ID: "one", Name: "审核"}, {ID: "two", Name: "审核"}},
|
||||
{{ID: "one", Name: "Audit"}, {ID: "two", Name: "aUDIT"}},
|
||||
{{ID: "one", Name: "CON"}},
|
||||
} {
|
||||
if err := store.Save(File{Instances: instances}); err == nil {
|
||||
t.Fatalf("unsafe instance configuration persisted: %#v", instances)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenDefaultAtMigratesValidLegacyWithoutRemovingIt(t *testing.T) {
|
||||
directory := t.TempDir()
|
||||
target := filepath.Join(directory, "portable", "config.json")
|
||||
@@ -176,7 +221,7 @@ func TestOpenDefaultAtPrefersExistingTargetOverLegacy(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := targetStore.Save(File{Instances: []Instance{{ID: "target", PreferredRemoteDebugPort: 9666}}}); err != nil {
|
||||
if err := targetStore.Save(File{Instances: []Instance{{ID: "target", Name: "目标实例", PreferredRemoteDebugPort: 9666}}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(legacy), 0o700); err != nil {
|
||||
@@ -241,7 +286,7 @@ func TestOpenDefaultAtRejectsUncreatableTargetWithoutTouchingLegacy(t *testing.T
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := legacyStore.Save(File{Instances: []Instance{{ID: "legacy", PreferredRemoteDebugPort: 9666}}}); err != nil {
|
||||
if err := legacyStore.Save(File{Instances: []Instance{{ID: "legacy", Name: "旧实例", PreferredRemoteDebugPort: 9666}}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := openDefaultAt(target, legacy); !errors.Is(err, ErrDefaultConfigUnavailable) {
|
||||
|
||||
Reference in New Issue
Block a user