mirror of
https://github.com/hanzo-fi/go-libs.git
synced 2026-10-30 20:53:44 +00:00
124 lines
3.2 KiB
Go
124 lines
3.2 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
bunpaginate "github.com/hanzo-fi/go-libs/v5/pkg/storage/bun/paginate"
|
|
)
|
|
|
|
func TestCursor(t *testing.T) {
|
|
t.Parallel()
|
|
c := bunpaginate.Cursor[int64]{
|
|
Data: []int64{1, 2, 3},
|
|
}
|
|
by, err := json.Marshal(c)
|
|
require.NoError(t, err)
|
|
require.Equal(t, `{"hasMore":false,"data":[1,2,3]}`, string(by))
|
|
|
|
c = bunpaginate.Cursor[int64]{
|
|
Data: []int64{1, 2, 3},
|
|
HasMore: true,
|
|
}
|
|
by, err = json.Marshal(c)
|
|
require.NoError(t, err)
|
|
require.Equal(t,
|
|
`{"hasMore":true,"data":[1,2,3]}`,
|
|
string(by))
|
|
}
|
|
|
|
func TestFetchAllPaginated(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("multi-page success", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
var rsp BaseResponse[int64]
|
|
switch r.URL.Query().Get("cursor") {
|
|
case "":
|
|
rsp = BaseResponse[int64]{
|
|
Cursor: &bunpaginate.Cursor[int64]{
|
|
HasMore: true,
|
|
Next: "page2",
|
|
Data: []int64{1, 2},
|
|
},
|
|
}
|
|
case "page2":
|
|
rsp = BaseResponse[int64]{
|
|
Cursor: &bunpaginate.Cursor[int64]{
|
|
HasMore: false,
|
|
Data: []int64{3, 4},
|
|
},
|
|
}
|
|
default:
|
|
http.Error(w, "unexpected cursor", http.StatusBadRequest)
|
|
return
|
|
}
|
|
require.NoError(t, json.NewEncoder(w).Encode(rsp))
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
ret, err := FetchAllPaginated[int64](context.Background(), srv.Client(), srv.URL, url.Values{})
|
|
require.NoError(t, err)
|
|
require.Equal(t, []int64{1, 2, 3, 4}, ret)
|
|
})
|
|
|
|
t.Run("200 without cursor returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
require.NoError(t, json.NewEncoder(w).Encode(BaseResponse[int64]{}))
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
ret, err := FetchAllPaginated[int64](context.Background(), srv.Client(), srv.URL, url.Values{})
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, "missing cursor")
|
|
require.Nil(t, ret)
|
|
})
|
|
|
|
t.Run("repeated next cursor returns an error instead of looping", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var calls int
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
calls++
|
|
require.NoError(t, json.NewEncoder(w).Encode(BaseResponse[int64]{
|
|
Cursor: &bunpaginate.Cursor[int64]{
|
|
HasMore: true,
|
|
Next: "same-token",
|
|
Data: []int64{1},
|
|
},
|
|
}))
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
ret, err := FetchAllPaginated[int64](context.Background(), srv.Client(), srv.URL, url.Values{})
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, "did not advance")
|
|
require.Nil(t, ret)
|
|
require.Equal(t, 2, calls)
|
|
})
|
|
|
|
t.Run("non-200 status code returns an error", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, "internal error", http.StatusInternalServerError)
|
|
}))
|
|
t.Cleanup(srv.Close)
|
|
|
|
ret, err := FetchAllPaginated[int64](context.Background(), srv.Client(), srv.URL, url.Values{})
|
|
require.Error(t, err)
|
|
require.ErrorContains(t, err, "unexpected status code 500")
|
|
require.Nil(t, ret)
|
|
})
|
|
}
|