Skip to content
quarry Artifact [2450ddb090]
Login

Artifact [2450ddb090]

Artifact 2450ddb0902475ccf0f481ddb95576fedb4fb195e2deef7149f2b883a1cf4812:


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)
	}
}