diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c2344cf83..84b7ffec1 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -9,22 +9,18 @@ jobs: name: Build & Verify runs-on: ubuntu-latest steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-go@v4 with: go-version: 1.13 - - name: Get dependencies run: go get -v -t -d ./... - - name: Build run: go build -v . - - name: Test - run: go test ./... + run: go test -v ./... -tags $GO_TEST_TAGS env: + GO_TEST_TAGS: ${{ github.ref == 'refs/heads/main' && 'integration' || 'unit' }} ADYEN_API_KEY: ${{ secrets.ADYEN_API_KEY }} ADYEN_MERCHANT: ${{ secrets.ADYEN_MERCHANT }} ADYEN_PASSWORD: ${{ secrets.ADYEN_PASSWORD }} diff --git a/src/adyen/api_test.go b/src/adyen/api_test.go index 2bc80ddb9..29d874920 100644 --- a/src/adyen/api_test.go +++ b/src/adyen/api_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package adyen import ( diff --git a/tests/api_modifications_test.go b/tests/api_modifications_test.go index b9f2afc27..6f542154c 100644 --- a/tests/api_modifications_test.go +++ b/tests/api_modifications_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package tests import ( diff --git a/tests/balanceplatform_acs_webhooks_handler_test.go b/tests/balanceplatform/acswebhook_test.go similarity index 95% rename from tests/balanceplatform_acs_webhooks_handler_test.go rename to tests/balanceplatform/acswebhook_test.go index 3498b9bff..0e3119a44 100644 --- a/tests/balanceplatform_acs_webhooks_handler_test.go +++ b/tests/balanceplatform/acswebhook_test.go @@ -1,4 +1,4 @@ -package tests +package balanceplatform import ( "github.com/adyen/adyen-go-api-library/v8/src/acswebhook" @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" ) -func Test_BalancePlatform_Acs_Webhooks_HandleRequest(t *testing.T) { +func TestHandleAuthenticationNotificationRequest(t *testing.T) { t.Run("on balancePlatform.authentication.created", func(t *testing.T) { notificationJson := `{ "data": { diff --git a/tests/balanceplatform_configuration_webhooks_handler_test.go b/tests/balanceplatform/configurationwebhook_test.go similarity index 95% rename from tests/balanceplatform_configuration_webhooks_handler_test.go rename to tests/balanceplatform/configurationwebhook_test.go index 95f783648..71833c895 100644 --- a/tests/balanceplatform_configuration_webhooks_handler_test.go +++ b/tests/balanceplatform/configurationwebhook_test.go @@ -1,4 +1,4 @@ -package tests +package balanceplatform import ( "testing" @@ -9,8 +9,7 @@ import ( "github.com/adyen/adyen-go-api-library/v8/src/configurationwebhook" ) -func Test_BalancePlatform_Configuration_Webhooks_HandleRequest(t *testing.T) { - +func TestHandleAccountHolderNotificationRequest(t *testing.T) { t.Run("should return accountHolder created success", func(t *testing.T) { notificationJson := `{ "data": { diff --git a/tests/balanceplatform_report_webhooks_handler_test.go b/tests/balanceplatform/reportwebhook_test.go similarity index 93% rename from tests/balanceplatform_report_webhooks_handler_test.go rename to tests/balanceplatform/reportwebhook_test.go index 19daada61..22560d38f 100644 --- a/tests/balanceplatform_report_webhooks_handler_test.go +++ b/tests/balanceplatform/reportwebhook_test.go @@ -1,4 +1,4 @@ -package tests +package balanceplatform import ( "testing" @@ -8,8 +8,7 @@ import ( "github.com/adyen/adyen-go-api-library/v8/src/reportwebhook" ) -func Test_BalancePlatform_Report_Webhooks_HandleRequest(t *testing.T) { - +func TestHandleReportNotificationRequest(t *testing.T) { t.Run("should return report created success", func(t *testing.T) { notificationJson := `{ "data": { diff --git a/tests/balanceplatform_transfer_webhooks_handler_test.go b/tests/balanceplatform/transferwebhook_test.go similarity index 91% rename from tests/balanceplatform_transfer_webhooks_handler_test.go rename to tests/balanceplatform/transferwebhook_test.go index 47a5d57df..b879a07fd 100644 --- a/tests/balanceplatform_transfer_webhooks_handler_test.go +++ b/tests/balanceplatform/transferwebhook_test.go @@ -1,4 +1,4 @@ -package tests +package balanceplatform import ( "testing" @@ -8,8 +8,7 @@ import ( "github.com/adyen/adyen-go-api-library/v8/src/transferwebhook" ) -func Test_BalancePlatform_Transfer_Webhooks_HandleRequest(t *testing.T) { - +func TestHandleTransferNotificationRequest(t *testing.T) { t.Run("should return transfer success", func(t *testing.T) { notificationJson := `{ "data": { diff --git a/tests/balanceplatform_test.go b/tests/balanceplatform/unit_test.go similarity index 84% rename from tests/balanceplatform_test.go rename to tests/balanceplatform/unit_test.go index 251b0218d..787c3dae6 100644 --- a/tests/balanceplatform_test.go +++ b/tests/balanceplatform/unit_test.go @@ -1,4 +1,4 @@ -package tests +package balanceplatform import ( "context" @@ -6,6 +6,7 @@ import ( "github.com/adyen/adyen-go-api-library/v8/src/adyen" "github.com/adyen/adyen-go-api-library/v8/src/balanceplatform" "github.com/adyen/adyen-go-api-library/v8/src/common" + "github.com/adyen/adyen-go-api-library/v8/tests" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "io" @@ -15,7 +16,7 @@ import ( "testing" ) -func Test_BalancePlatform(t *testing.T) { +func TestBalancePlatform(t *testing.T) { client := adyen.NewClient(&common.Config{ ApiKey: "YOUR_ADYEN_API_KEY", Environment: "TEST", @@ -24,19 +25,16 @@ func Test_BalancePlatform(t *testing.T) { service := client.BalancePlatform() mux := http.NewServeMux() - // Success case - mux.HandleFunc("/accountHolders/123", func(w http.ResponseWriter, r *http.Request) { - assert.Contains(t, [2]string{"GET", "PATCH"}, r.Method) - w.Header().Set("Content-Type", "application/json") - file, _ := os.Open("fixtures/account_holder.json") - io.Copy(w, file) - }) + mockResponse := tests.MockResponse(t, mux) + + // Success cases + mockResponse(http.StatusOK, "GET PATCH", "/accountHolders/123", "account_holder.json") mux.HandleFunc("/accountHolders/123/balanceAccounts", func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "GET", r.Method) assert.Equal(t, "5", r.URL.Query().Get("limit")) assert.Equal(t, "42", r.URL.Query().Get("offset")) w.Header().Set("Content-Type", "application/json") - file, _ := os.Open("fixtures/paginated_balance_accounts_response.json") + file, _ := os.Open("../fixtures/paginated_balance_accounts_response.json") io.Copy(w, file) }) mux.HandleFunc("/balanceAccounts/balanceAccountId/sweeps/sweepId", func(w http.ResponseWriter, r *http.Request) { @@ -48,26 +46,11 @@ func Test_BalancePlatform(t *testing.T) { require.Equal(t, "POST", r.Method) // no response }) - mux.HandleFunc("/balanceAccounts/BA123/sweeps/SWPC123", func(w http.ResponseWriter, r *http.Request) { - assert.Contains(t, [2]string{"GET", "PATCH"}, r.Method) - w.Header().Set("Content-Type", "application/json") - file, _ := os.Open("fixtures/sweep.json") - io.Copy(w, file) - }) - mux.HandleFunc("/transactionRules/transactionRuleId", func(w http.ResponseWriter, r *http.Request) { - require.Equal(t, "DELETE", r.Method) - w.Header().Set("Content-Type", "application/json") - file, _ := os.Open("fixtures/transaction_rule.json") - io.Copy(w, file) - }) + mockResponse(http.StatusOK, "GET PATCH", "/balanceAccounts/BA123/sweeps/SWPC123", "sweep.json") + mockResponse(http.StatusOK, "DELETE", "/transactionRules/transactionRuleId", "transaction_rule.json") + // Error case - mux.HandleFunc("/paymentInstruments/666", func(w http.ResponseWriter, r *http.Request) { - require.Equal(t, "PATCH", r.Method) - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusUnprocessableEntity) - file, _ := os.Open("fixtures/not_found.json") - io.Copy(w, file) - }) + mockResponse(http.StatusUnprocessableEntity, "PATCH", "/paymentInstruments/666", "not_found.json") mockServer := httptest.NewServer(mux) defer mockServer.Close() diff --git a/tests/binlookup_test.go b/tests/binlookup_test.go index d2adfcb34..440607919 100644 --- a/tests/binlookup_test.go +++ b/tests/binlookup_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package tests import ( diff --git a/tests/checkoutidempotency_test.go b/tests/checkout/idempotency_test.go similarity index 99% rename from tests/checkoutidempotency_test.go rename to tests/checkout/idempotency_test.go index fee7f38ff..1ae19c28b 100644 --- a/tests/checkoutidempotency_test.go +++ b/tests/checkout/idempotency_test.go @@ -1,4 +1,4 @@ -package tests +package checkout import ( "context" diff --git a/tests/checkout_test.go b/tests/checkout/integration_test.go similarity index 64% rename from tests/checkout_test.go rename to tests/checkout/integration_test.go index 5d1808f0c..f7e368935 100644 --- a/tests/checkout_test.go +++ b/tests/checkout/integration_test.go @@ -1,4 +1,7 @@ -package tests +//go:build integration +// +build integration + +package checkout import ( "context" @@ -6,9 +9,7 @@ import ( "github.com/adyen/adyen-go-api-library/v8/src/adyen" "github.com/adyen/adyen-go-api-library/v8/src/checkout" "github.com/adyen/adyen-go-api-library/v8/src/common" - "github.com/google/uuid" "io/ioutil" - _nethttp "net/http" "os" "strings" "testing" @@ -19,10 +20,10 @@ import ( "github.com/stretchr/testify/require" ) -func Test_Checkout(t *testing.T) { - godotenv.Load("./../.env") +func TestCheckoutIntegration(t *testing.T) { + godotenv.Load("./../../.env") - MerchantAccount := os.Getenv("ADYEN_MERCHANT") + merchantAccount := os.Getenv("ADYEN_MERCHANT") client := adyen.NewClient(&common.Config{ ApiKey: os.Getenv("ADYEN_API_KEY"), @@ -31,16 +32,6 @@ func Test_Checkout(t *testing.T) { }) service := client.Checkout() - t.Run("Configuration", func(t *testing.T) { - liveClient := adyen.NewClient(&common.Config{ - ApiKey: "LIVE_API_KEY", - Environment: common.LiveEnv, - LiveEndpointURLPrefix: "abc123", - Debug: false, - }) - require.Equal(t, "https://abc123-checkout-live.adyenpayments.com/checkout/v70", liveClient.Checkout().PaymentsApi.BasePath()) - }) - t.Run("PaymentMethods", func(t *testing.T) { t.Run("Create an API request that should fail", func(t *testing.T) { req := service.PaymentsApi.PaymentMethodsInput(). @@ -55,7 +46,7 @@ func Test_Checkout(t *testing.T) { }) t.Run("Create an API request that should pass", func(t *testing.T) { - paymentMethodsRequest := *checkout.NewPaymentMethodsRequest(MerchantAccount) + paymentMethodsRequest := *checkout.NewPaymentMethodsRequest(merchantAccount) req := service.PaymentsApi.PaymentMethodsInput().PaymentMethodsRequest(paymentMethodsRequest) res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) @@ -70,21 +61,6 @@ func Test_Checkout(t *testing.T) { }) t.Run("Payments", func(t *testing.T) { - t.Run("Create an API request that should fail", func(t *testing.T) { - res, httpRes, err := service.PaymentsApi.Payments( - context.Background(), - // missing payment method - service.PaymentsApi.PaymentsInput().PaymentRequest(checkout.PaymentRequest{ - MerchantAccount: MerchantAccount, - }), - ) - - require.NotNil(t, err) - assert.Contains(t, err.Error(), "error calling MarshalJSON for type checkout.CheckoutPaymentMethod") - require.Nil(t, httpRes) - require.NotNil(t, res) - }) - t.Run("Credit card payment", func(t *testing.T) { card := checkout.NewCardDetails() card.SetEncryptedCardNumber("test_4111111111111111") @@ -93,7 +69,7 @@ func Test_Checkout(t *testing.T) { card.SetEncryptedSecurityCode("test_737") paymentRequest := *checkout.NewPaymentRequest( *checkout.NewAmount("EUR", int64(1234)), - MerchantAccount, + merchantAccount, checkout.CardDetailsAsCheckoutPaymentMethod(card), "Reference_example", "ReturnUrl_example", @@ -121,7 +97,7 @@ func Test_Checkout(t *testing.T) { ideal := checkout.NewIdealDetails("1121") paymentRequest := *checkout.NewPaymentRequest( *checkout.NewAmount("EUR", int64(1234)), - MerchantAccount, + merchantAccount, checkout.IdealDetailsAsCheckoutPaymentMethod(ideal), "Reference_example", "ReturnUrl_example", @@ -140,41 +116,6 @@ func Test_Checkout(t *testing.T) { assert.Equal(t, "ideal", res.GetAction().CheckoutRedirectAction.GetPaymentMethodType()) assert.NotEmpty(t, res.GetResultCode()) }) - - t.Run("Create two APIs requests that should be identical when using the same Idempotency Key", func(t *testing.T) { - card := checkout.NewCardDetails() - card.SetEncryptedCardNumber("test_4111111111111111") - card.SetEncryptedExpiryMonth("test_03") - card.SetEncryptedExpiryYear("test_2030") - card.SetEncryptedSecurityCode("test_737") - card.SetHolderName("John Smith") - body := checkout.PaymentRequest{ - Reference: "123456781235", - Amount: checkout.Amount{ - Value: 1250, - Currency: "EUR", - }, - CountryCode: common.PtrString("NL"), - MerchantAccount: MerchantAccount, - Channel: common.PtrString("Web"), - ReturnUrl: "http://localhost:3000/redirect", - PaymentMethod: checkout.CardDetailsAsCheckoutPaymentMethod(card), - } - iKey := uuid.New().String() - ctx := context.Background() - - req := service.PaymentsApi.PaymentsInput().IdempotencyKey(iKey).PaymentRequest(body) - res, _, _ := service.PaymentsApi.Payments(ctx, req) - pspRef := res.GetPspReference() - - res, _, _ = service.PaymentsApi.Payments(ctx, req) - require.Equal(t, pspRef, res.GetPspReference()) - - // Idempotency Key is not set for this request. Should have a new PspReference. - req = service.PaymentsApi.PaymentsInput().PaymentRequest(body) - res, _, _ = service.PaymentsApi.Payments(context.Background(), req) - require.NotEqual(t, pspRef, res.GetPspReference()) - }) }) t.Run("PaymentDetails", func(t *testing.T) { @@ -199,7 +140,24 @@ func Test_Checkout(t *testing.T) { }) t.Run("PaymentLinks", func(t *testing.T) { - createPaymentLink := func() (checkout.PaymentLinkResponse, *_nethttp.Response, error) { + t.Run("Create an API request that should fail", func(t *testing.T) { + req := service.PaymentLinksApi.PaymentLinksInput() + req = req.PaymentLinkRequest(checkout.PaymentLinkRequest{ + Amount: checkout.Amount{ + Value: 1250, + Currency: "EUR", + }, + MerchantAccount: merchantAccount, + }) + res, httpRes, err := service.PaymentLinksApi.PaymentLinks(context.Background(), req) + + require.NotNil(t, err) + assert.Contains(t, err.Error(), "'reference' is not provided") + require.NotNil(t, httpRes) + require.NotNil(t, res) + }) + + t.Run("Create an API request that should pass", func(t *testing.T) { req := service.PaymentLinksApi.PaymentLinksInput() req = req.PaymentLinkRequest(checkout.PaymentLinkRequest{ Reference: "123456781235", @@ -219,30 +177,10 @@ func Test_Checkout(t *testing.T) { Country: "BR", StateOrProvince: common.PtrString("SP"), }, - MerchantAccount: MerchantAccount, - }) - return service.PaymentLinksApi.PaymentLinks(context.Background(), req) - } - - t.Run("Create an API request that should fail", func(t *testing.T) { - req := service.PaymentLinksApi.PaymentLinksInput() - req = req.PaymentLinkRequest(checkout.PaymentLinkRequest{ - Amount: checkout.Amount{ - Value: 1250, - Currency: "EUR", - }, - MerchantAccount: MerchantAccount, + MerchantAccount: merchantAccount, }) res, httpRes, err := service.PaymentLinksApi.PaymentLinks(context.Background(), req) - require.NotNil(t, err) - assert.Contains(t, err.Error(), "'reference' is not provided") - require.NotNil(t, httpRes) - require.NotNil(t, res) - }) - t.Run("Create an API request that should pass", func(t *testing.T) { - res, httpRes, err := createPaymentLink() - require.Nil(t, err) require.NotNil(t, httpRes) assert.Equal(t, 201, httpRes.StatusCode) @@ -250,37 +188,6 @@ func Test_Checkout(t *testing.T) { assert.Equal(t, checkout.Amount{Currency: "EUR", Value: 1250}, res.Amount) assert.NotNil(t, res.Url) }) - - t.Run("Get payment link", func(t *testing.T) { - paymentLink, _, _ := createPaymentLink() - req := service.PaymentLinksApi.GetPaymentLinkInput(paymentLink.Id) - res, httpRes, err := service.PaymentLinksApi.GetPaymentLink(context.Background(), req) - - require.Nil(t, err) - require.NotNil(t, httpRes) - assert.Equal(t, 200, httpRes.StatusCode) - require.NotNil(t, res) - assert.Equal(t, paymentLink.Reference, res.Reference) - assert.Equal(t, paymentLink.Status, res.Status) - assert.NotNil(t, res.Url) - }) - - t.Run("Update payment link", func(t *testing.T) { - paymentLink, _, _ := createPaymentLink() - req := service.PaymentLinksApi.UpdatePaymentLinkInput(paymentLink.Id) - req = req.UpdatePaymentLinkRequest(checkout.UpdatePaymentLinkRequest{ - Status: "expired", - }) - res, httpRes, err := service.PaymentLinksApi.UpdatePaymentLink(context.Background(), req) - - require.Nil(t, err) - require.NotNil(t, httpRes) - assert.Equal(t, 200, httpRes.StatusCode) - require.NotNil(t, res) - assert.Equal(t, paymentLink.Reference, res.Reference) - assert.NotEqual(t, paymentLink.Status, res.Status) - assert.NotNil(t, res.Url) - }) }) t.Run("PaymentSession", func(t *testing.T) { @@ -293,7 +200,7 @@ func Test_Checkout(t *testing.T) { Currency: "EUR", }, CountryCode: "NL", - MerchantAccount: MerchantAccount, + MerchantAccount: merchantAccount, Channel: common.PtrString("iOS"), ReturnUrl: "http://localhost:3000/redirect", }) @@ -305,6 +212,7 @@ func Test_Checkout(t *testing.T) { assert.Equal(t, 422, httpRes.StatusCode) require.NotNil(t, res) }) + t.Run("Create an API request that should pass", func(t *testing.T) { req := service.ClassicCheckoutSDKApi.PaymentSessionInput() req = req.PaymentSetupRequest(checkout.PaymentSetupRequest{ @@ -314,7 +222,7 @@ func Test_Checkout(t *testing.T) { Currency: "EUR", }, CountryCode: "NL", - MerchantAccount: MerchantAccount, + MerchantAccount: merchantAccount, Channel: common.PtrString("Web"), ReturnUrl: "http://localhost:3000/redirect", SdkVersion: common.PtrString("1.9.5"), @@ -374,77 +282,6 @@ func Test_Checkout(t *testing.T) { }) t.Run("Orders", func(t *testing.T) { - t.Run("Get balance", func(t *testing.T) { - // @TODO review this test/config - t.Skip("Payment method not correctly configured in the backoffice") - req := service.OrdersApi.GetBalanceOfGiftCardInput() - req = req.BalanceCheckRequest(checkout.BalanceCheckRequest{ - MerchantAccount: MerchantAccount, - PaymentMethod: map[string]string{ - "type": "giftcard", - "brand": "givex", - "number": "603628672882001915092", - "holderName": "balance EUR 100", - "cvc": "5754", - }, - }) - res, httpRes, err := service.OrdersApi.GetBalanceOfGiftCard(context.Background(), req) - - require.Nil(t, err) - require.NotNil(t, httpRes) - assert.Equal(t, 200, httpRes.StatusCode) - require.NotNil(t, res) - assert.Equal(t, int64(100), res.Balance.Value) - }) - - t.Run("Create order", func(t *testing.T) { - req := service.OrdersApi.OrdersInput() - req = req.CreateOrderRequest(checkout.CreateOrderRequest{ - Amount: checkout.Amount{ - Currency: "EUR", - Value: 1000, - }, - MerchantAccount: MerchantAccount, - Reference: "CREATE_ORDER_REF", - }) - res, httpRes, err := service.OrdersApi.Orders(context.Background(), req) - - require.Nil(t, err) - require.NotNil(t, httpRes) - assert.Equal(t, 200, httpRes.StatusCode) - require.NotNil(t, res) - assert.Equal(t, int64(1000), res.RemainingAmount.Value) - }) - - t.Run("Cancel order", func(t *testing.T) { - req := service.OrdersApi.OrdersInput() - req = req.CreateOrderRequest(checkout.CreateOrderRequest{ - Amount: checkout.Amount{ - Currency: "EUR", - Value: 1000, - }, - MerchantAccount: MerchantAccount, - Reference: "CREATE_ORDER_REF", - }) - order, _, _ := service.OrdersApi.Orders(context.Background(), req) - - cancelReq := service.OrdersApi.CancelOrderInput() - cancelReq = cancelReq.CancelOrderRequest(checkout.CancelOrderRequest{ - MerchantAccount: MerchantAccount, - Order: checkout.EncryptedOrderData{ - OrderData: order.OrderData, - PspReference: order.GetPspReference(), - }, - }) - res, httpRes, err := service.OrdersApi.CancelOrder(context.Background(), cancelReq) - - require.Nil(t, err) - require.NotNil(t, httpRes) - assert.Equal(t, 200, httpRes.StatusCode) - require.NotNil(t, res) - assert.Equal(t, "Received", res.ResultCode) - }) - t.Run("Create an API request that should fail", func(t *testing.T) { req := service.OrdersApi.OrdersInput() // missing required "reference" field @@ -453,7 +290,7 @@ func Test_Checkout(t *testing.T) { Currency: "EUR", Value: 1000, }, - MerchantAccount: MerchantAccount, + MerchantAccount: merchantAccount, }) res, httpRes, err := service.OrdersApi.Orders(context.Background(), req) @@ -474,7 +311,7 @@ func Test_Checkout(t *testing.T) { Currency: "EUR", }, CountryCode: common.PtrString("NL"), - MerchantAccount: MerchantAccount, + MerchantAccount: merchantAccount, Channel: common.PtrString("Web"), ReturnUrl: "http://localhost:3000/redirect", } @@ -507,7 +344,7 @@ func Test_Checkout(t *testing.T) { body := checkout.CardDetailsRequest{ CardNumber: "37000000", CountryCode: common.PtrString("NL"), - MerchantAccount: MerchantAccount, + MerchantAccount: merchantAccount, } req := service.PaymentsApi.CardDetailsInput().CardDetailsRequest(body) @@ -524,7 +361,7 @@ func Test_Checkout(t *testing.T) { body := checkout.CardDetailsRequest{ CardNumber: "3700", CountryCode: common.PtrString("NL"), - MerchantAccount: MerchantAccount, + MerchantAccount: merchantAccount, } req := service.PaymentsApi.CardDetailsInput().CardDetailsRequest(body) diff --git a/tests/checkout/unit_test.go b/tests/checkout/unit_test.go new file mode 100644 index 000000000..4f4377fbc --- /dev/null +++ b/tests/checkout/unit_test.go @@ -0,0 +1,244 @@ +package checkout + +import ( + "context" + "github.com/adyen/adyen-go-api-library/v8/src/adyen" + "github.com/adyen/adyen-go-api-library/v8/src/checkout" + "github.com/adyen/adyen-go-api-library/v8/src/common" + "github.com/adyen/adyen-go-api-library/v8/tests" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "io" + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" +) + +func TestCheckout(t *testing.T) { + client := adyen.NewClient(&common.Config{ + ApiKey: "YOUR_ADYEN_API_KEY", + Environment: "TEST", + }) + merchantAccount := "YOUR_MERCHANT_ACCOUNT" + + mux := http.NewServeMux() + + mockResponse := tests.MockResponse(t, mux) + mockOk := func(method, endpoint, fixture string) { + mockResponse(http.StatusOK, method, endpoint, fixture) + } + mockCreated := func(method, endpoint, fixture string) { + mockResponse(http.StatusCreated, method, endpoint, fixture) + } + + // Success cases + mockOk("POST", "/payments", "checkout/authorised_card.json") + mockOk("POST", "/paymentMethods", "checkout/payment_methods.json") + mockOk("POST", "/paymentMethods/balance", "checkout/gift_card_balance.json") + mockOk("POST", "/orders", "checkout/order_created.json") + mockOk("GET PATCH", "/paymentLinks/PL61C53A8B97E6915A", "checkout/payment_link.json") + mockCreated("POST", "/sessions", "checkout/session_created.json") + + mux.HandleFunc("/orders/cancel", func(w http.ResponseWriter, r *http.Request) { + require.Equal(t, "POST", r.Method) + w.Header().Set("Content-Type", "application/json") + io.WriteString(w, `{ + "pspReference": "8816178914079738", + "resultCode": "Received" + }`) + }) + + mockServer := httptest.NewServer(mux) + defer mockServer.Close() + client.Checkout().PaymentsApi.BasePath = func() string { return mockServer.URL } + service := client.Checkout() + + t.Run("Configuration", func(t *testing.T) { + liveClient := adyen.NewClient(&common.Config{ + ApiKey: "LIVE_API_KEY", + Environment: common.LiveEnv, + LiveEndpointURLPrefix: "abc123", + Debug: false, + }) + require.Equal(t, "https://abc123-checkout-live.adyenpayments.com/checkout/"+adyen.CheckoutAPIVersion, liveClient.Checkout().PaymentsApi.BasePath()) + }) + + t.Run("PaymentMethods", func(t *testing.T) { + t.Run("Create an API request that should pass", func(t *testing.T) { + paymentMethodsRequest := *checkout.NewPaymentMethodsRequest(merchantAccount) + req := service.PaymentsApi.PaymentMethodsInput().PaymentMethodsRequest(paymentMethodsRequest) + res, httpRes, err := service.PaymentsApi.PaymentMethods(context.Background(), req) + + require.NotNil(t, res) + require.NotNil(t, httpRes) + require.Nil(t, err) + assert.Equal(t, 200, httpRes.StatusCode) + resBody, readErr := ioutil.ReadAll(httpRes.Body) + require.NoError(t, readErr) + assert.Contains(t, string(resBody), "paymentMethods") + }) + }) + + t.Run("Payments", func(t *testing.T) { + t.Run("Create an API request that should fail", func(t *testing.T) { + res, httpRes, err := service.PaymentsApi.Payments( + context.Background(), + // missing payment method + service.PaymentsApi.PaymentsInput().PaymentRequest(checkout.PaymentRequest{ + MerchantAccount: merchantAccount, + }), + ) + + require.NotNil(t, err) + assert.Contains(t, err.Error(), "error calling MarshalJSON for type checkout.CheckoutPaymentMethod") + require.Nil(t, httpRes) + require.NotNil(t, res) + }) + + t.Run("Credit card payment", func(t *testing.T) { + card := checkout.NewCardDetails() + card.SetEncryptedCardNumber("test_4111111111111111") + card.SetEncryptedExpiryMonth("test_03") + card.SetEncryptedExpiryYear("test_2030") + card.SetEncryptedSecurityCode("test_737") + paymentRequest := *checkout.NewPaymentRequest( + *checkout.NewAmount("EUR", int64(1234)), + merchantAccount, + checkout.CardDetailsAsCheckoutPaymentMethod(card), + "Reference_example", + "ReturnUrl_example", + ) + paymentRequest.SetCaptureDelayHours(0) // assert int zero value is sent + + req := service.PaymentsApi.PaymentsInput() + req = req.PaymentRequest(paymentRequest) + res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req) + + require.NotNil(t, res) + require.NotNil(t, httpRes) + require.Nil(t, err) + + assert.Equal(t, 200, httpRes.StatusCode) + assert.Equal(t, "Authorised", res.GetResultCode()) + require.False(t, res.HasAction()) + assert.NotEmpty(t, res.GetPspReference()) + assert.NotEmpty(t, res.GetResultCode()) + }) + }) + + t.Run("Sessions", func(t *testing.T) { + t.Run("Create an API request that should pass", func(t *testing.T) { + body := checkout.CreateCheckoutSessionRequest{ + Reference: "123456781235", + Amount: checkout.Amount{ + Value: 1250, + Currency: "EUR", + }, + CountryCode: common.PtrString("NL"), + MerchantAccount: merchantAccount, + Channel: common.PtrString("Web"), + ReturnUrl: "http://localhost:3000/redirect", + } + req := service.PaymentsApi.SessionsInput().CreateCheckoutSessionRequest(body) + + res, httpRes, err := service.PaymentsApi.Sessions(context.Background(), req) + + require.Nil(t, err) + require.NotNil(t, httpRes) + assert.Equal(t, 201, httpRes.StatusCode) + require.Equal(t, "CS451F2AB1ED897A94", res.GetId()) + }) + }) + + t.Run("Orders", func(t *testing.T) { + t.Run("Get balance", func(t *testing.T) { + req := service.OrdersApi.GetBalanceOfGiftCardInput() + req = req.BalanceCheckRequest(checkout.BalanceCheckRequest{ + MerchantAccount: merchantAccount, + PaymentMethod: map[string]string{ + "type": "giftcard", + "brand": "givex", + "number": "603628672882001915092", + "holderName": "balance EUR 100", + "cvc": "5754", + }, + }) + res, httpRes, err := service.OrdersApi.GetBalanceOfGiftCard(context.Background(), req) + + require.Nil(t, err) + require.NotNil(t, httpRes) + assert.Equal(t, 200, httpRes.StatusCode) + require.NotNil(t, res) + assert.Equal(t, int64(5000), res.Balance.Value) + }) + + t.Run("Create order", func(t *testing.T) { + req := service.OrdersApi.OrdersInput() + req = req.CreateOrderRequest(checkout.CreateOrderRequest{ + Amount: checkout.Amount{ + Currency: "EUR", + Value: 2500, + }, + MerchantAccount: merchantAccount, + Reference: "CREATE_ORDER_REF", + }) + res, httpRes, err := service.OrdersApi.Orders(context.Background(), req) + + require.Nil(t, err) + require.NotNil(t, httpRes) + assert.Equal(t, 200, httpRes.StatusCode) + require.NotNil(t, res) + assert.Equal(t, int64(2500), res.RemainingAmount.Value) + }) + + t.Run("Cancel order", func(t *testing.T) { + cancelReq := service.OrdersApi.CancelOrderInput() + cancelReq = cancelReq.CancelOrderRequest(checkout.CancelOrderRequest{ + MerchantAccount: merchantAccount, + Order: checkout.EncryptedOrderData{ + OrderData: "823fh892f8f18f4...148f13f9f3f", + PspReference: "8815517812932012", + }, + }) + res, httpRes, err := service.OrdersApi.CancelOrder(context.Background(), cancelReq) + + require.Nil(t, err) + require.NotNil(t, httpRes) + assert.Equal(t, 200, httpRes.StatusCode) + require.NotNil(t, res) + assert.Equal(t, "Received", res.ResultCode) + }) + }) + + t.Run("PaymentLinks", func(t *testing.T) { + paymentLinkId := "PL61C53A8B97E6915A" + t.Run("Get payment link", func(t *testing.T) { + req := service.PaymentLinksApi.GetPaymentLinkInput(paymentLinkId) + res, httpRes, err := service.PaymentLinksApi.GetPaymentLink(context.Background(), req) + + require.Nil(t, err) + require.NotNil(t, httpRes) + assert.Equal(t, 200, httpRes.StatusCode) + require.NotNil(t, res) + assert.Equal(t, "shopper-reference-ekvL83", res.Reference) + assert.Equal(t, "active", res.Status) + assert.NotNil(t, res.Url) + }) + + t.Run("Update payment link", func(t *testing.T) { + req := service.PaymentLinksApi.UpdatePaymentLinkInput(paymentLinkId) + req = req.UpdatePaymentLinkRequest(checkout.UpdatePaymentLinkRequest{ + Status: "expired", + }) + res, httpRes, err := service.PaymentLinksApi.UpdatePaymentLink(context.Background(), req) + + require.Nil(t, err) + require.NotNil(t, httpRes) + assert.Equal(t, 200, httpRes.StatusCode) + require.NotNil(t, res) + assert.Equal(t, "shopper-reference-ekvL83", res.Reference) + assert.NotNil(t, res.Url) + }) + }) +} diff --git a/tests/fixtures/checkout/authorised_card.json b/tests/fixtures/checkout/authorised_card.json new file mode 100644 index 000000000..2a0d70891 --- /dev/null +++ b/tests/fixtures/checkout/authorised_card.json @@ -0,0 +1,15 @@ +{ + "additionalData": { + "cvcResult": "1 Matches", + "authCode": "065696", + "avsResult": "4 AVS not supported for this card type", + "avsResultRaw": "4", + "cvcResultRaw": "M", + "refusalReasonRaw": "AUTHORISED", + "acquirerCode": "TestPmmAcquirer", + "acquirerReference": "8PQMP9VIE9N" + }, + "pspReference": "993617895215577D", + "resultCode": "Authorised", + "merchantReference": "string" +} \ No newline at end of file diff --git a/tests/fixtures/checkout/gift_card_balance.json b/tests/fixtures/checkout/gift_card_balance.json new file mode 100644 index 000000000..f233c12d1 --- /dev/null +++ b/tests/fixtures/checkout/gift_card_balance.json @@ -0,0 +1,8 @@ +{ + "pspReference": "KHQC5N7G84BLNK43", + "resultCode": "Success", + "balance": { + "currency": "EUR", + "value": 5000 + } +} \ No newline at end of file diff --git a/tests/fixtures/checkout/order_created.json b/tests/fixtures/checkout/order_created.json new file mode 100644 index 000000000..04c5d26fc --- /dev/null +++ b/tests/fixtures/checkout/order_created.json @@ -0,0 +1,15 @@ +{ + "pspReference": "8616178914061985", + "resultCode": "Success", + "expiresAt": "2021-04-09T14:16:46Z", + "orderData": "Ab02b4c0!BQABAgCxXvknCldOcRElkxY8Za7iyym4Wv8aDzyNwmj/3nh4G6YtwnUIJHaK62NlN4oIsACdkn1FEjBwKlheG40jvXcYGBk4KFV5WvOhTVCpv/KXnkrI7xQv/u2lE7U4wA+HPB6K4Zj2L8xO/ogZi+zGZqFs5m16jmkH7ku6FzXygXLNuUCuOlmlXSZhdkHHTNVQSq1MELDK9OL74y532ETRPTCNxx8WlEiZB+LDqYrPvH9GgigtD5kw8Do45jfFfG72kWBEgfYqp4mbUmBB9ebXFYZKfF0qvW1x7A2Y9+/MFlTIdXfKW484bJeDBCTTrmKGXIj+U4r5imr5fXTyNLcrxyUqwrb9jg+5B4qg1XB6Cgj5UPlSI4O62I7v0s5TTj69dzLwUQRxSQbwLrZVGYavXzeVKI54BVLRV3d/+BbPvTqnTo34UhfZbPlOx9F2eyaS0ZXdOKnHw89uGUgxUpLsMqnbRysi/pxpZaulel+0mExb68wVxb/7Teob5eRG4gp7cfZVZs6tLXOYWL+W0TqIlsa3hWsfM0LeaovzkoDtW/pK5JABXwMtLig9tsxoEh9ONYtIzkXC21LZ8ebiuSIMaPizjF8yca+QxrCZalQsu6uKnBz/mm8nnsflaGU2QS5zcoxk1RudL1Bl36LM9UZGPpFEYWiYA4sUsnNLw7peJjWCGhDepnwMv4TlgsEtoDtz1T54AEp7ImtleSI6IkFGMEFBQTEwM0NBNTM3RUFFRDg3QzI0REQ1MzkwOUI4MEE3OEE5MjNFMzgyM0Q2OERBQ0M5NEI5RkY4MzA1REMifRslOdmfgUHTXl66WPD9xoW2whIeRx/jR++2MqNE16x6zQy+KtDN8/h60crZwmqkjVTQYqQlsYSYDHSIyb4wnnay16/5il1yS7vN3UCLaTXjYBIAyyx6Wr9j4P3CI/etB+PpviHoESC4mV6ZN4whMDQyziQ8s230GtboXbh42qND7rk9phySBogowQlXrtF+l2n2F46nyif0owEgik5fGARfvjZtY2w23s30KMLNwU4gWSvX4H6RMVS8TfZH2fKfNrwB3tZUXwYkELs5ntaHysswq5Mn5aq2BKAMHu/Rh/wureMSI73Qi0avjrzWCwzt3JH4wnzErMnOZwSdgA==", + "reference": "shopper-reference-ekvL83", + "remainingAmount": { + "currency": "EUR", + "value": 2500 + }, + "amount": { + "currency": "EUR", + "value": 300 + } +} \ No newline at end of file diff --git a/tests/fixtures/checkout/payment_link.json b/tests/fixtures/checkout/payment_link.json new file mode 100644 index 000000000..84a1b2166 --- /dev/null +++ b/tests/fixtures/checkout/payment_link.json @@ -0,0 +1,15 @@ +{ + "amount": { + "currency": "EUR", + "value": 8700 + }, + "countryCode": "NL", + "expiresAt": "2021-04-08T14:06:39Z", + "merchantAccount": "YOUR_MERCHANT_ACCOUNT", + "reference": "shopper-reference-ekvL83", + "shopperLocale": "hu-HU", + "shopperReference": "shopper-reference-LZfdWZ", + "status": "active", + "url": "https://test.adyen.link/PL61C53A8B97E6915A", + "id": "PL61C53A8B97E6915A" +} \ No newline at end of file diff --git a/tests/fixtures/checkout/payment_methods.json b/tests/fixtures/checkout/payment_methods.json new file mode 100644 index 000000000..56838b2f6 --- /dev/null +++ b/tests/fixtures/checkout/payment_methods.json @@ -0,0 +1,621 @@ +{ + "paymentMethods": [ + { + "details": [ + { + "items": [ + { + "id": "1121", + "name": "Test Issuer" + }, + { + "id": "1154", + "name": "Test Issuer 5" + }, + { + "id": "1153", + "name": "Test Issuer 4" + }, + { + "id": "1152", + "name": "Test Issuer 3" + }, + { + "id": "1151", + "name": "Test Issuer 2" + }, + { + "id": "1162", + "name": "Test Issuer Cancelled" + }, + { + "id": "1161", + "name": "Test Issuer Pending" + }, + { + "id": "1160", + "name": "Test Issuer Refused" + }, + { + "id": "1159", + "name": "Test Issuer 10" + }, + { + "id": "1158", + "name": "Test Issuer 9" + }, + { + "id": "1157", + "name": "Test Issuer 8" + }, + { + "id": "1156", + "name": "Test Issuer 7" + }, + { + "id": "1155", + "name": "Test Issuer 6" + } + ], + "key": "issuer", + "type": "select" + } + ], + "name": "iDEAL", + "type": "ideal" + }, + { + "details": [ + { + "key": "encryptedCardNumber", + "type": "cardToken" + }, + { + "key": "encryptedSecurityCode", + "type": "cardToken" + }, + { + "key": "encryptedExpiryMonth", + "type": "cardToken" + }, + { + "key": "encryptedExpiryYear", + "type": "cardToken" + }, + { + "key": "holderName", + "optional": true, + "type": "text" + } + ], + "name": "Credit Card", + "type": "scheme" + }, + { + "name": "PayPal", + "type": "paypal" + }, + { + "details": [ + { + "details": [ + { + "key": "firstName", + "type": "text" + }, + { + "key": "lastName", + "type": "text" + }, + { + "items": [ + { + "id": "M", + "name": "male" + }, + { + "id": "F", + "name": "female" + } + ], + "key": "gender", + "type": "radio" + }, + { + "key": "dateOfBirth", + "type": "date" + }, + { + "key": "telephoneNumber", + "type": "tel" + }, + { + "key": "shopperEmail", + "type": "emailAddress" + } + ], + "key": "personalDetails", + "type": "fieldSet" + }, + { + "details": [ + { + "key": "street", + "type": "text" + }, + { + "key": "houseNumberOrName", + "type": "text" + }, + { + "key": "city", + "type": "text" + }, + { + "key": "postalCode", + "type": "text" + }, + { + "key": "stateOrProvince", + "optional": true, + "type": "text" + }, + { + "items": [ + { + "id": "NL", + "name": "Netherlands" + }, + { + "id": "BE", + "name": "Belgium" + } + ], + "key": "country", + "type": "select", + "value": "NL" + } + ], + "key": "billingAddress", + "type": "address" + }, + { + "key": "separateDeliveryAddress", + "optional": true, + "type": "boolean", + "value": "false" + }, + { + "details": [ + { + "key": "street", + "type": "text" + }, + { + "key": "houseNumberOrName", + "type": "text" + }, + { + "key": "city", + "type": "text" + }, + { + "key": "postalCode", + "type": "text" + }, + { + "key": "stateOrProvince", + "optional": true, + "type": "text" + }, + { + "items": [ + { + "id": "NL", + "name": "Netherlands" + }, + { + "id": "BE", + "name": "Belgium" + } + ], + "key": "country", + "type": "select", + "value": "NL" + } + ], + "key": "deliveryAddress", + "optional": true, + "type": "address" + } + ], + "name": "AfterPay Invoice", + "type": "afterpay_default" + }, + { + "name": "Pay later with Klarna.", + "type": "klarna" + }, + { + "details": [ + { + "key": "sepa.ownerName", + "type": "text" + }, + { + "key": "sepa.ibanNumber", + "type": "text" + } + ], + "name": "SEPA Direct Debit", + "type": "sepadirectdebit" + }, + { + "name": "Paysafecard", + "type": "paysafecard" + }, + { + "name": "Bijenkorf Cadeaucard", + "type": "bijcadeaucard" + }, + { + "name": "Fonq Giftcard", + "type": "fonqgiftcard" + }, + { + "name": "Bank Transfer (NL)", + "type": "bankTransfer_NL" + }, + { + "name": "Pathe Giftcard", + "type": "pathegiftcard" + }, + { + "name": "VVV Giftcard", + "type": "vvvgiftcard" + }, + { + "name": "Podium Card", + "type": "podiumcard" + }, + { + "name": "RatePay Direct Debit", + "type": "ratepay_directdebit" + }, + { + "name": "Rituals Giftcard", + "type": "rituals" + }, + { + "name": "Hunkemoller Lingerie Card", + "type": "hmlingerie" + }, + { + "name": "Primera Cadeaukaart", + "type": "primeracadeaucard" + }, + { + "name": "Fashioncheque", + "type": "fashioncheque" + }, + { + "name": "NETELLER", + "type": "neteller" + }, + { + "name": "Adyen Voucher", + "type": "adyen_test_voucher" + }, + { + "name": "AfterPay B2B", + "type": "afterpay_b2b" + }, + { + "name": "AfterPay DirectDebit", + "type": "afterpay_directdebit" + }, + { + "name": "AliPay", + "type": "alipay" + }, + { + "name": "AliPay", + "type": "alipay_wap" + }, + { + "details": [ + { + "key": "additionalData.androidpay.token", + "type": "androidPayToken" + } + ], + "name": "Android Pay", + "type": "androidpay" + }, + { + "details": [ + { + "key": "additionalData.applepay.token", + "type": "applePayToken" + } + ], + "name": "Apple Pay", + "type": "applepay" + }, + { + "name": "Baby Gift Card", + "type": "babygiftcard" + }, + { + "name": "SEPA Bank Transfer", + "type": "bankTransfer_IBAN" + }, + { + "name": "Bloemen Giftcard", + "type": "bloemengiftcard" + }, + { + "name": "Boekenbon Giftcard", + "type": "boekenbon" + }, + { + "name": "Cash-Ticket", + "type": "cashticket" + }, + { + "name": "Chasin Giftcard", + "type": "chasingiftcard" + }, + { + "name": "ClickandBuy", + "type": "clickandbuy" + }, + { + "name": "Costes Giftcard", + "type": "costesgiftcard" + }, + { + "name": "custom_settlement", + "type": "custom_settlement" + }, + { + "name": "eft_directdebit_CA", + "type": "eft_directdebit_CA" + }, + { + "name": "Nationale Entertainment Card", + "type": "entertainmentcard" + }, + { + "name": "Expert Cadeaukaart", + "type": "expertgiftcard" + }, + { + "name": "FijnCadeau", + "type": "fijncadeau" + }, + { + "name": "Fleurop Bloemenbon", + "type": "fleuropbloemenbon" + }, + { + "name": "Gall & Gall", + "type": "gallgall" + }, + { + "name": "Generic GiftCard", + "type": "genericgiftcard" + }, + { + "name": "GiftFor2", + "type": "giftfor2card" + }, + { + "name": "Givex", + "type": "givex" + }, + { + "name": "Goldsmiths Card", + "type": "goldsmithscard" + }, + { + "name": "Hunkemoller Member Card", + "type": "hmclub" + }, + { + "name": "Phone Payment", + "type": "ivr" + }, + { + "name": "Landline phone", + "type": "ivrLandline" + }, + { + "name": "Mobile phone", + "type": "ivrMobile" + }, + { + "name": "Kado Wereld", + "type": "kadowereld" + }, + { + "name": "Karen Millen GiftCard", + "type": "karenmillengiftcard" + }, + { + "name": "Leisure Card", + "type": "leisurecard" + }, + { + "name": "Loods5 Cadeaukaart", + "type": "loods5giftcard" + }, + { + "name": "Loods5 Tegoedbon", + "type": "loods5prepaidcard" + }, + { + "details": [ + { + "key": "additionalData.amazonPayToken", + "type": "text" + } + ], + "name": "Amazon Pay", + "supportsRecurring": true, + "type": "amazonpay" + }, + { + "name": "MOLPoints", + "type": "molpay_points" + }, + { + "name": "Moneybookers", + "type": "moneybookers" + }, + { + "name": "De Nationale Musicalcard", + "type": "musicalcard" + }, + { + "name": "Nationale Bioscoopbon", + "type": "nationalebioscoopbon" + }, + { + "name": "Nationale Tuinbon", + "type": "nationaletuinbon" + }, + { + "name": "Nationale Verwen Cadeaubon", + "type": "nationaleverwencadeaubon" + }, + { + "name": "Onebip", + "type": "onebip" + }, + { + "details": [ + { + "key": "additionalData.paywithgoogle.token", + "type": "payWithGoogleToken" + } + ], + "name": "Google Pay", + "type": "paywithgoogle" + }, + { + "name": "Plastix", + "type": "plastix" + }, + { + "name": "Pluim", + "type": "pluimgiftcard" + }, + { + "name": "Illicado Gift Card", + "type": "prosodie_illicado" + }, + { + "name": "RatePay Invoice", + "type": "ratepay" + }, + { + "name": "Rob Peetoom Giftcard", + "type": "robpeetoomgiftcard" + }, + { + "name": "Shoes&Accessories Cadeau", + "type": "sagiftcard" + }, + { + "name": "Score Giftcard", + "type": "scoregiftcard" + }, + { + "name": "Premium SMS", + "type": "sms" + }, + { + "name": "SVS", + "type": "svs" + }, + { + "name": "TCS Test GiftCard", + "type": "tcstestgiftcard" + }, + { + "name": "The Sting Giftcard", + "type": "thestinggiftcard" + }, + { + "name": "Ukash", + "type": "ukash" + }, + { + "name": "UnionPay", + "type": "unionpay" + }, + { + "name": "Valuelink", + "type": "valuelink" + }, + { + "name": "V&D Cadeaukaart", + "type": "vdcadeaucard" + }, + { + "details": [ + { + "key": "additionalData.visacheckout.callId", + "type": "text" + } + ], + "name": "Visa Checkout", + "type": "visacheckout" + }, + { + "name": "VVV Cadeaubon", + "type": "vvvcadeaubon" + }, + { + "name": "Webshop Giftcard", + "type": "webshopgiftcard" + }, + { + "name": "WE Fashion Giftcard", + "type": "wefashiongiftcard" + }, + { + "name": "Western Union", + "type": "westernunion" + }, + { + "name": "Winkel Cheque", + "type": "winkelcheque" + }, + { + "name": "Your Gift", + "type": "yourgift" + } + ], + "storedPaymentMethods": [ + { + "brand": "visa", + "expiryMonth": "10", + "expiryYear": "30", + "holderName": "John Smith", + "id": "7219687191761347", + "issuerName": "ISSUER_NAME", + "lastFour": "1111", + "name": "VISA", + "shopperEmail": "john.smith@example.com", + "shopperReference": "YOUR_SHOPPER_REFERENCE", + "supportedRecurringProcessingModels": [ + "CardOnFile", + "Subscription", + "UnscheduledCardOnFile" + ], + "type": "scheme" + } + ] +} \ No newline at end of file diff --git a/tests/fixtures/checkout/session_created.json b/tests/fixtures/checkout/session_created.json new file mode 100644 index 000000000..82d76cdc4 --- /dev/null +++ b/tests/fixtures/checkout/session_created.json @@ -0,0 +1,13 @@ +{ + "amount": { + "currency": "EUR", + "value": 100 + }, + "countryCode": "NL", + "expiresAt": "2022-01-11T13:53:18+01:00", + "id": "CS451F2AB1ED897A94", + "merchantAccount": "YOUR_MERCHANT_ACCOUNT", + "reference": "YOUR_PAYMENT_REFERENCE", + "returnUrl": "https://your-company.com/checkout?shopperOrder=12xy..", + "sessionData": "Ab02b4c0!BQABAgBfYI29..." +} \ No newline at end of file diff --git a/tests/legalentity/integration_test.go b/tests/legalentity/integration_test.go index 96a56acc2..47c1c247c 100644 --- a/tests/legalentity/integration_test.go +++ b/tests/legalentity/integration_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package legalentity import ( diff --git a/tests/management/integration_test.go b/tests/management/integration_test.go index f30d67e6e..4dc947823 100644 --- a/tests/management/integration_test.go +++ b/tests/management/integration_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package management import ( @@ -15,10 +18,6 @@ import ( func Test_ManagementAPI_Integration(t *testing.T) { godotenv.Load("./../../.env") - if os.Getenv("ADYEN_API_KEY") == "" { - t.Skip("Integration tests require credentials") - } - client := adyen.NewClient(&common.Config{ ApiKey: os.Getenv("ADYEN_API_KEY"), Environment: common.TestEnv, diff --git a/tests/mocking.go b/tests/mocking.go new file mode 100644 index 000000000..11ca271f7 --- /dev/null +++ b/tests/mocking.go @@ -0,0 +1,36 @@ +package tests + +import ( + "github.com/stretchr/testify/assert" + "io" + "log" + "net/http" + "os" + "path/filepath" + "strings" + "testing" +) + +type MockHandlerFunc func(status int, method, endpoint, fixture string) + +func MockResponse(t *testing.T, mux *http.ServeMux) MockHandlerFunc { + return func(status int, method, endpoint, fixture string) { + mux.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) { + assert.Contains(t, strings.Fields(method), r.Method) + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + + file, err := os.Open(filepath.Join("fixtures", fixture)) + if err != nil { + file, err = os.Open(filepath.Join("..", "fixtures", fixture)) + } + if err != nil { + log.Fatal(err) + } + if _, err := io.Copy(w, file); err != nil { + log.Fatal(err) + } + }) + } +} diff --git a/tests/model_payment_response_test.go b/tests/model_payment_response_test.go index 415f1f16d..00aceb2de 100644 --- a/tests/model_payment_response_test.go +++ b/tests/model_payment_response_test.go @@ -1,13 +1,3 @@ -/* - * Adyen Checkout API - * - * Adyen Checkout API provides a simple and flexible way to initiate and authorise online payments. You can use the same integration for payments made with cards (including 3D Secure), mobile wallets, and local payment methods (for example, iDEAL and Sofort). This API reference provides information on available endpoints and how to interact with them. To learn more about the API, visit [Checkout documentation](https://docs.adyen.com/online-payments). ## Authentication Each response to the Checkout API must be signed with an API key. For this, obtain an API Key from your Customer Area, as described in [How to get the API key](https://docs.adyen.com/development-resources/api-credentials#generate-api-key). Then set this key to the `X-API-Key` header value, for example: ``` curl -H \"Content-Type: application/json\" \\ -H \"X-API-Key: Your_Checkout_API_key\" \\ ... ``` Note that when going live, you need to generate a new API Key to access the [live endpoints](https://docs.adyen.com/development-resources/live-endpoints). ## Versioning Checkout API supports versioning of its endpoints through a version suffix in the endpoint URL. This suffix has the following format: \"vXX\", where XX is the version number. For example: ``` https://checkout-test.adyen.com/v67/payments ``` - * - * API version: 67 - * Contact: developer-experience@adyen.com - * Generated by: OpenAPI Generator (https://openapi-generator.tech) - */ - package tests import ( diff --git a/tests/payment_test.go b/tests/payment_test.go index 05d0c6e98..22187275e 100644 --- a/tests/payment_test.go +++ b/tests/payment_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package tests import ( diff --git a/tests/platforms_test.go b/tests/platforms_test.go index 217d12f00..714b5446c 100644 --- a/tests/platforms_test.go +++ b/tests/platforms_test.go @@ -1,8 +1,5 @@ -/* - * Adyen API Client - * - * Contact: support@adyen.com - */ +//go:build integration +// +build integration package tests diff --git a/tests/recurring_test.go b/tests/recurring_test.go index 901b9e0af..25cb0ddc1 100644 --- a/tests/recurring_test.go +++ b/tests/recurring_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package tests import ( diff --git a/tests/storedvalue_test.go b/tests/storedvalue_test.go index 2fff17fdd..ed77d3c46 100644 --- a/tests/storedvalue_test.go +++ b/tests/storedvalue_test.go @@ -2,6 +2,7 @@ package tests import ( "context" + "errors" "github.com/adyen/adyen-go-api-library/v8/src/adyen" "github.com/adyen/adyen-go-api-library/v8/src/common" "github.com/adyen/adyen-go-api-library/v8/src/storedvalue" @@ -89,7 +90,8 @@ func Test_StoredValue(t *testing.T) { _, httpRes, err := client.StoredValue().VoidTransaction(context.Background(), req) assert.Equal(t, 500, httpRes.StatusCode) - apiError := err.(common.APIError) + var apiError common.APIError + errors.As(err, &apiError) assert.Equal(t, "306", apiError.Code) assert.Equal(t, "No voidable transaction found", apiError.Message) }) diff --git a/tests/transfers_test.go b/tests/transfers_test.go index 4c795de17..527b46426 100644 --- a/tests/transfers_test.go +++ b/tests/transfers_test.go @@ -7,7 +7,6 @@ import ( "io" "net/http" "net/http/httptest" - "os" "testing" "time" @@ -25,7 +24,7 @@ func Test_Transfers(t *testing.T) { mux := http.NewServeMux() - // Success case + // Success cases mux.HandleFunc("/transfers", func(w http.ResponseWriter, r *http.Request) { require.Equal(t, "POST", r.Method) w.Header().Set("Content-Type", "application/json") @@ -92,13 +91,9 @@ func Test_Transfers(t *testing.T) { "status": "Pending" }`) }) - mux.HandleFunc("/transactions", func(w http.ResponseWriter, r *http.Request) { - require.Equal(t, "GET", r.Method) - assert.Equal(t, "2022-01-01T01:02:03Z", r.URL.Query().Get("createdSince")) - w.Header().Set("Content-Type", "application/json") - file, _ := os.Open("fixtures/all_transactions.json") - io.Copy(w, file) - }) + + mockResponse := MockResponse(t, mux) + mockResponse(http.StatusOK, "GET", "/transactions", "all_transactions.json") // Error case mux.HandleFunc("/transactions/ERRForbidden403", func(w http.ResponseWriter, r *http.Request) {