Fix free features is still rendered when no recommendation (#33923)
* Fix free features is still rendered when there is no recommendation * Add changelog * Update BusinessDetails tab to go to next step if no installable extensions * Update spinner
This commit is contained in:
parent
9620704d42
commit
d09d59186d
|
@ -13,6 +13,7 @@ import {
|
||||||
__experimentalText as Text,
|
__experimentalText as Text,
|
||||||
FlexItem,
|
FlexItem,
|
||||||
CheckboxControl,
|
CheckboxControl,
|
||||||
|
Spinner,
|
||||||
} from '@wordpress/components';
|
} from '@wordpress/components';
|
||||||
import { withDispatch, withSelect } from '@wordpress/data';
|
import { withDispatch, withSelect } from '@wordpress/data';
|
||||||
import { SelectControl, Form, TextControl } from '@woocommerce/components';
|
import { SelectControl, Form, TextControl } from '@woocommerce/components';
|
||||||
|
@ -35,7 +36,10 @@ import { employeeOptions } from '../../data/employee-options';
|
||||||
import { sellingVenueOptions } from '../../data/selling-venue-options';
|
import { sellingVenueOptions } from '../../data/selling-venue-options';
|
||||||
import { getRevenueOptions } from '../../data/revenue-options';
|
import { getRevenueOptions } from '../../data/revenue-options';
|
||||||
import { getProductCountOptions } from '../../data/product-options';
|
import { getProductCountOptions } from '../../data/product-options';
|
||||||
import { SelectiveExtensionsBundle } from './selective-extensions-bundle';
|
import {
|
||||||
|
SelectiveExtensionsBundle,
|
||||||
|
getInstallableExtensions,
|
||||||
|
} from './selective-extensions-bundle';
|
||||||
import { getPluginSlug, getPluginTrackKey, getTimeFrame } from '~/utils';
|
import { getPluginSlug, getPluginTrackKey, getTimeFrame } from '~/utils';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
|
@ -146,6 +150,8 @@ class BusinessDetails extends Component {
|
||||||
this.state.savedValues,
|
this.state.savedValues,
|
||||||
this.persistValues
|
this.persistValues
|
||||||
);
|
);
|
||||||
|
// Refetch the free extensions data
|
||||||
|
props.invalidateResolutionForStoreSelector( 'getFreeExtensions' );
|
||||||
}
|
}
|
||||||
|
|
||||||
async onContinue(
|
async onContinue(
|
||||||
|
@ -430,6 +436,7 @@ class BusinessDetails extends Component {
|
||||||
<Form
|
<Form
|
||||||
initialValues={ this.state.savedValues.businessDetailsTab }
|
initialValues={ this.state.savedValues.businessDetailsTab }
|
||||||
onSubmit={ ( values ) => {
|
onSubmit={ ( values ) => {
|
||||||
|
if ( this.props.hasInstallableExtensions ) {
|
||||||
this.setState( {
|
this.setState( {
|
||||||
savedValues: {
|
savedValues: {
|
||||||
...this.state.savedValues,
|
...this.state.savedValues,
|
||||||
|
@ -437,6 +444,11 @@ class BusinessDetails extends Component {
|
||||||
},
|
},
|
||||||
currentTab: BUSINESS_FEATURES_TAB_NAME,
|
currentTab: BUSINESS_FEATURES_TAB_NAME,
|
||||||
} );
|
} );
|
||||||
|
} else {
|
||||||
|
goToNextStep( {
|
||||||
|
step: BUSINESS_FEATURES_TAB_NAME,
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
this.trackBusinessDetailsStep( values );
|
this.trackBusinessDetailsStep( values );
|
||||||
recordEvent( 'storeprofiler_step_view', {
|
recordEvent( 'storeprofiler_step_view', {
|
||||||
|
@ -645,13 +657,10 @@ class BusinessDetails extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderFreeFeaturesStep() {
|
renderFreeFeaturesStep() {
|
||||||
const { isInstallingActivating, settings, profileItems } = this.props;
|
const { isInstallingActivating } = this.props;
|
||||||
const {
|
const {
|
||||||
savedValues: { freeFeaturesTab },
|
savedValues: { freeFeaturesTab },
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const country = settings.woocommerce_default_country
|
|
||||||
? settings.woocommerce_default_country
|
|
||||||
: null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -681,9 +690,7 @@ class BusinessDetails extends Component {
|
||||||
<SelectiveExtensionsBundle
|
<SelectiveExtensionsBundle
|
||||||
isInstallingActivating={ isInstallingActivating }
|
isInstallingActivating={ isInstallingActivating }
|
||||||
onSubmit={ this.onContinue }
|
onSubmit={ this.onContinue }
|
||||||
country={ country }
|
installableExtensions={ this.props.installableExtensions }
|
||||||
industry={ profileItems.industry }
|
|
||||||
productTypes={ profileItems.product_types }
|
|
||||||
installExtensionOptions={
|
installExtensionOptions={
|
||||||
freeFeaturesTab.installExtensionOptions
|
freeFeaturesTab.installExtensionOptions
|
||||||
}
|
}
|
||||||
|
@ -700,10 +707,17 @@ class BusinessDetails extends Component {
|
||||||
this.setState( {
|
this.setState( {
|
||||||
savedValues,
|
savedValues,
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
if (
|
||||||
|
// Only update current step values when current state's installExtensionOptions is not undefined.
|
||||||
|
this.state.savedValues.freeFeaturesTab
|
||||||
|
.installExtensionOptions
|
||||||
|
) {
|
||||||
this.props.updateCurrentStepValues(
|
this.props.updateCurrentStepValues(
|
||||||
this.props.step.key,
|
this.props.step.key,
|
||||||
savedValues
|
savedValues
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} }
|
} }
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
@ -711,6 +725,36 @@ class BusinessDetails extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const tabs = [];
|
||||||
|
if ( ! this.props.hasFinishedGetFreeExtensionsResolution ) {
|
||||||
|
return (
|
||||||
|
<div className="woocommerce-admin__business-details__spinner">
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
tabs.push( {
|
||||||
|
name:
|
||||||
|
this.state.currentTab === BUSINESS_DETAILS_TAB_NAME
|
||||||
|
? 'current-tab'
|
||||||
|
: BUSINESS_DETAILS_TAB_NAME,
|
||||||
|
id: BUSINESS_DETAILS_TAB_NAME,
|
||||||
|
title: __( 'Business details', 'woocommerce' ),
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( this.props.hasInstallableExtensions ) {
|
||||||
|
tabs.push( {
|
||||||
|
name:
|
||||||
|
this.state.currentTab === BUSINESS_FEATURES_TAB_NAME
|
||||||
|
? 'current-tab'
|
||||||
|
: BUSINESS_FEATURES_TAB_NAME,
|
||||||
|
id: BUSINESS_FEATURES_TAB_NAME,
|
||||||
|
title: __( 'Free features', 'woocommerce' ),
|
||||||
|
className: this.state.isValid ? '' : 'is-disabled',
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
// There is a hack here to help us manage the selected tab programmatically.
|
// There is a hack here to help us manage the selected tab programmatically.
|
||||||
// We set the tab name "current-tab". when its the one we want selected. This tricks
|
// We set the tab name "current-tab". when its the one we want selected. This tricks
|
||||||
// the logic in the TabPanel and allows us to switch which tab has the name "current-tab"
|
// the logic in the TabPanel and allows us to switch which tab has the name "current-tab"
|
||||||
|
@ -733,25 +777,7 @@ class BusinessDetails extends Component {
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
} }
|
} }
|
||||||
tabs={ [
|
tabs={ tabs }
|
||||||
{
|
|
||||||
name:
|
|
||||||
this.state.currentTab === BUSINESS_DETAILS_TAB_NAME
|
|
||||||
? 'current-tab'
|
|
||||||
: BUSINESS_DETAILS_TAB_NAME,
|
|
||||||
id: BUSINESS_DETAILS_TAB_NAME,
|
|
||||||
title: __( 'Business details', 'woocommerce' ),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name:
|
|
||||||
this.state.currentTab === BUSINESS_FEATURES_TAB_NAME
|
|
||||||
? 'current-tab'
|
|
||||||
: BUSINESS_FEATURES_TAB_NAME,
|
|
||||||
id: BUSINESS_FEATURES_TAB_NAME,
|
|
||||||
title: __( 'Free features', 'woocommerce' ),
|
|
||||||
className: this.state.isValid ? '' : 'is-disabled',
|
|
||||||
},
|
|
||||||
] }
|
|
||||||
>
|
>
|
||||||
{ ( tab ) => <>{ this.getTab( tab.id ) }</> }
|
{ ( tab ) => <>{ this.getTab( tab.id ) }</> }
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
@ -771,29 +797,54 @@ BusinessDetails.contextType = CurrencyContext;
|
||||||
export const BusinessFeaturesList = compose(
|
export const BusinessFeaturesList = compose(
|
||||||
withSelect( ( select ) => {
|
withSelect( ( select ) => {
|
||||||
const { getSettings, getSettingsError } = select( SETTINGS_STORE_NAME );
|
const { getSettings, getSettingsError } = select( SETTINGS_STORE_NAME );
|
||||||
const { getProfileItems, getOnboardingError } = select(
|
const {
|
||||||
ONBOARDING_STORE_NAME
|
getProfileItems,
|
||||||
);
|
getOnboardingError,
|
||||||
|
getFreeExtensions,
|
||||||
|
hasFinishedResolution,
|
||||||
|
} = select( ONBOARDING_STORE_NAME );
|
||||||
const { getPluginsError, isPluginsRequesting } =
|
const { getPluginsError, isPluginsRequesting } =
|
||||||
select( PLUGINS_STORE_NAME );
|
select( PLUGINS_STORE_NAME );
|
||||||
const { general: settings = {} } = getSettings( 'general' );
|
const { general: settings = {} } = getSettings( 'general' );
|
||||||
|
|
||||||
|
const freeExtensions = getFreeExtensions();
|
||||||
|
const profileItems = getProfileItems();
|
||||||
|
const country = settings.woocommerce_default_country
|
||||||
|
? settings.woocommerce_default_country
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const installableExtensions = freeExtensions
|
||||||
|
? getInstallableExtensions( {
|
||||||
|
freeExtensionBundleByCategory: freeExtensions,
|
||||||
|
country,
|
||||||
|
productTypes: profileItems.product_types,
|
||||||
|
} )
|
||||||
|
: [];
|
||||||
|
const hasInstallableExtensions = installableExtensions.some(
|
||||||
|
( { plugins } ) => plugins.length > 0
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasInstallActivateError:
|
hasInstallActivateError:
|
||||||
getPluginsError( 'installPlugins' ) ||
|
getPluginsError( 'installPlugins' ) ||
|
||||||
getPluginsError( 'activatePlugins' ),
|
getPluginsError( 'activatePlugins' ),
|
||||||
|
hasInstallableExtensions,
|
||||||
|
hasFinishedGetFreeExtensionsResolution:
|
||||||
|
hasFinishedResolution( 'getFreeExtensions' ),
|
||||||
|
installableExtensions,
|
||||||
isError: Boolean( getOnboardingError( 'updateProfileItems' ) ),
|
isError: Boolean( getOnboardingError( 'updateProfileItems' ) ),
|
||||||
profileItems: getProfileItems(),
|
|
||||||
isSettingsError: Boolean( getSettingsError( 'general' ) ),
|
isSettingsError: Boolean( getSettingsError( 'general' ) ),
|
||||||
settings,
|
|
||||||
isInstallingActivating:
|
isInstallingActivating:
|
||||||
isPluginsRequesting( 'installPlugins' ) ||
|
isPluginsRequesting( 'installPlugins' ) ||
|
||||||
isPluginsRequesting( 'activatePlugins' ) ||
|
isPluginsRequesting( 'activatePlugins' ) ||
|
||||||
isPluginsRequesting( 'getJetpackConnectUrl' ),
|
isPluginsRequesting( 'getJetpackConnectUrl' ),
|
||||||
|
profileItems,
|
||||||
|
settings,
|
||||||
};
|
};
|
||||||
} ),
|
} ),
|
||||||
withDispatch( ( dispatch ) => {
|
withDispatch( ( dispatch ) => {
|
||||||
const { updateProfileItems } = dispatch( ONBOARDING_STORE_NAME );
|
const { updateProfileItems, invalidateResolutionForStoreSelector } =
|
||||||
|
dispatch( ONBOARDING_STORE_NAME );
|
||||||
const { installAndActivatePlugins } = dispatch( PLUGINS_STORE_NAME );
|
const { installAndActivatePlugins } = dispatch( PLUGINS_STORE_NAME );
|
||||||
const { createNotice } = dispatch( 'core/notices' );
|
const { createNotice } = dispatch( 'core/notices' );
|
||||||
|
|
||||||
|
@ -801,6 +852,7 @@ export const BusinessFeaturesList = compose(
|
||||||
createNotice,
|
createNotice,
|
||||||
installAndActivatePlugins,
|
installAndActivatePlugins,
|
||||||
updateProfileItems,
|
updateProfileItems,
|
||||||
|
invalidateResolutionForStoreSelector,
|
||||||
};
|
};
|
||||||
} )
|
} )
|
||||||
)( BusinessDetails );
|
)( BusinessDetails );
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
/**
|
/**
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { useEffect, useMemo, useState } from '@wordpress/element';
|
import { useEffect, useState } from '@wordpress/element';
|
||||||
import { Button, Card, CheckboxControl, Spinner } from '@wordpress/components';
|
import { Button, Card, CheckboxControl, Spinner } from '@wordpress/components';
|
||||||
import { Text } from '@woocommerce/experimental';
|
import { Text } from '@woocommerce/experimental';
|
||||||
import { Link } from '@woocommerce/components';
|
import { Link } from '@woocommerce/components';
|
||||||
import { __, _n, sprintf } from '@wordpress/i18n';
|
import { __, _n, sprintf } from '@wordpress/i18n';
|
||||||
import { Icon, chevronDown, chevronUp } from '@wordpress/icons';
|
import { Icon, chevronDown, chevronUp } from '@wordpress/icons';
|
||||||
import interpolateComponents from '@automattic/interpolate-components';
|
import interpolateComponents from '@automattic/interpolate-components';
|
||||||
import { pluginNames, ONBOARDING_STORE_NAME } from '@woocommerce/data';
|
import { pluginNames } from '@woocommerce/data';
|
||||||
import { recordEvent } from '@woocommerce/tracks';
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
import { useDispatch, useSelect } from '@wordpress/data';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal dependencies
|
* Internal dependencies
|
||||||
|
@ -234,37 +233,11 @@ export const createInstallExtensionOptions = (
|
||||||
}, prevInstallExtensionOptions );
|
}, prevInstallExtensionOptions );
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SelectiveExtensionsBundle = ( {
|
export const getInstallableExtensions = ( {
|
||||||
isInstallingActivating,
|
freeExtensionBundleByCategory,
|
||||||
onSubmit,
|
|
||||||
country,
|
country,
|
||||||
productTypes,
|
productTypes,
|
||||||
industry,
|
|
||||||
setInstallExtensionOptions,
|
|
||||||
installExtensionOptions = { install_extensions: true },
|
|
||||||
} ) => {
|
} ) => {
|
||||||
const [ showExtensions, setShowExtensions ] = useState( false );
|
|
||||||
const { freeExtensions: freeExtensionBundleByCategory, isResolving } =
|
|
||||||
useSelect( ( select ) => {
|
|
||||||
const { getFreeExtensions, hasFinishedResolution } = select(
|
|
||||||
ONBOARDING_STORE_NAME
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
freeExtensions: getFreeExtensions(),
|
|
||||||
isResolving: ! hasFinishedResolution( 'getFreeExtensions' ),
|
|
||||||
};
|
|
||||||
} );
|
|
||||||
|
|
||||||
const { invalidateResolutionForStoreSelector } = useDispatch(
|
|
||||||
ONBOARDING_STORE_NAME
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect( () => {
|
|
||||||
invalidateResolutionForStoreSelector( 'getFreeExtensions' );
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [ country, industry ] );
|
|
||||||
|
|
||||||
const installableExtensions = useMemo( () => {
|
|
||||||
return freeExtensionBundleByCategory.filter( ( extensionBundle ) => {
|
return freeExtensionBundleByCategory.filter( ( extensionBundle ) => {
|
||||||
if (
|
if (
|
||||||
window.wcAdminFeatures &&
|
window.wcAdminFeatures &&
|
||||||
|
@ -282,7 +255,16 @@ export const SelectiveExtensionsBundle = ( {
|
||||||
}
|
}
|
||||||
return ALLOWED_PLUGIN_CATEGORIES.includes( extensionBundle.key );
|
return ALLOWED_PLUGIN_CATEGORIES.includes( extensionBundle.key );
|
||||||
} );
|
} );
|
||||||
}, [ freeExtensionBundleByCategory, productTypes, country ] );
|
};
|
||||||
|
|
||||||
|
export const SelectiveExtensionsBundle = ( {
|
||||||
|
isInstallingActivating,
|
||||||
|
onSubmit,
|
||||||
|
setInstallExtensionOptions,
|
||||||
|
installableExtensions,
|
||||||
|
installExtensionOptions = { install_extensions: true },
|
||||||
|
} ) => {
|
||||||
|
const [ showExtensions, setShowExtensions ] = useState( false );
|
||||||
|
|
||||||
useEffect( () => {
|
useEffect( () => {
|
||||||
if ( isInstallingActivating || installableExtensions.length === 0 ) {
|
if ( isInstallingActivating || installableExtensions.length === 0 ) {
|
||||||
|
@ -401,8 +383,8 @@ export const SelectiveExtensionsBundle = ( {
|
||||||
installableExtensions
|
installableExtensions
|
||||||
);
|
);
|
||||||
} }
|
} }
|
||||||
isBusy={ isInstallingActivating || isResolving }
|
isBusy={ isInstallingActivating }
|
||||||
disabled={ isInstallingActivating || isResolving }
|
disabled={ isInstallingActivating }
|
||||||
isPrimary
|
isPrimary
|
||||||
>
|
>
|
||||||
{ __( 'Continue', 'woocommerce' ) }
|
{ __( 'Continue', 'woocommerce' ) }
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
* External dependencies
|
* External dependencies
|
||||||
*/
|
*/
|
||||||
import { render } from '@testing-library/react';
|
import { render } from '@testing-library/react';
|
||||||
import { useSelect, useDispatch } from '@wordpress/data';
|
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import { pluginNames } from '@woocommerce/data';
|
import { pluginNames } from '@woocommerce/data';
|
||||||
|
|
||||||
|
@ -15,25 +14,21 @@ jest.mock( '../../app-illustration', () => ( {
|
||||||
AppIllustration: jest.fn().mockReturnValue( '[illustration]' ),
|
AppIllustration: jest.fn().mockReturnValue( '[illustration]' ),
|
||||||
} ) );
|
} ) );
|
||||||
|
|
||||||
jest.mock( '@wordpress/data', () => ( {
|
|
||||||
...jest.requireActual( '@wordpress/data' ),
|
|
||||||
useSelect: jest.fn(),
|
|
||||||
useDispatch: jest.fn().mockImplementation( () => ( {
|
|
||||||
updateOptions: jest.fn(),
|
|
||||||
installAndActivatePlugins: jest.fn(),
|
|
||||||
} ) ),
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
jest.mock( '@woocommerce/data', () => ( {
|
|
||||||
pluginNames: {
|
|
||||||
'woocommerce-payments': 'WooCommerce Payments',
|
|
||||||
mailpoet: 'Mailpoet',
|
|
||||||
random: 'Random',
|
|
||||||
'google-listings-and-ads': 'Google Listings and Ads',
|
|
||||||
},
|
|
||||||
} ) );
|
|
||||||
|
|
||||||
const freeExtensions = [
|
const freeExtensions = [
|
||||||
|
{
|
||||||
|
key: 'task-list/reach',
|
||||||
|
title: 'Reach out to customers',
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
key: 'random',
|
||||||
|
name: 'Random',
|
||||||
|
description: 'Random description',
|
||||||
|
manage_url: 'admin.php?page=mailpoet-newsletters',
|
||||||
|
is_visible: true,
|
||||||
|
is_installed: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
key: 'obw/basics',
|
key: 'obw/basics',
|
||||||
title: 'Get the basics',
|
title: 'Get the basics',
|
||||||
|
@ -53,20 +48,6 @@ const freeExtensions = [
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
key: 'task-list/reach',
|
|
||||||
title: 'Reach out to customers',
|
|
||||||
plugins: [
|
|
||||||
{
|
|
||||||
key: 'random',
|
|
||||||
name: 'Random',
|
|
||||||
description: 'Random description',
|
|
||||||
manage_url: 'admin.php?page=mailpoet-newsletters',
|
|
||||||
is_visible: true,
|
|
||||||
is_installed: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'obw/grow',
|
key: 'obw/grow',
|
||||||
title: 'Grow your store',
|
title: 'Grow your store',
|
||||||
|
@ -84,23 +65,13 @@ const freeExtensions = [
|
||||||
];
|
];
|
||||||
|
|
||||||
describe( 'Selective extensions bundle', () => {
|
describe( 'Selective extensions bundle', () => {
|
||||||
beforeAll( () => {
|
|
||||||
useSelect.mockReturnValue( {
|
|
||||||
freeExtensions,
|
|
||||||
isResolving: false,
|
|
||||||
} );
|
|
||||||
|
|
||||||
useDispatch.mockReturnValue( {
|
|
||||||
invalidateResolutionForStoreSelector: () => {},
|
|
||||||
} );
|
|
||||||
} );
|
|
||||||
|
|
||||||
it( 'should list installable free extensions from obw/basics and obw/grow', () => {
|
it( 'should list installable free extensions from obw/basics and obw/grow', () => {
|
||||||
const mockSetInstallExtensionOptions = jest.fn();
|
const mockSetInstallExtensionOptions = jest.fn();
|
||||||
// Render once to get installExtensionOptions
|
// Render once to get installExtensionOptions
|
||||||
render(
|
render(
|
||||||
<SelectiveExtensionsBundle
|
<SelectiveExtensionsBundle
|
||||||
isInstallingActivating={ false }
|
isInstallingActivating={ false }
|
||||||
|
installableExtensions={ freeExtensions.slice( 1 ) }
|
||||||
setInstallExtensionOptions={ mockSetInstallExtensionOptions }
|
setInstallExtensionOptions={ mockSetInstallExtensionOptions }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -109,6 +80,7 @@ describe( 'Selective extensions bundle', () => {
|
||||||
<SelectiveExtensionsBundle
|
<SelectiveExtensionsBundle
|
||||||
isInstallingActivating={ false }
|
isInstallingActivating={ false }
|
||||||
setInstallExtensionOptions={ mockSetInstallExtensionOptions }
|
setInstallExtensionOptions={ mockSetInstallExtensionOptions }
|
||||||
|
installableExtensions={ freeExtensions.slice( 1 ) }
|
||||||
installExtensionOptions={
|
installExtensionOptions={
|
||||||
mockSetInstallExtensionOptions.mock.calls[ 0 ][ 0 ]
|
mockSetInstallExtensionOptions.mock.calls[ 0 ][ 0 ]
|
||||||
}
|
}
|
||||||
|
@ -126,15 +98,14 @@ describe( 'Selective extensions bundle', () => {
|
||||||
new RegExp( pluginNames[ 'google-listings-and-ads' ] )
|
new RegExp( pluginNames[ 'google-listings-and-ads' ] )
|
||||||
)
|
)
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
expect(
|
expect( queryByText( new RegExp( 'Random' ) ) ).not.toBeInTheDocument();
|
||||||
queryByText( new RegExp( pluginNames.random ) )
|
|
||||||
).not.toBeInTheDocument();
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
it( 'should list installable extensions when dropdown is clicked', () => {
|
it( 'should list installable extensions when dropdown is clicked', () => {
|
||||||
const { getAllByRole, getByText, queryByText } = render(
|
const { getAllByRole, getByText, queryByText } = render(
|
||||||
<SelectiveExtensionsBundle
|
<SelectiveExtensionsBundle
|
||||||
isInstallingActivating={ false }
|
isInstallingActivating={ false }
|
||||||
|
installableExtensions={ freeExtensions }
|
||||||
setInstallExtensionOptions={ jest.fn() }
|
setInstallExtensionOptions={ jest.fn() }
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
import { useSelect } from '@wordpress/data';
|
import { useSelect } from '@wordpress/data';
|
||||||
import { useMemo } from '@wordpress/element';
|
import { useMemo } from '@wordpress/element';
|
||||||
import { Spinner } from '@woocommerce/components';
|
import { Spinner } from '@wordpress/components';
|
||||||
import { ONBOARDING_STORE_NAME, SETTINGS_STORE_NAME } from '@woocommerce/data';
|
import { ONBOARDING_STORE_NAME, SETTINGS_STORE_NAME } from '@woocommerce/data';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: patch
|
||||||
|
Type: fix
|
||||||
|
|
||||||
|
Fix free features is still rendered when there is no recommendation
|
Loading…
Reference in New Issue