package config import ( "os" "path/filepath" "testing" ) func TestLoadMissingFileReturnsDefaults(t *testing.T) { s, err := Load(filepath.Join(t.TempDir(), "config.json")) if err != nil { t.Fatalf("a missing config must not be an error: %v", err) } if s != Default() { t.Errorf("expected defaults, got %+v", s) } if s.UpdateRepo != DefaultUpdateRepo { t.Errorf("update repo default = %q, want %q", s.UpdateRepo, DefaultUpdateRepo) } } // An absent field takes the default, but an explicitly empty one must stay // empty — that is how the update check is turned off. func TestExplicitEmptyUpdateRepoDisablesTheCheck(t *testing.T) { path := filepath.Join(t.TempDir(), "config.json") if err := os.WriteFile(path, []byte(`{"update_repo": ""}`), 0o644); err != nil { t.Fatal(err) } s, err := Load(path) if err != nil { t.Fatal(err) } if s.UpdateRepo != "" { t.Errorf("an explicit empty update_repo must be preserved, got %q", s.UpdateRepo) } // The rest of the file was absent, so it should still be defaulted. if s.ActivePollSeconds != Default().ActivePollSeconds { t.Errorf("unset fields should keep their defaults, got %+v", s) } } func TestLoadRepairsNonsense(t *testing.T) { path := filepath.Join(t.TempDir(), "config.json") if err := os.WriteFile(path, []byte(`{"mask_style":"wat","active_poll_seconds":0}`), 0o644); err != nil { t.Fatal(err) } s, err := Load(path) if err != nil { t.Fatal(err) } if s.MaskStyle != MaskPrefix { t.Errorf("an unknown mask style should fall back to prefix, got %q", s.MaskStyle) } if s.ActivePollSeconds != 30 { t.Errorf("a zero poll interval should be repaired, got %d", s.ActivePollSeconds) } } // A corrupt config must not stop the app from starting. func TestLoadCorruptFileReturnsDefaultsAndError(t *testing.T) { path := filepath.Join(t.TempDir(), "config.json") if err := os.WriteFile(path, []byte(`{not json`), 0o644); err != nil { t.Fatal(err) } s, err := Load(path) if err == nil { t.Error("expected an error for a corrupt config") } if s != Default() { t.Errorf("a corrupt config should still yield usable defaults, got %+v", s) } } func TestSaveRoundTrip(t *testing.T) { path := filepath.Join(t.TempDir(), "nested", "config.json") want := Default() want.MaskStyle = MaskDotted want.StartWithWindows = true want.UpdateRepo = "https://example.com/o/r" if err := want.Save(path); err != nil { t.Fatal(err) } got, err := Load(path) if err != nil { t.Fatal(err) } if got != want { t.Errorf("round trip changed the settings:\n got %+v\nwant %+v", got, want) } if !got.DottedMasks() { t.Error("DottedMasks should be true for MaskDotted") } }