Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove customer wrapper from getRecommendedPaymentMethods #2318

Merged
merged 1 commit into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/api/shopper-insights/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ function createRecommendedPaymentMethodsRequestPayload(
}),
// $FlowIssue
...(hasEmail(merchantPayload) && {
email: merchantPayload?.customer?.email,
email: merchantPayload?.email,
}),
...(hasPhoneNumber(merchantPayload) && {
phone: {
country_code: merchantPayload?.customer?.phone?.countryCode,
national_number: merchantPayload?.customer?.phone?.nationalNumber,
country_code: merchantPayload?.phone?.countryCode,
national_number: merchantPayload?.phone?.nationalNumber,
},
}),
},
Expand Down
113 changes: 40 additions & 73 deletions src/api/shopper-insights/component.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,10 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
const shopperInsightsComponent = getShopperInsightsComponent();
const recommendedPaymentMethods =
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678901",
},
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678901",
},
});

Expand All @@ -78,12 +76,10 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
test("should get recommended payment methods from memoized request for the exact same payload", async () => {
const shopperInsightsComponent = getShopperInsightsComponent();
const payload = {
customer: {
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678901",
},
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678901",
},
};
const response1 =
Expand Down Expand Up @@ -111,17 +107,13 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
const shopperInsightsComponent = getShopperInsightsComponent();
const response1 =
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
},
email: "[email protected]",
});
expect(request).toHaveBeenCalled();
expect(request).toHaveBeenCalledTimes(1);
const response2 =
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
},
email: "[email protected]",
});

expect(request).toHaveBeenCalled();
Expand Down Expand Up @@ -155,12 +147,10 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {

await expect(() =>
shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678905",
},
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678905",
},
})
).rejects.toThrow(
Expand All @@ -172,15 +162,13 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
expect.assertions(2);
});

test("create customer payload with email and phone number", async () => {
test("create payload with email and phone number", async () => {
const shopperInsightsComponent = getShopperInsightsComponent();
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678906",
},
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678906",
},
});

Expand All @@ -199,12 +187,10 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
);
});

test("create customer payload with email only", async () => {
test("create payload with email only", async () => {
const shopperInsightsComponent = getShopperInsightsComponent();
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
},
email: "[email protected]",
});

expect(request).toHaveBeenCalledWith(
Expand All @@ -218,15 +204,13 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
);
});

test("create customer payload with phone only", async () => {
test("create payload with phone only", async () => {
const shopperInsightsComponent = getShopperInsightsComponent();
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678901",
},
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678901",
},
});

Expand All @@ -244,12 +228,10 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
);
});

test("should default purchase units with currency code in the customer payload", async () => {
test("should default purchase units with currency code in the payload", async () => {
const shopperInsightsComponent = getShopperInsightsComponent();
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
},
email: "[email protected]",
});

expect(request).toHaveBeenCalledWith(
Expand All @@ -273,9 +255,7 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {

const shopperInsightsComponent = getShopperInsightsComponent();
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
},
email: "[email protected]",
});

expect(request).toHaveBeenCalledWith(
Expand All @@ -297,9 +277,7 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {

const shopperInsightsComponent = getShopperInsightsComponent();
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
},
email: "[email protected]",
});

expect(request).toHaveBeenCalledWith(
Expand All @@ -313,31 +291,22 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
);
});

test("should not set country code in prod env in the customer payload", async () => {
test("should not set country code in prod env in the payload", async () => {
const shopperInsightsComponent = getShopperInsightsComponent();
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
},
email: "[email protected]",
});

expect(request).toHaveBeenCalledWith(
expect.objectContaining({
json: expect.objectContaining({
customer: expect.not.objectContaining({
country_code: expect.anything(),
}),
}),
})
// $FlowIssue
expect(request.mock.calls[0][0].json.customer.country_code).toEqual(
undefined
);
});

test("should request recommended payment methods by setting account details in the payload", async () => {
const shopperInsightsComponent = getShopperInsightsComponent();
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
},
email: "[email protected]",
});

expect(request).toHaveBeenCalledWith(
Expand All @@ -362,12 +331,10 @@ describe("shopper insights component - getRecommendedPaymentMethods()", () => {
await expect(
async () =>
await shopperInsightsComponent.getRecommendedPaymentMethods({
customer: {
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678905",
},
email: "[email protected]",
phone: {
countryCode: "1",
nationalNumber: "2345678905",
},
})
).rejects.toThrowError(error);
Expand Down
56 changes: 19 additions & 37 deletions src/api/shopper-insights/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,63 +75,45 @@ export function validateMerchantConfig({
}
}

export const hasEmail = (merchantPayload: MerchantPayloadData): boolean => {
return Boolean(merchantPayload?.customer?.email);
};

export const hasPhoneNumber = (
merchantPayload: MerchantPayloadData
): boolean => {
return Boolean(
merchantPayload?.customer?.phone?.countryCode &&
merchantPayload?.customer?.phone?.nationalNumber
export const hasEmail = (merchantPayload: MerchantPayloadData): boolean =>
Boolean(merchantPayload?.email);

export const hasPhoneNumber = (merchantPayload: MerchantPayloadData): boolean =>
Boolean(
merchantPayload?.phone?.countryCode &&
merchantPayload?.phone?.nationalNumber
);
};

const isValidEmailFormat = (email: string): boolean => {
const emailRegex = /^.+@.+$/;
return email.length < 320 && emailRegex.test(email);
};
const isValidEmailFormat = (email: ?string): boolean =>
typeof email === "string" && email.length < 320 && /^.+@.+$/.test(email);

const isValidPhoneNumberFormat = (phoneNumber: string): boolean => {
const phoneNumberRegex = /\d{5,}/;
return phoneNumberRegex.test(phoneNumber);
};
const isValidPhoneNumberFormat = (phoneNumber: ?string): boolean =>
typeof phoneNumber === "string" && /\d{5,}/.test(phoneNumber);

export function validateMerchantPayload(merchantPayload: MerchantPayloadData) {
if (
typeof merchantPayload !== "object" ||
Object.keys(merchantPayload).length === 0 ||
!Object.keys(merchantPayload).includes("customer")
) {
throw new ValidationError(
`Expected shopper information to be passed into customer object`
);
}

const hasEmailOrPhoneNumber =
hasEmail(merchantPayload) || hasPhoneNumber(merchantPayload);
if (!hasEmailOrPhoneNumber) {
if (typeof merchantPayload !== "object" || !hasEmailOrPhoneNumber) {
throw new ValidationError(
`Expected shopper information to include an email or phone number`
`Expected either email or phone number for get recommended payment methods`
);
}

const merchantPayloadEmail = merchantPayload?.customer?.email || "";
if (hasEmail(merchantPayload) && !isValidEmailFormat(merchantPayloadEmail)) {
if (
hasEmail(merchantPayload) &&
!isValidEmailFormat(merchantPayload?.email)
) {
throw new ValidationError(
`Expected shopper information to include a valid email format`
);
}

const merchantPhonePayload = merchantPayload?.customer?.phone || {};
const nationalNumber = merchantPhonePayload?.nationalNumber || "";
if (
hasPhoneNumber(merchantPayload) &&
!isValidPhoneNumberFormat(nationalNumber)
!isValidPhoneNumberFormat(merchantPayload?.phone?.nationalNumber)
) {
throw new ValidationError(
`Expected shopper information to a valid phone number format`
`Expected shopper information to be a valid phone number format`
);
}
}
Loading