package store import ( "context" "testing" "time" ) // TestLastSentOnEmptyTableIsZero pins the aggregate-over-nothing trap that // nudges.go's OldestPendingTelegram already documents: MAX over an empty set is // one row holding NULL, not zero rows. Scanning that into a bare int64 is an // error, and the doc on LastSent promises a zero time instead. // // It is not a cosmetic promise. ack_sends is written only by MarkSent, and // MarkSent is called only after a repeat has already gone out, so the first // repeat for every rule reads an empty table. delivery.Dispatcher.RepeatUnacked // aborts the whole sweep on that error, which means the repeat-til-ack loop can // never take its first step for any rule. func TestLastSentOnEmptyTableIsZero(t *testing.T) { s := newTestStore(t) ctx := context.Background() last, err := s.LastSent(ctx, "service_down") if err != nil { t.Fatalf("last sent on an empty table must not error: %v", err) } if !last.IsZero() { t.Fatalf("want the zero time before anything was sent, got %v", last) } } // TestLastSentIsScopedToItsRule — a send for another rule must not answer for // this one, or the repeat interval is clocked off somebody else's alarm. func TestLastSentIsScopedToItsRule(t *testing.T) { s := newTestStore(t) ctx := context.Background() at := time.UnixMilli(1_700_000_000_000).UTC() if err := s.MarkSent(ctx, "other_rule", at); err != nil { t.Fatalf("mark sent: %v", err) } last, err := s.LastSent(ctx, "service_down") if err != nil { t.Fatalf("last sent: %v", err) } if !last.IsZero() { t.Fatalf("want zero for a rule with no sends, got %v", last) } if err := s.MarkSent(ctx, "service_down", at); err != nil { t.Fatalf("mark sent: %v", err) } last, err = s.LastSent(ctx, "service_down") if err != nil { t.Fatalf("last sent: %v", err) } if !last.Equal(at) { t.Fatalf("want %v, got %v", at, last) } }