Files
felhom.eu/hub/internal/notify/storage_reconnect_cooldown_test.go
T

44 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package notify
import (
"io"
"log"
"testing"
)
// R-521 F6 (S32, `09` §3 decision 227). MEASURED 2026-09-14 (BIGNIGHT): a drive was unplugged, plugged
// back (`storage_reconnected`), and unplugged again 40 minutes later — and the second loss mailed
// NOBODY: the per-key cooldown armed by the first `storage_disconnected` outlived the recovery.
// A re-plug ends the incident, so it ends that incident's cooldown, on both channels.
//
// Also pins the S32 rule: the household gets the lost-drive mail ONLY when its own list carries
// `storage_disconnected`; a household that did not switch it on gets none.
// RED-PROOF: without the reset in processEvent the second unplug gives 1 operator / 1 customer mail.
func TestDriveLostAgainAfterReplugMailsAgain(t *testing.T) {
st := newDispStore(t)
if err := st.SaveNotificationPrefs("on", "house-on@example.com", []string{"storage_disconnected"}, 6); err != nil {
t.Fatal(err)
}
if err := st.SaveNotificationPrefs("off", "house-off@example.com", []string{"backup_failed"}, 6); err != nil {
t.Fatal(err)
}
d := NewDispatcher(st, "test-key", "from@felhom.eu", "op@felhom.eu", true, log.New(io.Discard, "", 0))
sent := captureSeam(d)
for _, c := range []string{"on", "off"} {
d.ProcessEvent(c, "storage_disconnected", "error", "drive lost", `{}`, "controller")
d.ProcessEvent(c, "storage_reconnected", "info", "drive back", `{}`, "controller")
d.ProcessEvent(c, "storage_disconnected", "error", "drive lost again", `{}`, "controller")
}
// R-1049 (2026-10-15): the return now mails too — 2 losses + 1 return.
if got := len(mailsFor(*sent, "house-on@example.com")); got != 3 {
t.Fatalf("household that switched it on: %d mails, want 3 (one per loss + the return, R-1049)", got)
}
if got := len(mailsFor(*sent, "house-off@example.com")); got != 0 {
t.Fatalf("household that did not switch it on got %d mails, want 0", got)
}
if got := len(mailsFor(*sent, "op@felhom.eu")); got != 6 {
t.Fatalf("operator: %d mails, want 6 (two losses + one return, × two customers; R-1049)", got)
}
}