internal/repository/clickhouse/activity_test.go
Rama main · réplica de lectura del repositorio original.
package clickhouse
import (
"testing"
"time"
"github.com/flexprice/flexprice/internal/domain/activity"
"github.com/stretchr/testify/require"
)
func TestUniqueEntries(t *testing.T) {
base := time.Date(2026, 10, 13, 12, 0, 0, 0, time.UTC)
// table builds rows newest first; "b*3" is entry b stored three times.
table := func(spec ...string) []*activity.Log {
var rows []*activity.Log
for i, s := range spec {
id, copies := s, 1
if len(s) > 2 && s[len(s)-2] == '*' {
id, copies = s[:len(s)-2], int(s[len(s)-1]-'0')
}
for range copies {
rows = append(rows, &activity.Log{ID: id, OccurredAt: base.Add(-time.Duration(i) * time.Second)})
}
}
return rows
}
// fetcher serves the rows after the cursor, up to limit, as the ClickHouse query does.
fetcher := func(rows []*activity.Log, limit int, calls *int) func(*activity.Cursor) ([]*activity.Log, error) {
return func(after *activity.Cursor) ([]*activity.Log, error) {
*calls++
var out []*activity.Log
for _, l := range rows {
if after != nil && !(l.OccurredAt.Before(after.OccurredAt) || (l.OccurredAt.Equal(after.OccurredAt) && l.ID < after.ID)) {
continue
}
if len(out) == limit {
break
}
out = append(out, l)
}
return out, nil
}
}
ids := func(logs []*activity.Log) []string {
out := make([]string, len(logs))
for i, l := range logs {
out[i] = l.ID
}
return out
}
tests := []struct {
name string
rows []*activity.Log
limit int
want []string
wantCalls int
}{
{"no copies: one query", table("a", "b", "c", "d"), 3, []string{"a", "b", "c"}, 1},
{"copies eat into the page: refills", table("a", "b*3", "c", "d", "e"), 3, []string{"a", "b", "c"}, 2},
{"more copies than the page: cursor skips the rest", table("a*9", "b", "c"), 3, []string{"a", "b", "c"}, 2},
{"copies across a batch edge", table("a", "b", "c*4", "d"), 3, []string{"a", "b", "c"}, 1},
{"rows run out after a full batch", table("a*2", "b"), 3, []string{"a", "b"}, 2},
{"empty", nil, 3, []string{}, 1},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
calls := 0
got, err := uniqueEntries(tt.limit, nil, fetcher(tt.rows, tt.limit, &calls))
require.NoError(t, err)
require.Equal(t, tt.want, ids(got))
require.Equal(t, tt.wantCalls, calls)
})
}
}