package web import ( "strings" "testing" "time" "gitea.dooplex.hu/admin/felhom-controller/internal/stacks" ) // R-677 (v0.272.0) — a floating tag re-tested at a new digest: the badge's age must count from when that // digest was TESTED (today), not from the template's catalog_since (the tag's date, 3 days ago). Both badge // producers — the Hungarian literal one and the per-language one — are asserted, so they cannot drift. // // COMPANION RED-PROOF (REPORT.md): make stacks.BehindSinceAge return CatalogSinceAge always — this test fails // at "the badge dates the TAG, not the tested digest". func TestR677_DigestOnlyAgeFromTestedAt(t *testing.T) { now := time.Date(2026, 9, 25, 10, 0, 0, 0, time.UTC) dA := "sha256:" + strings.Repeat("a", 64) dB := "sha256:" + strings.Repeat("b", 64) st := stacks.Stack{Name: "redisapp", Deployed: true, Meta: stacks.Metadata{CatalogSince: "2026-09-22"}, CatalogImages: map[string]string{"web": "redis:7-alpine"}, CatalogDigests: map[string]string{"web": dB}, CatalogTestedAt: now.Add(-30 * time.Minute), AppConfig: &stacks.AppConfig{InstalledImages: map[string]stacks.InstalledImage{ "web": {Ref: "redis:7-alpine", Digest: dA, At: "2026-09-21T00:00:00Z"}}}} if stacks.CatalogOrder(st) != stacks.UpdateOrderBehind { t.Fatal("fixture must read Behind (a newer tested digest)") } if d, ok := stacks.BehindSinceAge(st, now); !ok || d != 0 { t.Fatalf("the badge dates the TAG, not the tested digest: got %d days (ok=%v), want 0", d, ok) } if b := updateBadgeAt(st, now); b == nil || !strings.HasSuffix(b.Label, "— ma") { t.Fatalf("Hungarian producer: %+v, want „… — ma\"", b) } // the per-language producer, on the real clock live := st live.CatalogTestedAt = time.Now().UTC().Add(-time.Minute) live.Meta.CatalogSince = time.Now().UTC().AddDate(0, 0, -3).Format("2006-01-02") en := testPageServer(t).localeFuncs("en")["updateBadge"].(func(stacks.Stack) *MetaBadge)(live) if en == nil || !strings.HasSuffix(en.Label, "today") { t.Fatalf("English producer: %+v, want \"… — today\"", en) } // a REAL version move keeps the template's date mv := st mv.CatalogImages = map[string]string{"web": "redis:7.4-alpine"} if d, ok := stacks.BehindSinceAge(mv, now); !ok || d != 3 { t.Fatalf("a version move must keep catalog_since's age (3), got %d (ok=%v)", d, ok) } }