package oltp
import (
"testing"
"time"
)
// The robot-line store is what turns the broker's pending count into an
// unread count without reading the window: it counts by (code, seq),
// idempotently, and forgets rows the chat window can no longer hold.
func TestRobotLinesCountAndPrune(t *testing.T) {
db := testDB(t)
now := time.Now().UTC()
at := now.Format(time.RFC3339Nano)
for _, seq := range []uint64{4, 7, 9} {
if err := db.RecordRobotLine("c1", seq, at); err != nil {
t.Fatal(err)
}
}
// A different channel's lines never count as this one's.
if err := db.RecordRobotLine("c2", 8, at); err != nil {
t.Fatal(err)
}
// A replay says the same thing and must not double the count.
if err := db.RecordRobotLine("c1", 7, at); err != nil {
t.Fatal(err)
}
for _, tc := range []struct {
since uint64
want int
}{{0, 3}, {4, 2}, {7, 1}, {9, 0}} {
got, err := db.RobotLines("c1", tc.since)
if err != nil {
t.Fatal(err)
}
if got != tc.want {
t.Errorf("RobotLines(c1, %d) = %d, want %d", tc.since, got, tc.want)
}
}
// A row older than the chat window is swept by the next record on
// that channel — the window only moves when something is posted.
old := now.Add(-30 * 24 * time.Hour).Format(time.RFC3339Nano)
if err := db.RecordRobotLine("c3", 1, old); err != nil {
t.Fatal(err)
}
if err := db.RecordRobotLine("c3", 2, at); err != nil {
t.Fatal(err)
}
got, err := db.RobotLines("c3", 0)
if err != nil {
t.Fatal(err)
}
if got != 1 {
t.Fatalf("RobotLines(c3, 0) = %d, want 1 (the aged row was not swept)", got)
}
}