-
Notifications
You must be signed in to change notification settings - Fork 74
chore: move ECE utilities into separate files #11389
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
Changes from all commits
10903a9
250bec7
c1004fb
0f6d158
ec6a0cd
5231d64
614258b
ab7ed6d
7fdb0a3
9a3f4ec
c05db87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Significance: patch | ||
| Type: dev | ||
|
|
||
| chore: move ECE utilities into separate files |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { shouldUseConfirmationTokens } from '../confirmation-tokens'; | ||
|
|
||
| describe( 'shouldUseConfirmationTokens', () => { | ||
| afterEach( () => { | ||
| delete window.wcpayExpressCheckoutParams; | ||
| } ); | ||
|
|
||
| test( 'returns true when flag is true', () => { | ||
| window.wcpayExpressCheckoutParams = { | ||
| flags: { isEceUsingConfirmationTokens: true }, | ||
| }; | ||
|
|
||
| expect( shouldUseConfirmationTokens() ).toBe( true ); | ||
| } ); | ||
|
|
||
| test( 'returns false when flag is false', () => { | ||
| window.wcpayExpressCheckoutParams = { | ||
| flags: { isEceUsingConfirmationTokens: false }, | ||
| }; | ||
|
|
||
| expect( shouldUseConfirmationTokens() ).toBe( false ); | ||
| } ); | ||
|
|
||
| test( 'defaults to true when flags are absent', () => { | ||
| window.wcpayExpressCheckoutParams = {}; | ||
|
|
||
| expect( shouldUseConfirmationTokens() ).toBe( true ); | ||
| } ); | ||
|
|
||
| test( 'defaults to true when params are not set', () => { | ||
| expect( shouldUseConfirmationTokens() ).toBe( true ); | ||
| } ); | ||
| } ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { createPaymentCredential } from '../payment-credentials'; | ||
|
|
||
| describe( 'createPaymentCredential', () => { | ||
| let stripeMock; | ||
| let elementsMock; | ||
|
|
||
| beforeEach( () => { | ||
| stripeMock = { | ||
| createConfirmationToken: jest.fn(), | ||
| createPaymentMethod: jest.fn(), | ||
| }; | ||
| elementsMock = {}; | ||
| } ); | ||
|
|
||
| describe( 'when using confirmation tokens', () => { | ||
| test( 'creates a confirmation token and returns its id', async () => { | ||
| stripeMock.createConfirmationToken.mockResolvedValue( { | ||
| confirmationToken: { id: 'ctoken_123' }, | ||
| } ); | ||
|
|
||
| const result = await createPaymentCredential( | ||
| stripeMock, | ||
| elementsMock, | ||
| true | ||
| ); | ||
|
|
||
| expect( stripeMock.createConfirmationToken ).toHaveBeenCalledWith( { | ||
| elements: elementsMock, | ||
| } ); | ||
| expect( result ).toBe( 'ctoken_123' ); | ||
| } ); | ||
|
|
||
| test( 'throws on Stripe error', async () => { | ||
| const stripeError = { message: 'Token creation failed' }; | ||
| stripeMock.createConfirmationToken.mockResolvedValue( { | ||
| error: stripeError, | ||
| } ); | ||
|
|
||
| await expect( | ||
| createPaymentCredential( stripeMock, elementsMock, true ) | ||
| ).rejects.toEqual( stripeError ); | ||
| } ); | ||
| } ); | ||
|
|
||
| describe( 'when using payment methods', () => { | ||
| test( 'creates a payment method and returns its id', async () => { | ||
| stripeMock.createPaymentMethod.mockResolvedValue( { | ||
| paymentMethod: { id: 'pm_456' }, | ||
| } ); | ||
|
|
||
| const result = await createPaymentCredential( | ||
| stripeMock, | ||
| elementsMock, | ||
| false | ||
| ); | ||
|
|
||
| expect( stripeMock.createPaymentMethod ).toHaveBeenCalledWith( { | ||
| elements: elementsMock, | ||
| } ); | ||
| expect( result ).toBe( 'pm_456' ); | ||
| } ); | ||
|
|
||
| test( 'throws on Stripe error', async () => { | ||
| const stripeError = { message: 'Payment method failed' }; | ||
| stripeMock.createPaymentMethod.mockResolvedValue( { | ||
| error: stripeError, | ||
| } ); | ||
|
|
||
| await expect( | ||
| createPaymentCredential( stripeMock, elementsMock, false ) | ||
| ).rejects.toEqual( stripeError ); | ||
| } ); | ||
| } ); | ||
| } ); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { getDefaultBorderRadius } from 'wcpay/utils/express-checkout'; | ||
| import { getExpressCheckoutData } from './express-checkout-data'; | ||
|
|
||
| export type ButtonAttributesType = | ||
| | { height: string; borderRadius: string } | ||
| | undefined; | ||
|
|
||
| /** | ||
| * Returns the appearance settings for the Express Checkout buttons. | ||
| * Currently only configures border radius for the buttons. | ||
| */ | ||
| export const getExpressCheckoutButtonAppearance = ( | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exported from |
||
| buttonAttributes: ButtonAttributesType | ||
| ) => { | ||
| let borderRadius = getDefaultBorderRadius(); | ||
| const buttonSettings = getExpressCheckoutData( 'button' ); | ||
|
|
||
| // Border radius from WooPayments settings | ||
| borderRadius = buttonSettings?.radius ?? borderRadius; | ||
|
|
||
| // Border radius from Cart & Checkout blocks attributes | ||
| if ( typeof buttonAttributes !== 'undefined' ) { | ||
| borderRadius = Number( buttonAttributes?.borderRadius ) ?? borderRadius; | ||
| } | ||
|
|
||
| return { | ||
| variables: { | ||
| borderRadius: `${ borderRadius }px`, | ||
| spacingUnit: '6px', | ||
| }, | ||
| }; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { getExpressCheckoutData } from './express-checkout-data'; | ||
|
|
||
| /** | ||
| * Returns the style settings for the Express Checkout buttons. | ||
| */ | ||
| export const getExpressCheckoutButtonStyleSettings = () => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exported from |
||
| const buttonSettings = getExpressCheckoutData( 'button' ); | ||
| const enabledMethods = getExpressCheckoutData( 'enabled_methods' ) ?? []; | ||
|
|
||
| const mapWooPaymentsThemeToButtonTheme = ( | ||
| buttonType: string, | ||
| theme: string | ||
| ) => { | ||
| switch ( theme ) { | ||
| case 'dark': | ||
| return 'black'; | ||
| case 'light': | ||
| return 'white'; | ||
| case 'light-outline': | ||
| if ( buttonType === 'googlePay' ) { | ||
| return 'white'; | ||
| } | ||
|
|
||
| return 'white-outline'; | ||
| default: | ||
| return 'black'; | ||
| } | ||
| }; | ||
|
|
||
| const googlePayType = | ||
| buttonSettings?.type === 'default' | ||
| ? 'plain' | ||
| : buttonSettings?.type ?? 'buy'; | ||
|
|
||
| const applePayType = | ||
| buttonSettings?.type === 'default' | ||
| ? 'plain' | ||
| : buttonSettings?.type ?? 'plain'; | ||
|
|
||
| const isGoogleApplePayEnabled = enabledMethods.includes( | ||
| 'payment_request' | ||
| ); | ||
|
|
||
| return { | ||
| paymentMethods: { | ||
| applePay: isGoogleApplePayEnabled ? 'always' : 'never', | ||
| googlePay: isGoogleApplePayEnabled ? 'always' : 'never', | ||
| amazonPay: enabledMethods.includes( 'amazon_pay' ) | ||
| ? 'auto' | ||
| : 'never', | ||
| link: 'never', | ||
| paypal: 'never', | ||
| klarna: 'never', | ||
| }, | ||
| layout: { overflow: 'never' }, | ||
| buttonTheme: { | ||
| googlePay: mapWooPaymentsThemeToButtonTheme( | ||
| 'googlePay', | ||
| buttonSettings?.theme ?? 'black' | ||
| ), | ||
| applePay: mapWooPaymentsThemeToButtonTheme( | ||
| 'applePay', | ||
| buttonSettings?.theme ?? 'black' | ||
| ), | ||
| }, | ||
| buttonType: { | ||
| googlePay: googlePayType, | ||
| applePay: applePayType, | ||
| }, | ||
| // Allowed height must be 40px to 55px. | ||
| buttonHeight: Math.min( | ||
| Math.max( parseInt( buttonSettings?.height ?? '48', 10 ), 40 ), | ||
| 55 | ||
| ), | ||
| }; | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| /** | ||
| * Internal dependencies | ||
| */ | ||
| import { getExpressCheckoutData } from './express-checkout-data'; | ||
|
|
||
| /** | ||
| * Determines whether to use Stripe confirmation tokens or legacy payment methods. | ||
| * | ||
| * This is a global setting controlled by the backend feature flag | ||
| * `isEceUsingConfirmationTokens`. It applies uniformly to ALL express payment | ||
| * methods (Apple Pay, Google Pay, Amazon Pay). No per-method overrides needed — | ||
| * the PHP backend already enforces that Amazon Pay can only be enabled when | ||
| * confirmation tokens are enabled (`is_amazon_pay_enabled()` requires | ||
| * `is_ece_confirmation_tokens_enabled()`). | ||
| * | ||
| * Defaults to true (confirmation tokens enabled) when the flag is absent. | ||
| */ | ||
| export function shouldUseConfirmationTokens(): boolean { | ||
| return ( | ||
| getExpressCheckoutData( 'flags' )?.isEceUsingConfirmationTokens ?? true | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| /** | ||
| * Get error messages from WooCommerce notice from server response. | ||
| * | ||
| * @param notice Error notice. | ||
| * @return Error messages. | ||
| */ | ||
| export const getErrorMessageFromNotice = ( notice: string | undefined ) => { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exported from |
||
| if ( ! notice ) return ''; | ||
|
|
||
| const div = document.createElement( 'div' ); | ||
| div.innerHTML = notice.trim(); | ||
| return div.firstChild ? div.firstChild.textContent : ''; | ||
| }; | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mostly extracted to
createPaymentCredentialfor reuse in the future. Tested inclient/express-checkout/utils/__tests__/payment-credentials.test.js