@paypal/checkout-components 5.0.363 → 5.0.365
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/dist/button.js +1 -1
- package/dist/test/button.js +1 -1
- package/package.json +1 -1
- package/src/constants/button.js +8 -2
- package/src/constants/class.js +1 -0
- package/src/funding/common.jsx +2 -0
- package/src/funding/paypal/config.jsx +6 -4
- package/src/funding/paypal/template.jsx +5 -4
- package/src/funding/venmo/style.scoped.scss +5 -0
- package/src/funding/venmo/template.jsx +1 -3
- package/src/marks/template.jsx +1 -1
- package/src/types.js +1 -3
- package/src/ui/buttons/button.jsx +3 -9
- package/src/ui/buttons/buttons.jsx +0 -1
- package/src/ui/buttons/poweredBy.jsx +1 -1
- package/src/ui/buttons/props.js +320 -11
- package/src/ui/buttons/props.test.js +830 -0
- package/src/ui/buttons/style.jsx +8 -6
- package/src/ui/buttons/styles/base.js +3 -5
- package/src/ui/buttons/styles/button.js +0 -2
- package/src/ui/buttons/styles/color.js +10 -10
- package/src/ui/buttons/styles/labels.js +15 -0
- package/src/ui/buttons/styles/page.js +1 -1
- package/src/ui/buttons/styles/responsive.js +10 -11
- package/src/ui/buttons/styles/styleUtils.js +4 -13
- package/src/ui/buttons/styles/styleUtils.test.js +21 -34
- package/src/ui/overlay/paypal-app-switch/style.jsx +1 -1
- package/src/ui/overlay/three-domain-secure/style.jsx +1 -1
- package/src/zoid/buttons/component.jsx +21 -0
- package/src/zoid/checkout/component.jsx +13 -0
- package/src/zoid/checkout/props.js +10 -0
|
@@ -0,0 +1,830 @@
|
|
|
1
|
+
/* @flow */
|
|
2
|
+
import { describe, expect, it, beforeEach, vi } from "vitest";
|
|
3
|
+
import { FUNDING } from "@paypal/sdk-constants";
|
|
4
|
+
|
|
5
|
+
import { BUTTON_COLOR } from "../../constants";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
getButtonColor,
|
|
9
|
+
getButtonColorExperience,
|
|
10
|
+
getColorForFullRedesign,
|
|
11
|
+
getColorForABTest,
|
|
12
|
+
getDefaultColorForFundingSource,
|
|
13
|
+
throwErrorForInvalidButtonColor,
|
|
14
|
+
hasInvalidScriptOptionsForFullRedesign,
|
|
15
|
+
determineRandomButtonColor,
|
|
16
|
+
getColorABTestFromStorage,
|
|
17
|
+
} from "./props";
|
|
18
|
+
|
|
19
|
+
describe("getColorABTestFromStorage", () => {
|
|
20
|
+
it("should return null when storage state has no colorABTest value", () => {
|
|
21
|
+
const storageState = {
|
|
22
|
+
get: vi.fn().mockReturnValue(null),
|
|
23
|
+
set: vi.fn(),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const result = getColorABTestFromStorage(storageState);
|
|
27
|
+
|
|
28
|
+
expect(result).toBeNull();
|
|
29
|
+
expect(storageState.get).toHaveBeenCalledWith("colorABTest");
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("should return null when storage state has colorABTest but no value property", () => {
|
|
33
|
+
const storageState = {
|
|
34
|
+
get: vi.fn().mockReturnValue({ someOtherProperty: "test" }),
|
|
35
|
+
set: vi.fn(),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const result = getColorABTestFromStorage(storageState);
|
|
39
|
+
|
|
40
|
+
expect(result).toBeNull();
|
|
41
|
+
expect(storageState.get).toHaveBeenCalledWith("colorABTest");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("should return value when storage state has colorABTest with value property", () => {
|
|
45
|
+
const mockStoredValue = {
|
|
46
|
+
shouldApplyRebrandedStyles: true,
|
|
47
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
48
|
+
sessionID: "test-session",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const storageState = {
|
|
52
|
+
get: vi.fn().mockReturnValue({ value: mockStoredValue }),
|
|
53
|
+
set: vi.fn(),
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const result = getColorABTestFromStorage(storageState);
|
|
57
|
+
|
|
58
|
+
expect(result).toEqual(mockStoredValue);
|
|
59
|
+
expect(storageState.get).toHaveBeenCalledWith("colorABTest");
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe("determineRandomButtonColor", () => {
|
|
64
|
+
let mathRandomSpy;
|
|
65
|
+
|
|
66
|
+
beforeEach(() => {
|
|
67
|
+
mathRandomSpy = vi.spyOn(Math, "random");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
afterEach(() => {
|
|
71
|
+
mathRandomSpy.mockRestore();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("should return rebrand blue when random value is less than 0.33", () => {
|
|
75
|
+
mathRandomSpy.mockReturnValue(0);
|
|
76
|
+
|
|
77
|
+
const result = determineRandomButtonColor({
|
|
78
|
+
buttonColorInput: BUTTON_COLOR.GOLD,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
expect(result).toEqual({
|
|
82
|
+
shouldApplyRebrandedStyles: true,
|
|
83
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("should return rebrand darkblue when random value is between 0.33 and 0.67", () => {
|
|
88
|
+
mathRandomSpy.mockReturnValue(0.4);
|
|
89
|
+
|
|
90
|
+
const result = determineRandomButtonColor({
|
|
91
|
+
buttonColorInput: BUTTON_COLOR.GOLD,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
expect(result).toEqual({
|
|
95
|
+
shouldApplyRebrandedStyles: true,
|
|
96
|
+
color: BUTTON_COLOR.REBRAND_DARKBLUE,
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("should return provided buttonColorInput when random value is above 0.67", () => {
|
|
101
|
+
mathRandomSpy.mockReturnValue(0.8);
|
|
102
|
+
|
|
103
|
+
const result = determineRandomButtonColor({
|
|
104
|
+
buttonColorInput: BUTTON_COLOR.BLACK,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
expect(result).toEqual({
|
|
108
|
+
shouldApplyRebrandedStyles: false,
|
|
109
|
+
color: BUTTON_COLOR.BLACK,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("should default to GOLD if buttonColorInput is not provided and random value is above 0.67", () => {
|
|
114
|
+
mathRandomSpy.mockReturnValue(0.8);
|
|
115
|
+
|
|
116
|
+
const result = determineRandomButtonColor({
|
|
117
|
+
buttonColorInput: null,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
expect(result).toEqual({
|
|
121
|
+
shouldApplyRebrandedStyles: false,
|
|
122
|
+
color: BUTTON_COLOR.GOLD,
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe("hasInvalidScriptOptionsForFullRedesign", () => {
|
|
128
|
+
const validFundingSources = [FUNDING.PAYPAL];
|
|
129
|
+
const invalidFundingSources = [
|
|
130
|
+
FUNDING.CARD,
|
|
131
|
+
FUNDING.VENMO,
|
|
132
|
+
FUNDING.PAYLATER,
|
|
133
|
+
FUNDING.CREDIT,
|
|
134
|
+
FUNDING.APPLEPAY,
|
|
135
|
+
FUNDING.IDEAL,
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
// Test valid funding sources
|
|
139
|
+
validFundingSources.forEach((fundingSource) => {
|
|
140
|
+
it(`should return false for fundingSource: ${fundingSource}`, () => {
|
|
141
|
+
const result = hasInvalidScriptOptionsForFullRedesign({
|
|
142
|
+
fundingSource,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
expect(result).toBe(false);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Test invalid funding sources
|
|
150
|
+
invalidFundingSources.forEach((fundingSource) => {
|
|
151
|
+
it(`should return true for fundingSource: ${fundingSource}`, () => {
|
|
152
|
+
const result = hasInvalidScriptOptionsForFullRedesign({
|
|
153
|
+
fundingSource,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
expect(result).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("should return true when no funding source is provided", () => {
|
|
161
|
+
const result = hasInvalidScriptOptionsForFullRedesign({});
|
|
162
|
+
|
|
163
|
+
expect(result).toBe(true);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it("should return true when funding source is null", () => {
|
|
167
|
+
const result = hasInvalidScriptOptionsForFullRedesign({
|
|
168
|
+
fundingSource: null,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
expect(result).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe("throwErrorForInvalidButtonColor", () => {
|
|
176
|
+
it("should throw error with appropriate message for invalid color", () => {
|
|
177
|
+
expect(() => {
|
|
178
|
+
throwErrorForInvalidButtonColor({
|
|
179
|
+
fundingSource: FUNDING.PAYPAL,
|
|
180
|
+
fundingSourceColors: [
|
|
181
|
+
BUTTON_COLOR.GOLD,
|
|
182
|
+
BUTTON_COLOR.BLUE,
|
|
183
|
+
BUTTON_COLOR.WHITE,
|
|
184
|
+
],
|
|
185
|
+
invalidButtonColor: BUTTON_COLOR.BLACK,
|
|
186
|
+
});
|
|
187
|
+
}).toThrow(/Unexpected style.color/);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it("should include funding source in error message", () => {
|
|
191
|
+
expect(() => {
|
|
192
|
+
throwErrorForInvalidButtonColor({
|
|
193
|
+
fundingSource: FUNDING.VENMO,
|
|
194
|
+
fundingSourceColors: [BUTTON_COLOR.BLUE, BUTTON_COLOR.WHITE],
|
|
195
|
+
invalidButtonColor: BUTTON_COLOR.GOLD,
|
|
196
|
+
});
|
|
197
|
+
}).toThrow(/venmo/i);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
it("should list available colors in error message", () => {
|
|
201
|
+
expect(() => {
|
|
202
|
+
throwErrorForInvalidButtonColor({
|
|
203
|
+
fundingSource: FUNDING.PAYPAL,
|
|
204
|
+
fundingSourceColors: [BUTTON_COLOR.GOLD, BUTTON_COLOR.SILVER],
|
|
205
|
+
invalidButtonColor: BUTTON_COLOR.BLUE,
|
|
206
|
+
});
|
|
207
|
+
}).toThrow(/(gold|Gold).*(silver|Silver)/);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it("should handle undefined funding source", () => {
|
|
211
|
+
expect(() => {
|
|
212
|
+
throwErrorForInvalidButtonColor({
|
|
213
|
+
fundingSource: undefined,
|
|
214
|
+
fundingSourceColors: [BUTTON_COLOR.GOLD],
|
|
215
|
+
invalidButtonColor: BUTTON_COLOR.BLUE,
|
|
216
|
+
});
|
|
217
|
+
}).toThrow(/paypal/i);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("should filter out rebranded colors from error message", () => {
|
|
221
|
+
// Define a local helper function to capture error message
|
|
222
|
+
function getErrorMessage(fn): string {
|
|
223
|
+
try {
|
|
224
|
+
fn();
|
|
225
|
+
return "";
|
|
226
|
+
} catch (err) {
|
|
227
|
+
return err.message;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const errorMessage = getErrorMessage(() => {
|
|
232
|
+
throwErrorForInvalidButtonColor({
|
|
233
|
+
fundingSource: FUNDING.PAYPAL,
|
|
234
|
+
fundingSourceColors: [
|
|
235
|
+
BUTTON_COLOR.GOLD,
|
|
236
|
+
BUTTON_COLOR.BLUE,
|
|
237
|
+
BUTTON_COLOR.REBRAND_BLUE, // This should be filtered out
|
|
238
|
+
],
|
|
239
|
+
invalidButtonColor: BUTTON_COLOR.BLACK,
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// Check that the error message contains gold and blue
|
|
244
|
+
expect(errorMessage).toMatch(/gold/i);
|
|
245
|
+
expect(errorMessage).toMatch(/blue/i);
|
|
246
|
+
|
|
247
|
+
// Check that the error message doesn't contain rebrand_blue
|
|
248
|
+
expect(errorMessage).not.toMatch(/rebrand_blue/i);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
describe("getDefaultColorForFundingSource", () => {
|
|
253
|
+
beforeEach(() => {
|
|
254
|
+
// Mock getFundingConfig to return consistent test data
|
|
255
|
+
vi.mock("../../funding", () => ({
|
|
256
|
+
getFundingConfig: () => ({
|
|
257
|
+
[FUNDING.PAYPAL]: {
|
|
258
|
+
colors: [BUTTON_COLOR.GOLD, BUTTON_COLOR.BLUE, BUTTON_COLOR.WHITE],
|
|
259
|
+
},
|
|
260
|
+
[FUNDING.VENMO]: {
|
|
261
|
+
colors: [BUTTON_COLOR.BLUE],
|
|
262
|
+
},
|
|
263
|
+
[FUNDING.PAYLATER]: {
|
|
264
|
+
colors: [BUTTON_COLOR.WHITE, BUTTON_COLOR.BLACK],
|
|
265
|
+
},
|
|
266
|
+
}),
|
|
267
|
+
}));
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
afterEach(() => {
|
|
271
|
+
vi.resetAllMocks();
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it("should return the first color in the funding source config when style.color is undefined", () => {
|
|
275
|
+
const result = getDefaultColorForFundingSource({
|
|
276
|
+
fundingSource: FUNDING.PAYPAL,
|
|
277
|
+
// $FlowFixMe
|
|
278
|
+
style: {},
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
expect(result).toBe(BUTTON_COLOR.GOLD);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it("should return style.color if it is valid for the funding source", () => {
|
|
285
|
+
const result = getDefaultColorForFundingSource({
|
|
286
|
+
fundingSource: FUNDING.PAYPAL,
|
|
287
|
+
// $FlowFixMe
|
|
288
|
+
style: { color: BUTTON_COLOR.BLUE },
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
expect(result).toBe(BUTTON_COLOR.BLUE);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it("should throw an error when provided style.color is invalid for the funding source", () => {
|
|
295
|
+
expect(() => {
|
|
296
|
+
getDefaultColorForFundingSource({
|
|
297
|
+
fundingSource: FUNDING.PAYPAL,
|
|
298
|
+
// $FlowFixMe
|
|
299
|
+
style: { color: BUTTON_COLOR.BLACK },
|
|
300
|
+
});
|
|
301
|
+
}).toThrow();
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("should return different default colors for different funding sources", () => {
|
|
305
|
+
const paypalResult = getDefaultColorForFundingSource({
|
|
306
|
+
fundingSource: FUNDING.PAYPAL,
|
|
307
|
+
// $FlowFixMe
|
|
308
|
+
style: {},
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
const venmoResult = getDefaultColorForFundingSource({
|
|
312
|
+
fundingSource: FUNDING.VENMO,
|
|
313
|
+
// $FlowFixMe
|
|
314
|
+
style: {},
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
const paylaterResult = getDefaultColorForFundingSource({
|
|
318
|
+
fundingSource: FUNDING.PAYLATER,
|
|
319
|
+
// $FlowFixMe
|
|
320
|
+
style: {},
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
expect(paypalResult).toBe(BUTTON_COLOR.GOLD);
|
|
324
|
+
expect(venmoResult).toBe(BUTTON_COLOR.BLUE);
|
|
325
|
+
expect(paylaterResult).toBe(BUTTON_COLOR.WHITE);
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
it("should default to GOLD for smart stack (fundingSource is undefined)", () => {
|
|
329
|
+
const result = getDefaultColorForFundingSource({
|
|
330
|
+
fundingSource: FUNDING.IDEAL,
|
|
331
|
+
// $FlowFixMe
|
|
332
|
+
style: {},
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
expect(result).toBe(BUTTON_COLOR.GOLD);
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it("should return style.color if provided for smart stack (fundingSource is undefined)", () => {
|
|
339
|
+
const result = getDefaultColorForFundingSource({
|
|
340
|
+
fundingSource: FUNDING.IDEAL,
|
|
341
|
+
// $FlowFixMe
|
|
342
|
+
style: { color: BUTTON_COLOR.BLACK },
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
expect(result).toBe(BUTTON_COLOR.BLACK);
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it("should handle null style", () => {
|
|
349
|
+
const result = getDefaultColorForFundingSource({
|
|
350
|
+
fundingSource: FUNDING.PAYPAL,
|
|
351
|
+
style: null,
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
expect(result).toBe(BUTTON_COLOR.GOLD);
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
it("should handle undefined fundingSource", () => {
|
|
358
|
+
const result = getDefaultColorForFundingSource({
|
|
359
|
+
fundingSource: undefined,
|
|
360
|
+
// $FlowFixMe
|
|
361
|
+
style: {},
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
expect(result).toBe(BUTTON_COLOR.GOLD);
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
describe("getColorForABTest", () => {
|
|
369
|
+
it("should return color from storage if sessionID matches", () => {
|
|
370
|
+
const mockSessionID = "test-session-123";
|
|
371
|
+
const mockStoredValue = {
|
|
372
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
373
|
+
shouldApplyRebrandedStyles: true,
|
|
374
|
+
sessionID: mockSessionID,
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
const storageState = {
|
|
378
|
+
get: vi.fn().mockReturnValue({ value: mockStoredValue }),
|
|
379
|
+
set: vi.fn(),
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const result = getColorForABTest({
|
|
383
|
+
storageState,
|
|
384
|
+
sessionID: mockSessionID,
|
|
385
|
+
// $FlowFixMe
|
|
386
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
expect(result).toEqual({
|
|
390
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
391
|
+
shouldApplyRebrandedStyles: true,
|
|
392
|
+
});
|
|
393
|
+
expect(storageState.get).toHaveBeenCalledWith("colorABTest");
|
|
394
|
+
expect(storageState.set).not.toHaveBeenCalled();
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
it("should generate new color and save it if sessionID does not match", () => {
|
|
398
|
+
const mockSessionID = "new-session-456";
|
|
399
|
+
const mockStoredValue = {
|
|
400
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
401
|
+
shouldApplyRebrandedStyles: true,
|
|
402
|
+
sessionID: "old-session-123",
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const storageState = {
|
|
406
|
+
get: vi.fn().mockReturnValue({ value: mockStoredValue }),
|
|
407
|
+
set: vi.fn(),
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
const result = getColorForABTest({
|
|
411
|
+
storageState,
|
|
412
|
+
sessionID: mockSessionID,
|
|
413
|
+
// $FlowFixMe
|
|
414
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
expect(result).toEqual(
|
|
418
|
+
expect.objectContaining({
|
|
419
|
+
color: expect.any(String),
|
|
420
|
+
shouldApplyRebrandedStyles: expect.any(Boolean),
|
|
421
|
+
})
|
|
422
|
+
);
|
|
423
|
+
expect(storageState.get).toHaveBeenCalledWith("colorABTest");
|
|
424
|
+
expect(storageState.set).toHaveBeenCalledWith("colorABTest", {
|
|
425
|
+
...result,
|
|
426
|
+
sessionID: mockSessionID,
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it("should generate new color and save it if no value in storage", () => {
|
|
431
|
+
const mockSessionID = "fresh-session-789";
|
|
432
|
+
|
|
433
|
+
const storageState = {
|
|
434
|
+
get: vi.fn().mockReturnValue(null),
|
|
435
|
+
set: vi.fn(),
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
const result = getColorForABTest({
|
|
439
|
+
storageState,
|
|
440
|
+
sessionID: mockSessionID,
|
|
441
|
+
// $FlowFixMe
|
|
442
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
expect(result).toEqual(
|
|
446
|
+
expect.objectContaining({
|
|
447
|
+
color: expect.any(String),
|
|
448
|
+
shouldApplyRebrandedStyles: expect.any(Boolean),
|
|
449
|
+
})
|
|
450
|
+
);
|
|
451
|
+
expect(storageState.get).toHaveBeenCalledWith("colorABTest");
|
|
452
|
+
expect(storageState.set).toHaveBeenCalledWith("colorABTest", {
|
|
453
|
+
...result,
|
|
454
|
+
sessionID: mockSessionID,
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it("should handle undefined style by generating a default color", () => {
|
|
459
|
+
const mockSessionID = "test-session-undefined-style";
|
|
460
|
+
|
|
461
|
+
const storageState = {
|
|
462
|
+
get: vi.fn().mockReturnValue(null),
|
|
463
|
+
set: vi.fn(),
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
const result = getColorForABTest({
|
|
467
|
+
storageState,
|
|
468
|
+
sessionID: mockSessionID,
|
|
469
|
+
style: undefined,
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
expect(result).toEqual(
|
|
473
|
+
expect.objectContaining({
|
|
474
|
+
color: expect.any(String),
|
|
475
|
+
shouldApplyRebrandedStyles: expect.any(Boolean),
|
|
476
|
+
})
|
|
477
|
+
);
|
|
478
|
+
expect(storageState.get).toHaveBeenCalledWith("colorABTest");
|
|
479
|
+
expect(storageState.set).toHaveBeenCalledWith("colorABTest", {
|
|
480
|
+
...result,
|
|
481
|
+
sessionID: mockSessionID,
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
describe("getColorForFullRedesign", () => {
|
|
487
|
+
it("should map BLUE to REBRAND_BLUE", () => {
|
|
488
|
+
const result = getColorForFullRedesign({
|
|
489
|
+
// $FlowFixMe
|
|
490
|
+
style: { color: BUTTON_COLOR.BLUE },
|
|
491
|
+
fundingSource: FUNDING.PAYPAL,
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
expect(result).toEqual({
|
|
495
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
496
|
+
shouldApplyRebrandedStyles: true,
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
it("should map DARKBLUE to REBRAND_DARKBLUE", () => {
|
|
501
|
+
const result = getColorForFullRedesign({
|
|
502
|
+
// $FlowFixMe
|
|
503
|
+
style: { color: BUTTON_COLOR.DARKBLUE },
|
|
504
|
+
fundingSource: FUNDING.PAYPAL,
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
expect(result).toEqual({
|
|
508
|
+
color: BUTTON_COLOR.REBRAND_DARKBLUE,
|
|
509
|
+
shouldApplyRebrandedStyles: true,
|
|
510
|
+
});
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
it("should map GOLD to REBRAND_BLUE", () => {
|
|
514
|
+
const result = getColorForFullRedesign({
|
|
515
|
+
// $FlowFixMe
|
|
516
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
517
|
+
fundingSource: FUNDING.PAYPAL,
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
expect(result).toEqual({
|
|
521
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
522
|
+
shouldApplyRebrandedStyles: true,
|
|
523
|
+
});
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
it("should handle REBRAND colors directly without remapping them", () => {
|
|
527
|
+
const result = getColorForFullRedesign({
|
|
528
|
+
// $FlowFixMe
|
|
529
|
+
style: { color: BUTTON_COLOR.REBRAND_DARKBLUE },
|
|
530
|
+
fundingSource: FUNDING.PAYPAL,
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
expect(result).toEqual({
|
|
534
|
+
color: BUTTON_COLOR.REBRAND_DARKBLUE,
|
|
535
|
+
shouldApplyRebrandedStyles: true,
|
|
536
|
+
});
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
it("should handle unspecified style.color by determining an appropriate color", () => {
|
|
540
|
+
const result = getColorForFullRedesign({
|
|
541
|
+
// $FlowFixMe
|
|
542
|
+
style: {},
|
|
543
|
+
fundingSource: FUNDING.PAYPAL,
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
// Since we're not mocking getDefaultColorForFundingSource, just verify
|
|
547
|
+
// we get a proper structured response
|
|
548
|
+
expect(result).toEqual(
|
|
549
|
+
expect.objectContaining({
|
|
550
|
+
color: expect.any(String),
|
|
551
|
+
shouldApplyRebrandedStyles: true,
|
|
552
|
+
})
|
|
553
|
+
);
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
it("should handle null style by determining an appropriate color", () => {
|
|
557
|
+
const result = getColorForFullRedesign({
|
|
558
|
+
style: null,
|
|
559
|
+
fundingSource: FUNDING.PAYPAL,
|
|
560
|
+
});
|
|
561
|
+
|
|
562
|
+
expect(result).toEqual(
|
|
563
|
+
expect.objectContaining({
|
|
564
|
+
color: expect.any(String),
|
|
565
|
+
shouldApplyRebrandedStyles: true,
|
|
566
|
+
})
|
|
567
|
+
);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
it("should handle different funding sources", () => {
|
|
571
|
+
const result = getColorForFullRedesign({
|
|
572
|
+
// $FlowFixMe
|
|
573
|
+
style: { color: BUTTON_COLOR.BLUE },
|
|
574
|
+
fundingSource: FUNDING.VENMO,
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
expect(result).toEqual({
|
|
578
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
579
|
+
shouldApplyRebrandedStyles: true,
|
|
580
|
+
});
|
|
581
|
+
});
|
|
582
|
+
|
|
583
|
+
it("should throw error for invalid colors", () => {
|
|
584
|
+
expect(() => {
|
|
585
|
+
getColorForFullRedesign({
|
|
586
|
+
// $FlowFixMe
|
|
587
|
+
style: { color: "green" },
|
|
588
|
+
fundingSource: FUNDING.PAYPAL,
|
|
589
|
+
});
|
|
590
|
+
}).toThrow();
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
describe("getButtonColorExperience", () => {
|
|
595
|
+
it("should return 'legacy' when PayPal rebrand is not enabled", () => {
|
|
596
|
+
const result = getButtonColorExperience({
|
|
597
|
+
experiment: {
|
|
598
|
+
isPaypalRebrandEnabled: false,
|
|
599
|
+
isPaypalRebrandABTestEnabled: false,
|
|
600
|
+
},
|
|
601
|
+
fundingSource: FUNDING.PAYPAL,
|
|
602
|
+
// $FlowFixMe
|
|
603
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
604
|
+
});
|
|
605
|
+
|
|
606
|
+
expect(result).toBe("legacy");
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
it("should return 'abTest' when PayPal rebrand AB test is enabled and funding source is valid", () => {
|
|
610
|
+
const result = getButtonColorExperience({
|
|
611
|
+
experiment: {
|
|
612
|
+
isPaypalRebrandEnabled: true,
|
|
613
|
+
isPaypalRebrandABTestEnabled: true,
|
|
614
|
+
},
|
|
615
|
+
fundingSource: FUNDING.PAYPAL,
|
|
616
|
+
// $FlowFixMe
|
|
617
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
expect(result).toBe("abTest");
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
it("should return 'legacy' when PayPal rebrand AB test is enabled but funding source is invalid", () => {
|
|
624
|
+
const result = getButtonColorExperience({
|
|
625
|
+
experiment: {
|
|
626
|
+
isPaypalRebrandEnabled: true,
|
|
627
|
+
isPaypalRebrandABTestEnabled: true,
|
|
628
|
+
},
|
|
629
|
+
fundingSource: FUNDING.VENMO,
|
|
630
|
+
// $FlowFixMe
|
|
631
|
+
style: { color: BUTTON_COLOR.BLUE },
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
expect(result).toBe("legacy");
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
it("should return 'fullRebrand' when rebrand is enabled and not in AB test mode", () => {
|
|
638
|
+
const result = getButtonColorExperience({
|
|
639
|
+
experiment: {
|
|
640
|
+
isPaypalRebrandEnabled: true,
|
|
641
|
+
isPaypalRebrandABTestEnabled: false,
|
|
642
|
+
},
|
|
643
|
+
fundingSource: FUNDING.PAYPAL,
|
|
644
|
+
// $FlowFixMe
|
|
645
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
646
|
+
});
|
|
647
|
+
|
|
648
|
+
expect(result).toBe("fullRebrand");
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it("should return 'legacy' when rebrand is enabled but style.color is not dev complete", () => {
|
|
652
|
+
const incompleteColors = [
|
|
653
|
+
BUTTON_COLOR.BLACK,
|
|
654
|
+
BUTTON_COLOR.WHITE,
|
|
655
|
+
BUTTON_COLOR.SILVER,
|
|
656
|
+
BUTTON_COLOR.TRANSPARENT,
|
|
657
|
+
BUTTON_COLOR.DEFAULT,
|
|
658
|
+
];
|
|
659
|
+
|
|
660
|
+
// Test each incomplete color
|
|
661
|
+
incompleteColors.forEach((incompleteColor) => {
|
|
662
|
+
const result = getButtonColorExperience({
|
|
663
|
+
experiment: {
|
|
664
|
+
isPaypalRebrandEnabled: true,
|
|
665
|
+
isPaypalRebrandABTestEnabled: false,
|
|
666
|
+
},
|
|
667
|
+
fundingSource: FUNDING.PAYPAL,
|
|
668
|
+
// $FlowFixMe
|
|
669
|
+
style: { color: incompleteColor },
|
|
670
|
+
});
|
|
671
|
+
|
|
672
|
+
expect(result).toBe("legacy");
|
|
673
|
+
});
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
it("should handle null/undefined experiment values", () => {
|
|
677
|
+
const result = getButtonColorExperience({
|
|
678
|
+
// $FlowFixMe
|
|
679
|
+
experiment: null,
|
|
680
|
+
fundingSource: FUNDING.PAYPAL,
|
|
681
|
+
// $FlowFixMe
|
|
682
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
expect(result).toBe("legacy");
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
it("should handle null/undefined style", () => {
|
|
689
|
+
const result = getButtonColorExperience({
|
|
690
|
+
experiment: {
|
|
691
|
+
isPaypalRebrandEnabled: true,
|
|
692
|
+
isPaypalRebrandABTestEnabled: false,
|
|
693
|
+
},
|
|
694
|
+
fundingSource: FUNDING.PAYPAL,
|
|
695
|
+
style: null,
|
|
696
|
+
});
|
|
697
|
+
|
|
698
|
+
expect(result).toBe("fullRebrand");
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
it("should return legacy for smart stack (fundingSource is undefined)", () => {
|
|
702
|
+
const result = getButtonColorExperience({
|
|
703
|
+
experiment: {
|
|
704
|
+
isPaypalRebrandEnabled: true,
|
|
705
|
+
isPaypalRebrandABTestEnabled: false,
|
|
706
|
+
},
|
|
707
|
+
fundingSource: undefined,
|
|
708
|
+
// $FlowFixMe
|
|
709
|
+
style: { color: BUTTON_COLOR.GOLD },
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
expect(result).toBe("legacy");
|
|
713
|
+
});
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
describe("getButtonColor", () => {
|
|
717
|
+
afterEach(() => {
|
|
718
|
+
vi.restoreAllMocks();
|
|
719
|
+
});
|
|
720
|
+
|
|
721
|
+
it("should return legacy styling for non-rebrand-enabled experiments", () => {
|
|
722
|
+
const style = { color: BUTTON_COLOR.GOLD };
|
|
723
|
+
const storageState = { get: vi.fn(), set: vi.fn() };
|
|
724
|
+
const sessionID = "test-session";
|
|
725
|
+
const fundingSource = FUNDING.PAYPAL;
|
|
726
|
+
const experiment = {
|
|
727
|
+
isPaypalRebrandEnabled: false,
|
|
728
|
+
isPaypalRebrandABTestEnabled: false,
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
const result = getButtonColor({
|
|
732
|
+
experiment,
|
|
733
|
+
// $FlowFixMe
|
|
734
|
+
style,
|
|
735
|
+
sessionID,
|
|
736
|
+
storageState,
|
|
737
|
+
fundingSource,
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
expect(result).toEqual({
|
|
741
|
+
color: BUTTON_COLOR.GOLD,
|
|
742
|
+
shouldApplyRebrandedStyles: false,
|
|
743
|
+
});
|
|
744
|
+
});
|
|
745
|
+
|
|
746
|
+
it("should return the rebranded blue color for rebrand-enabled experiments", () => {
|
|
747
|
+
const style = { color: BUTTON_COLOR.GOLD };
|
|
748
|
+
const storageState = { get: vi.fn(), set: vi.fn() };
|
|
749
|
+
const sessionID = "test-session";
|
|
750
|
+
const fundingSource = FUNDING.PAYPAL;
|
|
751
|
+
const experiment = {
|
|
752
|
+
isPaypalRebrandEnabled: true,
|
|
753
|
+
isPaypalRebrandABTestEnabled: false,
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
const result = getButtonColor({
|
|
757
|
+
experiment,
|
|
758
|
+
// $FlowFixMe
|
|
759
|
+
style,
|
|
760
|
+
sessionID,
|
|
761
|
+
storageState,
|
|
762
|
+
fundingSource,
|
|
763
|
+
});
|
|
764
|
+
|
|
765
|
+
expect(result).toEqual({
|
|
766
|
+
color: BUTTON_COLOR.REBRAND_BLUE,
|
|
767
|
+
shouldApplyRebrandedStyles: true,
|
|
768
|
+
});
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
it("should return the default color for non-PayPal funding sources", () => {
|
|
772
|
+
const style = { color: BUTTON_COLOR.BLUE };
|
|
773
|
+
const storageState = { get: vi.fn(), set: vi.fn() };
|
|
774
|
+
const sessionID = "test-session";
|
|
775
|
+
const fundingSource = FUNDING.VENMO;
|
|
776
|
+
const experiment = {
|
|
777
|
+
isPaypalRebrandEnabled: true,
|
|
778
|
+
isPaypalRebrandABTestEnabled: true,
|
|
779
|
+
};
|
|
780
|
+
|
|
781
|
+
const result = getButtonColor({
|
|
782
|
+
experiment,
|
|
783
|
+
// $FlowFixMe
|
|
784
|
+
style,
|
|
785
|
+
sessionID,
|
|
786
|
+
storageState,
|
|
787
|
+
fundingSource,
|
|
788
|
+
});
|
|
789
|
+
|
|
790
|
+
expect(result).toEqual({
|
|
791
|
+
color: BUTTON_COLOR.BLUE,
|
|
792
|
+
shouldApplyRebrandedStyles: false,
|
|
793
|
+
});
|
|
794
|
+
});
|
|
795
|
+
|
|
796
|
+
it("should respect specified colors in legacy mode", () => {
|
|
797
|
+
const style = { color: BUTTON_COLOR.WHITE };
|
|
798
|
+
const storageState = { get: vi.fn(), set: vi.fn() };
|
|
799
|
+
const sessionID = "test-session";
|
|
800
|
+
const fundingSource = FUNDING.PAYPAL;
|
|
801
|
+
const experiment = {
|
|
802
|
+
isPaypalRebrandEnabled: false,
|
|
803
|
+
};
|
|
804
|
+
|
|
805
|
+
const result = getButtonColor({
|
|
806
|
+
experiment,
|
|
807
|
+
// $FlowFixMe
|
|
808
|
+
style,
|
|
809
|
+
sessionID,
|
|
810
|
+
storageState,
|
|
811
|
+
fundingSource,
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
expect(result).toEqual({
|
|
815
|
+
color: BUTTON_COLOR.WHITE,
|
|
816
|
+
shouldApplyRebrandedStyles: false,
|
|
817
|
+
});
|
|
818
|
+
});
|
|
819
|
+
|
|
820
|
+
it("should handle undefined parameters", () => {
|
|
821
|
+
// $FlowFixMe
|
|
822
|
+
const result = getButtonColor({});
|
|
823
|
+
|
|
824
|
+
// The default color should be returned
|
|
825
|
+
expect(result).toEqual({
|
|
826
|
+
color: BUTTON_COLOR.GOLD,
|
|
827
|
+
shouldApplyRebrandedStyles: false,
|
|
828
|
+
});
|
|
829
|
+
});
|
|
830
|
+
});
|