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

56 lines
2.1 KiB
Go

package notify
import (
"database/sql"
"io"
"log"
"path/filepath"
"testing"
"time"
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
)
// R-873 (v0.134.0) — a household whose box is OFF EVERY NIGHT (Tester 2, a laptop) is told "your server cannot be
// reached" at most once per 7 days; the operator still hears every edge; the recovery mail stays paired.
// COMPANION RED-PROOF: drop the householdLivenessWeekly block in processCustomer → night 2 mails the household.
func TestR873_HouseholdHearsAnOutageAtMostWeekly(t *testing.T) {
path := filepath.Join(t.TempDir(), "d.db")
st, err := store.New(path, log.New(io.Discard, "", 0))
if err != nil {
t.Fatal(err)
}
defer st.Close()
st.SaveCustomerConfig(&store.CustomerConfig{CustomerID: "c1", APIKey: "k", RetrievalPassword: "p"})
if err := st.SaveNotificationPrefs("c1", "cust@example.com", []string{"node_down"}, 6); err != nil {
t.Fatal(err)
}
night := func() (cust, op int) {
// a fresh dispatcher each night: the in-memory 6 h cooldown is gone by the next evening anyway
d := NewDispatcher(st, "test-key", "from@felhom.eu", "op@felhom.eu", true, log.New(io.Discard, "", 0))
sent := captureSeam(d)
d.ProcessEvent("c1", "node_down", "error", "No report received for 90m", "{}", "hub")
d.ProcessEvent("c1", "node_recovered", "info", "Reports resumed", "{}", "hub")
return len(mailsFor(*sent, "cust@example.com")), len(mailsFor(*sent, "op@felhom.eu"))
}
if c, o := night(); c != 2 || o != 2 {
t.Fatalf("night 1: household %d mails, operator %d — want down+recovered to both", c, o)
}
if c, o := night(); c != 0 || o != 2 {
t.Fatalf("night 2: household %d mails (want 0 — told once this week), operator %d (want every edge)", c, o)
}
// Eight days later the household is told again.
db, err := sql.Open("sqlite", path)
if err != nil {
t.Fatal(err)
}
defer db.Close()
old := time.Now().UTC().Add(-8 * 24 * time.Hour).Format("2006-01-02 15:04:05")
if _, err := db.Exec(`UPDATE notification_log SET created_at = ?`, old); err != nil {
t.Fatal(err)
}
if c, _ := night(); c != 2 {
t.Fatalf("after 8 days the household got %d mails, want down+recovered again", c)
}
}