ci(cypress): add auto-retry tests to routing (#5713)

Co-authored-by: likhinbopanna <likhin.bopanna@juspay.in>
This commit is contained in:
Pa1NarK
2024-08-29 19:33:02 +05:30
committed by GitHub
parent 2049ab0554
commit b66f91034b
7 changed files with 968 additions and 19 deletions

View File

@ -0,0 +1,626 @@
import * as fixtures from "../../fixtures/imports";
import State from "../../utils/State";
import * as utils from "../RoutingUtils/Utils";
let globalState;
describe("Auto Retries & Step Up 3DS", () => {
context("Login", () => {
before("seed global state", () => {
cy.task("getGlobalState").then((state) => {
globalState = new State(state);
});
});
afterEach("flush global state", () => {
cy.task("setGlobalState", globalState.data);
});
it("Create JWT token", () => {
let data = utils.getConnectorDetails("common")["jwt"];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createJWTToken(req_data, res_data, globalState);
});
it("List MCA", () => {
cy.ListMcaByMid(globalState);
});
it("API key create call", () => {
cy.apiKeyCreateTest(fixtures.apiKeyCreateBody, globalState);
});
it("Customer create call", () => {
cy.createCustomerCallTest(fixtures.customerCreateBody, globalState);
});
it("Retrieve Merchant", () => {
cy.merchantRetrieveCall(globalState);
});
});
context("Auto Retries", () => {
context("[Config: enable] Auto retries", () => {
it("Enable auto retries", () => {
cy.autoRetryConfig(fixtures.configs.gsm, globalState, "true");
});
context("Max auto retries", () => {
context("Adyen -> Stripe auto retries", () => {
context("Enable routing configs", () => {
before("seed global state", () => {
cy.task("getGlobalState").then((state) => {
globalState = new State(state);
});
});
afterEach("flush global state", () => {
cy.task("setGlobalState", globalState.data);
});
it("Add routing config", () => {
let data = utils.getConnectorDetails("common")["routing"];
let req_data = data["Request"];
let res_data = data["Response"];
let routing_data = [
{
connector: "adyen",
merchant_connector_id: globalState.get("adyenMcaId"),
},
{
connector: "stripe",
merchant_connector_id: globalState.get("stripeMcaId"),
},
{
connector: "bluesnap",
merchant_connector_id: globalState.get("bluesnapMcaId"),
},
];
cy.addRoutingConfig(
fixtures.routingConfigBody,
req_data,
res_data,
"priority",
routing_data,
globalState
);
});
it("Activate routing config", () => {
let data = utils.getConnectorDetails("common")["routing"];
let req_data = data["Request"];
let res_data = data["Response"];
cy.activateRoutingConfig(req_data, res_data, globalState);
});
});
context("Max auto retries = 2", () => {
const max_auto_retries = 2;
it("Update max auto retries", () => {
cy.setMaxAutoRetries(
fixtures.configs.max_auto_retries,
globalState,
`${max_auto_retries}`
);
});
context("Make payment", () => {
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"BluesnapConfirm"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(
globalState,
true,
max_auto_retries + 1
);
});
});
});
context("Max auto retries = 1", () => {
const max_auto_retries = 1;
it("Update max auto retries", () => {
cy.setMaxAutoRetries(
fixtures.configs.max_auto_retries,
globalState,
`${max_auto_retries}`
);
});
context("Make payment", () => {
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"StripeConfirmSuccess"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(
globalState,
true,
max_auto_retries + 1
);
});
});
});
context("Max auto retries = 0", () => {
const max_auto_retries = 0;
it("Update max auto retries", () => {
cy.setMaxAutoRetries(
fixtures.configs.max_auto_retries,
globalState,
`${max_auto_retries}`
);
});
context("Make payment", () => {
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"AdyenConfirmFail"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(
globalState,
true,
max_auto_retries + 1
);
});
});
});
});
context("Stripe -> Adyen auto retries", () => {
context("Enable routing configs", () => {
before("seed global state", () => {
cy.task("getGlobalState").then((state) => {
globalState = new State(state);
});
});
afterEach("flush global state", () => {
cy.task("setGlobalState", globalState.data);
});
it("Add routing config", () => {
let data = utils.getConnectorDetails("common")["routing"];
let req_data = data["Request"];
let res_data = data["Response"];
let routing_data = [
{
connector: "stripe",
merchant_connector_id: globalState.get("stripeMcaId"),
},
{
connector: "adyen",
merchant_connector_id: globalState.get("adyenMcaId"),
},
{
connector: "bluesnap",
merchant_connector_id: globalState.get("bluesnapMcaId"),
},
];
cy.addRoutingConfig(
fixtures.routingConfigBody,
req_data,
res_data,
"priority",
routing_data,
globalState
);
});
it("Activate routing config", () => {
let data = utils.getConnectorDetails("common")["routing"];
let req_data = data["Request"];
let res_data = data["Response"];
cy.activateRoutingConfig(req_data, res_data, globalState);
});
});
context("Max auto retries = 2", () => {
const max_auto_retries = 2;
it("Update max auto retries", () => {
cy.setMaxAutoRetries(
fixtures.configs.max_auto_retries,
globalState,
`${max_auto_retries}`
);
});
context("Make payment", () => {
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"BluesnapConfirm"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(
globalState,
true,
max_auto_retries + 1
);
});
});
});
context("Max auto retries = 1", () => {
const max_auto_retries = 1;
it("Update max auto retries", () => {
cy.setMaxAutoRetries(
fixtures.configs.max_auto_retries,
globalState,
`${max_auto_retries}`
);
});
context("Make payment", () => {
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"AdyenConfirm"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(
globalState,
true,
max_auto_retries + 1
);
});
});
});
context("Max auto retries = 0", () => {
const max_auto_retries = 0;
it("Update max auto retries", () => {
cy.setMaxAutoRetries(
fixtures.configs.max_auto_retries,
globalState,
`${max_auto_retries}`
);
});
context("Make payment", () => {
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"StripeConfirmFail"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(
globalState,
true,
max_auto_retries + 1
);
});
});
});
});
});
context("Step up 3DS", () => {
context("[Config: set] GSM", () => {
it("[Config: enable] Step up GSM", () => {
cy.updateGsmConfig(fixtures.gsmBody.gsm_update, globalState, true);
});
it("[Config: enable] Step up for Stripe", () => {
cy.stepUp(fixtures.configs.step_up, globalState, '["stripe"]');
});
});
context("Make Payment", () => {
const max_auto_retries = 1;
it("Update max auto retries", () => {
cy.setMaxAutoRetries(
fixtures.configs.max_auto_retries,
globalState,
`${max_auto_retries}`
);
});
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"StripeConfirm3DS"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(globalState, true, max_auto_retries + 1);
});
});
});
});
context("[Config: disable] Auto retries", () => {
it("[Config: disable] Auto retries", () => {
cy.autoRetryConfig(fixtures.configs.gsm, globalState, "false");
});
it("[Config: disable] Step up GSM", () => {
cy.updateGsmConfig(fixtures.gsmBody.gsm_update, globalState, false);
});
context("Make payment", () => {
context("[Failed] Make payment", () => {
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"StripeConfirmFail"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(globalState, true);
});
});
context("[Succeeded] Make payment", () => {
it("Payment create call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"PaymentIntent"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.createPaymentIntentTest(
fixtures.createPaymentBody,
req_data,
res_data,
"no_three_ds",
"automatic",
globalState
);
});
it("Payment confirm call", () => {
let data =
utils.getConnectorDetails("autoretries")["card_pm"][
"StripeConfirmSuccess"
];
let req_data = data["Request"];
let res_data = data["Response"];
cy.confirmCallTest(
fixtures.confirmBody,
req_data,
res_data,
true,
globalState
);
});
it("Payment retrieve call", () => {
cy.retrievePaymentCallTest(globalState, true);
});
});
});
});
});
});

View File

@ -0,0 +1,149 @@
const card_1142 = {
card_number: "4111111145551142",
card_exp_month: "03",
card_exp_year: "30",
card_holder_name: "Borino",
card_cvc: "737",
};
const card_4242 = {
card_number: "4242424242424242",
card_exp_month: "03",
card_exp_year: "30",
card_holder_name: "Borino",
card_cvc: "737",
};
const card_9299 = {
card_number: "4263982640269299",
card_exp_month: "02",
card_exp_year: "26",
card_holder_name: "Borino",
card_cvc: "837",
};
export const connectorDetails = {
card_pm: {
AdyenConfirm: {
Request: {
payment_method: "card",
payment_method_type: "debit",
payment_method_data: {
card: card_1142,
},
currency: "USD",
customer_acceptance: null,
setup_future_usage: "on_session",
},
Response: {
status: 200,
body: {
status: "succeeded",
connector: "adyen",
},
},
},
AdyenConfirmFail: {
Request: {
payment_method: "card",
payment_method_type: "debit",
payment_method_data: {
card: card_4242,
},
},
Response: {
body: {
status: "failed",
connector: "adyen",
},
},
},
BluesnapConfirm: {
Request: {
payment_method: "card",
payment_method_type: "debit",
payment_method_data: {
card: card_9299,
},
currency: "USD",
customer_acceptance: null,
setup_future_usage: "on_session",
},
Response: {
status: 200,
body: {
status: "succeeded",
connector: "bluesnap",
},
},
},
PaymentIntent: {
Request: {
currency: "USD",
customer_acceptance: null,
setup_future_usage: "on_session",
},
Response: {
status: 200,
body: {
status: "requires_payment_method",
},
},
},
StripeConfirmFail: {
Request: {
payment_method: "card",
payment_method_type: "debit",
payment_method_data: {
card: card_1142,
},
currency: "USD",
customer_acceptance: null,
setup_future_usage: "on_session",
},
Response: {
status: 200,
body: {
status: "failed",
connector: "stripe",
},
},
},
StripeConfirm3DS: {
Request: {
payment_method: "card",
payment_method_type: "debit",
payment_method_data: {
card: card_1142,
},
currency: "USD",
customer_acceptance: null,
setup_future_usage: "on_session",
},
Response: {
status: 200,
body: {
status: "requires_customer_action",
connector: "stripe",
},
},
},
StripeConfirmSuccess: {
Request: {
payment_method: "card",
payment_method_type: "debit",
payment_method_data: {
card: card_4242,
},
currency: "USD",
customer_acceptance: null,
setup_future_usage: "on_session",
},
Response: {
status: 200,
body: {
status: "succeeded",
connector: "stripe",
},
},
},
},
};

View File

@ -1,9 +1,11 @@
import { connectorDetails as adyenConnectorDetails } from "./Adyen.js";
import { connectorDetails as autoretryConnectorDetails } from "./Autoretries.js";
import { connectorDetails as commonConnectorDetails } from "./Commons.js";
import { connectorDetails as stripeConnectorDetails } from "./Stripe.js";
const connectorDetails = {
adyen: adyenConnectorDetails,
autoretries: autoretryConnectorDetails,
common: commonConnectorDetails,
stripe: stripeConnectorDetails,
};

View File

@ -0,0 +1,14 @@
{
"gsm": {
"key": "",
"value": ""
},
"max_auto_retries": {
"key": "",
"value": ""
},
"step_up": {
"key": "",
"value": ""
}
}

View File

@ -0,0 +1,12 @@
{
"gsm_update": {
"connector": "stripe",
"flow": "Authorize",
"sub_flow": "sub_flow",
"code": "card_declined",
"message": "card_declined",
"status": "failure",
"decision": "retry",
"step_up_possible": ""
}
}

View File

@ -1,4 +1,5 @@
import captureBody from "./capture-flow-body.json";
import configs from "./configs.json";
import confirmBody from "./confirm-body.json";
import apiKeyCreateBody from "./create-api-key-body.json";
import createConfirmPaymentBody from "./create-confirm-body.json";
@ -9,6 +10,7 @@ import mitConfirmBody from "./create-mandate-mit.json";
import createPaymentBody from "./create-payment-body.json";
import createPayoutBody from "./create-payout-confirm-body.json";
import pmIdConfirmBody from "./create-pm-id-mit.json";
import gsmBody from "./gsm-body.json";
import listRefundCall from "./list-refund-call-body.json";
import merchantCreateBody from "./merchant-create-body.json";
import merchantUpdateBody from "./merchant-update-body.json";
@ -25,6 +27,7 @@ export {
apiKeyUpdateBody,
captureBody,
citConfirmBody,
configs,
confirmBody,
createConfirmPaymentBody,
createConnectorBody,
@ -32,6 +35,7 @@ export {
createPayoutBody,
customerCreateBody,
customerUpdateBody,
gsmBody,
listRefundCall,
merchantCreateBody,
merchantUpdateBody,

View File

@ -84,7 +84,10 @@ Cypress.Commands.add("merchantRetrieveCall", (globalState) => {
expect(response.body.default_profile).to.not.be.empty;
expect(response.body.organization_id).to.not.be.empty;
globalState.set("organizationId", response.body.organization_id);
globalState.set("publishableKey", response.body.publishable_key);
if (globalState.get("publishableKey") === undefined) {
globalState.set("publishableKey", response.body.publishable_key);
}
});
});
@ -1394,25 +1397,56 @@ Cypress.Commands.add(
}
);
Cypress.Commands.add("retrievePaymentCallTest", (globalState) => {
const payment_id = globalState.get("paymentID");
cy.request({
method: "GET",
url: `${globalState.get("baseUrl")}/payments/${payment_id}?force_sync=true`,
headers: {
"Content-Type": "application/json",
"api-key": globalState.get("apiKey"),
},
failOnStatusCode: false,
}).then((response) => {
logRequestId(response.headers["x-request-id"]);
Cypress.Commands.add(
"retrievePaymentCallTest",
(globalState, autoretries = false, attempt = 1) => {
const payment_id = globalState.get("paymentID");
cy.request({
method: "GET",
url: `${globalState.get("baseUrl")}/payments/${payment_id}?force_sync=true&expand_attempts=true`,
headers: {
"Content-Type": "application/json",
"api-key": globalState.get("apiKey"),
},
failOnStatusCode: false,
}).then((response) => {
logRequestId(response.headers["x-request-id"]);
expect(response.headers["content-type"]).to.include("application/json");
expect(response.body.payment_id).to.equal(payment_id);
expect(response.body.amount).to.equal(globalState.get("paymentAmount"));
globalState.set("paymentID", response.body.payment_id);
});
});
expect(response.headers["content-type"]).to.include("application/json");
expect(response.body.payment_id).to.equal(payment_id);
expect(response.body.amount).to.equal(globalState.get("paymentAmount"));
globalState.set("paymentID", response.body.payment_id);
if (autoretries) {
expect(response.body).to.have.property("attempts");
expect(response.body.attempts).to.be.an("array").and.not.empty;
expect(response.body.attempts.length).to.equal(attempt);
expect(response.body.attempts[0].attempt_id).to.include(
`${payment_id}_`
);
for (const key in response.body.attempts) {
if (
response.body.attempts[key].attempt_id ===
`${payment_id}_${attempt}` &&
response.body.status === "succeeded"
) {
expect(response.body.attempts[key].status).to.equal("charged");
} else if (
response.body.attempts[key].attempt_id ===
`${payment_id}_${attempt}` &&
response.body.status === "requires_customer_action"
) {
expect(response.body.attempts[key].status).to.equal(
"authentication_pending"
);
} else {
expect(response.body.attempts[key].status).to.equal("failure");
}
}
}
});
}
);
Cypress.Commands.add(
"refundCallTest",
@ -2092,6 +2126,7 @@ Cypress.Commands.add("ListMcaByMid", (globalState) => {
globalState.set("profileId", response.body[0].profile_id);
globalState.set("stripeMcaId", response.body[0].merchant_connector_id);
globalState.set("adyenMcaId", response.body[1].merchant_connector_id);
globalState.set("bluesnapMcaId", response.body[3].merchant_connector_id);
});
});
@ -2190,3 +2225,110 @@ Cypress.Commands.add(
});
}
);
Cypress.Commands.add(
"autoRetryConfig",
(autoRetryGsmBody, globalState, value) => {
const key = `should_call_gsm_${globalState.get("merchantId")}`;
autoRetryGsmBody.key = key;
autoRetryGsmBody.value = value;
cy.request({
method: "POST",
url: `${globalState.get("baseUrl")}/configs/${key}`,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"api-key": globalState.get("adminApiKey"),
},
body: autoRetryGsmBody,
failOnStatusCode: false,
}).then((response) => {
logRequestId(response.headers["x-request-id"]);
if (response.status === 200) {
expect(response.body).to.have.property("key").to.equal(key);
expect(response.body).to.have.property("value").to.equal(value);
}
});
}
);
Cypress.Commands.add(
"setMaxAutoRetries",
(maxAutoRetryBody, globalState, value) => {
const key = `max_auto_retries_enabled_${globalState.get("merchantId")}`;
maxAutoRetryBody.key = key;
maxAutoRetryBody.value = value;
cy.request({
method: "POST",
url: `${globalState.get("baseUrl")}/configs/${key}`,
headers: {
Accept: "application/json",
"Content-Type": "application/json",
"api-key": globalState.get("adminApiKey"),
},
body: maxAutoRetryBody,
failOnStatusCode: false,
}).then((response) => {
logRequestId(response.headers["x-request-id"]);
if (response.status === 200) {
expect(response.body).to.have.property("key").to.equal(key);
expect(response.body).to.have.property("value").to.equal(value);
}
});
}
);
Cypress.Commands.add(
"updateGsmConfig",
(gsmBody, globalState, step_up_possible) => {
gsmBody.step_up_possible = step_up_possible;
cy.request({
method: "POST",
url: `${globalState.get("baseUrl")}/gsm/update`,
headers: {
"Content-Type": "application/json",
"api-key": globalState.get("adminApiKey"),
},
body: gsmBody,
failOnStatusCode: false,
}).then((response) => {
logRequestId(response.headers["x-request-id"]);
if (response.status === 200) {
expect(response.body)
.to.have.property("message")
.to.equal("card_declined");
expect(response.body).to.have.property("connector").to.equal("stripe");
expect(response.body)
.to.have.property("step_up_possible")
.to.equal(step_up_possible);
}
});
}
);
Cypress.Commands.add("stepUp", (stepUpBody, globalState, value) => {
const key = `step_up_enabled_${globalState.get("merchantId")}`;
stepUpBody.key = key;
stepUpBody.value = value;
cy.request({
method: "POST",
url: `${globalState.get("baseUrl")}/configs/${key}`,
headers: {
"Content-Type": "application/json",
"api-key": globalState.get("adminApiKey"),
},
body: stepUpBody,
failOnStatusCode: false,
}).then((response) => {
logRequestId(response.headers["x-request-id"]);
if (response.status === 200) {
expect(response.body).to.have.property("key").to.equal(key);
expect(response.body).to.have.property("value").to.equal(value);
}
});
});