Skip to content

Commit

Permalink
fix: cursor unmarshalling (#1270)
Browse files Browse the repository at this point in the history
  • Loading branch information
gfyrag authored Feb 22, 2024
1 parent 742815a commit b5632c3
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,13 @@ func TestGetTransactions(t *testing.T) {
}).
WithPageSize(v2.MaxPageSize),
},
{
name: "using cursor",
queryParams: url.Values{
"cursor": []string{"eyJwYWdlU2l6ZSI6MTUsImJvdHRvbSI6bnVsbCwiY29sdW1uIjoiaWQiLCJwYWdpbmF0aW9uSUQiOm51bGwsIm9yZGVyIjoxLCJmaWx0ZXJzIjp7InFiIjp7fSwicGFnZVNpemUiOjE1LCJvcHRpb25zIjp7InBpdCI6bnVsbCwidm9sdW1lcyI6ZmFsc2UsImVmZmVjdGl2ZVZvbHVtZXMiOmZhbHNlfX0sInJldmVyc2UiOmZhbHNlfQ"},
},
expectQuery: ledgerstore.NewPaginatedQueryOptions(ledgerstore.PITFilterWithVolumes{}),
},
}
for _, testCase := range testCases {
testCase := testCase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ func (store *Store) GetTransactions(ctx context.Context, q GetTransactionsQuery)
args []any
err error
)

if q.Options.QueryBuilder != nil {
where, args, err = store.transactionQueryContext(q.Options.QueryBuilder, q)
if err != nil {
Expand Down
27 changes: 27 additions & 0 deletions components/ledger/internal/storage/ledgerstore/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,33 @@ type PaginatedQueryOptions[T any] struct {
Options T `json:"options"`
}

func (v *PaginatedQueryOptions[T]) UnmarshalJSON(data []byte) error {
type aux struct {
QueryBuilder json.RawMessage `json:"qb"`
PageSize uint64 `json:"pageSize"`
Options T `json:"options"`
}
x := &aux{}
if err := json.Unmarshal(data, x); err != nil {
return err
}

*v = PaginatedQueryOptions[T]{
PageSize: x.PageSize,
Options: x.Options,
}

var err error
if x.QueryBuilder != nil {
v.QueryBuilder, err = query.ParseJSON(string(x.QueryBuilder))
if err != nil {
return err
}
}

return nil
}

func (opts PaginatedQueryOptions[T]) WithQueryBuilder(qb query.Builder) PaginatedQueryOptions[T] {
opts.QueryBuilder = qb

Expand Down
18 changes: 18 additions & 0 deletions components/ledger/libs/query/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ type set struct {
items []Builder
}

func (s set) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]any{
"$" + s.operator: s.items,
})
}

var _ Builder = (*set)(nil)

func (set set) Build(ctx Context) (string, []any, error) {
Expand All @@ -52,6 +58,14 @@ type keyValue struct {
value any
}

func (s keyValue) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]any{
s.operator: map[string]any{
s.key: s.value,
},
})
}

var _ Builder = (*keyValue)(nil)

func (k keyValue) Build(ctx Context) (string, []any, error) {
Expand Down Expand Up @@ -223,5 +237,9 @@ func ParseJSON(data string) (Builder, error) {
return nil, err
}

if len(m) == 0 {
return nil, nil
}

return mapMapToExpression(m)
}
18 changes: 18 additions & 0 deletions libs/go-libs/query/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ type set struct {
items []Builder
}

func (s set) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]any{
"$" + s.operator: s.items,
})
}

var _ Builder = (*set)(nil)

func (set set) Build(ctx Context) (string, []any, error) {
Expand All @@ -52,6 +58,14 @@ type keyValue struct {
value any
}

func (s keyValue) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]any{
s.operator: map[string]any{
s.key: s.value,
},
})
}

var _ Builder = (*keyValue)(nil)

func (k keyValue) Build(ctx Context) (string, []any, error) {
Expand Down Expand Up @@ -223,5 +237,9 @@ func ParseJSON(data string) (Builder, error) {
return nil, err
}

if len(m) == 0 {
return nil, nil
}

return mapMapToExpression(m)
}
101 changes: 101 additions & 0 deletions tests/integration/suite/ledger-list-transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package suite

import (
"fmt"
"github.com/formancehq/stack/libs/go-libs/bun/bunpaginate"
"math/big"
"net/http"
"time"
Expand Down Expand Up @@ -210,6 +211,106 @@ var _ = WithModules([]*Module{modules.Ledger}, func() {
})
})

Then("listing transactions using filter on a single match", func() {
var (
err error
response *operations.V2ListTransactionsResponse
now = time.Now().Round(time.Second).UTC()
)
BeforeEach(func() {
response, err = Client().Ledger.V2ListTransactions(
TestContext(),
operations.V2ListTransactionsRequest{
RequestBody: map[string]interface{}{
"$match": map[string]any{
"source": "world",
},
},
Ledger: "default",
PageSize: ptr(pageSize),
Pit: &now,
},
)
Expect(err).To(BeNil())
})
It("Should be ok", func() {
Expect(response.V2TransactionsCursorResponse.Cursor.Next).NotTo(BeNil())
cursor := &bunpaginate.ColumnPaginatedQuery[map[string]any]{}
Expect(bunpaginate.UnmarshalCursor(*response.V2TransactionsCursorResponse.Cursor.Next, cursor)).To(BeNil())
Expect(cursor.Options).To(Equal(map[string]any{
"qb": map[string]any{
"$match": map[string]any{
"source": "world",
},
},
"pageSize": float64(10),
"options": map[string]any{
"pit": now.Format(time.RFC3339),
"volumes": false,
"effectiveVolumes": false,
},
}))
})
})
Then("listing transactions using filter on a single match", func() {
var (
err error
response *operations.V2ListTransactionsResponse
now = time.Now().Round(time.Second).UTC()
)
BeforeEach(func() {
response, err = Client().Ledger.V2ListTransactions(
TestContext(),
operations.V2ListTransactionsRequest{
RequestBody: map[string]interface{}{
"$and": []map[string]any{
{
"$match": map[string]any{
"source": "world",
},
},
{
"$match": map[string]any{
"destination": "account:",
},
},
},
},
Ledger: "default",
PageSize: ptr(pageSize),
Pit: &now,
},
)
Expect(err).To(BeNil())
})
It("Should be ok", func() {
Expect(response.V2TransactionsCursorResponse.Cursor.Next).NotTo(BeNil())
cursor := &bunpaginate.ColumnPaginatedQuery[map[string]any]{}
Expect(bunpaginate.UnmarshalCursor(*response.V2TransactionsCursorResponse.Cursor.Next, cursor)).To(BeNil())
Expect(cursor.Options).To(Equal(map[string]any{
"qb": map[string]any{
"$and": []any{
map[string]any{
"$match": map[string]any{
"source": "world",
},
},
map[string]any{
"$match": map[string]any{
"destination": "account:",
},
},
},
},
"pageSize": float64(10),
"options": map[string]any{
"pit": now.Format(time.RFC3339),
"volumes": false,
"effectiveVolumes": false,
},
}))
})
})
Then("listing transactions using invalid filter", func() {
var (
err error
Expand Down

0 comments on commit b5632c3

Please sign in to comment.