Skip to content

Commit

Permalink
[feat] Add paginated children (#206)
Browse files Browse the repository at this point in the history
- Add functions to retrieve all children and subsequent pages
- Add missing "verified" field for User class (for child user deserialization)
  • Loading branch information
nwithan8 authored Jan 4, 2024
1 parent 6a911d3 commit 82f1d92
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## Next Release

- Add `ListChildUsers` and `GetNextChildUserPage` functions to `User` service

## v4.0.0 (2023-12-06)

- Removes the undocumented `CreateAndBuy` function from the Batch service. The proper usage is to create a batch first and buy it separately
Expand Down
2 changes: 1 addition & 1 deletion referral_customer.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func (c *Client) BetaRefundByAmountWithContext(ctx context.Context, refundAmount
return
}

// BetaRefundByAmount refunds a payment by paymenbt log ID.
// BetaRefundByPaymentLog refunds a payment by payment log ID.
func (c *Client) BetaRefundByPaymentLog(paymentLogId string) (out *BetaPaymentRefund, err error) {
return c.BetaRefundByPaymentLogWithContext(context.Background(), paymentLogId)
}
Expand Down
59 changes: 59 additions & 0 deletions tests/cassettes/TestUserAllChildUsers.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions tests/cassettes/TestUserGetNextChildUserPage.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions tests/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,52 @@ func (c *ClientTests) TestUserRetrieveMe() {
assert.True(strings.HasPrefix(user.ID, "user_"))
}

func (c *ClientTests) TestUserAllChildUsers() {
client := c.ProdClient()
assert, require := c.Assert(), c.Require()

childUsers, err := client.ListChildUsers(
&easypost.ListOptions{
PageSize: c.fixture.pageSize(),
},
)
require.NoError(err)

assert.LessOrEqual(len(childUsers.Children), c.fixture.pageSize())
assert.NotNil(childUsers.HasMore)
for _, user := range childUsers.Children {
assert.Equal(reflect.TypeOf(&easypost.User{}), reflect.TypeOf(user))
}
}

func (c *ClientTests) TestUserGetNextChildUserPage() {
client := c.ProdClient()
assert, require := c.Assert(), c.Require()

firstPage, err := client.ListChildUsers(
&easypost.ListOptions{
PageSize: c.fixture.pageSize(),
},
)
require.NoError(err)

nextPage, err := client.GetNextChildUserPageWithPageSize(firstPage, c.fixture.pageSize())
defer func() {
if err == nil {
assert.True(len(nextPage.Children) <= c.fixture.pageSize())

lastIDOfFirstPage := firstPage.Children[len(firstPage.Children)-1].ID
firstIdOfSecondPage := nextPage.Children[0].ID

assert.NotEqual(lastIDOfFirstPage, firstIdOfSecondPage)
}
}()
if err != nil {
assert.Equal(err.Error(), easypost.EndOfPaginationError.Error())
return
}
}

func (c *ClientTests) TestUserUpdate() {
client := c.ProdClient()
assert, require := c.Assert(), c.Require()
Expand Down
50 changes: 50 additions & 0 deletions user.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package easypost
import (
"context"
"fmt"
"net/http"
)

// A User contains data about an EasyPost account and child accounts.
Expand All @@ -19,6 +20,7 @@ type User struct {
RechargeThreshold string `json:"recharge_threshold,omitempty"`
Children []*User `json:"children,omitempty"`
APIKeys []*APIKey `json:"api_keys,omitempty"`
Verified bool `json:"verified,omitempty"`
}

// UserOptions specifies options for creating or updating a user.
Expand All @@ -40,6 +42,11 @@ type userRequest struct {
UserOptions *UserOptions `json:"user,omitempty"`
}

type ListChildUsersResult struct {
Children []*User `json:"children,omitempty"`
PaginatedCollection
}

// CreateUser creates a new child user.
//
// c := easypost.New(MyEasyPostAPIKey)
Expand Down Expand Up @@ -110,6 +117,49 @@ func (c *Client) RetrieveMeWithContext(ctx context.Context) (out *User, err erro
return
}

// ListChildUsers retrieves a list of child users.
func (c *Client) ListChildUsers(opts *ListOptions) (out *ListChildUsersResult, err error) {
return c.ListChildUsersWithContext(context.Background(), opts)
}

// ListChildUsersWithContext performs the same operation as ListChildUsers, but allows
// specifying a context that can interrupt the request.
func (c *Client) ListChildUsersWithContext(ctx context.Context, opts *ListOptions) (out *ListChildUsersResult, err error) {
err = c.do(ctx, http.MethodGet, "users/children", c.convertOptsToURLValues(opts), &out)
return
}

// GetNextChildUserPage returns the next page of child users.
func (c *Client) GetNextChildUserPage(collection *ListChildUsersResult) (out *ListChildUsersResult, err error) {
return c.GetNextChildUserPageWithContext(context.Background(), collection)
}

// GetNextChildUserPageWithPageSize returns the next page of child users with a specific page size.
func (c *Client) GetNextChildUserPageWithPageSize(collection *ListChildUsersResult, pageSize int) (out *ListChildUsersResult, err error) {
return c.GetNextChildUserPageWithPageSizeWithContext(context.Background(), collection, pageSize)
}

// GetNextChildUserPageWithContext performs the same operation as GetNextChildUserPage, but
// allows specifying a context that can interrupt the request.
func (c *Client) GetNextChildUserPageWithContext(ctx context.Context, collection *ListChildUsersResult) (out *ListChildUsersResult, err error) {
return c.GetNextChildUserPageWithPageSizeWithContext(ctx, collection, 0)
}

// GetNextChildUserPageWithPageSizeWithContext performs the same operation as GetNextChildUserPageWithPageSize, but
// allows specifying a context that can interrupt the request.
func (c *Client) GetNextChildUserPageWithPageSizeWithContext(ctx context.Context, collection *ListChildUsersResult, pageSize int) (out *ListChildUsersResult, err error) {
if len(collection.Children) == 0 {
err = EndOfPaginationError
return
}
lastID := collection.Children[len(collection.Children)-1].ID
params, err := nextPageParameters(collection.HasMore, lastID, pageSize)
if err != nil {
return
}
return c.ListChildUsersWithContext(ctx, params)
}

// UpdateBrand updates the user brand.
func (c *Client) UpdateBrand(params map[string]interface{}, userID string) (out *Brand, err error) {
return c.UpdateBrandWithContext(context.Background(), params, userID)
Expand Down

0 comments on commit 82f1d92

Please sign in to comment.