package settings import ( "io" "log" "path/filepath" "testing" ) // R-922: the clear marker's rule as a table — set only by a deliberate clear, kept while the address stays // empty, dropped by a new address — and it survives a reload from disk (a clear the hub missed is pushed // again by the next start: SyncOnStartup). func TestR922_ClearedByRule(t *testing.T) { for _, tc := range []struct { name string stored *NotificationPrefs newEmail string want bool }{ {"never configured, empty save", &NotificationPrefs{}, "", false}, {"nil stored prefs", nil, "", false}, {"had an address, empty save = clear", &NotificationPrefs{Email: "a@example.hu"}, "", true}, {"already cleared, empty save keeps it", &NotificationPrefs{EmailCleared: true}, "", true}, {"cleared, new address drops it", &NotificationPrefs{EmailCleared: true}, "b@example.hu", false}, {"address changed", &NotificationPrefs{Email: "a@example.hu"}, "b@example.hu", false}, } { if got := tc.stored.ClearedBy(tc.newEmail); got != tc.want { t.Errorf("%s: ClearedBy(%q) = %v, want %v", tc.name, tc.newEmail, got, tc.want) } } } func TestR922_MarkerPersistsAndDrivesStartupSync(t *testing.T) { path := filepath.Join(t.TempDir(), "settings.json") lg := log.New(io.Discard, "", 0) s, err := Load(path, lg) if err != nil { t.Fatal(err) } if s.GetNotificationPrefs().SyncOnStartup() { t.Fatal("a never-configured box would push on startup") } if err := s.SetNotificationPrefs(&NotificationPrefs{EmailCleared: true, CooldownHours: 6}); err != nil { t.Fatal(err) } s2, err := Load(path, lg) if err != nil { t.Fatal(err) } p := s2.GetNotificationPrefs() if !p.EmailCleared { t.Fatal("the clear marker did not survive a reload") } if !p.SyncOnStartup() { t.Fatal("a cleared box does not push its clear on startup — a clear the hub missed would never reach it") } }