package web import ( "testing" "time" "gitea.dooplex.hu/admin/felhom-controller/internal/stacks" ) // v0.279.0 (decision 45) — when the default login is IN EFFECT, and the sentence the household reads. // COMPANION RED-PROOF: make defaultLoginInEffect ignore after_install (the pre-0.279.0 page: the default // card always shown) → the "replaced" rows fail — the page would send the household to a dead login. // R-710 RED-PROOF (v0.280.0): return false for an absent record again (the 0.279.0 shape) → the two "R-710: // installed long before / no install time" rows fail — measured live on demo-hp's bookstack. func TestKnownLogin_InEffectOnlyUntilReplaced(t *testing.T) { withCreds := &stacks.Metadata{AppInfo: stacks.AppInfo{DefaultCreds: "admin / admin"}} withFix := &stacks.Metadata{AppInfo: stacks.AppInfo{DefaultCreds: "admin@claper.co / claper"}, AfterInstall: &stacks.AfterInstallCommand{Service: "claper", Command: []string{"x"}, Success: "OK"}} ok := &stacks.AppConfig{AfterInstall: &stacks.AfterInstallRecord{OK: true}} failed := &stacks.AppConfig{AfterInstall: &stacks.AfterInstallRecord{OK: false}} now := time.Date(2026, 9, 29, 8, 0, 0, 0, time.UTC) knownLoginNow = func() time.Time { return now } t.Cleanup(func() { knownLoginNow = time.Now }) recent, old := now.Add(-5*time.Minute).Format(time.RFC3339), now.Add(-48*time.Hour).Format(time.RFC3339) for _, c := range []struct { name string meta *stacks.Metadata cfg *stacks.AppConfig installed bool want bool }{ {"no default login", &stacks.Metadata{}, nil, false, false}, {"default, nothing replaces it: before install", withCreds, nil, false, true}, {"default, nothing replaces it: installed", withCreds, &stacks.AppConfig{}, true, true}, {"after_install declared: before install", withFix, nil, false, false}, {"after_install succeeded", withFix, ok, true, false}, {"after_install not run yet (installed minutes ago)", withFix, &stacks.AppConfig{DeployedAt: recent}, true, false}, {"after_install FAILED", withFix, failed, true, true}, // R-710: installed BEFORE the template gained its after_install — the command never runs for it. {"R-710: installed long before the after_install existed", withFix, &stacks.AppConfig{DeployedAt: old}, true, true}, {"R-710: no install time on record", withFix, &stacks.AppConfig{}, true, true}, {"R-710: the household changed it by hand", withCreds, &stacks.AppConfig{DeployedAt: old, DefaultLogin: &stacks.DefaultLoginRecord{ChangedAt: "t", By: "household"}}, true, false}, {"R-710: ...and on an app with an after_install", withFix, &stacks.AppConfig{DeployedAt: old, DefaultLogin: &stacks.DefaultLoginRecord{ChangedAt: "t", By: "household"}}, true, false}, } { if got := defaultLoginInEffect(c.meta, c.cfg, c.installed); got != c.want { t.Errorf("%s: in effect = %v, want %v", c.name, got, c.want) } } s := testServer(t) if got, want := s.knownLoginLine("hu", withCreds, nil, false), "Ez az alkalmazás egy ismert, közös jelszóval indul: admin / admin. Telepítés után azonnal változtasd meg."; got != want { t.Fatalf("hu sentence %q, want %q", got, want) } if got, want := s.knownLoginLine("en", withFix, failed, true), "This app starts with a known, shared password: admin@claper.co / claper. Change it right after the install."; got != want { t.Fatalf("en sentence %q, want %q", got, want) } } // The card's "I changed it" press is on the installed app's page while the default is named, and the card goes // once the household pressed it (R-710). defaultLoginReplaced is what hides it. func TestKnownLogin_ReplacedByTheHouseholdHidesTheCard(t *testing.T) { meta := &stacks.Metadata{AppInfo: stacks.AppInfo{DefaultCreds: "admin / admin123"}} if defaultLoginReplaced(meta, &stacks.AppConfig{DeployedAt: "2020-01-01T00:00:00Z"}, true) { t.Fatal("nothing replaced the default, but the card would hide") } if !defaultLoginReplaced(meta, &stacks.AppConfig{DefaultLogin: &stacks.DefaultLoginRecord{ChangedAt: "t", By: "household"}}, true) { t.Fatal("the household changed it, but the card stays") } if defaultLoginReplaced(meta, &stacks.AppConfig{DefaultLogin: &stacks.DefaultLoginRecord{}}, false) { t.Fatal("the install dialog is never 'replaced'") } }