github.com/Ingenico-ePayments/connect-sdk-go@v0.0.0-20240318153750-1f8cd329b9c9/Client_Logging_test.go (about) 1 package connectsdk 2 3 import ( 4 "math/rand" 5 "net" 6 "net/http" 7 "net/url" 8 "strconv" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/Ingenico-ePayments/connect-sdk-go/domain/definitions" 14 "github.com/Ingenico-ePayments/connect-sdk-go/domain/payment" 15 sdkErrors "github.com/Ingenico-ePayments/connect-sdk-go/errors" 16 "github.com/Ingenico-ePayments/connect-sdk-go/logging" 17 "github.com/Ingenico-ePayments/connect-sdk-go/merchant/services" 18 "github.com/Ingenico-ePayments/connect-sdk-go/merchant/tokens" 19 ) 20 21 var testConnectionJSON = `{ 22 "result": "OK" 23 }` 24 25 var convertAmountJSON = `{ 26 "convertedAmount": 4547504 27 }` 28 29 var createPaymentUnicodeJSON = `{ 30 "creationOutput": { 31 "additionalReference": "00000012341000059598", 32 "externalReference": "000000123410000595980000100001" 33 }, 34 "payment": { 35 "id": "000000123410000595980000100001", 36 "paymentOutput": { 37 "amountOfMoney": { 38 "amount": 2345, 39 "currencyCode": "CAD" 40 }, 41 "references": { 42 "paymentReference": "0" 43 }, 44 "paymentMethod": "redirect", 45 "redirectPaymentMethodSpecificOutput":{ 46 "paymentProductId":840, 47 "paymentProduct840SpecificOutput":{ 48 "customerAccount":{ 49 "firstName":"Theresa", 50 "surname":"Schröder" 51 }, 52 "customerAddress":{ 53 "city":"sittensen", 54 "countryCode":"DE", 55 "street":"Westerberg 25", 56 "zip":"27419" 57 } 58 } 59 } 60 }, 61 "status": "PENDING_APPROVAL", 62 "statusOutput": { 63 "isCancellable": true, 64 "statusCategory": "PENDING_MERCHANT", 65 "statusCode": 600, 66 "statusCodeChangeDateTime": "20160310094054", 67 "isAuthorized": true 68 } 69 } 70 } 71 ` 72 73 var createPaymentJSON = `{ 74 "creationOutput": { 75 "additionalReference": "00000012341000059598", 76 "externalReference": "000000123410000595980000100001" 77 }, 78 "payment": { 79 "id": "000000123410000595980000100001", 80 "paymentOutput": { 81 "amountOfMoney": { 82 "amount": 2345, 83 "currencyCode": "CAD" 84 }, 85 "references": { 86 "paymentReference": "0" 87 }, 88 "paymentMethod": "card", 89 "cardPaymentMethodSpecificOutput": { 90 "paymentProductId": 1, 91 "authorisationCode": "OK1131", 92 "card": { 93 "cardNumber": "************3456", 94 "expiryDate": "1220" 95 }, 96 "fraudResults": { 97 "fraudServiceResult": "error", 98 "avsResult": "X", 99 "cvvResult": "M" 100 } 101 } 102 }, 103 "status": "PENDING_APPROVAL", 104 "statusOutput": { 105 "isCancellable": true, 106 "statusCategory": "PENDING_MERCHANT", 107 "statusCode": 600, 108 "statusCodeChangeDateTime": "20160310094054", 109 "isAuthorized": true 110 } 111 } 112 }` 113 114 var createPaymentFailedInvalidCardNumberJSON = `{ 115 "errorId": "0953f236-9e54-4f23-9556-d66bc757dda8", 116 "errors": [{ 117 "code": "21000020", 118 "requestId": "24146", 119 "message": "VALUE **************** OF FIELD CREDITCARDNUMBER DID NOT PASS THE LUHNCHECK", 120 "httpStatusCode": 400 121 }] 122 }` 123 124 var createPaymentFailedRejectedJSON = `{ 125 "errorId": "833dfd83-52ae-419c-b871-9df1278da93e", 126 "errors": [{ 127 "code": "430330", 128 "message": "Not authorised", 129 "httpStatusCode": 402 130 }], 131 "paymentResult": { 132 "creationOutput": { 133 "additionalReference": "00000200001000059614", 134 "externalReference": "000002000010000596140000100001" 135 }, 136 "payment": { 137 "id": "000002000010000596140000100001", 138 "paymentOutput": { 139 "amountOfMoney": { 140 "amount": 2345, 141 "currencyCode": "CAD" 142 }, 143 "references": { 144 "paymentReference": "0" 145 }, 146 "paymentMethod": "card", 147 "cardPaymentMethodSpecificOutput": { 148 "paymentProductId": 1 149 } 150 }, 151 "status": "REJECTED", 152 "statusOutput": { 153 "errors": [{ 154 "code": "430330", 155 "requestId": "24162", 156 "message": "Not authorised", 157 "httpStatusCode": 402 158 }], 159 "isCancellable": false, 160 "statusCategory": "UNSUCCESSFUL", 161 "statusCode": 100, 162 "statusCodeChangeDateTime": "20160310121151", 163 "isAuthorized": false 164 } 165 } 166 } 167 }` 168 169 var unknownServerErrorJSON = `{ 170 "errorId": "fbff1179-7ba4-4894-9021-d8a0011d23a7", 171 "errors": [{ 172 "code": "9999", 173 "message": "UNKNOWN_SERVER_ERROR", 174 "httpStatusCode": 500 175 }] 176 }` 177 178 var notFoundErrorHTML = `Not Found` 179 180 func TestLoggingTestConnection(t *testing.T) { 181 logPrefix := "TestLoggingTestConnection" 182 183 responseHeaders := map[string]string{ 184 "Content-Type": "application/json", 185 "Dummy": "dummy", 186 } 187 requestHeaders := map[string][]string{} 188 189 listener, sl, client, err := createTestEnvironment( 190 "/v1/1234/services/testconnection", 191 createRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders)) 192 if err != nil { 193 t.Fatalf("%v: %v", logPrefix, err) 194 } 195 defer listener.Close() 196 defer sl.Close() 197 defer client.Close() 198 199 logger := &testLogger{} 200 client.EnableLogging(logger) 201 202 response, err := client.Merchant("1234").Services().Testconnection(nil) 203 if err != nil { 204 t.Fatalf("%v: %v", logPrefix, err) 205 } 206 207 if response.Result != nil && *response.Result != "OK" { 208 t.Fatalf("%v: responseResult %v", logPrefix, response.Result) 209 } 210 211 if len(logger.entries) != 2 { 212 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 213 } 214 215 firstEntry := logger.entries[0] 216 if firstEntry.request == nil { 217 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 218 } 219 if firstEntry.request.Method() != "GET" { 220 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 221 } 222 if firstEntry.request.URL().Path != "/v1/1234/services/testconnection" { 223 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 224 } 225 if firstEntry.request.Headers() == nil { 226 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 227 } 228 foundDate, foundMetainfo := false, false 229 for k, v := range firstEntry.request.Headers() { 230 switch k { 231 case "Authorization": 232 { 233 if v[0] != "********" { 234 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 235 } 236 237 break 238 } 239 case "Date": 240 { 241 foundDate = true 242 243 break 244 } 245 case "X-GCS-ServerMetaInfo": 246 { 247 foundMetainfo = true 248 249 break 250 } 251 } 252 } 253 if !foundDate { 254 t.Fatalf("%v: date header not found", logPrefix) 255 } 256 if !foundMetainfo { 257 t.Fatalf("%v: meta info header not found", logPrefix) 258 } 259 if firstEntry.err != nil { 260 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 261 } 262 263 secondEntry := logger.entries[1] 264 if secondEntry.response == nil { 265 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 266 } 267 if secondEntry.response.StatusCode() != http.StatusOK { 268 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 269 } 270 if secondEntry.response.ContentType() != "application/json" { 271 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType()) 272 } 273 if secondEntry.response.Headers() == nil { 274 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 275 } 276 if secondEntry.response.Body() == "" { 277 t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body()) 278 } 279 foundDate, foundDummy := false, false 280 for k := range secondEntry.response.Headers() { 281 switch k { 282 case "Date": 283 { 284 foundDate = true 285 286 break 287 } 288 case "Dummy": 289 { 290 foundDummy = true 291 292 break 293 } 294 } 295 } 296 if !foundDate { 297 t.Fatalf("%v: date header not found", logPrefix) 298 } 299 if !foundDummy { 300 t.Fatalf("%v: dummy header not found", logPrefix) 301 } 302 if secondEntry.err != nil { 303 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 304 } 305 } 306 307 func TestLoggingConvertAmount(t *testing.T) { 308 logPrefix := "TestLoggingConvertAmount" 309 310 responseHeaders := map[string]string{ 311 "Content-Type": "application/json", 312 "Dummy": "dummy", 313 } 314 requestHeaders := map[string][]string{} 315 316 listener, sl, client, err := createTestEnvironment( 317 "/v1/1234/services/convert/amount", 318 createRecordRequest(http.StatusOK, convertAmountJSON, responseHeaders, requestHeaders)) 319 if err != nil { 320 t.Fatalf("%v: %v", logPrefix, err) 321 } 322 defer listener.Close() 323 defer sl.Close() 324 defer client.Close() 325 326 logger := &testLogger{} 327 client.EnableLogging(logger) 328 329 var query services.ConvertAmountParams 330 amount := int64(1000) 331 query.Amount = &amount 332 source := "EUR" 333 query.Source = &source 334 target := "USD" 335 query.Target = &target 336 337 response, err := client.Merchant("1234").Services().ConvertAmount(query, nil) 338 if err != nil { 339 t.Fatalf("%v: %v", logPrefix, err) 340 } 341 342 if response.ConvertedAmount == nil { 343 t.Fatalf("%v: responseResult %v", logPrefix, response.ConvertedAmount) 344 } 345 346 if len(logger.entries) != 2 { 347 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 348 } 349 350 firstEntry := logger.entries[0] 351 if firstEntry.request == nil { 352 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 353 } 354 if firstEntry.request.Method() != "GET" { 355 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 356 } 357 if firstEntry.request.URL().Path != "/v1/1234/services/convert/amount" { 358 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 359 } 360 if firstEntry.request.Headers() == nil { 361 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 362 } 363 if firstEntry.request.Body() != "" { 364 t.Fatalf("%v: firstEntryRequestBody %v", logPrefix, firstEntry.request.Body()) 365 } 366 foundDate, foundMetainfo := false, false 367 for k, v := range firstEntry.request.Headers() { 368 switch k { 369 case "Authorization": 370 { 371 if v[0] != "********" { 372 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 373 } 374 375 break 376 } 377 case "Date": 378 { 379 foundDate = true 380 381 break 382 } 383 case "X-GCS-ServerMetaInfo": 384 { 385 foundMetainfo = true 386 387 break 388 } 389 } 390 } 391 if !foundDate { 392 t.Fatalf("%v: date header not found", logPrefix) 393 } 394 if !foundMetainfo { 395 t.Fatalf("%v: meta info header not found", logPrefix) 396 } 397 if firstEntry.err != nil { 398 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 399 } 400 401 secondEntry := logger.entries[1] 402 if secondEntry.response == nil { 403 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 404 } 405 if secondEntry.response.StatusCode() != http.StatusOK { 406 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 407 } 408 if secondEntry.response.ContentType() != "application/json" { 409 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType()) 410 } 411 if secondEntry.response.Headers() == nil { 412 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 413 } 414 if secondEntry.response.Body() == "" { 415 t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body()) 416 } 417 foundDate, foundDummy := false, false 418 for k := range secondEntry.response.Headers() { 419 switch k { 420 case "Date": 421 { 422 foundDate = true 423 424 break 425 } 426 case "Dummy": 427 { 428 foundDummy = true 429 430 break 431 } 432 } 433 } 434 if !foundDate { 435 t.Fatalf("%v: date header not found", logPrefix) 436 } 437 if !foundDummy { 438 t.Fatalf("%v: dummy header not found", logPrefix) 439 } 440 if secondEntry.err != nil { 441 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 442 } 443 } 444 445 func TestDeleteToken(t *testing.T) { 446 logPrefix := "TestDeleteToken" 447 448 responseHeaders := map[string]string{ 449 "Content-Type": "application/json", 450 "Dummy": "dummy", 451 } 452 requestHeaders := map[string][]string{} 453 454 listener, sl, client, err := createTestEnvironment( 455 "/v1/1234/tokens/5678", 456 createRecordRequest(http.StatusNoContent, "", responseHeaders, requestHeaders)) 457 if err != nil { 458 t.Fatalf("%v: %v", logPrefix, err) 459 } 460 defer listener.Close() 461 defer sl.Close() 462 defer client.Close() 463 464 logger := &testLogger{} 465 client.EnableLogging(logger) 466 467 var query tokens.DeleteParams 468 469 err = client.Merchant("1234").Tokens().Delete("5678", query, nil) 470 if err != nil { 471 t.Fatalf("%v: %v", logPrefix, err) 472 } 473 474 if len(logger.entries) != 2 { 475 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 476 } 477 478 firstEntry := logger.entries[0] 479 if firstEntry.request == nil { 480 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 481 } 482 if firstEntry.request.Method() != "DELETE" { 483 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 484 } 485 if firstEntry.request.URL().Path != "/v1/1234/tokens/5678" { 486 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 487 } 488 if firstEntry.request.Headers() == nil { 489 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 490 } 491 if firstEntry.request.Body() != "" { 492 t.Fatalf("%v: firstEntryRequestBody %v", logPrefix, firstEntry.request.Body()) 493 } 494 foundDate, foundMetainfo := false, false 495 for k, v := range firstEntry.request.Headers() { 496 switch k { 497 case "Authorization": 498 { 499 if v[0] != "********" { 500 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 501 } 502 503 break 504 } 505 case "Date": 506 { 507 foundDate = true 508 509 break 510 } 511 case "X-GCS-ServerMetaInfo": 512 { 513 foundMetainfo = true 514 515 break 516 } 517 } 518 } 519 if !foundDate { 520 t.Fatalf("%v: date header not found", logPrefix) 521 } 522 if !foundMetainfo { 523 t.Fatalf("%v: meta info header not found", logPrefix) 524 } 525 if firstEntry.err != nil { 526 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 527 } 528 529 secondEntry := logger.entries[1] 530 if secondEntry.response == nil { 531 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 532 } 533 if secondEntry.response.StatusCode() != http.StatusNoContent { 534 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 535 } 536 if secondEntry.response.ContentType() != "application/json" { 537 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType()) 538 } 539 if secondEntry.response.Headers() == nil { 540 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 541 } 542 if secondEntry.response.Body() != "" { 543 t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body()) 544 } 545 foundDate, foundDummy := false, false 546 for k := range secondEntry.response.Headers() { 547 switch k { 548 case "Date": 549 { 550 foundDate = true 551 552 break 553 } 554 case "Dummy": 555 { 556 foundDummy = true 557 558 break 559 } 560 } 561 } 562 if !foundDate { 563 t.Fatalf("%v: date header not found", logPrefix) 564 } 565 if !foundDummy { 566 t.Fatalf("%v: dummy header not found", logPrefix) 567 } 568 if secondEntry.err != nil { 569 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 570 } 571 } 572 573 func TestLoggingCreatePaymentUnicode(t *testing.T) { 574 logPrefix := "TestLoggingCreatePayment" 575 576 responseHeaders := map[string]string{ 577 "Content-Type": "application/json", 578 "Dummy": "dummy", 579 "Location": "http://localhost/v1/1234/payments/000000123410000595980000100001", 580 } 581 requestHeaders := map[string][]string{} 582 583 listener, sl, client, err := createTestEnvironment( 584 "/v1/1234/payments", 585 createRecordRequest(http.StatusCreated, createPaymentUnicodeJSON, responseHeaders, requestHeaders)) 586 if err != nil { 587 t.Fatalf("%v: %v", logPrefix, err) 588 } 589 defer listener.Close() 590 defer sl.Close() 591 defer client.Close() 592 593 logger := &testLogger{} 594 client.EnableLogging(logger) 595 596 var card definitions.Card 597 card.CardNumber = newString("1234567890123456") 598 card.Cvv = newString("123") 599 card.ExpiryDate = newString("1220") 600 601 var cardPaymentMethodSpecificInput payment.CardPaymentMethodSpecificInput 602 cardPaymentMethodSpecificInput.Card = &card 603 cardPaymentMethodSpecificInput.PaymentProductID = newInt32(1) 604 605 var amountOfMoney definitions.AmountOfMoney 606 amountOfMoney.Amount = newInt64(2345) 607 amountOfMoney.CurrencyCode = newString("CAD") 608 609 var billingAddress definitions.Address 610 billingAddress.CountryCode = newString("CA") 611 612 var customer payment.Customer 613 customer.BillingAddress = &billingAddress 614 615 var order payment.Order 616 order.AmountOfMoney = &amountOfMoney 617 order.Customer = &customer 618 619 var reqBody payment.CreateRequest 620 reqBody.CardPaymentMethodSpecificInput = &cardPaymentMethodSpecificInput 621 reqBody.Order = &order 622 623 response, err := client.Merchant("1234").Payments().Create(reqBody, nil) 624 if err != nil { 625 t.Fatalf("%v: %v", logPrefix, err) 626 } 627 628 if len(logger.entries) != 2 { 629 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 630 } 631 632 if response.Payment == nil { 633 t.Fatalf("%v: responsePayment nil", logPrefix) 634 } 635 if response.Payment.ID == nil { 636 t.Fatalf("%v: responsePaymentID nil", logPrefix) 637 } 638 639 firstEntry := logger.entries[0] 640 if firstEntry.request == nil { 641 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 642 } 643 if firstEntry.request.Method() != "POST" { 644 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 645 } 646 if firstEntry.request.URL().Path != "/v1/1234/payments" { 647 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 648 } 649 if firstEntry.request.Headers() == nil { 650 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 651 } 652 foundDate, foundMetainfo := false, false 653 for k, v := range firstEntry.request.Headers() { 654 switch k { 655 case "Authorization": 656 { 657 if v[0] != "********" { 658 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 659 } 660 661 break 662 } 663 case "Date": 664 { 665 foundDate = true 666 667 break 668 } 669 case "X-GCS-ServerMetaInfo": 670 { 671 foundMetainfo = true 672 673 break 674 } 675 } 676 } 677 if !foundDate { 678 t.Fatalf("%v: date header not found", logPrefix) 679 } 680 if !foundMetainfo { 681 t.Fatalf("%v: meta info header not found", logPrefix) 682 } 683 if firstEntry.err != nil { 684 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 685 } 686 687 secondEntry := logger.entries[1] 688 if !strings.Contains(secondEntry.response.Body(), "Schröder") { 689 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 690 } 691 if secondEntry.response == nil { 692 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 693 } 694 if secondEntry.response.StatusCode() != http.StatusCreated { 695 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 696 } 697 if secondEntry.response.ContentType() != "application/json" { 698 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType()) 699 } 700 if secondEntry.response.Headers() == nil { 701 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 702 } 703 if secondEntry.response.Body() == "" { 704 t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body()) 705 } 706 707 foundDate, foundDummy := false, false 708 for k := range secondEntry.response.Headers() { 709 switch k { 710 case "Date": 711 { 712 foundDate = true 713 714 break 715 } 716 case "Dummy": 717 { 718 foundDummy = true 719 720 break 721 } 722 } 723 } 724 if !foundDate { 725 t.Fatalf("%v: date header not found", logPrefix) 726 } 727 if !foundDummy { 728 t.Fatalf("%v: dummy header not found", logPrefix) 729 } 730 if secondEntry.err != nil { 731 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 732 } 733 } 734 func TestLoggingCreatePayment(t *testing.T) { 735 logPrefix := "TestLoggingCreatePayment" 736 737 responseHeaders := map[string]string{ 738 "Content-Type": "application/json", 739 "Dummy": "dummy", 740 "Location": "http://localhost/v1/1234/payments/000000123410000595980000100001", 741 } 742 requestHeaders := map[string][]string{} 743 744 listener, sl, client, err := createTestEnvironment( 745 "/v1/1234/payments", 746 createRecordRequest(http.StatusCreated, createPaymentJSON, responseHeaders, requestHeaders)) 747 if err != nil { 748 t.Fatalf("%v: %v", logPrefix, err) 749 } 750 defer listener.Close() 751 defer sl.Close() 752 defer client.Close() 753 754 logger := &testLogger{} 755 client.EnableLogging(logger) 756 757 var card definitions.Card 758 card.CardNumber = newString("1234567890123456") 759 card.Cvv = newString("123") 760 card.ExpiryDate = newString("1220") 761 762 var cardPaymentMethodSpecificInput payment.CardPaymentMethodSpecificInput 763 cardPaymentMethodSpecificInput.Card = &card 764 cardPaymentMethodSpecificInput.PaymentProductID = newInt32(1) 765 766 var amountOfMoney definitions.AmountOfMoney 767 amountOfMoney.Amount = newInt64(2345) 768 amountOfMoney.CurrencyCode = newString("CAD") 769 770 var billingAddress definitions.Address 771 billingAddress.CountryCode = newString("CA") 772 773 var customer payment.Customer 774 customer.BillingAddress = &billingAddress 775 776 var order payment.Order 777 order.AmountOfMoney = &amountOfMoney 778 order.Customer = &customer 779 780 var reqBody payment.CreateRequest 781 reqBody.CardPaymentMethodSpecificInput = &cardPaymentMethodSpecificInput 782 reqBody.Order = &order 783 784 response, err := client.Merchant("1234").Payments().Create(reqBody, nil) 785 if err != nil { 786 t.Fatalf("%v: %v", logPrefix, err) 787 } 788 789 if len(logger.entries) != 2 { 790 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 791 } 792 793 if response.Payment == nil { 794 t.Fatalf("%v: responsePayment nil", logPrefix) 795 } 796 if response.Payment.ID == nil { 797 t.Fatalf("%v: responsePaymentID nil", logPrefix) 798 } 799 800 firstEntry := logger.entries[0] 801 if firstEntry.request == nil { 802 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 803 } 804 if firstEntry.request.Method() != "POST" { 805 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 806 } 807 if firstEntry.request.URL().Path != "/v1/1234/payments" { 808 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 809 } 810 if firstEntry.request.Headers() == nil { 811 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 812 } 813 foundDate, foundMetainfo := false, false 814 for k, v := range firstEntry.request.Headers() { 815 switch k { 816 case "Authorization": 817 { 818 if v[0] != "********" { 819 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 820 } 821 822 break 823 } 824 case "Date": 825 { 826 foundDate = true 827 828 break 829 } 830 case "X-GCS-ServerMetaInfo": 831 { 832 foundMetainfo = true 833 834 break 835 } 836 } 837 } 838 if !foundDate { 839 t.Fatalf("%v: date header not found", logPrefix) 840 } 841 if !foundMetainfo { 842 t.Fatalf("%v: meta info header not found", logPrefix) 843 } 844 if firstEntry.err != nil { 845 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 846 } 847 848 secondEntry := logger.entries[1] 849 if secondEntry.response == nil { 850 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 851 } 852 if secondEntry.response.StatusCode() != http.StatusCreated { 853 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 854 } 855 if secondEntry.response.ContentType() != "application/json" { 856 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType()) 857 } 858 if secondEntry.response.Headers() == nil { 859 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 860 } 861 if secondEntry.response.Body() == "" { 862 t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body()) 863 } 864 865 foundDate, foundDummy := false, false 866 for k := range secondEntry.response.Headers() { 867 switch k { 868 case "Date": 869 { 870 foundDate = true 871 872 break 873 } 874 case "Dummy": 875 { 876 foundDummy = true 877 878 break 879 } 880 } 881 } 882 if !foundDate { 883 t.Fatalf("%v: date header not found", logPrefix) 884 } 885 if !foundDummy { 886 t.Fatalf("%v: dummy header not found", logPrefix) 887 } 888 if secondEntry.err != nil { 889 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 890 } 891 } 892 893 func TestCreatePaymentInvalidCardNumber(t *testing.T) { 894 logPrefix := "TestCreatePaymentInvalidCardNumber" 895 896 responseHeaders := map[string]string{ 897 "Content-Type": "application/json", 898 "Dummy": "dummy", 899 } 900 requestHeaders := map[string][]string{} 901 902 listener, sl, client, err := createTestEnvironment( 903 "/v1/1234/payments", 904 createRecordRequest(http.StatusBadRequest, createPaymentFailedInvalidCardNumberJSON, responseHeaders, requestHeaders)) 905 if err != nil { 906 t.Fatalf("%v: %v", logPrefix, err) 907 } 908 defer listener.Close() 909 defer sl.Close() 910 defer client.Close() 911 912 logger := &testLogger{} 913 client.EnableLogging(logger) 914 915 var card definitions.Card 916 card.CardNumber = newString("1234567890123456") 917 card.Cvv = newString("123") 918 card.ExpiryDate = newString("1220") 919 920 var cardPaymentMethodSpecificInput payment.CardPaymentMethodSpecificInput 921 cardPaymentMethodSpecificInput.Card = &card 922 cardPaymentMethodSpecificInput.PaymentProductID = newInt32(1) 923 924 var amountOfMoney definitions.AmountOfMoney 925 amountOfMoney.Amount = newInt64(2345) 926 amountOfMoney.CurrencyCode = newString("CAD") 927 928 var billingAddress definitions.Address 929 billingAddress.CountryCode = newString("CA") 930 931 var customer payment.Customer 932 customer.BillingAddress = &billingAddress 933 934 var order payment.Order 935 order.AmountOfMoney = &amountOfMoney 936 order.Customer = &customer 937 938 var reqBody payment.CreateRequest 939 reqBody.CardPaymentMethodSpecificInput = &cardPaymentMethodSpecificInput 940 reqBody.Order = &order 941 942 _, err = client.Merchant("1234").Payments().Create(reqBody, nil) 943 switch ce := err.(type) { 944 case *sdkErrors.ValidateError: 945 { 946 if ce.StatusCode() != http.StatusBadRequest { 947 t.Fatalf("%v: statusCode %v", logPrefix, ce.StatusCode()) 948 } 949 if ce.ResponseBody() != createPaymentFailedInvalidCardNumberJSON { 950 t.Fatalf("%v: responseBody %v", logPrefix, ce.ResponseBody()) 951 } 952 953 break 954 } 955 default: 956 { 957 t.Fatalf("%v: %v", logPrefix, err) 958 959 break 960 } 961 } 962 963 if len(logger.entries) != 2 { 964 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 965 } 966 967 firstEntry := logger.entries[0] 968 if firstEntry.request == nil { 969 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 970 } 971 if firstEntry.request.Method() != "POST" { 972 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 973 } 974 if firstEntry.request.URL().Path != "/v1/1234/payments" { 975 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 976 } 977 if firstEntry.request.Headers() == nil { 978 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 979 } 980 foundDate, foundMetainfo := false, false 981 for k, v := range firstEntry.request.Headers() { 982 switch k { 983 case "Authorization": 984 { 985 if v[0] != "********" { 986 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 987 } 988 989 break 990 } 991 case "Date": 992 { 993 foundDate = true 994 995 break 996 } 997 case "X-GCS-ServerMetaInfo": 998 { 999 foundMetainfo = true 1000 1001 break 1002 } 1003 } 1004 } 1005 if !foundDate { 1006 t.Fatalf("%v: date header not found", logPrefix) 1007 } 1008 if !foundMetainfo { 1009 t.Fatalf("%v: meta info header not found", logPrefix) 1010 } 1011 if firstEntry.err != nil { 1012 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 1013 } 1014 1015 secondEntry := logger.entries[1] 1016 if secondEntry.response == nil { 1017 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 1018 } 1019 if secondEntry.response.StatusCode() != http.StatusBadRequest { 1020 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 1021 } 1022 if secondEntry.response.ContentType() != "application/json" { 1023 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType()) 1024 } 1025 if secondEntry.response.Headers() == nil { 1026 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 1027 } 1028 foundDate, foundDummy := false, false 1029 for k := range secondEntry.response.Headers() { 1030 switch k { 1031 case "Date": 1032 { 1033 foundDate = true 1034 1035 break 1036 } 1037 case "Dummy": 1038 { 1039 foundDummy = true 1040 1041 break 1042 } 1043 } 1044 } 1045 if !foundDate { 1046 t.Fatalf("%v: date header not found", logPrefix) 1047 } 1048 if !foundDummy { 1049 t.Fatalf("%v: dummy header not found", logPrefix) 1050 } 1051 if secondEntry.err != nil { 1052 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 1053 } 1054 } 1055 1056 func TestCreatePaymentRejected(t *testing.T) { 1057 logPrefix := "TestCreatePaymentRejected" 1058 1059 responseHeaders := map[string]string{ 1060 "Content-Type": "application/json", 1061 "Dummy": "dummy", 1062 } 1063 requestHeaders := map[string][]string{} 1064 1065 listener, sl, client, err := createTestEnvironment( 1066 "/v1/1234/payments", 1067 createRecordRequest(http.StatusPaymentRequired, createPaymentFailedRejectedJSON, responseHeaders, requestHeaders)) 1068 if err != nil { 1069 t.Fatalf("%v: %v", logPrefix, err) 1070 } 1071 defer listener.Close() 1072 defer sl.Close() 1073 defer client.Close() 1074 1075 logger := &testLogger{} 1076 client.EnableLogging(logger) 1077 1078 var card definitions.Card 1079 card.CardNumber = newString("1234567890123456") 1080 card.Cvv = newString("123") 1081 card.ExpiryDate = newString("1220") 1082 1083 var cardPaymentMethodSpecificInput payment.CardPaymentMethodSpecificInput 1084 cardPaymentMethodSpecificInput.Card = &card 1085 cardPaymentMethodSpecificInput.PaymentProductID = newInt32(1) 1086 1087 var amountOfMoney definitions.AmountOfMoney 1088 amountOfMoney.Amount = newInt64(2345) 1089 amountOfMoney.CurrencyCode = newString("CAD") 1090 1091 var billingAddress definitions.Address 1092 billingAddress.CountryCode = newString("CA") 1093 1094 var customer payment.Customer 1095 customer.BillingAddress = &billingAddress 1096 1097 var order payment.Order 1098 order.AmountOfMoney = &amountOfMoney 1099 order.Customer = &customer 1100 1101 var reqBody payment.CreateRequest 1102 reqBody.CardPaymentMethodSpecificInput = &cardPaymentMethodSpecificInput 1103 reqBody.Order = &order 1104 1105 _, err = client.Merchant("1234").Payments().Create(reqBody, nil) 1106 switch ce := err.(type) { 1107 case *sdkErrors.DeclinedPaymentError: 1108 { 1109 if ce.StatusCode() != http.StatusPaymentRequired { 1110 t.Fatalf("%v: statusCode %v", logPrefix, ce.StatusCode()) 1111 } 1112 if ce.ResponseBody() != createPaymentFailedRejectedJSON { 1113 t.Fatalf("%v: responseBody %v", logPrefix, ce.ResponseBody()) 1114 } 1115 1116 break 1117 } 1118 default: 1119 { 1120 t.Fatalf("%v: %v", logPrefix, err) 1121 1122 break 1123 } 1124 } 1125 1126 if len(logger.entries) != 2 { 1127 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 1128 } 1129 1130 firstEntry := logger.entries[0] 1131 if firstEntry.request == nil { 1132 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 1133 } 1134 if firstEntry.request.Method() != "POST" { 1135 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 1136 } 1137 if firstEntry.request.URL().Path != "/v1/1234/payments" { 1138 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 1139 } 1140 if firstEntry.request.Headers() == nil { 1141 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 1142 } 1143 foundDate, foundMetainfo := false, false 1144 for k, v := range firstEntry.request.Headers() { 1145 switch k { 1146 case "Authorization": 1147 { 1148 if v[0] != "********" { 1149 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 1150 } 1151 1152 break 1153 } 1154 case "Date": 1155 { 1156 foundDate = true 1157 1158 break 1159 } 1160 case "X-GCS-ServerMetaInfo": 1161 { 1162 foundMetainfo = true 1163 1164 break 1165 } 1166 } 1167 } 1168 if !foundDate { 1169 t.Fatalf("%v: date header not found", logPrefix) 1170 } 1171 if !foundMetainfo { 1172 t.Fatalf("%v: meta info header not found", logPrefix) 1173 } 1174 if firstEntry.err != nil { 1175 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 1176 } 1177 1178 secondEntry := logger.entries[1] 1179 if secondEntry.response == nil { 1180 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 1181 } 1182 if secondEntry.response.StatusCode() != http.StatusPaymentRequired { 1183 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 1184 } 1185 if secondEntry.response.ContentType() != "application/json" { 1186 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType()) 1187 } 1188 if secondEntry.response.Headers() == nil { 1189 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 1190 } 1191 foundDate, foundDummy := false, false 1192 for k := range secondEntry.response.Headers() { 1193 switch k { 1194 case "Date": 1195 { 1196 foundDate = true 1197 1198 break 1199 } 1200 case "Dummy": 1201 { 1202 foundDummy = true 1203 1204 break 1205 } 1206 } 1207 } 1208 if !foundDate { 1209 t.Fatalf("%v: date header not found", logPrefix) 1210 } 1211 if !foundDummy { 1212 t.Fatalf("%v: dummy header not found", logPrefix) 1213 } 1214 if secondEntry.err != nil { 1215 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 1216 } 1217 } 1218 1219 func TestLoggingUnknownServerError(t *testing.T) { 1220 logPrefix := "TestLoggingUnknownServerError" 1221 1222 responseHeaders := map[string]string{ 1223 "Content-Type": "application/json", 1224 "Dummy": "dummy", 1225 } 1226 requestHeaders := map[string][]string{} 1227 1228 listener, sl, client, err := createTestEnvironment( 1229 "/v1/1234/services/testconnection", 1230 createRecordRequest(http.StatusInternalServerError, unknownServerErrorJSON, responseHeaders, requestHeaders)) 1231 if err != nil { 1232 t.Fatalf("%v: %v", logPrefix, err) 1233 } 1234 defer listener.Close() 1235 defer sl.Close() 1236 defer client.Close() 1237 1238 logger := &testLogger{} 1239 client.EnableLogging(logger) 1240 1241 _, err = client.Merchant("1234").Services().Testconnection(nil) 1242 switch ce := err.(type) { 1243 case *sdkErrors.GlobalCollectError: 1244 { 1245 if ce.StatusCode() != http.StatusInternalServerError { 1246 t.Fatalf("%v: statusCode %v", logPrefix, ce.StatusCode()) 1247 } 1248 if ce.ResponseBody() != unknownServerErrorJSON { 1249 t.Fatalf("%v: responseBody %v", logPrefix, ce.ResponseBody()) 1250 } 1251 1252 break 1253 } 1254 default: 1255 { 1256 t.Fatalf("%v: %v", logPrefix, err) 1257 1258 break 1259 } 1260 } 1261 1262 if len(logger.entries) != 2 { 1263 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 1264 } 1265 1266 firstEntry := logger.entries[0] 1267 if firstEntry.request == nil { 1268 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 1269 } 1270 if firstEntry.request.Method() != "GET" { 1271 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 1272 } 1273 if firstEntry.request.URL().Path != "/v1/1234/services/testconnection" { 1274 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 1275 } 1276 if firstEntry.request.Headers() == nil { 1277 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 1278 } 1279 foundDate, foundMetainfo := false, false 1280 for k, v := range firstEntry.request.Headers() { 1281 switch k { 1282 case "Authorization": 1283 { 1284 if v[0] != "********" { 1285 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 1286 } 1287 1288 break 1289 } 1290 case "Date": 1291 { 1292 foundDate = true 1293 1294 break 1295 } 1296 case "X-GCS-ServerMetaInfo": 1297 { 1298 foundMetainfo = true 1299 1300 break 1301 } 1302 } 1303 } 1304 if !foundDate { 1305 t.Fatalf("%v: date header not found", logPrefix) 1306 } 1307 if !foundMetainfo { 1308 t.Fatalf("%v: meta info header not found", logPrefix) 1309 } 1310 if firstEntry.err != nil { 1311 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 1312 } 1313 1314 secondEntry := logger.entries[1] 1315 if secondEntry.response == nil { 1316 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 1317 } 1318 if secondEntry.response.StatusCode() != http.StatusInternalServerError { 1319 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 1320 } 1321 if secondEntry.response.ContentType() != "application/json" { 1322 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, secondEntry.response.ContentType()) 1323 } 1324 if secondEntry.response.Headers() == nil { 1325 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 1326 } 1327 if secondEntry.response.Body() == "" { 1328 t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body()) 1329 } 1330 foundDate, foundDummy := false, false 1331 for k := range secondEntry.response.Headers() { 1332 switch k { 1333 case "Date": 1334 { 1335 foundDate = true 1336 1337 break 1338 } 1339 case "Dummy": 1340 { 1341 foundDummy = true 1342 1343 break 1344 } 1345 } 1346 } 1347 if !foundDate { 1348 t.Fatalf("%v: date header not found", logPrefix) 1349 } 1350 if !foundDummy { 1351 t.Fatalf("%v: dummy header not found", logPrefix) 1352 } 1353 if secondEntry.err != nil { 1354 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 1355 } 1356 } 1357 1358 func TestNonJson(t *testing.T) { 1359 logPrefix := "TestNonJson" 1360 1361 responseHeaders := map[string]string{ 1362 "Dummy": "dummy", 1363 } 1364 requestHeaders := map[string][]string{} 1365 1366 listener, sl, client, err := createTestEnvironment( 1367 "/v1/1234/services/testconnection", 1368 createRecordRequest(http.StatusNotFound, notFoundErrorHTML, responseHeaders, requestHeaders)) 1369 if err != nil { 1370 t.Fatalf("%v: %v", logPrefix, err) 1371 } 1372 defer listener.Close() 1373 defer sl.Close() 1374 defer client.Close() 1375 1376 logger := &testLogger{} 1377 client.EnableLogging(logger) 1378 1379 _, err = client.Merchant("1234").Services().Testconnection(nil) 1380 switch err.(type) { 1381 case *sdkErrors.NotFoundError: 1382 { 1383 break 1384 } 1385 default: 1386 { 1387 t.Fatalf("%v: %v", logPrefix, err) 1388 1389 break 1390 } 1391 } 1392 1393 if len(logger.entries) != 2 { 1394 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 1395 } 1396 1397 firstEntry := logger.entries[0] 1398 if firstEntry.request == nil { 1399 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 1400 } 1401 if firstEntry.request.Method() != "GET" { 1402 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 1403 } 1404 if firstEntry.request.URL().Path != "/v1/1234/services/testconnection" { 1405 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 1406 } 1407 if firstEntry.request.Headers() == nil { 1408 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 1409 } 1410 foundDate, foundMetainfo := false, false 1411 for k, v := range firstEntry.request.Headers() { 1412 switch k { 1413 case "Authorization": 1414 { 1415 if v[0] != "********" { 1416 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 1417 } 1418 1419 break 1420 } 1421 case "Date": 1422 { 1423 foundDate = true 1424 1425 break 1426 } 1427 case "X-GCS-ServerMetaInfo": 1428 { 1429 foundMetainfo = true 1430 1431 break 1432 } 1433 } 1434 } 1435 if !foundDate { 1436 t.Fatalf("%v: date header not found", logPrefix) 1437 } 1438 if !foundMetainfo { 1439 t.Fatalf("%v: meta info header not found", logPrefix) 1440 } 1441 if firstEntry.err != nil { 1442 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 1443 } 1444 1445 secondEntry := logger.entries[1] 1446 if secondEntry.response == nil { 1447 t.Fatalf("%v: secondEntryResponse %v", logPrefix, secondEntry.response) 1448 } 1449 if secondEntry.response.StatusCode() != http.StatusNotFound { 1450 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, secondEntry.response.StatusCode()) 1451 } 1452 if secondEntry.response.Headers() == nil { 1453 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, secondEntry.response.Headers()) 1454 } 1455 if secondEntry.response.Body() == "" { 1456 t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, secondEntry.response.Body()) 1457 } 1458 foundDate, foundDummy := false, false 1459 for k := range secondEntry.response.Headers() { 1460 switch k { 1461 case "Date": 1462 { 1463 foundDate = true 1464 1465 break 1466 } 1467 case "Dummy": 1468 { 1469 foundDummy = true 1470 1471 break 1472 } 1473 } 1474 } 1475 if !foundDate { 1476 t.Fatalf("%v: date header not found", logPrefix) 1477 } 1478 if !foundDummy { 1479 t.Fatalf("%v: dummy header not found", logPrefix) 1480 } 1481 if secondEntry.err != nil { 1482 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 1483 } 1484 } 1485 1486 func TestReadTimeout(t *testing.T) { 1487 logPrefix := "TestReadTimeout" 1488 1489 responseHeaders := map[string]string{ 1490 "Content-Type": "application/json", 1491 "Dummy": "dummy", 1492 } 1493 requestHeaders := map[string][]string{} 1494 1495 listener, sl, client, err := createTimedTestEnvironment( 1496 "/v1/1234/services/testconnection", 1497 createDelayedRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders, 1*time.Second), 1498 1*time.Millisecond, 1499 10*time.Millisecond) 1500 if err != nil { 1501 t.Fatalf("%v: %v", logPrefix, err) 1502 } 1503 defer listener.Close() 1504 defer sl.Close() 1505 defer client.Close() 1506 1507 logger := &testLogger{} 1508 client.EnableLogging(logger) 1509 1510 _, err = client.Merchant("1234").Services().Testconnection(nil) 1511 switch ce := err.(type) { 1512 case *sdkErrors.CommunicationError: 1513 { 1514 internalError := ce.InternalError() 1515 1516 if uErr, ok := internalError.(*url.Error); ok && uErr.Timeout() { 1517 break 1518 } 1519 1520 t.Fatalf("%v: %v", logPrefix, internalError) 1521 1522 break 1523 } 1524 default: 1525 { 1526 t.Fatalf("%v: %v", logPrefix, err) 1527 1528 break 1529 } 1530 } 1531 1532 if len(logger.entries) != 2 { 1533 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 1534 } 1535 1536 firstEntry := logger.entries[0] 1537 if firstEntry.request == nil { 1538 t.Fatalf("%v: firstEntryRequest %v", logPrefix, firstEntry.request) 1539 } 1540 if firstEntry.request.Method() != "GET" { 1541 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, firstEntry.request.Method()) 1542 } 1543 if firstEntry.request.URL().Path != "/v1/1234/services/testconnection" { 1544 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, firstEntry.request.URL().Path) 1545 } 1546 if firstEntry.request.Headers() == nil { 1547 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, firstEntry.request.Headers()) 1548 } 1549 foundDate, foundMetainfo := false, false 1550 for k, v := range firstEntry.request.Headers() { 1551 switch k { 1552 case "Authorization": 1553 { 1554 if v[0] != "********" { 1555 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 1556 } 1557 1558 break 1559 } 1560 case "Date": 1561 { 1562 foundDate = true 1563 1564 break 1565 } 1566 case "X-GCS-ServerMetaInfo": 1567 { 1568 foundMetainfo = true 1569 1570 break 1571 } 1572 } 1573 } 1574 if !foundDate { 1575 t.Fatalf("%v: date header not found", logPrefix) 1576 } 1577 if !foundMetainfo { 1578 t.Fatalf("%v: meta info header not found", logPrefix) 1579 } 1580 if firstEntry.err != nil { 1581 t.Fatalf("%v: firstEntryErr %v", logPrefix, firstEntry.err) 1582 } 1583 1584 secondEntry := logger.entries[1] 1585 if secondEntry.err == nil { 1586 t.Fatalf("%v: secondEntryErr %v", logPrefix, secondEntry.err) 1587 } 1588 } 1589 1590 func TestLogRequestOnly(t *testing.T) { 1591 logPrefix := "TestLogRequestOnly" 1592 1593 responseHeaders := map[string]string{ 1594 "Content-Type": "application/json", 1595 "Dummy": "dummy", 1596 } 1597 requestHeaders := map[string][]string{} 1598 1599 listener, sl, client, mux, err := createEmptyTestEnvironment() 1600 if err != nil { 1601 t.Fatalf("%v: %v", logPrefix, err) 1602 } 1603 defer listener.Close() 1604 defer sl.Close() 1605 defer client.Close() 1606 1607 mux.HandleFunc("/v1/1234/services/testconnection", 1608 createNonLoggedRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders, client)) 1609 1610 logger := &testLogger{} 1611 client.EnableLogging(logger) 1612 1613 _, err = client.Merchant("1234").Services().Testconnection(nil) 1614 if err != nil { 1615 t.Fatalf("%v: %v", logPrefix, err) 1616 } 1617 1618 if len(logger.entries) != 1 { 1619 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 1620 } 1621 1622 requestEntry := logger.entries[0] 1623 if requestEntry.request == nil { 1624 t.Fatalf("%v: firstEntryRequest %v", logPrefix, requestEntry.request) 1625 } 1626 if requestEntry.request.Method() != "GET" { 1627 t.Fatalf("%v: firstEntryRequestMethod %v", logPrefix, requestEntry.request.Method()) 1628 } 1629 if requestEntry.request.URL().Path != "/v1/1234/services/testconnection" { 1630 t.Fatalf("%v: firstEntryRequestURL %v", logPrefix, requestEntry.request.URL().Path) 1631 } 1632 if requestEntry.request.Headers() == nil { 1633 t.Fatalf("%v: firstEntryRequestHeaders %v", logPrefix, requestEntry.request.Headers()) 1634 } 1635 foundDate, foundMetainfo := false, false 1636 for k, v := range requestEntry.request.Headers() { 1637 switch k { 1638 case "Authorization": 1639 { 1640 if v[0] != "********" { 1641 t.Fatalf("%v: authorizationHeader %v", logPrefix, v) 1642 } 1643 1644 break 1645 } 1646 case "Date": 1647 { 1648 foundDate = true 1649 1650 break 1651 } 1652 case "X-GCS-ServerMetaInfo": 1653 { 1654 foundMetainfo = true 1655 1656 break 1657 } 1658 } 1659 } 1660 if !foundDate { 1661 t.Fatalf("%v: date header not found", logPrefix) 1662 } 1663 if !foundMetainfo { 1664 t.Fatalf("%v: meta info header not found", logPrefix) 1665 } 1666 if requestEntry.err != nil { 1667 t.Fatalf("%v: firstEntryErr %v", logPrefix, requestEntry.err) 1668 } 1669 } 1670 1671 func TestLogResponseOnly(t *testing.T) { 1672 logPrefix := "TestLogResponseOnly" 1673 1674 responseHeaders := map[string]string{ 1675 "Content-Type": "application/json", 1676 "Dummy": "dummy", 1677 } 1678 requestHeaders := map[string][]string{} 1679 1680 listener, sl, client, mux, err := createEmptyTestEnvironment() 1681 if err != nil { 1682 t.Fatalf("%v: %v", logPrefix, err) 1683 } 1684 defer listener.Close() 1685 defer sl.Close() 1686 defer client.Close() 1687 1688 logger := &testLogger{} 1689 1690 mux.HandleFunc("/v1/1234/services/testconnection", 1691 createLoggedRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders, client, logger)) 1692 1693 _, err = client.Merchant("1234").Services().Testconnection(nil) 1694 if err != nil { 1695 t.Fatalf("%v: %v", logPrefix, err) 1696 } 1697 1698 if len(logger.entries) != 1 { 1699 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 1700 } 1701 1702 responseEntry := logger.entries[0] 1703 if responseEntry.response == nil { 1704 t.Fatalf("%v: secondEntryResponse %v", logPrefix, responseEntry.response) 1705 } 1706 if responseEntry.response.StatusCode() != http.StatusOK { 1707 t.Fatalf("%v: secondEntryResponseStatusCode %v", logPrefix, responseEntry.response.StatusCode()) 1708 } 1709 if responseEntry.response.ContentType() != "application/json" { 1710 t.Fatalf("%v: secondEntryResponseContentType %v", logPrefix, responseEntry.response.ContentType()) 1711 } 1712 if responseEntry.response.Headers() == nil { 1713 t.Fatalf("%v: secondEntryResponseHeaders %v", logPrefix, responseEntry.response.Headers()) 1714 } 1715 if responseEntry.response.Body() == "" { 1716 t.Fatalf("%v: secondEntryResponseBody %v", logPrefix, responseEntry.response.Body()) 1717 } 1718 foundDate, foundDummy := false, false 1719 for k := range responseEntry.response.Headers() { 1720 switch k { 1721 case "Date": 1722 { 1723 foundDate = true 1724 1725 break 1726 } 1727 case "Dummy": 1728 { 1729 foundDummy = true 1730 1731 break 1732 } 1733 } 1734 } 1735 if !foundDate { 1736 t.Fatalf("%v: date header not found", logPrefix) 1737 } 1738 if !foundDummy { 1739 t.Fatalf("%v: dummy header not found", logPrefix) 1740 } 1741 if responseEntry.err != nil { 1742 t.Fatalf("%v: secondEntryErr %v", logPrefix, responseEntry.err) 1743 } 1744 } 1745 1746 func TestLogErrorOnly(t *testing.T) { 1747 logPrefix := "TestLogErrorOnly" 1748 1749 responseHeaders := map[string]string{ 1750 "Content-Type": "application/json", 1751 "Dummy": "dummy", 1752 } 1753 requestHeaders := map[string][]string{} 1754 1755 listener, sl, client, mux, err := createEmptyTimedTestEnvironment( 1756 20*time.Millisecond, 1757 50*time.Millisecond) 1758 if err != nil { 1759 t.Fatalf("%v: %v", logPrefix, err) 1760 } 1761 defer listener.Close() 1762 defer sl.Close() 1763 defer client.Close() 1764 1765 logger := &testLogger{} 1766 1767 mux.HandleFunc("/v1/1234/services/testconnection", 1768 createLoggedDelayedRecordRequest(http.StatusOK, testConnectionJSON, responseHeaders, requestHeaders, 1*time.Second, client, logger)) 1769 1770 _, err = client.Merchant("1234").Services().Testconnection(nil) 1771 switch ce := err.(type) { 1772 case *sdkErrors.CommunicationError: 1773 { 1774 internalError := ce.InternalError() 1775 1776 if uErr, ok := internalError.(*url.Error); ok && uErr.Timeout() { 1777 break 1778 } 1779 1780 t.Fatalf("%v: %v", logPrefix, internalError) 1781 1782 break 1783 } 1784 default: 1785 { 1786 t.Fatalf("%v: %v", logPrefix, err) 1787 1788 break 1789 } 1790 } 1791 1792 if len(logger.entries) != 1 { 1793 t.Fatalf("%v: loggerEntries %v", logPrefix, len(logger.entries)) 1794 } 1795 1796 errorEntry := logger.entries[0] 1797 if errorEntry.err == nil { 1798 t.Fatalf("%v: secondEntryErr %v", logPrefix, errorEntry.err) 1799 } 1800 } 1801 1802 func createNonLoggedRecordRequest(statusCode int, body string, responseHeaders map[string]string, requestHeaders map[string][]string, client *Client) func(http.ResponseWriter, *http.Request) { 1803 return func(rw http.ResponseWriter, r *http.Request) { 1804 client.DisableLogging() 1805 1806 for k, v := range r.Header { 1807 if k == "X-Gcs-Idempotence-Key" { 1808 k = "X-GCS-Idempotence-Key" 1809 } 1810 1811 requestHeaders[k] = v 1812 } 1813 1814 for k, v := range responseHeaders { 1815 rw.Header()[k] = []string{v} 1816 } 1817 1818 rw.WriteHeader(statusCode) 1819 1820 rw.Write([]byte(body)) 1821 } 1822 } 1823 1824 func createLoggedRecordRequest(statusCode int, body string, responseHeaders map[string]string, requestHeaders map[string][]string, client *Client, logger logging.CommunicatorLogger) func(http.ResponseWriter, *http.Request) { 1825 return func(rw http.ResponseWriter, r *http.Request) { 1826 client.EnableLogging(logger) 1827 1828 for k, v := range r.Header { 1829 if k == "X-Gcs-Idempotence-Key" { 1830 k = "X-GCS-Idempotence-Key" 1831 } 1832 1833 requestHeaders[k] = v 1834 } 1835 1836 for k, v := range responseHeaders { 1837 rw.Header()[k] = []string{v} 1838 } 1839 1840 rw.WriteHeader(statusCode) 1841 1842 rw.Write([]byte(body)) 1843 } 1844 } 1845 1846 func createDelayedRecordRequest(statusCode int, body string, responseHeaders map[string]string, requestHeaders map[string][]string, delay time.Duration) func(http.ResponseWriter, *http.Request) { 1847 return func(rw http.ResponseWriter, r *http.Request) { 1848 time.Sleep(delay) 1849 1850 for k, v := range r.Header { 1851 if k == "X-Gcs-Idempotence-Key" { 1852 k = "X-GCS-Idempotence-Key" 1853 } 1854 1855 requestHeaders[k] = v 1856 } 1857 1858 for k, v := range responseHeaders { 1859 rw.Header()[k] = []string{v} 1860 } 1861 1862 rw.WriteHeader(statusCode) 1863 1864 rw.Write([]byte(body)) 1865 } 1866 } 1867 1868 func createLoggedDelayedRecordRequest(statusCode int, body string, responseHeaders map[string]string, requestHeaders map[string][]string, delay time.Duration, client *Client, logger logging.CommunicatorLogger) func(http.ResponseWriter, *http.Request) { 1869 return func(rw http.ResponseWriter, r *http.Request) { 1870 client.EnableLogging(logger) 1871 time.Sleep(delay) 1872 1873 for k, v := range r.Header { 1874 if k == "X-Gcs-Idempotence-Key" { 1875 k = "X-GCS-Idempotence-Key" 1876 } 1877 1878 requestHeaders[k] = v 1879 } 1880 1881 for k, v := range responseHeaders { 1882 rw.Header()[k] = []string{v} 1883 } 1884 1885 rw.WriteHeader(statusCode) 1886 1887 rw.Write([]byte(body)) 1888 } 1889 } 1890 1891 func createTimedTestEnvironment(path string, handleFunc http.HandlerFunc, socketTimeout, connectTimeout time.Duration) (net.Listener, *stoppableListener, *Client, error) { 1892 mux := http.NewServeMux() 1893 mux.Handle(path, handleFunc) 1894 1895 httpServer := &http.Server{ 1896 Handler: mux, 1897 } 1898 1899 randomPort := (1 << 12) + rand.Intn(1<<15) 1900 listener, err := net.Listen("tcp", ":"+strconv.Itoa(randomPort)) 1901 if err != nil { 1902 return nil, nil, nil, err 1903 } 1904 1905 sl, err := mockServer(httpServer, listener) 1906 if err != nil { 1907 return nil, nil, nil, err 1908 } 1909 1910 client, err := createClient(socketTimeout, connectTimeout, randomPort) 1911 if err != nil { 1912 return nil, nil, nil, err 1913 } 1914 1915 return listener, sl, client, nil 1916 } 1917 1918 func createEmptyTestEnvironment() (net.Listener, *stoppableListener, *Client, *http.ServeMux, error) { 1919 mux := http.NewServeMux() 1920 1921 httpServer := &http.Server{ 1922 Handler: mux, 1923 } 1924 1925 randomPort := (1 << 12) + rand.Intn(1<<15) 1926 listener, err := net.Listen("tcp", ":"+strconv.Itoa(randomPort)) 1927 if err != nil { 1928 return nil, nil, nil, nil, err 1929 } 1930 1931 sl, err := mockServer(httpServer, listener) 1932 if err != nil { 1933 return nil, nil, nil, nil, err 1934 } 1935 1936 client, err := createClient(50*time.Second, 50*time.Second, randomPort) 1937 if err != nil { 1938 return nil, nil, nil, nil, err 1939 } 1940 1941 return listener, sl, client, mux, nil 1942 } 1943 1944 func createEmptyTimedTestEnvironment(socketTimeout, connectTimeout time.Duration) (net.Listener, *stoppableListener, *Client, *http.ServeMux, error) { 1945 mux := http.NewServeMux() 1946 1947 httpServer := &http.Server{ 1948 Handler: mux, 1949 } 1950 1951 randomPort := (1 << 12) + rand.Intn(1<<15) 1952 listener, err := net.Listen("tcp", ":"+strconv.Itoa(randomPort)) 1953 if err != nil { 1954 return nil, nil, nil, nil, err 1955 } 1956 1957 sl, err := mockServer(httpServer, listener) 1958 if err != nil { 1959 return nil, nil, nil, nil, err 1960 } 1961 1962 client, err := createClient(socketTimeout, connectTimeout, randomPort) 1963 if err != nil { 1964 return nil, nil, nil, nil, err 1965 } 1966 1967 return listener, sl, client, mux, nil 1968 } 1969 1970 type testLogger struct { 1971 entries []testLoggerEntry 1972 } 1973 1974 func (t *testLogger) Log(message string) { 1975 t.entries = append(t.entries, testLoggerEntry{message, nil, nil, nil}) 1976 } 1977 1978 func (t *testLogger) LogError(message string, err error) { 1979 t.entries = append(t.entries, testLoggerEntry{message, err, nil, nil}) 1980 } 1981 1982 func (t *testLogger) LogResponseLogMessage(response *logging.ResponseLogMessage) { 1983 t.entries = append(t.entries, testLoggerEntry{"", nil, response, nil}) 1984 } 1985 1986 func (t *testLogger) LogRequestLogMessage(request *logging.RequestLogMessage) { 1987 t.entries = append(t.entries, testLoggerEntry{"", nil, nil, request}) 1988 } 1989 1990 type testLoggerEntry struct { 1991 message string 1992 err error 1993 response *logging.ResponseLogMessage 1994 request *logging.RequestLogMessage 1995 }