Skip to content

Commit

Permalink
Merge pull request #2609 from woocommerce/update/add-and-edit-shippin…
Browse files Browse the repository at this point in the history
…g-time-inputs

Update Add/Edit Shipping Time Modals to support minimum and maximum shipping times stepper
  • Loading branch information
jorgemd24 authored Sep 24, 2024
2 parents cd67ca0 + c5e4dc3 commit d23fcd9
Show file tree
Hide file tree
Showing 13 changed files with 330 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Form } from '@woocommerce/components';
import { Flex, FlexItem } from '@wordpress/components';

/**
* Internal dependencies
*/
import AppButton from '.~/components/app-button';
import AppModal from '.~/components/app-modal';
import AppInputNumberControl from '.~/components/app-input-number-control';
import VerticalGapLayout from '.~/components/vertical-gap-layout';
import SupportedCountrySelect from '.~/components/supported-country-select';
import validateShippingTimeGroup from '.~/utils/validateShippingTimeGroup';
import MinMaxShippingTimes from '../../min-max-inputs';
import './index.scss';

/**
* Form to add a new time for selected country(-ies).
Expand Down Expand Up @@ -42,7 +44,12 @@ const AddTimeModal = ( { countries, onRequestClose, onSubmit } ) => {
onSubmit={ handleSubmitCallback }
>
{ ( formProps ) => {
const { getInputProps, isValidForm, handleSubmit } = formProps;
const { getInputProps, isValidForm, handleSubmit, errors } =
formProps;

const handleIncrement = ( numberValue, field ) => {
getInputProps( field ).onChange( numberValue );
};

return (
<AppModal
Expand All @@ -67,6 +74,7 @@ const AddTimeModal = ( { countries, onRequestClose, onSubmit } ) => {
</AppButton>,
] }
onRequestClose={ onRequestClose }
className="gla-add-time-modal"
>
<VerticalGapLayout>
<SupportedCountrySelect
Expand All @@ -80,28 +88,31 @@ const AddTimeModal = ( { countries, onRequestClose, onSubmit } ) => {
}
{ ...getInputProps( 'countries' ) }
/>
<AppInputNumberControl
label={ __(
'Then the minimum estimated shipping time displayed in the product listing is',
'google-listings-and-ads'
) }
suffix={ __(
'days',
'google-listings-and-ads'
) }
{ ...getInputProps( 'time' ) }
/>
<AppInputNumberControl
label={ __(
'And the maximum time is',
'google-listings-and-ads'
) }
suffix={ __(
'days',
<div className="label">
{ __(
'Then the estimated shipping times displayed in the product listing are:',
'google-listings-and-ads'
) }
{ ...getInputProps( 'maxTime' ) }
/>
</div>
<Flex
direction="column"
className="gla-countries-time-input-container"
>
<FlexItem>
<MinMaxShippingTimes
time={ getInputProps( 'time' ).value }
maxTime={
getInputProps( 'maxTime' ).value
}
handleBlur={ handleIncrement }
handleIncrement={ handleIncrement }
/>

<ul className="gla-validation-errors">
<li>{ errors.time }</li>
</ul>
</FlexItem>
</Flex>
</VerticalGapLayout>
</AppModal>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.gla-add-time-modal .gla-countries-time-stepper .components-input-control {
margin-bottom: 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* External dependencies
*/
import '@testing-library/jest-dom';
import { render, fireEvent, waitFor } from '@testing-library/react';

/**
* Internal dependencies
*/
import AddTimeModal from './index';
import useMCCountryTreeOptions from '.~/components/supported-country-select/useMCCountryTreeOptions';

jest.mock( '.~/components/supported-country-select/useMCCountryTreeOptions' );

describe( 'Add time Modal', () => {
it( 'The min and max shipping time inputs should be displayed, and both values should be submitted', async () => {
const onSubmit = jest.fn();

useMCCountryTreeOptions.mockImplementation( () => {
return [
{
value: 'EU',
label: 'Europe',
children: [
{
value: 'ES',
label: 'Spain',
parent: 'EU',
},
],
},
];
} );

const { getByRole, getAllByRole } = render(
<AddTimeModal
countries={ [ 'ES' ] }
onRequestClose={ jest.fn() }
onSubmit={ onSubmit }
/>
);

const inputs = getAllByRole( 'textbox' );
// it should render 2 inputs ( the min and max shipping time inputs )
expect( inputs ).toHaveLength( 2 );

const [ minInput, maxInput ] = inputs;

expect( minInput ).toHaveValue( '' );
expect( maxInput ).toHaveValue( '' );

fireEvent.blur( minInput, { target: { value: '2' } } );
expect( minInput ).toHaveValue( '2' );

fireEvent.blur( maxInput, { target: { value: '11' } } );
expect( maxInput ).toHaveValue( '11' );

const submitButton = getByRole( 'button', {
name: 'Add shipping time',
} );

expect( submitButton ).toBeEnabled();

fireEvent.click( submitButton );

await waitFor( () => {
expect( onSubmit ).toHaveBeenCalledTimes( 1 );
} );

expect( onSubmit ).toHaveBeenCalledWith( {
countries: [ 'ES' ],
time: 2,
maxTime: 11,
} );
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Form } from '@woocommerce/components';
import { Flex, FlexItem } from '@wordpress/components';

/**
* Internal dependencies
*/
import AppButton from '.~/components/app-button';
import AppModal from '.~/components/app-modal';
import AppInputNumberControl from '.~/components/app-input-number-control';
import VerticalGapLayout from '.~/components/vertical-gap-layout';
import SupportedCountrySelect from '.~/components/supported-country-select';
import validateShippingTimeGroup from '.~/utils/validateShippingTimeGroup';
import MinMaxShippingTimes from '../../../min-max-inputs';
import '../index.scss';

/**
*Form to edit time for selected country(-ies).
Expand Down Expand Up @@ -63,13 +65,19 @@ const EditTimeModal = ( {
onSubmit={ handleSubmitCallback }
>
{ ( formProps ) => {
const { getInputProps, isValidForm, handleSubmit } = formProps;
const { getInputProps, isValidForm, handleSubmit, errors } =
formProps;

const handleIncrement = ( numberValue, field ) => {
getInputProps( field ).onChange( numberValue );
};

return (
<AppModal
overflow="visible"
shouldCloseOnEsc={ ! dropdownVisible }
shouldCloseOnClickOutside={ ! dropdownVisible }
className="gla-edit-time-modal"
title={ __(
'Estimate shipping time',
'google-listings-and-ads'
Expand Down Expand Up @@ -110,29 +118,31 @@ const EditTimeModal = ( {
{ ...getInputProps( 'countries' ) }
/>

<AppInputNumberControl
label={ __(
'Then the minimum estimated shipping time displayed in the product listing is',
'google-listings-and-ads'
) }
suffix={ __(
'days',
<div className="label">
{ __(
'Then the estimated shipping times displayed in the product listing are',
'google-listings-and-ads'
) }
{ ...getInputProps( 'time' ) }
/>
</div>

<AppInputNumberControl
label={ __(
'And the maximum time is',
'google-listings-and-ads'
) }
suffix={ __(
'days',
'google-listings-and-ads'
) }
{ ...getInputProps( 'maxTime' ) }
/>
<Flex
direction="column"
className="gla-countries-time-input-container"
>
<FlexItem>
<MinMaxShippingTimes
time={ getInputProps( 'time' ).value }
maxTime={
getInputProps( 'maxTime' ).value
}
handleBlur={ handleIncrement }
handleIncrement={ handleIncrement }
/>
<ul className="gla-validation-errors">
<li>{ errors.time }</li>
</ul>
</FlexItem>
</Flex>
</VerticalGapLayout>
</AppModal>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* External dependencies
*/
import '@testing-library/jest-dom';
import { render, fireEvent, waitFor } from '@testing-library/react';

/**
* Internal dependencies
*/
import EditTimeModal from './index';
import useMCCountryTreeOptions from '.~/components/supported-country-select/useMCCountryTreeOptions';

jest.mock( '.~/components/supported-country-select/useMCCountryTreeOptions' );

describe( 'Edit time Modal', () => {
it( 'The min and max shipping time inputs should be displayed, and both values should be submitted', async () => {
const onSubmit = jest.fn();

useMCCountryTreeOptions.mockImplementation( () => {
return [
{
value: 'EU',
label: 'Europe',
children: [
{
value: 'ES',
label: 'Spain',
parent: 'EU',
},
],
},
];
} );

const { getByRole, getAllByRole } = render(
<EditTimeModal
audienceCountries={ [ 'ES' ] }
time={ { countries: [ 'ES' ], time: 1, maxTime: 9 } }
onRequestClose={ jest.fn() }
onSubmit={ onSubmit }
onDelete={ jest.fn() }
/>
);

const inputs = getAllByRole( 'textbox' );
// it should render 2 inputs ( the min and max shipping time inputs )
expect( inputs ).toHaveLength( 2 );

const [ minInput, maxInput ] = inputs;

expect( minInput ).toHaveValue( '1' );
expect( maxInput ).toHaveValue( '9' );

fireEvent.blur( minInput, { target: { value: '2' } } );
expect( minInput ).toHaveValue( '2' );

fireEvent.blur( maxInput, { target: { value: '11' } } );
expect( maxInput ).toHaveValue( '11' );

const submitButton = getByRole( 'button', {
name: 'Update shipping time',
} );

expect( submitButton ).toBeEnabled();

fireEvent.click( submitButton );

await waitFor( () => {
expect( onSubmit ).toHaveBeenCalledTimes( 1 );
} );

expect( onSubmit ).toHaveBeenCalledWith(
{ countries: [ 'ES' ], time: 2, maxTime: 11 },
[]
);
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
padding: 0;
}
}

.gla-edit-time-modal .gla-countries-time-stepper .components-input-control {
margin-bottom: 0;
}
Loading

0 comments on commit d23fcd9

Please sign in to comment.