207 lines
5.3 KiB
JavaScript
207 lines
5.3 KiB
JavaScript
/**
|
|
* External dependencies
|
|
*/
|
|
import { act, render, screen, waitFor } from '@testing-library/react';
|
|
import { previewCart } from '@woocommerce/resource-previews';
|
|
import * as wpDataFunctions from '@wordpress/data';
|
|
import { CART_STORE_KEY, PAYMENT_STORE_KEY } from '@woocommerce/block-data';
|
|
import { default as fetchMock } from 'jest-fetch-mock';
|
|
import {
|
|
registerPaymentMethod,
|
|
__experimentalDeRegisterPaymentMethod,
|
|
} from '@woocommerce/blocks-registry';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { dispatch } from '@wordpress/data';
|
|
|
|
/**
|
|
* Internal dependencies
|
|
*/
|
|
import PaymentMethods from '../payment-methods';
|
|
|
|
jest.mock( '../saved-payment-method-options', () => ( { onChange } ) => {
|
|
return (
|
|
<>
|
|
<span>Saved payment method options</span>
|
|
<button onClick={ () => onChange( '0' ) }>Select saved</button>
|
|
</>
|
|
);
|
|
} );
|
|
|
|
jest.mock( '@woocommerce/blocks-components', () => {
|
|
const originalModule = jest.requireActual(
|
|
'@woocommerce/blocks-components'
|
|
);
|
|
|
|
return {
|
|
__esModule: true,
|
|
...originalModule,
|
|
RadioControlAccordion: ( { onChange } ) => (
|
|
<>
|
|
<span>Payment method options</span>
|
|
<button onClick={ () => onChange( 'credit-card' ) }>
|
|
Select new payment
|
|
</button>
|
|
</>
|
|
),
|
|
};
|
|
} );
|
|
|
|
const originalSelect = jest.requireActual( '@wordpress/data' ).select;
|
|
const selectMock = jest
|
|
.spyOn( wpDataFunctions, 'select' )
|
|
.mockImplementation( ( storeName ) => {
|
|
const originalStore = originalSelect( storeName );
|
|
if ( storeName === PAYMENT_STORE_KEY ) {
|
|
return {
|
|
...originalStore,
|
|
getState: () => {
|
|
const originalState = originalStore.getState();
|
|
return {
|
|
...originalState,
|
|
savedPaymentMethods: {},
|
|
availablePaymentMethods: {},
|
|
paymentMethodsInitialized: true,
|
|
};
|
|
},
|
|
};
|
|
}
|
|
return originalStore;
|
|
} );
|
|
|
|
const registerMockPaymentMethods = () => {
|
|
[ 'cod', 'credit-card' ].forEach( ( name ) => {
|
|
registerPaymentMethod( {
|
|
name,
|
|
label: name,
|
|
content: <div>A payment method</div>,
|
|
edit: <div>A payment method</div>,
|
|
icons: null,
|
|
canMakePayment: () => true,
|
|
supports: {
|
|
showSavedCards: true,
|
|
showSaveOption: true,
|
|
features: [ 'products' ],
|
|
},
|
|
ariaLabel: name,
|
|
} );
|
|
} );
|
|
dispatch( PAYMENT_STORE_KEY ).__internalUpdateAvailablePaymentMethods();
|
|
};
|
|
|
|
const resetMockPaymentMethods = () => {
|
|
[ 'cod', 'credit-card' ].forEach( ( name ) => {
|
|
__experimentalDeRegisterPaymentMethod( name );
|
|
} );
|
|
};
|
|
|
|
describe( 'PaymentMethods', () => {
|
|
beforeEach( () => {
|
|
fetchMock.mockResponse( ( req ) => {
|
|
if ( req.url.match( /wc\/store\/v1\/cart/ ) ) {
|
|
return Promise.resolve( JSON.stringify( previewCart ) );
|
|
}
|
|
return Promise.resolve( '' );
|
|
} );
|
|
// need to clear the store resolution state between tests.
|
|
wpDataFunctions
|
|
.dispatch( CART_STORE_KEY )
|
|
.invalidateResolutionForStore();
|
|
wpDataFunctions.dispatch( CART_STORE_KEY ).receiveCart( {
|
|
...previewCart,
|
|
payment_methods: [ 'cod', 'credit-card' ],
|
|
} );
|
|
} );
|
|
|
|
afterEach( () => {
|
|
fetchMock.resetMocks();
|
|
} );
|
|
|
|
test( 'should show no payment methods component when there are no payment methods', async () => {
|
|
render( <PaymentMethods /> );
|
|
|
|
await waitFor( () => {
|
|
const noPaymentMethods = screen.queryAllByText(
|
|
/no payment methods available/
|
|
);
|
|
// We might get more than one match because the `speak()` function
|
|
// creates an extra `div` with the notice contents used for a11y.
|
|
expect( noPaymentMethods.length ).toBeGreaterThanOrEqual( 1 );
|
|
|
|
// Reset the mock back to how it was because we don't need it anymore after this test.
|
|
selectMock.mockRestore();
|
|
} );
|
|
} );
|
|
|
|
test( 'selecting new payment method', async () => {
|
|
const ShowActivePaymentMethod = () => {
|
|
const { activePaymentMethod, activeSavedToken } =
|
|
wpDataFunctions.useSelect( ( select ) => {
|
|
const store = select( PAYMENT_STORE_KEY );
|
|
return {
|
|
activePaymentMethod: store.getActivePaymentMethod(),
|
|
activeSavedToken: store.getActiveSavedToken(),
|
|
};
|
|
} );
|
|
return (
|
|
<>
|
|
<div>
|
|
{ 'Active Payment Method: ' + activePaymentMethod }
|
|
</div>
|
|
<div>{ 'Active Saved Token: ' + activeSavedToken }</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
act( () => {
|
|
registerMockPaymentMethods();
|
|
} );
|
|
// Wait for the payment methods to finish loading before rendering.
|
|
await waitFor( () => {
|
|
expect(
|
|
wpDataFunctions
|
|
.select( PAYMENT_STORE_KEY )
|
|
.getActivePaymentMethod()
|
|
).toBe( 'cod' );
|
|
} );
|
|
|
|
render(
|
|
<>
|
|
<PaymentMethods />
|
|
<ShowActivePaymentMethod />
|
|
</>
|
|
);
|
|
|
|
await waitFor( () => {
|
|
const savedPaymentMethodOptions = screen.queryByText(
|
|
/Saved payment method options/
|
|
);
|
|
expect( savedPaymentMethodOptions ).not.toBeNull();
|
|
} );
|
|
|
|
await waitFor( () => {
|
|
const paymentMethodOptions = screen.queryByText(
|
|
/Payment method options/
|
|
);
|
|
expect( paymentMethodOptions ).not.toBeNull();
|
|
} );
|
|
|
|
await waitFor( () => {
|
|
const savedToken = screen.queryByText(
|
|
/Active Payment Method: credit-card/
|
|
);
|
|
expect( savedToken ).toBeNull();
|
|
} );
|
|
|
|
userEvent.click( screen.getByText( 'Select new payment' ) );
|
|
|
|
await waitFor( () => {
|
|
const activePaymentMethod = screen.queryByText(
|
|
/Active Payment Method: credit-card/
|
|
);
|
|
expect( activePaymentMethod ).not.toBeNull();
|
|
} );
|
|
|
|
act( () => resetMockPaymentMethods() );
|
|
} );
|
|
} );
|