Files
felhom-controller/controller/internal/settings/notif_migration_test.go
T
admin 0cfcc42464 Placement hardening (F-3a-1..4) + enlarge-blocked delivery chain (Task 3a-fix, v0.134.1)
PlaceOffsiteRestore: live target via raw GetStackHDDPath not AppNamespaceRoot (F-3a-1a: no SSD
merge; undeployed refused), placement headroom gate (F-3a-1b), stat pre-pass over all placements
before any copy (F-3a-4: no partial writes), scratch removed on success/kept on failure (F-3a-2).
mapOffsiteRestorePaths refuses the namespace root itself (F-3a-3).
Delivery chain: DefaultEnabledEvents + GetNotificationPrefs append-if-absent migration + settings
checkbox + handler slice; paired with hub v0.55.0 allowlist (no customerMessages entry — raw
dynamic message survives). +8 tests; all 6 controller §10 red-proofs verified.
2026-07-15 07:54:29 +02:00

80 lines
2.3 KiB
Go

package settings
import (
"path/filepath"
"testing"
)
func contains(list []string, want string) bool {
for _, e := range list {
if e == want {
return true
}
}
return false
}
func count(list []string, want string) int {
n := 0
for _, e := range list {
if e == want {
n++
}
}
return n
}
// F2a: the new warning type is on by default for new customers.
func TestDefaultEnabledEvents_ContainsEnlargeBlocked(t *testing.T) {
if !contains(DefaultEnabledEvents, "offbox_enlarge_blocked") {
t.Error("DefaultEnabledEvents must contain offbox_enlarge_blocked (new customers get it)")
}
}
// F2b: an EXISTING customer's stored prefs (predating the type) gain it via append-if-absent —
// idempotent (two reads → one entry) and their OTHER choices are preserved.
func TestGetNotificationPrefs_MigratesExisting(t *testing.T) {
s, err := Load(filepath.Join(t.TempDir(), "settings.json"), discardLog())
if err != nil {
t.Fatal(err)
}
// A customer who kept only two events and never had the new one.
if err := s.SetNotificationPrefs(&NotificationPrefs{
Email: "c@example.com",
EnabledEvents: []string{"backup_failed", "disk_warning"},
CooldownHours: 6,
}); err != nil {
t.Fatal(err)
}
p1 := s.GetNotificationPrefs()
if !contains(p1.EnabledEvents, "offbox_enlarge_blocked") {
t.Error("existing prefs must gain offbox_enlarge_blocked (append-if-absent migration)")
}
if !contains(p1.EnabledEvents, "backup_failed") || !contains(p1.EnabledEvents, "disk_warning") {
t.Error("the customer's existing choices must be preserved")
}
// idempotent: a second read still has exactly ONE entry.
p2 := s.GetNotificationPrefs()
if c := count(p2.EnabledEvents, "offbox_enlarge_blocked"); c != 1 {
t.Errorf("migration must be idempotent, got %d entries", c)
}
}
// A customer who already has the type keeps exactly one (no duplication).
func TestGetNotificationPrefs_AlreadyPresentNoDuplicate(t *testing.T) {
s, err := Load(filepath.Join(t.TempDir(), "settings.json"), discardLog())
if err != nil {
t.Fatal(err)
}
if err := s.SetNotificationPrefs(&NotificationPrefs{
EnabledEvents: []string{"offbox_enlarge_blocked", "backup_failed"},
CooldownHours: 6,
}); err != nil {
t.Fatal(err)
}
if c := count(s.GetNotificationPrefs().EnabledEvents, "offbox_enlarge_blocked"); c != 1 {
t.Errorf("already-present type must not duplicate, got %d", c)
}
}