Skip to content
This repository has been archived by the owner on Jan 2, 2022. It is now read-only.

Commit

Permalink
New: support for changesSince filter on the v2 feed endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
billglover authored Jul 1, 2018
1 parent 5a4f169 commit bc3cc35
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 11 deletions.
21 changes: 18 additions & 3 deletions feed.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,26 @@ type Item struct {
SpendingCategory string `json:"spendingCategory"`
}

// Feed returns a slice of Items for a given account and category
func (c *Client) Feed(ctx context.Context, act, cat string) ([]Item, *http.Response, error) {
// FeedOpts defines options that can be passed when requesting a feed
type FeedOpts struct {
Since time.Time
}

// Feed returns a slice of Items for a given account and category. It returns an error if unable
// to retrieve the feed.
// Note: Feed uses the v2 API which is still under active development.
func (c *Client) Feed(ctx context.Context, act, cat string, opts *FeedOpts) ([]Item, *http.Response, error) {
req, err := c.NewRequest("GET", "/api/v2/feed/account/"+act+"/category/"+cat, nil)
if err != nil {
return nil, nil, err
}

if opts != nil {
q := req.URL.Query()
q.Add("changesSince", opts.Since.Format(time.RFC3339Nano))
req.URL.RawQuery = q.Encode()
}

var f feed
resp, err := c.Do(ctx, req, &f)
if err != nil {
Expand All @@ -45,7 +58,9 @@ func (c *Client) Feed(ctx context.Context, act, cat string) ([]Item, *http.Respo
return f.Items, resp, nil
}

// FeedItem returns a feed Item
// FeedItem returns a feed Item for a given account and category. It returns an error if unable to
// retrieve the feed Item.
// Note: FeedItem uses the v2 API which is still under active development.
func (c *Client) FeedItem(ctx context.Context, act, cat, itm string) (*Item, *http.Response, error) {
req, err := c.NewRequest("GET", "/api/v2/feed/account/"+act+"/category/"+cat+"/"+itm, nil)
if err != nil {
Expand Down
63 changes: 55 additions & 8 deletions feed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import (
"net/http"
"reflect"
"testing"
"time"
)

var feedTC = []struct {
name string
act string
cat string
mock string
name string
act string
cat string
since time.Time
mock string
}{
{
name: "no transactions",
Expand Down Expand Up @@ -129,17 +131,49 @@ var feedTC = []struct {
]
}`,
},
{
name: "transaction since",
act: "30aa7ab8-4389-4658-a4f8-0bc6d0015ba0",
cat: "c423ab8d-9a6a-44b2-8db6-ac6000fe58e0",
since: time.Now(),
mock: `{
"feedItems": [
{
"feedItemUid": "dbb59f1c-39e6-4558-87ba-11c142965393",
"categoryUid": "c423ab8d-9a6a-44b2-8db6-ac6000fe58e0",
"amount": {
"currency": "GBP",
"minorUnits": 32
},
"sourceAmount": {
"currency": "GBP",
"minorUnits": 32
},
"direction": "OUT",
"transactionTime": "2018-06-28T07:16:28.364Z",
"source": "MASTER_CARD",
"sourceSubType": "CHIP_AND_PIN",
"status": "SETTLED",
"counterPartyType": "MERCHANT",
"counterPartyUid": "e6dbe57e-7c23-4015-97a4-4afbbf7faa23",
"reference": "ATM 111072\\35 REGENT ST), LONDON\\LONDON\\SW1Y 4ND 00 GBR",
"country": "GB",
"spendingCategory": "HOLIDAYS"
}
]
}`,
},
}

func TestFeed(t *testing.T) {
for _, tc := range feedTC {
t.Run(tc.name, func(t *testing.T) {
testFeed(t, tc.name, tc.act, tc.cat, tc.mock)
testFeed(t, tc.name, tc.act, tc.cat, tc.mock, tc.since)
})
}
}

func testFeed(t *testing.T, name, act, cat, mock string) {
func testFeed(t *testing.T, name, act, cat, mock string, since time.Time) {
client, mux, _, teardown := setup()
defer teardown()

Expand All @@ -150,10 +184,23 @@ func testFeed(t *testing.T, name, act, cat, mock string) {
t.Error("should sent a request to the correct path")
}

params := r.URL.Query()

if time.Time.IsZero(since) == false {
if got, want := params.Get("changesSince"), since.Format(time.RFC3339Nano); got != want {
t.Errorf("should include 'changesSince=%s' query string parameter %s 'changesSince=%s'", want, cross, got)
}
}

fmt.Fprint(w, mock)
})

got, _, err := client.Feed(context.Background(), act, cat)
opts := &FeedOpts{}
if time.Time.IsZero(since) == false {
opts.Since = since
}

got, _, err := client.Feed(context.Background(), act, cat, opts)
checkNoError(t, err)

want := &feed{}
Expand All @@ -179,7 +226,7 @@ func TestFeedForbidden(t *testing.T) {
w.WriteHeader(http.StatusForbidden)
})

got, resp, err := client.Feed(context.Background(), "30aa7ab8-4389-4658-a4f8-0bc6d0015ba0", "c423ab8d-9a6a-44b2-8db6-ac6000fe58e0")
got, resp, err := client.Feed(context.Background(), "30aa7ab8-4389-4658-a4f8-0bc6d0015ba0", "c423ab8d-9a6a-44b2-8db6-ac6000fe58e0", nil)
checkHasError(t, err)

if resp.StatusCode != http.StatusForbidden {
Expand Down

0 comments on commit bc3cc35

Please sign in to comment.