package hub import ( "context" "errors" "testing" "time" ) // R-998: the power-off path waits on SetReportedHook, so the hook must fire only for a report the hub // ACCEPTED — a failed push must not let the box power off believing the hub knows. func TestLoop_ReportedHookOnlyAfterAcceptedReport(t *testing.T) { var cn, rn int32 rep := &HostReport{DeliberateOff: &DeliberateOff{RequestedAt: "2026-10-13T18:00:00Z"}} loop := NewLoop(&fakeCollector{report: rep, n: &cn}, &fakeReporter{env: &ControlEnvelope{}, errSeq: []error{errors.New("hub 5xx")}, n: &rn}, 900*time.Second, quietLogger()) var seen []*HostReport loop.SetReportedHook(func(r *HostReport) { seen = append(seen, r) }) loop.cycle(context.Background(), 900*time.Second) // the push fails if len(seen) != 0 { t.Fatalf("hook fired for a refused report: %d", len(seen)) } loop.cycle(context.Background(), 900*time.Second) // the push is accepted if len(seen) != 1 || seen[0].DeliberateOff == nil || seen[0].DeliberateOff.RequestedAt != "2026-10-13T18:00:00Z" { t.Fatalf("hook after an accepted report = %+v", seen) } }