Files
felhom-controller/controller/internal/web/report_trigger_seam_test.go
T
admin fe9266f53f feat(report): v0.139.0 — immediate out-of-cycle hub report on user actions (Direction 1)
New report.Trigger (buffered-1 chan + worker; quiet 2s, min spacing 15s,
trailing-edge coalescing) generalizes the v0.70.0 geo out-of-band push.
One canonical fire closure in main.go; wired: geo save/sync + app
deploy/remove/delete (api reportPushNow), escrow recovery-code claim,
notification-prefs save, app-email toggle, offsite config + per-app
toggle, customer claim (web SetReportTrigger seam, nil-safe, fired only
after a successful local commit). 15-min hub-report cycle untouched as
the reconciliation backbone; hub.enabled=false stays a strict no-op.
Tests: trigger engine (2 red-proofs), seam fires-after-commit-only,
nil-seam no-ops.
2026-07-16 19:31:19 +02:00

57 lines
2.0 KiB
Go

package web
import (
"io"
"log"
"net/http/httptest"
"net/url"
"path/filepath"
"strings"
"testing"
"gitea.dooplex.hu/admin/felhom-controller/internal/settings"
)
// Group D (Scenario D): with the seam unset (hub reporting off / nil trigger), the helper
// is a strict nil-safe no-op — a handler calling it must never panic.
func TestReportTriggerNow_NilSeamIsNoOp(t *testing.T) {
s := &Server{}
s.reportTriggerNow() // must not panic with reportTriggerFn == nil
}
// The wired seam fires on a SUCCESSFUL local commit and does NOT fire on the error path
// (§Part 3: after the successful local commit — never before, never on error). Exercised
// through a real handler (offbox per-app toggle) so deleting the call site fails this test.
func TestReportTriggerNow_FiresAfterSuccessfulCommitOnly(t *testing.T) {
tmp := t.TempDir()
lg := log.New(io.Discard, "", 0)
sett, err := settings.Load(filepath.Join(tmp, "settings.json"), lg)
if err != nil {
t.Fatal(err)
}
fired := 0
s := &Server{settings: sett, logger: lg}
s.SetReportTrigger(func() { fired++ })
// Error path: missing app param → refused, trigger must NOT fire.
w := httptest.NewRecorder()
req := httptest.NewRequest("POST", "/backup/offbox/toggle", strings.NewReader(url.Values{"enabled": {"on"}}.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
s.offboxToggleHandler(w, req)
if fired != 0 {
t.Fatalf("trigger fired %d time(s) on the refused save, want 0 (never on the error path)", fired)
}
// Success path: the setting commits → the trigger fires exactly once.
w2 := httptest.NewRecorder()
req2 := httptest.NewRequest("POST", "/backup/offbox/toggle", strings.NewReader(url.Values{"app": {"immich"}, "enabled": {"on"}}.Encode()))
req2.Header.Set("Content-Type", "application/x-www-form-urlencoded")
s.offboxToggleHandler(w2, req2)
if !sett.IsAppOffbox("immich") {
t.Fatal("toggle did not commit — precondition for the trigger assertion")
}
if fired != 1 {
t.Fatalf("trigger fired %d time(s) after the successful save, want exactly 1", fired)
}
}