package web import ( "context" "net/http/httptest" "strings" "testing" "gitea.dooplex.hu/admin/felhom-controller/internal/agentapi" "gitea.dooplex.hu/admin/felhom-controller/internal/settings" ) // R-112 — SCENARIO E: THE SEAM. This is the test whose absence let E-2 ship. // // The endpoint was byte-correct the whole time. `resolveBackupTargetState` produced the right state, // `degradedMessageFor` produced the right Hungarian, and v0.185.1 even added a test proving the route // dispatched. None of that was ever reachable by a customer, because NOTHING fetched or rendered it: // the controller's templates fetch 18 distinct /api/storage/* endpoints and backup-target was one of // only two with zero references (felhom.eu audits/E2D-fresh-vm-2026-07-29.md §5.1). // // So these tests deliberately do NOT call the resolver and assert its string — that proves the // resolver, which was never broken. They drive `backupsHandler` over httptest and assert the RENDERED // HTML, travelling handler → backupTargetView → resolveBackupTargetState → degradedMessageFor → // the production "backups" template. Delete the one line in backupsHandler that sets // data["BackupTarget"] and every assertion below fails, which is precisely the class of regression // that shipped five times in this project. // renderBackupsPage drives the REAL page handler and returns the HTML a browser would receive. func renderBackupsPage(t *testing.T, primary string, disks []agentapi.DiskInfo, registerPath string) string { t.Helper() s := absentHarness(t, primary, disks, registerPath) s.loadTemplates() rr := httptest.NewRecorder() s.backupsHandler(rr, httptest.NewRequest("GET", "/backups", nil)) if rr.Code != 200 { t.Fatalf("backups page returned %d, want 200", rr.Code) } return rr.Body.String() } // C — configured, drive absent: the truthful copy reaches the page, and no offer does. func TestBackupsPageRendersTheAbsentDriveCopy(t *testing.T) { html := renderBackupsPage(t, "felhom-backup", []agentapi.DiskInfo{theVanishedDrive}, "/mnt/felhom-drives/mentes2") if !strings.Contains(html, backupTargetAbsentText) { t.Error("the absent-drive copy never reached the page — the customer is told nothing while " + "their backup drive is missing (R-112: the state had no consumer at all)") } if strings.Contains(html, backupTargetDegradedText) { t.Error("the page shows the SYSTEM-DISK copy for an absent configured drive (R-114)") } // Assert the CONTROL's markup, not the bare id: the page script always contains // getElementById('backup-target-assign'), so a substring match on the id alone matches the // script and reports a control that is not there. (This test caught exactly that on itself.) if strings.Contains(html, `id="backup-target-assign"`) { t.Error("an offer control rendered while the configured target is absent — the remedy is to " + "reconnect that drive, not to pick another") } if strings.Contains(html, `id="backup-target-offer"`) { t.Error("the offer block rendered while the configured target is absent") } } // A — never configured: the copy AND the offer control both render, and the control carries the // drive's path so accepting it can only ever assign that one. func TestBackupsPageRendersTheOfferWhenNeverConfigured(t *testing.T) { html := renderBackupsPage(t, builtinLocalTarget, []agentapi.DiskInfo{{ Name: "hdd1", MountPath: "/mnt/hdd1", GuestPath: "/mnt/felhom-drives/hdd1", Role: "user-data", }}, "/mnt/felhom-drives/hdd1") if !strings.Contains(html, backupTargetDegradedText) { t.Error("the degraded copy never reached the page") } if !strings.Contains(html, backupTargetOfferText) { t.Error("the offer copy never reached the page") } if !strings.Contains(html, `id="backup-target-assign"`) { t.Error("no offer control rendered — the customer is told to attach a drive but given no way " + "to assign the one they already have") } if !strings.Contains(html, `data-path="/mnt/felhom-drives/hdd1"`) { t.Error("the offer control does not carry the offered drive's path") } // It is an OFFER: it must not submit itself. if strings.Contains(html, "backup-target-assign.click()") || strings.Contains(html, "autosubmit") { t.Error("the offer control auto-submits — declining must be possible by doing nothing") } } // B — healthy renders NOTHING. Assert the absence of all three strings, not the absence of an error. func TestBackupsPageRendersNothingWhenHealthy(t *testing.T) { html := renderBackupsPage(t, "felhom-backup", []agentapi.DiskInfo{{ Name: "mentes2", MountPath: "/mnt/mentes2", GuestPath: "/mnt/felhom-drives/mentes2", Role: "user-data", BackupTarget: true, }}, "/mnt/felhom-drives/mentes2") assertNoBackupTargetCopy(t, html, "a HEALTHY box grew a banner — a working configuration must "+ "look normal, or every dashboard carries a permanent notice and warnings stop being read") } // D — unknown renders NOTHING. Not being able to ask the agent is not evidence of degradation. func TestBackupsPageRendersNothingWhenAgentUnreachable(t *testing.T) { s := testServer(t) if err := s.settings.AddStoragePath(settings.StoragePath{Path: "/mnt/felhom-drives/hdd1"}); err != nil { t.Fatalf("register: %v", err) } // No tiersFn/disksFn seams and no configured endpoint → agentClient() fails → Known:false. s.loadTemplates() rr := httptest.NewRecorder() s.backupsHandler(rr, httptest.NewRequest("GET", "/backups", nil)) assertNoBackupTargetCopy(t, rr.Body.String(), "an UNREACHABLE agent produced a customer warning — "+ "absence of an answer is not evidence of degradation (R-88 Part 2's mistake)") } func assertNoBackupTargetCopy(t *testing.T, html, why string) { t.Helper() for _, s := range []struct{ frag, name string }{ {backupTargetDegradedText, "the system-disk copy"}, {backupTargetAbsentText, "the absent-drive copy"}, {backupTargetOfferText, "the offer copy"}, } { if strings.Contains(html, s.frag) { t.Errorf("%s rendered: %s", s.name, why) } } if strings.Contains(html, `id="backup-target-alert"`) { t.Errorf("the banner element rendered: %s", why) } } // The view is nil — not an empty struct — in the two silent states, so a template typo cannot // accidentally decorate a working box with an empty alert box. func TestBackupTargetViewIsNilWhenNothingShouldRender(t *testing.T) { healthy := absentHarness(t, "felhom-backup", []agentapi.DiskInfo{{ MountPath: "/mnt/mentes2", GuestPath: "/mnt/felhom-drives/mentes2", Role: "user-data", BackupTarget: true, }}, "") if v := healthy.backupTargetView(context.Background()); v != nil { t.Errorf("healthy returned a non-nil view %+v — nil is what makes the template render nothing", v) } unknown := testServer(t) if v := unknown.backupTargetView(context.Background()); v != nil { t.Errorf("unknown returned a non-nil view %+v", v) } }