diff --git a/client_test.go b/client_test.go index 5c113cf..871fe52 100644 --- a/client_test.go +++ b/client_test.go @@ -2,8 +2,10 @@ package clearbank import ( "context" + "fmt" "testing" + "github.com/google/uuid" logrustest "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" ) @@ -24,3 +26,11 @@ func TestRequestIdFromContext(t *testing.T) { assert.Equal(t, "", RequestIdFromContext(context.TODO())) assert.Equal(t, "123", RequestIdFromContext(RequestIdContext(context.TODO(), "123"))) } + +func TestUUID(t *testing.T) { + raw := "018223b0-b499-43c6-be4f-518c916d9256" + id := uuid.MustParse(raw) + + //lint:ignore S1025 testing how uuid is printed + assert.Equal(t, raw, fmt.Sprintf("%s", id)) +} diff --git a/testdata/transactions-fetch-one-for-account.json b/testdata/transactions-fetch-one-for-account.json new file mode 100644 index 0000000..85742e2 --- /dev/null +++ b/testdata/transactions-fetch-one-for-account.json @@ -0,0 +1,52 @@ +{ + "transaction": { + "amount": { + "instructedAmount": 100.00, + "currency": "GBP" + }, + "counterpartAccount": { + "identification": { + "iban": "string", + "accountName": "string", + "sortCode": "string", + "accountNumber": "string", + "reference": "string", + "other": { + "identification": "string", + "schemeName": { + "code": "BBAN", + "proprietary": "string" + }, + "issuer": "string" + } + } + }, + "debitCreditCode": "CRDT", + "endToEndIdentifier": "string", + "transactionId": "6ea6dd13-eaad-4e1a-990c-6533a177dbb4", + "transactionReference": "string", + "transactionTime": "2019-08-24T14:15:22Z", + "status": "ACCP", + "ultimateBeneficiaryAccount": { + "id": "e98f9678-582f-4b12-979b-a6f9f6dc9ce7", + "iban": "string", + "bban": "string", + "upic": "string", + "cuid": "string" + }, + "ultimateRemitterAccount": { + "id": "09998c4f-eef4-43f8-beb5-46cd879439fb", + "iban": "string", + "bban": "string", + "upic": "string", + "cuid": "string" + } + }, + "halLinks": [ + { + "name": "string", + "href": "string", + "templated": true + } + ] +} \ No newline at end of file diff --git a/transactions.go b/transactions.go index ffb2100..7a81f50 100644 --- a/transactions.go +++ b/transactions.go @@ -17,6 +17,7 @@ type TransactionsClient interface { FetchTransactions(ctx context.Context, params FetchTransactionsParams) (TransactionsResponse, error) FetchTransactionForAccount(ctx context.Context, accountID uuid.UUID, trxID uuid.UUID) (TransactionResponse, error) FetchTransactionsForAccount(ctx context.Context, accountID uuid.UUID, params FetchTransactionsParams) (TransactionsResponse, error) + FetchTransactionForVirtualAccount(ctx context.Context, accountID, virtualAccountID uuid.UUID, trxID uuid.UUID) (TransactionResponse, error) FetchTransactionsForVirtualAccount(ctx context.Context, accountID, virtualAccountID uuid.UUID, params FetchTransactionsParams) (TransactionsResponse, error) } @@ -307,7 +308,7 @@ func (p FetchTransactionsParams) ApplyFor(req *request) { } } -type TransactionResponse struct { +type TransactionResponseData struct { Amount struct { InstructedAmount float64 `json:"instructedAmount"` Currency string `json:"currency"` @@ -337,8 +338,12 @@ type TransactionResponse struct { } `json:"ultimateRemitterAccount"` } +type TransactionResponse struct { + Transaction TransactionResponseData `json:"transaction"` +} + type TransactionsResponse struct { - Transactions []TransactionResponse `json:"transactions"` + Transactions []TransactionResponseData `json:"transactions"` } func (c *client) FetchTransactions(ctx context.Context, params FetchTransactionsParams) (data TransactionsResponse, err error) { @@ -354,7 +359,7 @@ func (c *client) FetchTransactions(ctx context.Context, params FetchTransactions } func (c *client) FetchTransactionForAccount(ctx context.Context, accountID uuid.UUID, trxID uuid.UUID) (data TransactionResponse, err error) { - req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/v2/Accounts/%s/Transactions/%s", accountID.String(), trxID.String()), nil) + req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/v2/Accounts/%s/Transactions/%s", accountID, trxID), nil) if err != nil { return data, fmt.Errorf("failed to create request: %w", err) } @@ -365,7 +370,7 @@ func (c *client) FetchTransactionForAccount(ctx context.Context, accountID uuid. } func (c *client) FetchTransactionsForAccount(ctx context.Context, accountID uuid.UUID, params FetchTransactionsParams) (data TransactionsResponse, err error) { - req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/v2/Accounts/%s/Transactions", accountID.String()), nil) + req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/v2/Accounts/%s/Transactions", accountID), nil) if err != nil { return data, fmt.Errorf("failed to create request: %w", err) } @@ -377,7 +382,7 @@ func (c *client) FetchTransactionsForAccount(ctx context.Context, accountID uuid } func (c *client) FetchTransactionsForVirtualAccount(ctx context.Context, accountID, virtualAccountID uuid.UUID, params FetchTransactionsParams) (data TransactionsResponse, err error) { - req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/v2/Accounts/%s/Virtual/%s/Transactions", accountID.String(), virtualAccountID.String()), nil) + req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/v2/Accounts/%s/Virtual/%s/Transactions", accountID, virtualAccountID), nil) if err != nil { return data, fmt.Errorf("failed to create request: %w", err) } @@ -387,3 +392,14 @@ func (c *client) FetchTransactionsForVirtualAccount(ctx context.Context, account req.DecodeTo(&data) return data, c.do(ctx, req) } + +func (c *client) FetchTransactionForVirtualAccount(ctx context.Context, accountID, virtualAccountID uuid.UUID, trxID uuid.UUID) (data TransactionResponse, err error) { + req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/v2/Accounts/%s/Virtual/%s/Transactions/%s", accountID, virtualAccountID, trxID), nil) + if err != nil { + return data, fmt.Errorf("failed to create request: %w", err) + } + + req.ExpectStatus(http.StatusOK) + req.DecodeTo(&data) + return data, c.do(ctx, req) +} diff --git a/transactions_test.go b/transactions_test.go new file mode 100644 index 0000000..0d18371 --- /dev/null +++ b/transactions_test.go @@ -0,0 +1,42 @@ +package clearbank_test + +import ( + "bytes" + "context" + _ "embed" + "io" + "net/http" + "testing" + + "github.com/brokeyourbike/clearbank-api-client-go" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + mock "github.com/stretchr/testify/mock" +) + +//go:embed testdata/transactions-fetch-one-for-account.json +var transactionsFetchOneForAccount []byte + +func TestFetchTransactionForAccount(t *testing.T) { + mockHttpClient := clearbank.NewMockHttpClient(t) + client := clearbank.NewClient("token", nil, clearbank.WithHTTPClient(mockHttpClient)) + + resp := &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewReader(transactionsFetchOneForAccount))} + mockHttpClient.On("Do", mock.AnythingOfType("*http.Request")).Return(resp, nil).Once() + + got, err := client.FetchTransactionForAccount(context.TODO(), uuid.New(), uuid.New()) + assert.NoError(t, err) + assert.Equal(t, "6ea6dd13-eaad-4e1a-990c-6533a177dbb4", got.Transaction.TransactionID.String()) +} + +func TestFetchTransactionForVirtualAccount(t *testing.T) { + mockHttpClient := clearbank.NewMockHttpClient(t) + client := clearbank.NewClient("token", nil, clearbank.WithHTTPClient(mockHttpClient)) + + resp := &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewReader(transactionsFetchOneForAccount))} + mockHttpClient.On("Do", mock.AnythingOfType("*http.Request")).Return(resp, nil).Once() + + got, err := client.FetchTransactionForVirtualAccount(context.TODO(), uuid.New(), uuid.New(), uuid.New()) + assert.NoError(t, err) + assert.Equal(t, "6ea6dd13-eaad-4e1a-990c-6533a177dbb4", got.Transaction.TransactionID.String()) +}