Skip to content

Commit

Permalink
fix: supports empty message object (#2369)
Browse files Browse the repository at this point in the history
  • Loading branch information
danzhaaspaypal committed Apr 3, 2024
1 parent 5d93bc6 commit 3435784
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 65 deletions.
18 changes: 6 additions & 12 deletions src/ui/buttons/buttons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import { TagLine } from "./tagline";
import { Script } from "./script";
import { PoweredByPayPal } from "./poweredBy";
import { Message } from "./message";
import { calculateMessagePosition } from "./util";
import { calculateShowPoweredBy } from "./util";

type GetWalletInstrumentOptions = {|
wallet: ?Wallet,
Expand Down Expand Up @@ -247,14 +247,8 @@ export function Buttons(props: ButtonsProps): ElementNode {
layout === BUTTON_LAYOUT.HORIZONTAL &&
!fundingSource &&
!message;
const showPoweredBy =
layout === BUTTON_LAYOUT.VERTICAL && fundingSources.includes(FUNDING.CARD);

const calculatedMessagePosition = calculateMessagePosition({
message,
showPoweredBy,
layout,
});
const showPoweredBy = calculateShowPoweredBy(layout, fundingSources);

return (
<div
Expand All @@ -275,8 +269,8 @@ export function Buttons(props: ButtonsProps): ElementNode {
fundingEligibility={fundingEligibility}
/>

{message && calculatedMessagePosition === MESSAGE_POSITION.TOP ? (
<Message markup={messageMarkup} position={calculatedMessagePosition} />
{message && message.position === MESSAGE_POSITION.TOP ? (
<Message markup={messageMarkup} position={message.position} />
) : null}

{fundingSources.map((source, i) => (
Expand Down Expand Up @@ -332,8 +326,8 @@ export function Buttons(props: ButtonsProps): ElementNode {

{showPoweredBy ? <PoweredByPayPal locale={locale} nonce={nonce} /> : null}

{message && calculatedMessagePosition === MESSAGE_POSITION.BOTTOM ? (
<Message markup={messageMarkup} position={calculatedMessagePosition} />
{message && message.position === MESSAGE_POSITION.BOTTOM ? (
<Message markup={messageMarkup} position={message.position} />
) : null}

<Script nonce={nonce} />
Expand Down
32 changes: 23 additions & 9 deletions src/ui/buttons/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
import { getFundingConfig, isFundingEligible } from "../../funding";

import { BUTTON_SIZE_STYLE } from "./config";
import { isBorderRadiusNumber } from "./util";
import { isBorderRadiusNumber, calculateMessagePosition } from "./util";

export type CreateOrderData = {||} | {||};

Expand Down Expand Up @@ -431,9 +431,9 @@ export type ApplePaySessionConfigRequest = (
export type ButtonMessage = {|
amount?: number,
offer?: $ReadOnlyArray<$Values<typeof MESSAGE_OFFER>>,
color?: $Values<typeof MESSAGE_COLOR>,
position?: $Values<typeof MESSAGE_POSITION>,
align?: $Values<typeof MESSAGE_ALIGN>,
color: $Values<typeof MESSAGE_COLOR>,
position: $Values<typeof MESSAGE_POSITION>,
align: $Values<typeof MESSAGE_ALIGN>,
|};

export type ButtonMessageInputs = {|
Expand Down Expand Up @@ -585,6 +585,7 @@ export type ButtonPropsInputs = {
displayOnly: $ReadOnlyArray<$Values<typeof DISPLAY_ONLY_VALUES>>,
message?: ButtonMessageInputs | void,
messageMarkup?: string | void,
renderedButtons: $ReadOnlyArray<$Values<typeof FUNDING>>,
};

export const DEFAULT_STYLE = {
Expand Down Expand Up @@ -734,10 +735,17 @@ export function normalizeButtonStyle(
}

export function normalizeButtonMessage(
props: ?ButtonPropsInputs,
message: ButtonMessageInputs
message: ButtonMessageInputs,
layout: $Values<typeof BUTTON_LAYOUT>,
fundingSources: $ReadOnlyArray<$Values<typeof FUNDING>>
): ButtonMessage {
const { amount, offer, color, position, align } = message;
const {
amount,
offer,
color = MESSAGE_COLOR.BLACK,
position,
align = MESSAGE_ALIGN.CENTER,
} = message;

if (typeof amount !== "undefined") {
if (typeof amount !== "number") {
Expand Down Expand Up @@ -787,7 +795,7 @@ export function normalizeButtonMessage(
amount,
offer,
color,
position,
position: calculateMessagePosition(fundingSources, layout, position),
align,
};
}
Expand Down Expand Up @@ -848,6 +856,7 @@ export function normalizeButtonProps(
displayOnly = [],
message,
messageMarkup,
renderedButtons,
} = props;

const { country, lang } = locale;
Expand Down Expand Up @@ -906,6 +915,11 @@ export function normalizeButtonProps(
}

style = normalizeButtonStyle(props, style);
const { layout } = style;

message = message
? normalizeButtonMessage(message, layout, renderedButtons)
: undefined;

return {
clientID,
Expand Down Expand Up @@ -939,7 +953,7 @@ export function normalizeButtonProps(
supportedNativeBrowser,
showPayLabel,
displayOnly,
message: message ? normalizeButtonMessage(props, message) : undefined,
message,
messageMarkup,
};
}
32 changes: 16 additions & 16 deletions src/ui/buttons/util.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
/* @flow */
import { FUNDING } from "@paypal/sdk-constants/src";

import { BUTTON_LAYOUT, MESSAGE_POSITION } from "../../constants";
import { ValidationError } from "../../lib";

import type { ButtonMessage } from "./props";

export function isBorderRadiusNumber(borderRadius?: number): boolean {
return typeof borderRadius === "number";
}

type calculateMessagePositionProps = {|
message: ButtonMessage | void,
showPoweredBy: boolean,
layout: string,
|};
export function calculateShowPoweredBy(
layout: $Values<typeof BUTTON_LAYOUT>,
fundingSources: $ReadOnlyArray<$Values<typeof FUNDING>>
): boolean {
return (
layout === BUTTON_LAYOUT.VERTICAL && fundingSources.includes(FUNDING.CARD)
);
}

export function calculateMessagePosition({
message,
showPoweredBy,
layout,
}: calculateMessagePositionProps): string {
if (!message) {
return "none";
}
const { position } = message;
export function calculateMessagePosition(
fundingSources: $ReadOnlyArray<$Values<typeof FUNDING>>,
layout: $Values<typeof BUTTON_LAYOUT>,
position?: $Values<typeof MESSAGE_POSITION>
): $Values<typeof MESSAGE_POSITION> {
const showPoweredBy = calculateShowPoweredBy(layout, fundingSources);

if (showPoweredBy && position === MESSAGE_POSITION.BOTTOM) {
throw new ValidationError(
Expand Down
28 changes: 18 additions & 10 deletions src/zoid/buttons/component.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,24 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
value: getMerchantRequestedPopupsDisabled,
},

message: {
type: "object",
queryParam: true,
required: false,
decorate: ({ props, value }) => {
const {
style: { layout },
renderedButtons: fundingSources,
} = props;
return normalizeButtonMessage(
// $FlowFixMe
value,
layout,
fundingSources
);
},
},

nonce: {
type: "string",
default: getCSPNonce,
Expand Down Expand Up @@ -987,16 +1005,6 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
required: false,
default: () => window.__TEST_WALLET__,
},

message: {
type: "object",
queryParam: true,
required: false,
decorate: ({ props, value }) => {
// $FlowFixMe
return normalizeButtonMessage(props, value);
},
},
},
});
});
107 changes: 89 additions & 18 deletions test/integration/tests/button/message.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,95 @@ describe(`paypal button message`, () => {
destroyTestContainer();
});

describe("sets computed default values for undefined message properties", () => {
it("should populate message color when it is undefined", () => {
return wrapPromise(({ expect }) => {
window.paypal
.Buttons({
message: {},
test: {
onRender: expect("onRender", ({ xprops }) => {
const {
message: { color },
} = xprops;
if (!color) {
throw new Error(
`Expected message color property to be populated: ${JSON.stringify(
xprops.message
)}`
);
}
}),
},
})
.render("#testContainer");
});
});
it("should populate message align(ment) when it is undefined", () => {
return wrapPromise(({ expect }) => {
window.paypal
.Buttons({
message: {},
test: {
onRender: expect("onRender", ({ xprops }) => {
const {
message: { align },
} = xprops;
if (!align) {
throw new Error(
`Expected message align property to be populated: ${JSON.stringify(
xprops.message
)}`
);
}
}),
},
})
.render("#testContainer");
});
});
it("should populate position with bottom when layout is horizontal", () => {
return wrapPromise(({ expect }) => {
window.paypal
.Buttons({
style: {
layout: "horizontal",
},
message: {},
test: {
onRender: expect("onRender", ({ xprops }) => {
const {
message: { position },
} = xprops;
assert.equal(position, "bottom");
}),
},
})
.render("#testContainer");
});
});
it("should populate position with top when layout is vertical", () => {
return wrapPromise(({ expect }) => {
window.paypal
.Buttons({
style: {
layout: "vertical",
},
message: {},
test: {
onRender: expect("onRender", ({ xprops }) => {
const {
message: { position },
} = xprops;
assert.equal(position, "top");
}),
},
})
.render("#testContainer");
});
});
});

describe("reserves space for message", () => {
it("should reserve space for a message when messageMarkup is undefined", (done) => {
window.paypal
Expand Down Expand Up @@ -121,24 +210,6 @@ describe(`paypal button message`, () => {
});
});

describe("error handling", () => {
it("should throw error when position is bottom and credit/debit is a funding source", () => {
return wrapPromise(({ expect }) => {
window.paypal
.Buttons({
style: {
layout: "vertical",
},
message: {
position: "bottom",
},
onError: expect("onError"),
})
.render("#testContainer");
});
});
});

describe(`prop considerations`, () => {
it("message should take precedence over tagline when both are truthy", (done) => {
window.paypal
Expand Down
11 changes: 11 additions & 0 deletions test/integration/tests/button/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,17 @@ const buttonConfigs = [
valid: false,
},

{
message: {
amount: 100,
offer: ["pay_later_long_term"],
color: "black",
position: "bottom", // Message position must be 'top' when Debit and/or Credit Card button is present
align: "left",
},
valid: false,
},

{
message: {},
valid: true,
Expand Down

0 comments on commit 3435784

Please sign in to comment.