7aacb7dfc9
continuous-integration/drone/push Build is passing
- Updated the ListPaginationOptions struct to include SkipCount and IncludeCount fields, allowing for more flexible pagination behavior. - Modified the BuildListPagination function to handle cursor pagination with count options, improving performance by running count queries in parallel with data retrieval. - Enhanced the FindAll method in the repository to support concurrent counting of documents, reducing overall latency for list operations. - Added tests for pagination behavior, ensuring accurate handling of count scenarios in both offset and cursor pagination. This update improves the efficiency and flexibility of pagination in the MongoDB repository, enhancing the overall performance of list operations.
115 lines
3.0 KiB
Go
115 lines
3.0 KiB
Go
package mongo
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"go.mongodb.org/mongo-driver/v2/bson"
|
|
)
|
|
|
|
func TestEncodeDecodePageCursor(t *testing.T) {
|
|
encoded, err := encodePageCursor("created_at", -1, int64(1700000000), "507f1f77bcf86cd799439011", "abc123", 10)
|
|
if err != nil {
|
|
t.Fatalf("encode: %v", err)
|
|
}
|
|
if strings.Contains(encoded, "+") || strings.Contains(encoded, "/") {
|
|
t.Fatalf("expected URL-safe cursor, got %q", encoded)
|
|
}
|
|
|
|
decoded, err := decodePageCursor(encoded)
|
|
if err != nil {
|
|
t.Fatalf("decode: %v", err)
|
|
}
|
|
|
|
if decoded.SortField != "created_at" || decoded.SortOrder != -1 {
|
|
t.Fatalf("unexpected sort: %+v", decoded)
|
|
}
|
|
if decoded.FiltersHash != "abc123" || decoded.PageOffset != 10 {
|
|
t.Fatalf("unexpected metadata: %+v", decoded)
|
|
}
|
|
}
|
|
|
|
func TestBuildListPaginationCursorAndOffsetConflict(t *testing.T) {
|
|
_, err := BuildListPagination(10, 5, "cursor-token", "created_at", "desc", bson.M{}, ListPaginationOptions{})
|
|
if err == nil {
|
|
t.Fatal("expected error when cursor and offset are both set")
|
|
}
|
|
}
|
|
|
|
func TestBuildListPaginationOffsetMode(t *testing.T) {
|
|
p, err := BuildListPagination(10, 20, "", "created_at", "desc", bson.M{"status": "active"}, ListPaginationOptions{})
|
|
if err != nil {
|
|
t.Fatalf("build: %v", err)
|
|
}
|
|
if p.Skip != 20 || p.Limit != 10 || p.Cursor != "" {
|
|
t.Fatalf("unexpected pagination: %+v", p)
|
|
}
|
|
if p.SkipCount {
|
|
t.Fatal("expected count on offset pagination")
|
|
}
|
|
}
|
|
|
|
func TestBuildListPaginationCursorSkipsCount(t *testing.T) {
|
|
encoded, err := encodePageCursor("created_at", -1, int64(1700000000), "507f1f77bcf86cd799439011", "abc123", 10)
|
|
if err != nil {
|
|
t.Fatalf("encode: %v", err)
|
|
}
|
|
|
|
p, err := BuildListPagination(10, 0, encoded, "created_at", "desc", bson.M{}, ListPaginationOptions{})
|
|
if err != nil {
|
|
t.Fatalf("build: %v", err)
|
|
}
|
|
if !p.SkipCount {
|
|
t.Fatal("expected SkipCount on cursor pagination")
|
|
}
|
|
}
|
|
|
|
func TestBuildListPaginationCursorIncludeCount(t *testing.T) {
|
|
encoded, err := encodePageCursor("created_at", -1, int64(1700000000), "507f1f77bcf86cd799439011", "abc123", 10)
|
|
if err != nil {
|
|
t.Fatalf("encode: %v", err)
|
|
}
|
|
|
|
p, err := BuildListPagination(10, 0, encoded, "created_at", "desc", bson.M{}, ListPaginationOptions{IncludeCount: true})
|
|
if err != nil {
|
|
t.Fatalf("build: %v", err)
|
|
}
|
|
if p.SkipCount {
|
|
t.Fatal("expected count when IncludeCount is set")
|
|
}
|
|
}
|
|
|
|
func TestHashFilterStable(t *testing.T) {
|
|
a := HashFilter(bson.M{"status": "active"})
|
|
b := HashFilter(bson.M{"status": "active"})
|
|
if a == "" || a != b {
|
|
t.Fatalf("expected stable non-empty hash, got %q and %q", a, b)
|
|
}
|
|
}
|
|
|
|
func TestDocumentSortValueNestedField(t *testing.T) {
|
|
doc := bson.M{
|
|
"_id": bson.NewObjectID(),
|
|
"address": bson.M{
|
|
"country": "US",
|
|
"state": "NY",
|
|
},
|
|
}
|
|
|
|
country, err := documentSortValue(doc, "address.country")
|
|
if err != nil {
|
|
t.Fatalf("address.country: %v", err)
|
|
}
|
|
if country != "US" {
|
|
t.Fatalf("expected US, got %v", country)
|
|
}
|
|
|
|
state, err := documentSortValue(doc, "address.state")
|
|
if err != nil {
|
|
t.Fatalf("address.state: %v", err)
|
|
}
|
|
if state != "NY" {
|
|
t.Fatalf("expected NY, got %v", state)
|
|
}
|
|
}
|