/** * External dependencies */ import { render, fireEvent, waitFor } from '@testing-library/react'; import { useSelect, useDispatch } from '@wordpress/data'; import { recordEvent } from '@woocommerce/tracks'; /** * Internal dependencies */ import PaymentRecommendations from '../payment-recommendations'; import { isWCPaySupported } from '../../tasks/fills/PaymentGatewaySuggestions/components/WCPay'; import { createNoticesFromResponse } from '~/lib/notices'; jest.mock( '@woocommerce/tracks', () => ( { recordEvent: jest.fn() } ) ); jest.mock( '@wordpress/data', () => ( { ...jest.requireActual( '@wordpress/data' ), useSelect: jest.fn(), useDispatch: jest.fn().mockImplementation( () => ( { updateOptions: jest.fn(), installAndActivatePlugins: jest.fn(), } ) ), } ) ); jest.mock( '@woocommerce/components', () => ( { EllipsisMenu: ( { renderContent: Content, }: { renderContent: React.FunctionComponent; } ) => , List: ( { items, }: { items: { key: string; title: string; after?: React.Component }[]; } ) => (
{ items.map( ( item ) => (
{ item.title } { item.after }
) ) }
), } ) ); jest.mock( '../../tasks/fills/PaymentGatewaySuggestions/components/WCPay', () => ( { isWCPaySupported: jest.fn(), } ) ); jest.mock( '../../lib/notices', () => ( { createNoticesFromResponse: jest.fn().mockImplementation( () => { // do nothing } ), } ) ); describe( 'Payment recommendations', () => { it( 'should render nothing with no paymentGatewaySuggestions and country not defined', () => { ( useSelect as jest.Mock ).mockReturnValue( { installedPaymentGateways: {}, paymentGatewaySuggestions: undefined, } ); const { container } = render( ); expect( container.firstChild ).toBe( null ); } ); it( 'should render the list if displayable is true and has paymentGatewaySuggestions', () => { ( isWCPaySupported as jest.Mock ).mockReturnValue( true ); ( useSelect as jest.Mock ).mockReturnValue( { installedPaymentGateways: {}, paymentGatewaySuggestions: [ { title: 'test', id: 'test', plugins: [ 'test' ] }, ], } ); const { container, getByText } = render( ); expect( container.firstChild ).not.toBeNull(); expect( getByText( 'test' ) ).toBeInTheDocument(); } ); it( 'should not trigger event payments_recommendations_pageview, when it is not rendered', () => { ( recordEvent as jest.Mock ).mockClear(); ( isWCPaySupported as jest.Mock ).mockReturnValue( true ); ( useSelect as jest.Mock ).mockReturnValue( { displayable: false, installedPaymentGateways: {}, } ); const { container } = render( ); expect( container.firstChild ).toBeNull(); expect( recordEvent ).not.toHaveBeenCalledWith( 'settings_payments_recommendations_pageview', {} ); } ); it( 'should trigger event payments_recommendations_pageview, when first rendered', () => { ( isWCPaySupported as jest.Mock ).mockReturnValue( true ); ( useSelect as jest.Mock ).mockReturnValue( { installedPaymentGateways: {}, paymentGatewaySuggestions: [ { title: 'test', id: 'test', plugins: [ 'test' ] }, ], } ); const { container } = render( ); expect( container.firstChild ).not.toBeNull(); expect( recordEvent ).toHaveBeenCalledWith( 'settings_payments_recommendations_pageview', { test_displayed: true, woocommerce_payments_displayed: false, } ); } ); it( 'should set woocommerce-payments-displayed prop to true if pre install wc pay promotion gateway is displayed', () => { ( isWCPaySupported as jest.Mock ).mockReturnValue( true ); ( useSelect as jest.Mock ).mockReturnValue( { installedPaymentGateways: {}, paymentGatewaySuggestions: [ { title: 'test', id: 'test', plugins: [ 'test' ] }, ], } ); const { container } = render(
); expect( container.firstChild ).not.toBeNull(); expect( recordEvent ).toHaveBeenCalledWith( 'settings_payments_recommendations_pageview', { test_displayed: true, woocommerce_payments_displayed: false, } ); } ); it( 'should not render if there are no paymentGatewaySuggestions', () => { ( isWCPaySupported as jest.Mock ).mockReturnValue( true ); ( useSelect as jest.Mock ).mockReturnValue( { installedPaymentGateways: {}, paymentGatewaySuggestions: [], } ); const { container } = render( ); expect( container.firstChild ).toBeNull(); } ); describe( 'interactions', () => { let oldLocation: Location; const mockLocation = { href: 'test', } as Location; const updateOptionsMock = jest.fn(); const installAndActivateMock = jest .fn() .mockImplementation( () => Promise.resolve() ); beforeEach( () => { ( isWCPaySupported as jest.Mock ).mockReturnValue( true ); ( useDispatch as jest.Mock ).mockReturnValue( { updateOptions: updateOptionsMock, installAndActivatePlugins: installAndActivateMock, } ); ( useSelect as jest.Mock ).mockReturnValue( { installedPaymentGateways: {}, installedPaymentGateway: { settings_url: 'https://test.ca/random-link', }, paymentGatewaySuggestions: [ { title: 'test', id: 'test', plugins: [ 'test-product' ], actionText: 'install', }, { title: 'another', id: 'another', plugins: [ 'another-product' ], actionText: 'install2', }, ], } ); oldLocation = global.window.location; mockLocation.href = 'test'; Object.defineProperty( global.window, 'location', { value: mockLocation, } ); } ); afterEach( () => { Object.defineProperty( global.window, 'location', oldLocation ); } ); it( 'should install plugin and trigger event and redirect when finished, when clicking the action button', async () => { const { container, getByText } = render( ); expect( container.firstChild ).not.toBeNull(); fireEvent.click( getByText( 'install' ) ); expect( installAndActivateMock ).toHaveBeenCalledWith( [ 'test-product', ] ); expect( recordEvent ).toHaveBeenCalledWith( 'settings_payments_recommendations_setup', { extension_selected: 'test-product', } ); expect( mockLocation.href ).toEqual( 'https://test.ca/random-link' ); } ); it( 'should call create notice if install and activate failed', async () => { ( useSelect as jest.Mock ).mockReturnValue( { installedPaymentGateway: false, installedPaymentGateways: {}, paymentGatewaySuggestions: [ { title: 'test', id: 'test', plugins: [ 'test-product' ], actionText: 'install', }, ], } ); installAndActivateMock.mockClear(); installAndActivateMock.mockImplementation( () => new Promise( () => { throw { code: 500, message: 'failed to install plugin', }; } ) ); const { container, getByText } = render( ); expect( container.firstChild ).not.toBeNull(); fireEvent.click( getByText( 'install' ) ); expect( installAndActivateMock ).toHaveBeenCalledWith( [ 'test-product', ] ); expect( recordEvent ).toHaveBeenCalledWith( 'settings_payments_recommendations_setup', { extension_selected: 'test-product', } ); await waitFor( () => { expect( createNoticesFromResponse ).toHaveBeenCalled(); } ); expect( mockLocation.href ).toEqual( 'test' ); } ); it( 'should only show gateways that have not been installed', async () => { ( useSelect as jest.Mock ).mockReturnValue( { installedPaymentGateway: false, installedPaymentGateways: { test: true, }, paymentGatewaySuggestions: [ { title: 'test', id: 'test', plugins: [ 'test-product' ], actionText: 'install', }, { title: 'another', id: 'another', plugins: [ 'another-product' ], actionText: 'install2', }, ], } ); const { queryByText } = render( ); expect( queryByText( 'test' ) ).not.toBeInTheDocument(); expect( queryByText( 'another' ) ).toBeInTheDocument(); } ); } ); } );