6da3a7d866
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
56 lines
2.1 KiB
Go
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)
|
|
}
|
|
}
|