package web import ( "strings" "testing" "time" "gitea.dooplex.hu/admin/felhom-hub/internal/monitor" "gitea.dooplex.hu/admin/felhom-hub/internal/store" ) const gib = int64(1) << 30 // Not configured (no HETZNER_TOKEN) → honest "not configured", never an error or fake zeros. // (Uses renderOffsite from offsite_test.go — the real handler via httptest.) func TestOffsiteBoxPanel_NotConfigured(t *testing.T) { s, _ := newRenderServer(t) // s.offsiteBox left nil body := renderOffsite(t, s) if !strings.Contains(body, "Offsite pool metrics not configured") { t.Fatalf("unconfigured panel must say 'not configured':\n%s", body) } if strings.Contains(body, "0.0 GB") { t.Fatal("unconfigured panel must not render fake zeros") } } // With data + per-customer rows: the panel renders capacity/fill/ratio; a shared customer with a report // shows usage, a customer with NO report shows 'no usage reported yet' (never an asserted 0 GB). func TestOffsiteBoxPanel_WithData(t *testing.T) { s, st := newRenderServer(t) s.SetOffsiteBox(func() (monitor.BoxSnapshot, bool) { return monitor.BoxSnapshot{ CapacityBytes: 1 << 40, UsedBytes: 300 * gib, DataBytes: 300 * gib, FillPercent: 27, FillBand: "ok", SumQuotaGB: 1200, Ratio: 1.17, OversubBand: "ok", BoxType: "bx11", FetchedAt: time.Now().UTC(), }, true }) // "acme": shared, enabled, 500 GB, WITH a report (200 GiB used). "newbie": shared, enabled, no report. saveCfg(t, st, "acme", `{"offsite":{"enabled":true,"type":"shared","quota_gb":500}}`) saveCfg(t, st, "newbie", `{"offsite":{"enabled":true,"type":"shared","quota_gb":300}}`) if err := st.SaveReport("acme", []byte(`{"customer_id":"acme","offsite":{"enabled":true,"repo_size_bytes":`+itoa(200*gib)+`}}`)); err != nil { t.Fatal(err) } body := renderOffsite(t, s) for _, want := range []string{"Offsite pool box", "1.00 TB", "1.17×", "acme", "newbie", "no usage reported yet"} { if !strings.Contains(body, want) { t.Fatalf("panel missing %q:\n%s", want, body) } } // The RESTIC panel is configured — its specific not-configured message must be absent. (The PBS DR // panel legitimately shows its own "not configured" here since s.pbsdrBox is unset.) if strings.Contains(body, "Offsite pool metrics not configured") { t.Fatal("a configured restic panel must not show the not-configured message") } } func saveCfg(t *testing.T, st *store.Store, id, cfgJSON string) { t.Helper() if err := st.SaveCustomerConfig(&store.CustomerConfig{CustomerID: id, CustomerName: id, APIKey: "k-" + id, RetrievalPassword: "p", ConfigJSON: cfgJSON}); err != nil { t.Fatalf("save config %s: %v", id, err) } } // itoa avoids importing strconv just for the report body. func itoa(v int64) string { if v == 0 { return "0" } neg := v < 0 if neg { v = -v } var b [20]byte i := len(b) for v > 0 { i-- b[i] = byte('0' + v%10) v /= 10 } if neg { i-- b[i] = '-' } return string(b[i:]) }