Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Uchencho committed Sep 23, 2023
1 parent 66438b7 commit 19aa2fd
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ OUTPUT = main

.PHONY: test
test:
go test -failfast ./...
go test -failfast -cover ./...

.PHONY: clean
clean:
Expand Down
9 changes: 8 additions & 1 deletion client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,15 @@ func main() {
// each mapping, think country, have a number of correspondents, pick the one you are trying to send money to
// ideally you will take this as an input and map to the correspondent of your choice
correspondent := allCorrespondentMappings[0].Correspondents[0]
req := pawapay.PayoutRequest{
Amount: amt,
PhoneNumber: pn,
Description: description,
PayoutId: "uniqueId",
Correspondent: correspondent.Correspondent,
}

resp, err := service.CreatePayout(time.Now, "uniqueId", amt, description, pn, correspondent.Correspondent)
resp, err := service.CreatePayout(time.Now, req)
if err != nil {
log.Printf("something went wrong, we will confirm through their webhook")

Expand Down
20 changes: 10 additions & 10 deletions default.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import (
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"

"github.com/biter777/countries"
"github.com/pariz/gountries"
"github.com/pkg/errors"
)

Expand Down Expand Up @@ -44,9 +43,9 @@ type Amount struct {

type PayoutRequest struct {
PayoutId string
Amt Amount
Amount Amount
Description string
Pn PhoneNumber
PhoneNumber PhoneNumber
Correspondent string
}

Expand Down Expand Up @@ -235,15 +234,16 @@ func (s *Service) newCreateBulkPayoutRequest(timeProvider TimeProviderFunc, req
requests := []CreatePayoutRequest{}
for _, payload := range req {

cc, err := strconv.Atoi(payload.Pn.CountryCode)
query := gountries.New()
se, err := query.FindCountryByCallingCode(payload.PhoneNumber.CountryCode)
if err != nil {
return []CreatePayoutRequest{}, errors.Wrapf(err, "unable to convert countryCode=%s to integer", payload.Pn.CountryCode)
return []CreatePayoutRequest{}, err
}
c := countries.ByNumeric(cc)
countryCode := c.Alpha3()

requests = append(requests, s.newCreatePayoutRequest(timeProvider, payload.PayoutId, payload.Amt,
countryCode, payload.Correspondent, payload.Description, payload.Pn))
countryCode := se.Alpha3

requests = append(requests, s.newCreatePayoutRequest(timeProvider, payload.PayoutId, payload.Amount,
countryCode, payload.Correspondent, payload.Description, payload.PhoneNumber))
}

return requests, nil
Expand Down
10 changes: 9 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ module github.com/Uchencho/pawapay
go 1.20

require (
github.com/biter777/countries v1.6.6
github.com/pariz/gountries v0.1.6
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.8.4
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
16 changes: 14 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
github.com/biter777/countries v1.6.6 h1:07RfPdL1INfMBhxVGBgNMM8cTrhdqMtgIc3N1KrUMR8=
github.com/biter777/countries v1.6.6/go.mod h1:1HSpZ526mYqKJcpT5Ti1kcGQ0L0SrXWIaptUWjFfv2E=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pariz/gountries v0.1.6 h1:Cu8sBSvD6HvAtzinKJ7Yw8q4wAF2dD7oXjA5yDJQt1I=
github.com/pariz/gountries v0.1.6/go.mod h1:Et5QWMc75++5nUKSYKNtz/uc+2LHl4LKhNd6zwdTu+0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
170 changes: 170 additions & 0 deletions pawapay_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
package pawapay_test

import (
"bytes"
"encoding/json"
"io"
"log"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"time"

"github.com/Uchencho/pawapay"
"github.com/stretchr/testify/assert"
)

const (
testPayoutId = "d334c312-6c18-4d7e-a0f1-097d398543d3"
)

func timeProvider() pawapay.TimeProviderFunc {
return func() time.Time {
t, _ := time.Parse("2006-01-02", "2021-01-01")
return t
}
}

func fileToStruct(filepath string, s interface{}) io.Reader {
bb, _ := os.ReadFile(filepath)
json.Unmarshal(bb, s)
return bytes.NewReader(bb)
}

type row struct {
Name string
Input interface{}
CustomServerURL func(t *testing.T) string
}

func TestCreatePayout(t *testing.T) {
table := []row{
{
Name: "Creating payout succeeds",
Input: pawapay.PayoutRequest{
PayoutId: testPayoutId,
Amount: pawapay.Amount{Currency: "GHS", Value: "1000"},
Description: "test",
PhoneNumber: pawapay.PhoneNumber{CountryCode: "233", Number: "247492147"},
Correspondent: "MTN_MOMO_GHA",
},
CustomServerURL: func(t *testing.T) string {
pawapayService := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {

var actualBody, expectedBody pawapay.CreatePayoutRequest

if err := json.NewDecoder(req.Body).Decode(&actualBody); err != nil {
log.Printf("error in unmarshalling %+v", err)
w.WriteHeader(http.StatusBadRequest)
return
}

t.Run("URL and request method is as expected", func(t *testing.T) {
expectedURL := "/payouts"
assert.Equal(t, http.MethodPost, req.Method)
assert.Equal(t, expectedURL, req.RequestURI)
})

t.Run("Request is as expected", func(t *testing.T) {
fileToStruct(filepath.Join("testdata", "create-payout-request.json"), &expectedBody)
assert.Equal(t, expectedBody, actualBody)
})

var resp pawapay.CreatePayoutResponse
fileToStruct(filepath.Join("testdata", "create-payout-response.json"), &resp)

w.WriteHeader(http.StatusOK)
bb, _ := json.Marshal(resp)
w.Write(bb)

}))
return pawapayService.URL
},
},
}

for _, row := range table {

c := pawapay.NewService(pawapay.Config{
BaseURL: row.CustomServerURL(t),
})

req := row.Input.(pawapay.PayoutRequest)

log.Printf("======== Running row: %s ==========", row.Name)

_, err := c.CreatePayout(timeProvider(), req)
t.Run("No error is returned", func(t *testing.T) {
assert.NoError(t, err)
})

}
}

func TestCreateBulkPayout(t *testing.T) {
table := []row{
{
Name: "Creating payout succeeds",
Input: []pawapay.PayoutRequest{
{
PayoutId: testPayoutId,
Amount: pawapay.Amount{Currency: "GHS", Value: "1000"},
Description: "test",
PhoneNumber: pawapay.PhoneNumber{CountryCode: "233", Number: "247492147"},
Correspondent: "MTN_MOMO_GHA",
},
},
CustomServerURL: func(t *testing.T) string {
pawapayService := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {

var actualBody, expectedBody []pawapay.CreatePayoutRequest

if err := json.NewDecoder(req.Body).Decode(&actualBody); err != nil {
log.Printf("error in unmarshalling %+v", err)
w.WriteHeader(http.StatusBadRequest)
return
}

t.Run("URL and request method is as expected", func(t *testing.T) {
expectedURL := "/payouts/bulk"
assert.Equal(t, http.MethodPost, req.Method)
assert.Equal(t, expectedURL, req.RequestURI)
})

t.Run("Request payload is as expected", func(t *testing.T) {
fileToStruct(filepath.Join("testdata", "create-bulk-payout-request.json"), &expectedBody)
assert.Equal(t, expectedBody, actualBody)
})

var resp []pawapay.CreatePayoutResponse
fileToStruct(filepath.Join("testdata", "create-bulk-payout-response.json"), &resp)

w.WriteHeader(http.StatusOK)
bb, _ := json.Marshal(resp)
w.Write(bb)

}))
return pawapayService.URL
},
},
}

for _, row := range table {

c := pawapay.NewService(pawapay.Config{
BaseURL: row.CustomServerURL(t),
})

req := row.Input.([]pawapay.PayoutRequest)

log.Printf("======== Running row: %s ==========", row.Name)

_, err := c.CreateBulkPayout(timeProvider(), req)
t.Run("No error is returned", func(t *testing.T) {
assert.NoError(t, err)
})

}
}
18 changes: 8 additions & 10 deletions payout.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@ import (
"fmt"
"net/http"
"os"
"strconv"
"time"

"github.com/biter777/countries"
"github.com/pkg/errors"
"github.com/pariz/gountries"
)

// Config represents the pawapay config
Expand Down Expand Up @@ -60,18 +58,18 @@ func NewService(c Config) Service {

// CreatePayout provides the functionality of creating a payout
// See docs https://docs.pawapay.co.uk/#operation/createPayout for more details
func (s *Service) CreatePayout(timeProvider TimeProviderFunc, payoutId string, amt Amount,
description string, pn PhoneNumber, correspondent string) (CreatePayoutResponse, error) {
func (s *Service) CreatePayout(timeProvider TimeProviderFunc, payoutReq PayoutRequest) (CreatePayoutResponse, error) {

cc, err := strconv.Atoi(pn.CountryCode)
query := gountries.New()
se, err := query.FindCountryByCallingCode(payoutReq.PhoneNumber.CountryCode)
if err != nil {
return CreatePayoutResponse{}, errors.Wrapf(err, "unable to convert countryCode=%s to integer", pn.CountryCode)
return CreatePayoutResponse{}, err
}
c := countries.ByNumeric(cc)
countryCode := c.Alpha3()
countryCode := se.Alpha3

resource := "payouts"
payload := s.newCreatePayoutRequest(timeProvider, payoutId, amt, countryCode, correspondent, description, pn)
payload := s.newCreatePayoutRequest(timeProvider, payoutReq.PayoutId, payoutReq.Amount, countryCode,
payoutReq.Correspondent, payoutReq.Description, payoutReq.PhoneNumber)

var response CreatePayoutResponse
annotation, err := s.makeRequest(http.MethodPost, resource, payload, &response)
Expand Down
15 changes: 15 additions & 0 deletions testdata/create-bulk-payout-request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"payoutId": "d334c312-6c18-4d7e-a0f1-097d398543d3",
"amount": "1000",
"currency": "GHS",
"country": "GHA",
"correspondent": "MTN_MOMO_GHA",
"recipient": {
"type": "MSISDN",
"address": { "value": "233247492147" }
},
"customerTimestamp": "2021-01-01T00:00:00Z",
"statementDescription": "test"
}
]
7 changes: 7 additions & 0 deletions testdata/create-bulk-payout-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"payoutId": "d334c312-6c18-4d7e-a0f1-097d398543d3",
"status": "ACCEPTED",
"created": "2020-10-19T11:17:01Z"
}
]
13 changes: 13 additions & 0 deletions testdata/create-payout-request.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"payoutId": "d334c312-6c18-4d7e-a0f1-097d398543d3",
"amount": "1000",
"currency": "GHS",
"country": "GHA",
"correspondent": "MTN_MOMO_GHA",
"recipient": {
"type": "MSISDN",
"address": { "value": "233247492147" }
},
"customerTimestamp": "2021-01-01T00:00:00Z",
"statementDescription": "test"
}
5 changes: 5 additions & 0 deletions testdata/create-payout-response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"payoutId": "d334c312-6c18-4d7e-a0f1-097d398543d3",
"status": "ACCEPTED",
"created": "2020-10-19T11:17:01Z"
}

0 comments on commit 19aa2fd

Please sign in to comment.