@paypal/checkout-components 5.0.416-alpha-620789e.0 → 5.0.420

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paypal/checkout-components",
3
- "version": "5.0.416-alpha-620789e.0",
3
+ "version": "5.0.420",
4
4
  "description": "PayPal Checkout components, for integrating checkout products.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -119,11 +119,7 @@ export function isFundingEligible(
119
119
  return false;
120
120
  }
121
121
 
122
- if (
123
- !fundingConfig.automatic &&
124
- source !== fundingSource &&
125
- !experiment?.forceAllFundingAutomatic
126
- ) {
122
+ if (!fundingConfig.automatic && source !== fundingSource) {
127
123
  return false;
128
124
  }
129
125
 
@@ -20,7 +20,11 @@ import {
20
20
  isFirefox,
21
21
  } from "@krakenjs/belter/src";
22
22
 
23
- import { supportsVenmoPopups, isSupportedNativeVenmoBrowser } from "./util";
23
+ import {
24
+ getFundingSourceColors,
25
+ supportsVenmoPopups,
26
+ isSupportedNativeVenmoBrowser,
27
+ } from "./util";
24
28
 
25
29
  // Mock all the browser detection functions from belter
26
30
  vi.mock("@krakenjs/belter/src", () => ({
@@ -76,6 +80,85 @@ describe("funding/util", () => {
76
80
  vi.resetAllMocks();
77
81
  });
78
82
 
83
+ describe("getFundingSourceColors", () => {
84
+ const mockFundingConfig = {
85
+ colors: ["gold", "blue", "silver"],
86
+ colorsRebrand: ["blue", "black", "white"],
87
+ logoColors: { default: "blue", white: "blue" },
88
+ logoColorsRebrand: { blue: "black", black: "white", white: "black" },
89
+ secondaryColors: { default: "silver", black: "black" },
90
+ secondaryColorsRebrand: { default: "white", black: "black" },
91
+ textColors: { gold: "black", blue: "white" },
92
+ textColorsRebrand: { default: "black", blue: "black", black: "white" },
93
+ };
94
+
95
+ it("should return legacy color fields when shouldApplyRebrandedStyles is false", () => {
96
+ const result = getFundingSourceColors({
97
+ // $FlowFixMe
98
+ fundingConfig: mockFundingConfig,
99
+ shouldApplyRebrandedStyles: false,
100
+ });
101
+
102
+ expect(result.colors).toBe(mockFundingConfig.colors);
103
+ expect(result.logoColors).toBe(mockFundingConfig.logoColors);
104
+ expect(result.secondaryColors).toBe(mockFundingConfig.secondaryColors);
105
+ expect(result.textColors).toBe(mockFundingConfig.textColors);
106
+ });
107
+
108
+ it("should return rebrand color fields when shouldApplyRebrandedStyles is true", () => {
109
+ const result = getFundingSourceColors({
110
+ // $FlowFixMe
111
+ fundingConfig: mockFundingConfig,
112
+ shouldApplyRebrandedStyles: true,
113
+ });
114
+
115
+ expect(result.colors).toBe(mockFundingConfig.colorsRebrand);
116
+ expect(result.logoColors).toBe(mockFundingConfig.logoColorsRebrand);
117
+ expect(result.secondaryColors).toBe(
118
+ mockFundingConfig.secondaryColorsRebrand
119
+ );
120
+ expect(result.textColors).toBe(mockFundingConfig.textColorsRebrand);
121
+ });
122
+
123
+ it("should fall back to legacy colors array when shouldApplyRebrandedStyles is true but colorsRebrand is not defined", () => {
124
+ const configWithoutColorsRebrand = {
125
+ ...mockFundingConfig,
126
+ colorsRebrand: undefined,
127
+ };
128
+
129
+ const result = getFundingSourceColors({
130
+ // $FlowFixMe
131
+ fundingConfig: configWithoutColorsRebrand,
132
+ shouldApplyRebrandedStyles: true,
133
+ });
134
+
135
+ expect(result.colors).toBe(configWithoutColorsRebrand.colors);
136
+ });
137
+
138
+ it("should still return rebrand logo/secondary/text colors even when colorsRebrand is not defined", () => {
139
+ const configWithoutColorsRebrand = {
140
+ ...mockFundingConfig,
141
+ colorsRebrand: undefined,
142
+ };
143
+
144
+ const result = getFundingSourceColors({
145
+ // $FlowFixMe
146
+ fundingConfig: configWithoutColorsRebrand,
147
+ shouldApplyRebrandedStyles: true,
148
+ });
149
+
150
+ expect(result.logoColors).toBe(
151
+ configWithoutColorsRebrand.logoColorsRebrand
152
+ );
153
+ expect(result.secondaryColors).toBe(
154
+ configWithoutColorsRebrand.secondaryColorsRebrand
155
+ );
156
+ expect(result.textColors).toBe(
157
+ configWithoutColorsRebrand.textColorsRebrand
158
+ );
159
+ });
160
+ });
161
+
79
162
  describe("supportsVenmoPopups", () => {
80
163
  describe("when in supported webview", () => {
81
164
  beforeEach(() => {
package/src/types.js CHANGED
@@ -70,7 +70,6 @@ export type Experiment = {|
70
70
  paypalCreditButtonCreateVaultSetupTokenExists?: boolean,
71
71
  isPaylaterCobrandedLabelEnabled?: boolean,
72
72
  isPaylaterCobrandedLabelRandomizationEnabled?: boolean,
73
- forceAllFundingAutomatic?: boolean,
74
73
  |};
75
74
 
76
75
  export type Requires = {|
@@ -2,7 +2,7 @@
2
2
  import { describe, expect, it, beforeEach, vi } from "vitest";
3
3
  import { FUNDING } from "@paypal/sdk-constants";
4
4
 
5
- import { BUTTON_COLOR } from "../../constants";
5
+ import { BUTTON_COLOR, BUTTON_LAYOUT, BUTTON_SHAPE } from "../../constants";
6
6
 
7
7
  import {
8
8
  getButtonColor,
@@ -14,6 +14,7 @@ import {
14
14
  determineRandomButtonColor,
15
15
  getColorABTestFromStorage,
16
16
  getBrandVersion,
17
+ normalizeButtonStyle,
17
18
  } from "./props";
18
19
 
19
20
  describe("getBrandVersion", () => {
@@ -182,7 +183,25 @@ describe("getDefaultColorForFundingSource", () => {
182
183
  ...actual,
183
184
  getFundingConfig: () => ({
184
185
  [FUNDING.PAYPAL]: {
185
- colors: [BUTTON_COLOR.GOLD, BUTTON_COLOR.BLUE, BUTTON_COLOR.WHITE],
186
+ colors: [
187
+ BUTTON_COLOR.GOLD,
188
+ BUTTON_COLOR.BLUE,
189
+ BUTTON_COLOR.SILVER,
190
+ BUTTON_COLOR.WHITE,
191
+ ],
192
+ colorsRebrand: [
193
+ BUTTON_COLOR.BLUE,
194
+ BUTTON_COLOR.BLACK,
195
+ BUTTON_COLOR.WHITE,
196
+ ],
197
+ layouts: [BUTTON_LAYOUT.VERTICAL, BUTTON_LAYOUT.HORIZONTAL],
198
+ shapes: [BUTTON_SHAPE.RECT, BUTTON_SHAPE.PILL, BUTTON_SHAPE.SHARP],
199
+ logoColors: {},
200
+ logoColorsRebrand: {},
201
+ textColors: {},
202
+ textColorsRebrand: {},
203
+ secondaryColors: {},
204
+ secondaryColorsRebrand: {},
186
205
  },
187
206
  [FUNDING.VENMO]: {
188
207
  colors: [BUTTON_COLOR.BLUE],
@@ -469,6 +488,21 @@ describe("getColorForFullRedesign", () => {
469
488
  });
470
489
  });
471
490
 
491
+ it("should map SILVER to WHITE", () => {
492
+ const result = getColorForFullRedesign({
493
+ // $FlowFixMe
494
+ style: { color: BUTTON_COLOR.SILVER },
495
+ fundingSource: FUNDING.PAYPAL,
496
+ });
497
+
498
+ expect(result).toEqual({
499
+ color: BUTTON_COLOR.WHITE,
500
+ shouldApplyRebrandedStyles: true,
501
+ isButtonColorABTestMerchant: false,
502
+ brandVersion: "v2",
503
+ });
504
+ });
505
+
472
506
  it("should handle unspecified style.color by determining an appropriate color", () => {
473
507
  const result = getColorForFullRedesign({
474
508
  // $FlowFixMe
@@ -802,3 +836,51 @@ describe("HideSubmitButtonProps type validation", () => {
802
836
  expect(validButtonProps.hideSubmitButtonForCardForm).toBe(false);
803
837
  });
804
838
  });
839
+
840
+ describe("normalizeButtonStyle requestedButtonColor", () => {
841
+ it("should preserve the merchant-provided color as requestedButtonColor when rebrand maps it to a different color", () => {
842
+ const result = normalizeButtonStyle(
843
+ // $FlowFixMe
844
+ {
845
+ fundingSource: FUNDING.PAYPAL,
846
+ buttonColor: {
847
+ color: BUTTON_COLOR.BLUE,
848
+ shouldApplyRebrandedStyles: true,
849
+ brandVersion: "v2",
850
+ isButtonColorABTestMerchant: false,
851
+ },
852
+ },
853
+ // $FlowFixMe
854
+ { color: BUTTON_COLOR.GOLD }
855
+ );
856
+
857
+ // Merchant configured gold — rebrand maps it to blue
858
+ expect(result.requestedButtonColor).toBe(BUTTON_COLOR.GOLD);
859
+ expect(result.color).toBe(BUTTON_COLOR.BLUE);
860
+ expect(result.shouldApplyRebrandedStyles).toBe(true);
861
+ expect(result.brandVersion).toBe("v2");
862
+ });
863
+
864
+ it("should preserve merchant silver as requestedButtonColor when rebrand maps it to white", () => {
865
+ const result = normalizeButtonStyle(
866
+ // $FlowFixMe
867
+ {
868
+ fundingSource: FUNDING.PAYPAL,
869
+ buttonColor: {
870
+ color: BUTTON_COLOR.WHITE,
871
+ shouldApplyRebrandedStyles: true,
872
+ brandVersion: "v2",
873
+ isButtonColorABTestMerchant: false,
874
+ },
875
+ },
876
+ // $FlowFixMe
877
+ { color: BUTTON_COLOR.SILVER }
878
+ );
879
+
880
+ // Merchant configured silver — rebrand maps it to white
881
+ expect(result.requestedButtonColor).toBe(BUTTON_COLOR.SILVER);
882
+ expect(result.color).toBe(BUTTON_COLOR.WHITE);
883
+ expect(result.shouldApplyRebrandedStyles).toBe(true);
884
+ expect(result.brandVersion).toBe("v2");
885
+ });
886
+ });
@@ -244,6 +244,7 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
244
244
  },
245
245
 
246
246
  eligible: ({ props }) => {
247
+ const buttonExperiments = props.experiment ?? getButtonExperiments();
247
248
  const {
248
249
  fundingSource,
249
250
  onShippingChange,
@@ -256,15 +257,15 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
256
257
  supportsPopups = userAgentSupportsPopups(),
257
258
  supportedNativeBrowser = isSupportedNativeBrowser(),
258
259
  supportsVenmoPopups = supportsVenmoPopupsUtil(
259
- props.experiment,
260
+ buttonExperiments,
260
261
  userAgentSupportsPopups(),
261
262
  getUserAgent()
262
263
  ),
263
264
  supportedNativeVenmoBrowser = isSupportedNativeVenmoBrowser(
264
- props.experiment,
265
+ buttonExperiments,
265
266
  getUserAgent()
266
267
  ),
267
- experiment = getButtonExperiments(),
268
+ experiment = buttonExperiments,
268
269
  createBillingAgreement,
269
270
  createSubscription,
270
271
  createVaultSetupToken,
@@ -803,6 +804,12 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
803
804
 
804
805
  return {
805
806
  nativeUrl: window.popupBridge.getReturnUrlPrefix(),
807
+ deepLinkReturnUrlPrefix:
808
+ typeof window.popupBridge.getDeepLinkReturnUrlPrefix ===
809
+ "function"
810
+ ? window.popupBridge.getDeepLinkReturnUrlPrefix()
811
+ : null,
812
+ isPayPalInstalled: Boolean(window.popupBridge.isPayPalInstalled),
806
813
  start: (url) => {
807
814
  return new ZalgoPromise((resolve, reject) => {
808
815
  window.popupBridge.onComplete = (err, result) => {
@@ -813,11 +820,41 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => {
813
820
  }
814
821
  const queryItems =
815
822
  result && result.queryItems ? result.queryItems : {};
816
- return err ? reject(err) : resolve(queryItems);
823
+ const payload = result
824
+ ? {
825
+ ...queryItems,
826
+ path: result.path,
827
+ hash: result.hash,
828
+ }
829
+ : queryItems;
830
+ return err ? reject(err) : resolve(payload);
817
831
  };
818
832
  window.popupBridge.open(url);
819
833
  });
820
834
  },
835
+ launchApp: (url) => {
836
+ return new ZalgoPromise((resolve, reject) => {
837
+ window.popupBridge.onComplete = (err, result) => {
838
+ if (!err && !result) {
839
+ resolve({
840
+ opType: "user_closed_window",
841
+ });
842
+ }
843
+ const queryItems =
844
+ result && result.queryItems ? result.queryItems : {};
845
+ const payload = result
846
+ ? {
847
+ ...queryItems,
848
+ queryItems,
849
+ path: result.path,
850
+ hash: result.hash,
851
+ }
852
+ : queryItems;
853
+ return err ? reject(err) : resolve(payload);
854
+ };
855
+ window.popupBridge.launchApp(url);
856
+ });
857
+ },
821
858
  };
822
859
  };
823
860
  },