|
| 1 | +/** |
| 2 | + * External dependencies |
| 3 | + */ |
| 4 | +import * as wpDataFunctions from '@wordpress/data'; |
| 5 | +import { PAYMENT_STORE_KEY } from '@woocommerce/block-data'; |
| 6 | +import { |
| 7 | + registerPaymentMethod, |
| 8 | + registerExpressPaymentMethod, |
| 9 | + __experimentalDeRegisterPaymentMethod, |
| 10 | + __experimentalDeRegisterExpressPaymentMethod, |
| 11 | +} from '@woocommerce/blocks-registry'; |
| 12 | +import { CanMakePaymentArgument } from '@woocommerce/type-defs/payments'; |
| 13 | + |
| 14 | +/** |
| 15 | + * Internal dependencies |
| 16 | + */ |
| 17 | +import { checkPaymentMethodsCanPay } from '../utils/check-payment-methods'; |
| 18 | + |
| 19 | +const requiredKeyCheck = ( args: CanMakePaymentArgument ) => { |
| 20 | + const requiredKeys = [ |
| 21 | + 'billingData', |
| 22 | + 'billingAddress', |
| 23 | + 'cart', |
| 24 | + 'cartNeedsShipping', |
| 25 | + 'cartTotals', |
| 26 | + 'paymentRequirements', |
| 27 | + 'selectedShippingMethods', |
| 28 | + 'shippingAddress', |
| 29 | + ]; |
| 30 | + const argKeys = Object.keys( args ); |
| 31 | + |
| 32 | + const requiredCartKeys = [ |
| 33 | + 'cartCoupons', |
| 34 | + 'cartItems', |
| 35 | + 'crossSellsProducts', |
| 36 | + 'cartFees', |
| 37 | + 'cartItemsCount', |
| 38 | + 'cartItemsWeight', |
| 39 | + 'cartNeedsPayment', |
| 40 | + 'cartNeedsShipping', |
| 41 | + 'cartItemErrors', |
| 42 | + 'cartTotals', |
| 43 | + 'cartIsLoading', |
| 44 | + 'cartErrors', |
| 45 | + 'billingData', |
| 46 | + 'billingAddress', |
| 47 | + 'shippingAddress', |
| 48 | + 'extensions', |
| 49 | + 'shippingRates', |
| 50 | + 'isLoadingRates', |
| 51 | + 'cartHasCalculatedShipping', |
| 52 | + 'paymentRequirements', |
| 53 | + 'receiveCart', |
| 54 | + ]; |
| 55 | + const cartKeys = Object.keys( args.cart ); |
| 56 | + const requiredTotalsKeys = [ |
| 57 | + 'total_items', |
| 58 | + 'total_items_tax', |
| 59 | + 'total_fees', |
| 60 | + 'total_fees_tax', |
| 61 | + 'total_discount', |
| 62 | + 'total_discount_tax', |
| 63 | + 'total_shipping', |
| 64 | + 'total_shipping_tax', |
| 65 | + 'total_price', |
| 66 | + 'total_tax', |
| 67 | + 'tax_lines', |
| 68 | + 'currency_code', |
| 69 | + 'currency_symbol', |
| 70 | + 'currency_minor_unit', |
| 71 | + 'currency_decimal_separator', |
| 72 | + 'currency_thousand_separator', |
| 73 | + 'currency_prefix', |
| 74 | + 'currency_suffix', |
| 75 | + ]; |
| 76 | + const totalsKeys = Object.keys( args.cartTotals ); |
| 77 | + return ( |
| 78 | + requiredKeys.every( ( key ) => argKeys.includes( key ) ) && |
| 79 | + requiredTotalsKeys.every( ( key ) => totalsKeys.includes( key ) ) && |
| 80 | + requiredCartKeys.every( ( key ) => cartKeys.includes( key ) ) |
| 81 | + ); |
| 82 | +}; |
| 83 | + |
| 84 | +const mockedCanMakePayment = jest.fn().mockImplementation( requiredKeyCheck ); |
| 85 | +const mockedExpressCanMakePayment = jest |
| 86 | + .fn() |
| 87 | + .mockImplementation( requiredKeyCheck ); |
| 88 | + |
| 89 | +const registerMockPaymentMethods = ( savedCards = true ) => { |
| 90 | + [ 'credit-card' ].forEach( ( name ) => { |
| 91 | + registerPaymentMethod( { |
| 92 | + name, |
| 93 | + label: name, |
| 94 | + content: <div>A payment method</div>, |
| 95 | + edit: <div>A payment method</div>, |
| 96 | + icons: null, |
| 97 | + canMakePayment: mockedCanMakePayment, |
| 98 | + supports: { |
| 99 | + showSavedCards: savedCards, |
| 100 | + showSaveOption: true, |
| 101 | + features: [ 'products' ], |
| 102 | + }, |
| 103 | + ariaLabel: name, |
| 104 | + } ); |
| 105 | + } ); |
| 106 | + [ 'express-payment' ].forEach( ( name ) => { |
| 107 | + const Content = ( { |
| 108 | + onClose = () => void null, |
| 109 | + onClick = () => void null, |
| 110 | + } ) => { |
| 111 | + return ( |
| 112 | + <> |
| 113 | + <button onClick={ onClick }> |
| 114 | + { name + ' express payment method' } |
| 115 | + </button> |
| 116 | + <button onClick={ onClose }> |
| 117 | + { name + ' express payment method close' } |
| 118 | + </button> |
| 119 | + </> |
| 120 | + ); |
| 121 | + }; |
| 122 | + registerExpressPaymentMethod( { |
| 123 | + name, |
| 124 | + content: <Content />, |
| 125 | + edit: <div>An express payment method</div>, |
| 126 | + canMakePayment: mockedExpressCanMakePayment, |
| 127 | + paymentMethodId: name, |
| 128 | + supports: { |
| 129 | + features: [ 'products' ], |
| 130 | + }, |
| 131 | + } ); |
| 132 | + } ); |
| 133 | + wpDataFunctions |
| 134 | + .dispatch( PAYMENT_STORE_KEY ) |
| 135 | + .__internalUpdateAvailablePaymentMethods(); |
| 136 | +}; |
| 137 | + |
| 138 | +const resetMockPaymentMethods = () => { |
| 139 | + [ 'cheque', 'bacs', 'credit-card' ].forEach( ( name ) => { |
| 140 | + __experimentalDeRegisterPaymentMethod( name ); |
| 141 | + } ); |
| 142 | + [ 'express-payment' ].forEach( ( name ) => { |
| 143 | + __experimentalDeRegisterExpressPaymentMethod( name ); |
| 144 | + } ); |
| 145 | +}; |
| 146 | + |
| 147 | +describe( 'checkPaymentMethods', () => { |
| 148 | + beforeEach( registerMockPaymentMethods ); |
| 149 | + afterEach( resetMockPaymentMethods ); |
| 150 | + |
| 151 | + it( `Sends correct arguments to regular payment methods' canMakePayment functions`, async () => { |
| 152 | + await checkPaymentMethodsCanPay(); |
| 153 | + expect( mockedCanMakePayment ).toHaveReturnedWith( true ); |
| 154 | + } ); |
| 155 | + |
| 156 | + it( `Sends correct arguments to express payment methods' canMakePayment functions`, async () => { |
| 157 | + await checkPaymentMethodsCanPay( true ); |
| 158 | + expect( mockedExpressCanMakePayment ).toHaveReturnedWith( true ); |
| 159 | + } ); |
| 160 | +} ); |
0 commit comments