package settings import ( "io" "log" "path/filepath" "reflect" "testing" ) func loadTmp(t *testing.T) (*Settings, string) { t.Helper() p := filepath.Join(t.TempDir(), "settings.json") s, err := Load(p, log.New(io.Discard, "", 0)) if err != nil { t.Fatal(err) } return s, p } // Decision 50 (R-720). The CONSEQUENCE is asserted: after a fresh install on a box with off-site, the app is in // the list the off-site run reads (GetOffboxApps), and it survives a reload from disk. // COMPANION RED-PROOF: make DefaultOffboxOnForNewApp return (false, "") at the top → this test fails with // „the new app is not in the off-site run". func TestDecision50_NewAppIsOffsiteByDefault(t *testing.T) { s, p := loadTmp(t) if err := s.SetOffboxTarget(&OffboxTarget{Enabled: true, Host: "u1.your-storagebox.de", Port: 23, User: "u1", RepoPath: "/home/r"}); err != nil { t.Fatal(err) } on, why := s.DefaultOffboxOnForNewApp("bookstack") if !on { t.Fatalf("switched=false (%s)", why) } s2, err := Load(p, log.New(io.Discard, "", 0)) if err != nil { t.Fatal(err) } if got := s2.GetOffboxApps(); !reflect.DeepEqual(got, []string{"bookstack"}) { t.Fatalf("the new app is not in the off-site run after a reload: %v", got) } } // No off-site target → nothing is switched (a box without off-site keeps no phantom choice). func TestDecision50_NoTargetSwitchesNothing(t *testing.T) { for name, tgt := range map[string]*OffboxTarget{ "none": nil, "disabled": {Enabled: false, Host: "h"}, "no host": {Enabled: true}, } { s, _ := loadTmp(t) if tgt != nil { _ = s.SetOffboxTarget(tgt) } if on, _ := s.DefaultOffboxOnForNewApp("bookstack"); on { t.Fatalf("%s: switched an app on with no usable off-site target", name) } if len(s.GetOffboxApps()) != 0 || s.AppsWithoutOffbox([]string{"bookstack"}) != nil { t.Fatalf("%s: phantom off-site state", name) } } } // A household's earlier OFF survives a reinstall: an app removed WITHOUT deleting its backups keeps its record // (R-474), and the default never overrides a record. // COMPANION RED-PROOF: drop the „already has a backup choice" check → this test fails. func TestDecision50_EarlierChoiceIsKept(t *testing.T) { s, _ := loadTmp(t) _ = s.SetOffboxTarget(&OffboxTarget{Enabled: true, Host: "h"}) _ = s.SetAppOffbox("immich", false) // the household switched it off (e.g. too big) if on, _ := s.DefaultOffboxOnForNewApp("immich"); on { t.Fatal("the default overrode the household's own OFF") } if len(s.GetOffboxApps()) != 0 { t.Fatalf("immich is off-site against the household's choice: %v", s.GetOffboxApps()) } } // The one-press offer lists exactly the installed apps that are off. func TestDecision50_AppsWithoutOffbox(t *testing.T) { s, _ := loadTmp(t) _ = s.SetOffboxTarget(&OffboxTarget{Enabled: true, Host: "h"}) _ = s.SetAppOffbox("bookstack", true) got := s.AppsWithoutOffbox([]string{"actualbudget", "bookstack", "vikunja"}) if !reflect.DeepEqual(got, []string{"actualbudget", "vikunja"}) { t.Fatalf("got %v", got) } }