woocommerce/plugins/woocommerce-admin/client/payments/test/payment-recommendations.tes...

381 lines
10 KiB
TypeScript
Raw Normal View History

/**
* External dependencies
*/
import { render, fireEvent, waitFor } from '@testing-library/react';
import { useSelect, useDispatch } from '@wordpress/data';
import { recordEvent } from '@woocommerce/tracks';
import {
PLUGINS_STORE_NAME,
SETTINGS_STORE_NAME,
OPTIONS_STORE_NAME,
WCDataStoreName,
Plugin,
} from '@woocommerce/data';
Allow packages to be built in isolation. (https://github.com/woocommerce/woocommerce-admin/pull/7286) * Use yarn instead of npm. In prep for workspaces, since we're locked to npm < 7. See: https://github.com/woocommerce/woocommerce-admin/pull/7126#issue-661287749 * Initial workspace creation. * Add initial tsc build to @woocommerce/number. * Attempt to build experimental package. * Try currency package. * Define all packages as workspaces. * Use tsconfig common to packages. * Fix currency package build. * Build csv-export with tsc. * Try to build customer-effort-score with tsc. * Fix JSX pragma. * Build data package with tsc. * Build date package with tsc. * Build experimental package with tsc. * Try to build explat package with tsc. * Build navigation package with tsc. * Build notices package with tsc. * Build onboarding package with tsc. * Build components package with tsc. * Swap in package JS build into main script. * Fix experimental package build. * Try per-package css build with components. * Try to run components package tests in isolation. Broken on JSX in test files not being transformed. * Move @woocommerce/wc-admin-settings into a package. * Try to fix components package tests. Fails because we aren't setting up the jest/jest-dom globals. * Move JS test code to reusable (private) package. * Enable incremental TS builds. * Use workspaces to run JS tests. * Use new jest configs for update snapshot scripts. * Fix style builds. * Fix package version in components. * Fix client test debug and watch scripts. * Update yarn lock. * Update test-staged behavior. * Try to fix storybook. * Fix storybook. * Update more npm commands to yarn. * Add changelog. * Fix lint errors. * Update packages readme script references. * Clean up unused gitignore match. * Fix another npm command. * Fix JS builds on watch. * Fix start script. * Fix start scripts for packages. * Use tsc to build packages before tests * yarn -> npm. # Conflicts: # package-lock.json # package.json * Fix linter error. * Remove workspace definitions. * Fix missing Fragment import. * Fix package lock. * Fix missing reference. * Only build commonjs module for js-tests helper. * Remove errant dependency from components. * Remove noop scripts. * Fix package JS build before testing. * Revert noisy formatting changes. * Fix precommit and test scripts. * Fix minimum expected recommended extension count. Japan test case breaks this. * Revert babel config changes. * chore(release): publish - @woocommerce/components@7.2.0 - @woocommerce/csv-export@1.4.0 - @woocommerce/currency@3.2.0 - @woocommerce/customer-effort-score@1.1.0 - @woocommerce/data@1.4.0 - @woocommerce/date@3.1.0 - @woocommerce/dependency-extraction-webpack-plugin@1.7.0 - @woocommerce/eslint-plugin@1.3.0 - @woocommerce/experimental@1.5.0 - @woocommerce/explat@1.1.0 - @woocommerce/js-tests@1.1.0 - @woocommerce/navigation@6.1.0 - @woocommerce/notices@3.1.0 - @woocommerce/number@2.2.0 - @woocommerce/onboarding@1.1.0 - @woocommerce/tracks@1.1.0 - @woocommerce/wc-admin-settings@1.1.0 * Add script for running 'start' in a package. * Remove yarn from gitignore. * Update package changelogs, prep versions for release. * Try to fix E2E tests after main merge. * Some cleanup. * Add changelog. Co-authored-by: Paul Sealock <psealock@gmail.com>
2021-07-14 20:38:57 +00:00
import { getAdminLink } from '@woocommerce/wc-admin-settings';
/**
* Internal dependencies
*/
import PaymentRecommendations, {
getPaymentRecommendationData,
} from '../payment-recommendations';
Allow packages to be built in isolation. (https://github.com/woocommerce/woocommerce-admin/pull/7286) * Use yarn instead of npm. In prep for workspaces, since we're locked to npm < 7. See: https://github.com/woocommerce/woocommerce-admin/pull/7126#issue-661287749 * Initial workspace creation. * Add initial tsc build to @woocommerce/number. * Attempt to build experimental package. * Try currency package. * Define all packages as workspaces. * Use tsconfig common to packages. * Fix currency package build. * Build csv-export with tsc. * Try to build customer-effort-score with tsc. * Fix JSX pragma. * Build data package with tsc. * Build date package with tsc. * Build experimental package with tsc. * Try to build explat package with tsc. * Build navigation package with tsc. * Build notices package with tsc. * Build onboarding package with tsc. * Build components package with tsc. * Swap in package JS build into main script. * Fix experimental package build. * Try per-package css build with components. * Try to run components package tests in isolation. Broken on JSX in test files not being transformed. * Move @woocommerce/wc-admin-settings into a package. * Try to fix components package tests. Fails because we aren't setting up the jest/jest-dom globals. * Move JS test code to reusable (private) package. * Enable incremental TS builds. * Use workspaces to run JS tests. * Use new jest configs for update snapshot scripts. * Fix style builds. * Fix package version in components. * Fix client test debug and watch scripts. * Update yarn lock. * Update test-staged behavior. * Try to fix storybook. * Fix storybook. * Update more npm commands to yarn. * Add changelog. * Fix lint errors. * Update packages readme script references. * Clean up unused gitignore match. * Fix another npm command. * Fix JS builds on watch. * Fix start script. * Fix start scripts for packages. * Use tsc to build packages before tests * yarn -> npm. # Conflicts: # package-lock.json # package.json * Fix linter error. * Remove workspace definitions. * Fix missing Fragment import. * Fix package lock. * Fix missing reference. * Only build commonjs module for js-tests helper. * Remove errant dependency from components. * Remove noop scripts. * Fix package JS build before testing. * Revert noisy formatting changes. * Fix precommit and test scripts. * Fix minimum expected recommended extension count. Japan test case breaks this. * Revert babel config changes. * chore(release): publish - @woocommerce/components@7.2.0 - @woocommerce/csv-export@1.4.0 - @woocommerce/currency@3.2.0 - @woocommerce/customer-effort-score@1.1.0 - @woocommerce/data@1.4.0 - @woocommerce/date@3.1.0 - @woocommerce/dependency-extraction-webpack-plugin@1.7.0 - @woocommerce/eslint-plugin@1.3.0 - @woocommerce/experimental@1.5.0 - @woocommerce/explat@1.1.0 - @woocommerce/js-tests@1.1.0 - @woocommerce/navigation@6.1.0 - @woocommerce/notices@3.1.0 - @woocommerce/number@2.2.0 - @woocommerce/onboarding@1.1.0 - @woocommerce/tracks@1.1.0 - @woocommerce/wc-admin-settings@1.1.0 * Add script for running 'start' in a package. * Remove yarn from gitignore. * Update package changelogs, prep versions for release. * Try to fix E2E tests after main merge. * Some cleanup. * Add changelog. Co-authored-by: Paul Sealock <psealock@gmail.com>
2021-07-14 20:38:57 +00:00
import { isWCPaySupported } from '../../task-list/tasks/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;
} ) => <Content />,
List: ( {
items,
}: {
items: { key: string; title: string; after?: React.Component }[];
} ) => (
<div>
{ items.map( ( item ) => (
<div key={ item.key }>
<span>{ item.title }</span>
{ item.after }
</div>
) ) }
</div>
),
} ) );
jest.mock(
'../../task-list/tasks/PaymentGatewaySuggestions/components/WCPay',
() => ( {
isWCPaySupported: jest.fn(),
} )
);
Allow packages to be built in isolation. (https://github.com/woocommerce/woocommerce-admin/pull/7286) * Use yarn instead of npm. In prep for workspaces, since we're locked to npm < 7. See: https://github.com/woocommerce/woocommerce-admin/pull/7126#issue-661287749 * Initial workspace creation. * Add initial tsc build to @woocommerce/number. * Attempt to build experimental package. * Try currency package. * Define all packages as workspaces. * Use tsconfig common to packages. * Fix currency package build. * Build csv-export with tsc. * Try to build customer-effort-score with tsc. * Fix JSX pragma. * Build data package with tsc. * Build date package with tsc. * Build experimental package with tsc. * Try to build explat package with tsc. * Build navigation package with tsc. * Build notices package with tsc. * Build onboarding package with tsc. * Build components package with tsc. * Swap in package JS build into main script. * Fix experimental package build. * Try per-package css build with components. * Try to run components package tests in isolation. Broken on JSX in test files not being transformed. * Move @woocommerce/wc-admin-settings into a package. * Try to fix components package tests. Fails because we aren't setting up the jest/jest-dom globals. * Move JS test code to reusable (private) package. * Enable incremental TS builds. * Use workspaces to run JS tests. * Use new jest configs for update snapshot scripts. * Fix style builds. * Fix package version in components. * Fix client test debug and watch scripts. * Update yarn lock. * Update test-staged behavior. * Try to fix storybook. * Fix storybook. * Update more npm commands to yarn. * Add changelog. * Fix lint errors. * Update packages readme script references. * Clean up unused gitignore match. * Fix another npm command. * Fix JS builds on watch. * Fix start script. * Fix start scripts for packages. * Use tsc to build packages before tests * yarn -> npm. # Conflicts: # package-lock.json # package.json * Fix linter error. * Remove workspace definitions. * Fix missing Fragment import. * Fix package lock. * Fix missing reference. * Only build commonjs module for js-tests helper. * Remove errant dependency from components. * Remove noop scripts. * Fix package JS build before testing. * Revert noisy formatting changes. * Fix precommit and test scripts. * Fix minimum expected recommended extension count. Japan test case breaks this. * Revert babel config changes. * chore(release): publish - @woocommerce/components@7.2.0 - @woocommerce/csv-export@1.4.0 - @woocommerce/currency@3.2.0 - @woocommerce/customer-effort-score@1.1.0 - @woocommerce/data@1.4.0 - @woocommerce/date@3.1.0 - @woocommerce/dependency-extraction-webpack-plugin@1.7.0 - @woocommerce/eslint-plugin@1.3.0 - @woocommerce/experimental@1.5.0 - @woocommerce/explat@1.1.0 - @woocommerce/js-tests@1.1.0 - @woocommerce/navigation@6.1.0 - @woocommerce/notices@3.1.0 - @woocommerce/number@2.2.0 - @woocommerce/onboarding@1.1.0 - @woocommerce/tracks@1.1.0 - @woocommerce/wc-admin-settings@1.1.0 * Add script for running 'start' in a package. * Remove yarn from gitignore. * Update package changelogs, prep versions for release. * Try to fix E2E tests after main merge. * Some cleanup. * Add changelog. Co-authored-by: Paul Sealock <psealock@gmail.com>
2021-07-14 20:38:57 +00:00
jest.mock( '@woocommerce/wc-admin-settings', () => ( {
getAdminLink: jest
.fn()
.mockImplementation( ( link: string ) => 'https://test.ca/' + link ),
} ) );
jest.mock( '../../lib/notices', () => ( {
createNoticesFromResponse: jest.fn().mockImplementation( () => {
// do nothing
} ),
} ) );
describe( 'Payment recommendations', () => {
it( 'should render nothing with no recommendedPlugins and country not defined', () => {
( useSelect as jest.Mock ).mockReturnValue( {
displayable: false,
recommendedPlugins: undefined,
} );
const { container } = render( <PaymentRecommendations /> );
expect( container.firstChild ).toBe( null );
} );
describe( 'getPaymentRecommendationData', () => {
const plugin = {
title: 'test',
slug: 'test',
product: 'test',
} as Plugin;
const baseSelectValues = {
plugins: undefined,
optionsResolving: false,
country: undefined,
optionValues: {},
};
const recommendedPluginsMock = jest.fn();
const createFakeSelect = ( data: {
optionsResolving?: boolean;
optionValues: Record< string, boolean | string >;
country?: string;
plugins?: Plugin[];
} ) => {
return jest
.fn()
.mockImplementation( ( storeName: WCDataStoreName ) => {
switch ( storeName ) {
case OPTIONS_STORE_NAME:
return {
isResolving: () => data.optionsResolving,
getOption: ( option: string ) =>
data.optionValues[ option ],
};
case SETTINGS_STORE_NAME:
return {
getSettings: () => ( {
general: {
woocommerce_default_country:
data.country,
},
} ),
};
case PLUGINS_STORE_NAME:
return {
getRecommendedPlugins: recommendedPluginsMock.mockReturnValue(
data.plugins
),
};
}
} );
};
it( 'should render nothing if the country is not supported', () => {
( isWCPaySupported as jest.Mock ).mockReturnValue( false );
const selectData = getPaymentRecommendationData(
createFakeSelect( {
...baseSelectValues,
country: 'FR',
plugins: [ plugin ],
} )
);
expect( selectData.displayable ).toBe( false );
} );
it( 'should not call getRecommendedPlugins when displayable is false', () => {
( isWCPaySupported as jest.Mock ).mockReturnValue( false );
const selectData = getPaymentRecommendationData(
createFakeSelect( {
...baseSelectValues,
country: 'FR',
plugins: [ plugin ],
} )
);
expect( selectData.displayable ).toBe( false );
expect( recommendedPluginsMock ).not.toHaveBeenCalled();
} );
it( 'should have displayable as true if country is supported', () => {
( isWCPaySupported as jest.Mock ).mockReturnValue( true );
const selectData = getPaymentRecommendationData(
createFakeSelect( {
...baseSelectValues,
country: 'US',
plugins: [ plugin ],
optionValues: {},
} )
);
expect( selectData.displayable ).toBeTruthy();
} );
it( 'should have displayable as false if hidden is set to true', () => {
( isWCPaySupported as jest.Mock ).mockReturnValue( true );
const selectData = getPaymentRecommendationData(
createFakeSelect( {
...baseSelectValues,
country: 'US',
plugins: [ plugin ],
optionValues: {
woocommerce_setting_payments_recommendations_hidden:
'yes',
},
} )
);
expect( selectData.displayable ).toBeFalsy();
} );
it( 'should set displayable to true if isHidden is not defined', () => {
( isWCPaySupported as jest.Mock ).mockReturnValue( true );
const selectData = getPaymentRecommendationData(
createFakeSelect( {
...baseSelectValues,
country: 'US',
plugins: [ plugin ],
optionValues: {
woocommerce_setting_payments_recommendations_hidden:
'no',
},
} )
);
expect( selectData.displayable ).toBeTruthy();
} );
it( 'have displayable as false if still requesting options', () => {
( isWCPaySupported as jest.Mock ).mockReturnValue( true );
const selectData = getPaymentRecommendationData(
createFakeSelect( {
...baseSelectValues,
country: 'US',
plugins: [ plugin ],
optionsResolving: true,
} )
);
expect( selectData.displayable ).toBeFalsy();
} );
} );
it( 'should render the list if displayable is true and has recommendedPlugins', () => {
( isWCPaySupported as jest.Mock ).mockReturnValue( true );
( useSelect as jest.Mock ).mockReturnValue( {
displayable: true,
recommendedPlugins: [ { title: 'test', slug: 'test' } ],
} );
const { container, getByText } = render( <PaymentRecommendations /> );
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,
} );
const { container } = render( <PaymentRecommendations /> );
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( {
displayable: true,
recommendedPlugins: [ { title: 'test', slug: 'test' } ],
} );
const { container } = render( <PaymentRecommendations /> );
expect( container.firstChild ).not.toBeNull();
expect( recordEvent ).toHaveBeenCalledWith(
'settings_payments_recommendations_pageview',
{}
);
} );
it( 'should not render if there are no recommendedPlugins', () => {
( isWCPaySupported as jest.Mock ).mockReturnValue( true );
( useSelect as jest.Mock ).mockReturnValue( {
displayable: true,
recommendedPlugins: [],
} );
const { container } = render( <PaymentRecommendations /> );
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( {
displayable: true,
recommendedPlugins: [
{
title: 'test',
slug: 'test',
product: 'test-product',
'button-text': 'install',
'setup-link': '/wp-admin/random-link',
},
{
title: 'another',
slug: 'another',
product: 'another-product',
'button-text': 'install2',
'setup-link': '/wp-admin/random-link',
},
],
} );
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(
<PaymentRecommendations />
);
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( getAdminLink ).toHaveBeenCalledWith( 'random-link' );
} );
expect( mockLocation.href ).toEqual(
'https://test.ca/random-link'
);
} );
it( 'should call create notice if install and activate failed', async () => {
installAndActivateMock.mockClear();
installAndActivateMock.mockImplementation(
() =>
Allow packages to be built in isolation. (https://github.com/woocommerce/woocommerce-admin/pull/7286) * Use yarn instead of npm. In prep for workspaces, since we're locked to npm < 7. See: https://github.com/woocommerce/woocommerce-admin/pull/7126#issue-661287749 * Initial workspace creation. * Add initial tsc build to @woocommerce/number. * Attempt to build experimental package. * Try currency package. * Define all packages as workspaces. * Use tsconfig common to packages. * Fix currency package build. * Build csv-export with tsc. * Try to build customer-effort-score with tsc. * Fix JSX pragma. * Build data package with tsc. * Build date package with tsc. * Build experimental package with tsc. * Try to build explat package with tsc. * Build navigation package with tsc. * Build notices package with tsc. * Build onboarding package with tsc. * Build components package with tsc. * Swap in package JS build into main script. * Fix experimental package build. * Try per-package css build with components. * Try to run components package tests in isolation. Broken on JSX in test files not being transformed. * Move @woocommerce/wc-admin-settings into a package. * Try to fix components package tests. Fails because we aren't setting up the jest/jest-dom globals. * Move JS test code to reusable (private) package. * Enable incremental TS builds. * Use workspaces to run JS tests. * Use new jest configs for update snapshot scripts. * Fix style builds. * Fix package version in components. * Fix client test debug and watch scripts. * Update yarn lock. * Update test-staged behavior. * Try to fix storybook. * Fix storybook. * Update more npm commands to yarn. * Add changelog. * Fix lint errors. * Update packages readme script references. * Clean up unused gitignore match. * Fix another npm command. * Fix JS builds on watch. * Fix start script. * Fix start scripts for packages. * Use tsc to build packages before tests * yarn -> npm. # Conflicts: # package-lock.json # package.json * Fix linter error. * Remove workspace definitions. * Fix missing Fragment import. * Fix package lock. * Fix missing reference. * Only build commonjs module for js-tests helper. * Remove errant dependency from components. * Remove noop scripts. * Fix package JS build before testing. * Revert noisy formatting changes. * Fix precommit and test scripts. * Fix minimum expected recommended extension count. Japan test case breaks this. * Revert babel config changes. * chore(release): publish - @woocommerce/components@7.2.0 - @woocommerce/csv-export@1.4.0 - @woocommerce/currency@3.2.0 - @woocommerce/customer-effort-score@1.1.0 - @woocommerce/data@1.4.0 - @woocommerce/date@3.1.0 - @woocommerce/dependency-extraction-webpack-plugin@1.7.0 - @woocommerce/eslint-plugin@1.3.0 - @woocommerce/experimental@1.5.0 - @woocommerce/explat@1.1.0 - @woocommerce/js-tests@1.1.0 - @woocommerce/navigation@6.1.0 - @woocommerce/notices@3.1.0 - @woocommerce/number@2.2.0 - @woocommerce/onboarding@1.1.0 - @woocommerce/tracks@1.1.0 - @woocommerce/wc-admin-settings@1.1.0 * Add script for running 'start' in a package. * Remove yarn from gitignore. * Update package changelogs, prep versions for release. * Try to fix E2E tests after main merge. * Some cleanup. * Add changelog. Co-authored-by: Paul Sealock <psealock@gmail.com>
2021-07-14 20:38:57 +00:00
new Promise( () => {
throw {
code: 500,
message: 'failed to install plugin',
};
} )
);
const { container, getByText } = render(
<PaymentRecommendations />
);
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' );
} );
} );
} );