v0.234.0: seed installed_images at startup, so the label appears on an app nobody touched
gates / gates (push) Successful in 13s
gates / gates (push) Successful in 13s
The operator looked at demo-felhom the morning after v0.233.0 and found OpenGist - up 15 hours, running exactly the catalog pin - showing no badge at all. v0.233.0 wrote the record only from the four bring-up paths, so an app nobody restarts carried no record indefinitely. On a quiet box that is every app, which is the box we most want to see. The known limitation WAS the feature not working. BackfillInstalledImages runs once at startup, beside BackfillDesiredState and before the boot reconciler. It READS containers: starts nothing, restarts nothing, writes no compose file. It never overwrites an existing record. And it REFUSES to seed a partial observation, which is why this is not a three-line loop: the badge reads a service-count mismatch as BEHIND, so seeding a degraded app from what is visible would render 'Frissites elerheto' over an app that is perfectly current. The bring-up paths may write a partial because they follow a successful up -d where a gap is real news; a backfill meets any state. Same data, two writers, two admission rules - deliberately. Also fixes a calendar bomb of mine: the render test hardcoded catalog_since and the string '46 napja', but the render path reads time.Now(), so it was green on the day it was written and red the next morning. Now derived. Filed as R-457 with six other candidate files named as unchecked, not accused. +5 tests (1724 -> 1729), 28 packages green. Red-proof of the partial guard run and reverted; the wiring and its ORDER pinned by an AST walk.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -175,11 +176,21 @@ func ubStacksData(st stacks.Stack) map[string]interface{} {
|
||||
// COMPANION RED-PROOF (run 2026-09-02): delete the {{template "meta_badge" (updateBadge …)}} line
|
||||
// from stacks.html and the "app list" sub-test fails; delete it from app_info.html and the "app page"
|
||||
// sub-test fails. Reverted.
|
||||
//
|
||||
// THE CLOCK, and why `catalog_since` is computed rather than written down: the templates call the
|
||||
// funcmap entry `updateBadge`, which uses time.Now() — the injected `badgeNow` reaches only the pure
|
||||
// tests. A hardcoded date plus a hardcoded age is therefore a test that passes on the day it is
|
||||
// written and FAILS THE NEXT MORNING, which is exactly what this one did (written 2026-09-02
|
||||
// asserting "46 napja", red on 2026-09-03). Derive the date from the same clock the code will read.
|
||||
func TestGroupD_BadgeRendersOnBothSurfaces(t *testing.T) {
|
||||
const behindDays = 46
|
||||
since := time.Now().UTC().AddDate(0, 0, -behindDays).Format("2006-01-02")
|
||||
wantBehind := fmt.Sprintf("Frissítés elérhető — %d napja", behindDays)
|
||||
|
||||
tpl := map[string]string{"web": "lscr.io/linuxserver/bookstack:26.05.2"}
|
||||
behind := ubStack(map[string]stacks.InstalledImage{"web": rec("lscr.io/linuxserver/bookstack:25.02.2")}, tpl, "2026-07-18")
|
||||
current := ubStack(map[string]stacks.InstalledImage{"web": rec(tpl["web"])}, tpl, "2026-07-18")
|
||||
legacy := ubStack(nil, tpl, "2026-07-18")
|
||||
behind := ubStack(map[string]stacks.InstalledImage{"web": rec("lscr.io/linuxserver/bookstack:25.02.2")}, tpl, since)
|
||||
current := ubStack(map[string]stacks.InstalledImage{"web": rec(tpl["web"])}, tpl, since)
|
||||
legacy := ubStack(nil, tpl, since)
|
||||
|
||||
for _, surface := range []struct {
|
||||
name string
|
||||
@@ -191,7 +202,7 @@ func TestGroupD_BadgeRendersOnBothSurfaces(t *testing.T) {
|
||||
} {
|
||||
t.Run(surface.name, func(t *testing.T) {
|
||||
h := renderBackupPage(t, surface.tmpl, surface.data(behind))
|
||||
if !strings.Contains(h, "Frissítés elérhető — 46 napja") {
|
||||
if !strings.Contains(h, wantBehind) {
|
||||
t.Errorf("the behind badge is missing from %s", surface.tmpl)
|
||||
}
|
||||
h = renderBackupPage(t, surface.tmpl, surface.data(current))
|
||||
|
||||
Reference in New Issue
Block a user