github.com/companieshouse/lfp-pay-api@v0.0.0-20230203133422-0ca455cd79f9/service/penalties_test.go (about) 1 package service 2 3 import ( 4 j "encoding/json" 5 "errors" 6 "net/http" 7 "testing" 8 9 "github.com/companieshouse/lfp-pay-api-core/models" 10 "github.com/companieshouse/lfp-pay-api-core/validators" 11 "github.com/companieshouse/lfp-pay-api/e5" 12 "github.com/companieshouse/lfp-pay-api/mocks" 13 "github.com/golang/mock/gomock" 14 "github.com/jarcoal/httpmock" 15 . "github.com/smartystreets/goconvey/convey" 16 ) 17 18 var e5ValidationError = ` 19 { 20 "httpStatusCode" : 400, 21 "status" : "BAD_REQUEST", 22 "timestamp" : "2019-07-07T18:40:07Z", 23 "messageCode" : null, 24 "message" : "Constraint Validation error", 25 "debugMessage" : null, 26 "subErrors" : [ { 27 "object" : "String", 28 "field" : "companyCode", 29 "rejectedValue" : "LPs", 30 "message" : "size must be between 0 and 2" 31 } ] 32 } 33 ` 34 35 func TestUnitMarkTransactionsAsPaid(t *testing.T) { 36 Convey("amount must be okay to parse as float", t, func() { 37 mockCtrl := gomock.NewController(t) 38 defer mockCtrl.Finish() 39 mockService := mocks.NewMockService(mockCtrl) 40 svc := &PayableResourceService{DAO: mockService} 41 42 c := &e5.Client{} 43 r := models.PayableResource{} 44 p := validators.PaymentInformation{Amount: "foo"} 45 46 err := MarkTransactionsAsPaid(svc, c, r, p) 47 So(err, ShouldNotBeNil) 48 }) 49 50 Convey("E5 request errors", t, func() { 51 httpmock.Activate() 52 defer httpmock.DeactivateAndReset() 53 54 mockCtrl := gomock.NewController(t) 55 defer mockCtrl.Finish() 56 mockService := mocks.NewMockService(mockCtrl) 57 svc := &PayableResourceService{DAO: mockService} 58 59 Convey("failure in creating a new payment", func() { 60 defer httpmock.Reset() 61 e5Responder := httpmock.NewStringResponder(http.StatusBadRequest, e5ValidationError) 62 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment", e5Responder) 63 64 mockService.EXPECT().SaveE5Error("10000024", "123", e5.CreateAction).Return(errors.New("")) 65 66 c := &e5.Client{} 67 p := validators.PaymentInformation{Amount: "150", PaymentID: "123"} 68 r := models.PayableResource{ 69 Reference: "123", 70 CompanyNumber: "10000024", 71 Transactions: []models.TransactionItem{ 72 {TransactionID: "123", Amount: 150}, 73 }, 74 } 75 76 err := MarkTransactionsAsPaid(svc, c, r, p) 77 78 So(err, ShouldBeError, e5.ErrE5BadRequest) 79 }) 80 81 Convey("failure in authorising a payment", func() { 82 defer httpmock.Reset() 83 e5Responder := httpmock.NewStringResponder(http.StatusBadRequest, e5ValidationError) 84 okResponder := httpmock.NewBytesResponder(http.StatusOK, nil) 85 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment", okResponder) 86 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment/authorise", e5Responder) 87 88 mockService.EXPECT().SaveE5Error("10000024", "123", e5.AuthoriseAction).Return(errors.New("")) 89 90 c := &e5.Client{} 91 p := validators.PaymentInformation{ 92 Amount: "150", 93 PaymentID: "123", 94 CreatedBy: "test@example.com", 95 } 96 97 r := models.PayableResource{ 98 Reference: "123", 99 CompanyNumber: "10000024", 100 Transactions: []models.TransactionItem{ 101 {TransactionID: "123", Amount: 150}, 102 }, 103 } 104 105 err := MarkTransactionsAsPaid(svc, c, r, p) 106 107 So(err, ShouldBeError, e5.ErrE5BadRequest) 108 }) 109 110 Convey("failure in confirming a payment", func() { 111 defer httpmock.Reset() 112 e5Responder := httpmock.NewStringResponder(http.StatusBadRequest, e5ValidationError) 113 okResponder := httpmock.NewBytesResponder(http.StatusOK, nil) 114 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment", okResponder) 115 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment/authorise", okResponder) 116 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment/confirm", e5Responder) 117 118 mockService.EXPECT().SaveE5Error("10000024", "123", e5.ConfirmAction).Return(errors.New("")) 119 120 c := &e5.Client{} 121 p := validators.PaymentInformation{ 122 Amount: "150", 123 PaymentID: "123", 124 CreatedBy: "test@example.com", 125 } 126 127 r := models.PayableResource{ 128 Reference: "123", 129 CompanyNumber: "10000024", 130 Transactions: []models.TransactionItem{ 131 {TransactionID: "123", Amount: 150}, 132 }, 133 } 134 135 err := MarkTransactionsAsPaid(svc, c, r, p) 136 137 So(err, ShouldBeError, e5.ErrE5BadRequest) 138 }) 139 140 Convey("no errors when all 3 calls to E5 succeed", func() { 141 defer httpmock.Reset() 142 okResponder := httpmock.NewBytesResponder(http.StatusOK, nil) 143 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment", okResponder) 144 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment/authorise", okResponder) 145 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment/confirm", okResponder) 146 147 c := &e5.Client{} 148 p := validators.PaymentInformation{ 149 Amount: "150", 150 PaymentID: "123", 151 CreatedBy: "test@example.com", 152 } 153 154 r := models.PayableResource{ 155 Reference: "123", 156 CompanyNumber: "10000024", 157 Transactions: []models.TransactionItem{ 158 {TransactionID: "123", Amount: 150}, 159 }, 160 } 161 162 err := MarkTransactionsAsPaid(svc, c, r, p) 163 164 So(err, ShouldBeNil) 165 }) 166 167 Convey("paymentId (PUON) is prefixed with 'X'", func() { 168 defer httpmock.Reset() 169 170 // struct to decode the request body 171 type body struct { 172 PaymentID string `json:"paymentId"` 173 } 174 175 // check the payment id value before responding. 176 paymentIDResponder := func(req *http.Request) (*http.Response, error) { 177 resp := httpmock.NewBytesResponse(http.StatusOK, nil) 178 defer req.Body.Close() 179 var b body 180 err := j.NewDecoder(req.Body).Decode(&b) 181 if err != nil { 182 return nil, errors.New("failed to read request body") 183 } 184 185 if b.PaymentID[0] != 'X' { 186 return nil, errors.New("paymentId does not begin with an X") 187 } 188 return resp, nil 189 } 190 191 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment", paymentIDResponder) 192 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment/authorise", paymentIDResponder) 193 httpmock.RegisterResponder(http.MethodPost, "/arTransactions/payment/confirm", paymentIDResponder) 194 195 c := &e5.Client{} 196 p := validators.PaymentInformation{ 197 Amount: "150", 198 PaymentID: "123", 199 CreatedBy: "test@example.com", 200 } 201 202 r := models.PayableResource{ 203 Reference: "123", 204 CompanyNumber: "10000024", 205 Transactions: []models.TransactionItem{ 206 {TransactionID: "123", Amount: 150}, 207 }, 208 } 209 210 err := MarkTransactionsAsPaid(svc, c, r, p) 211 So(err, ShouldBeNil) 212 213 }) 214 }) 215 }