Files
felhom.eu/hub/internal/notify/r1150_operator_only_test.go
T
admin 5121536f10 hub v0.159.0: a refused whole-guest backup has its own alarm (R-1150); a reinstall re-issues the claim code and the off-site login when the old host is stale or off (R-1154)
R-1150: the agent's localapi:backup-cadence-cap is a separate per-host state in
HostCapabilityChecker: alone it raises whole_guest_backup_refused (warning, plain text,
agent reason in details) and whole_guest_backup_refusal_cleared (info); other critical
caps keep agent_capability_degraded/_recovered unchanged. New types operator-only and
hub-origin only (not in allowedEventTypes: the suspected controller must not post them).
agent_capability_degraded/_recovered join operatorOnlyEvents (the checker's "never the
customer" claim was configuration only).

R-1154: handleHostEnroll's reuse path re-issues (claim code + off-site login) when no
controller wait is open and either deliberate_off_at is held or both the host report and
the controller report are older than alerting.stale_threshold (wired from main); once per
silence (host_reenroll_reissued record, also written at mint); a live box gets nothing
re-issued and the skip is recorded (host_reenroll_not_reissued). 05 section 8 [DESIGN].

Tests red-proved; go build/vet/test green.
2026-10-19 03:18:34 +02:00

44 lines
1.9 KiB
Go

package notify
import "testing"
// R-1150 (v0.159.0) — the refused whole-guest backup pair and the agent's capability pair never reach a
// household, under the configuration that would break it: the customer HAS the type in enabled_events and
// HAS an e-mail. The operator still gets the warning. (The api package pins the other register: none of
// these is in allowedEventTypes, so no box can POST one.)
//
// COMPANION RED-PROOF (observed 2026-10-19): with the four lines removed from operatorOnlyEvents this fails
// with
//
// r1150_operator_only_test.go: whole_guest_backup_refused: the household was mailed (customer@example.com) — enabled_events opted it in
// r1150_operator_only_test.go: agent_capability_degraded: the household was mailed (customer@example.com) — enabled_events opted it in
//
// Restored.
func TestR1150_RefusedBackupAndCapabilityEventsNeverReachTheCustomer(t *testing.T) {
for _, et := range []string{"whole_guest_backup_refused", "agent_capability_degraded"} {
st := opOnlyStore(t)
if err := st.SaveNotificationPrefs("c1", "customer@example.com", []string{et}, 6); err != nil {
t.Fatalf("SaveNotificationPrefs: %v", err)
}
rec := &sentTo{}
d := opOnlyDispatcher(t, st, rec)
d.ProcessEvent("c1", et, "warning", "Host c1-abc123: test", `{"host_id":"c1-abc123"}`, "hub")
var customer, operator bool
for _, to := range rec.to {
customer = customer || to == "customer@example.com"
operator = operator || to == "operator@felhom.eu"
}
if customer {
t.Errorf("%s: the household was mailed (customer@example.com) — enabled_events opted it in", et)
}
if !operator {
t.Errorf("%s: the operator was not mailed — the guard must be customer-only", et)
}
}
for _, et := range []string{"whole_guest_backup_refusal_cleared", "agent_capability_recovered"} {
if !operatorOnlyEvents[et] {
t.Errorf("%s must be operator-only (the pair's other edge)", et)
}
}
}