Skip to content

Commit

Permalink
Moves the state and functions associated with the request verificatio…
Browse files Browse the repository at this point in the history
…n from `CampaignAssetsForm` to `AdaptiveForm`
  • Loading branch information
eason9487 committed Jul 14, 2023
1 parent e780106 commit 534657d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 7 deletions.
4 changes: 4 additions & 0 deletions js/src/components/adaptive-form/adaptive-form-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ import { createContext, useContext } from '@wordpress/element';
* @property {boolean} isSubmitting `true` if the form is currently being submitted.
* @property {boolean} isSubmitted Set to `true` after the form is submitted. Initial value and during submission are set to `false`.
* @property { HTMLElement | null} submitter Set to the element triggering the `handleSubmit` callback until the processing of `onSubmit` is completed. `null` otherwise.
* @property {number} validationRequestCount The current validation request count.
* @property {boolean} requestedShowValidation Whether have requested verification. It will be reset to false after calling hideValidation.
* @property {() => void} showValidation Increase the validation request count by 1.
* @property {() => void} hideValidation Reset the validation request count to 0.
*/

/**
Expand Down
13 changes: 13 additions & 0 deletions js/src/components/adaptive-form/adaptive-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ function AdaptiveForm( { onSubmit, extendAdapter, children, ...props }, ref ) {

const isMounted = useIsMounted();

// Add states for form user sides to determine whether to show validation results.
const [ validationRequestCount, setValidationRequestCount ] = useState( 0 );
const showValidation = useCallback( () => {
setValidationRequestCount( ( count ) => count + 1 );
}, [] );
const hideValidation = useCallback( () => {
setValidationRequestCount( 0 );
}, [] );

// Add `isSubmitting` and `isSubmitted` states for facilitating across multiple layers of
// component controlling, such as disabling inputs or buttons.
const [ submission, setSubmission ] = useState( null );
Expand Down Expand Up @@ -208,6 +217,10 @@ function AdaptiveForm( { onSubmit, extendAdapter, children, ...props }, ref ) {
isSubmitting,
isSubmitted,
submitter: adapterRef.current.submitter,
validationRequestCount,
requestedShowValidation: validationRequestCount > 0,
showValidation,
hideValidation,
};

if ( typeof extendAdapter === 'function' ) {
Expand Down
50 changes: 49 additions & 1 deletion js/src/components/adaptive-form/adaptive-form.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const alwaysValid = () => ( {} );
const delayOneSecond = () => new Promise( ( r ) => setTimeout( r, 1000 ) );

describe( 'AdaptiveForm', () => {
it( 'Should have `formContext.adapter` with initial states', () => {
it( 'Should have `formContext.adapter` with functions and initial states', () => {
const children = jest.fn();

render(
Expand All @@ -27,6 +27,10 @@ describe( 'AdaptiveForm', () => {
isSubmitting: false,
isSubmitted: false,
submitter: null,
validationRequestCount: 0,
requestedShowValidation: false,
showValidation: expect.any( Function ),
hideValidation: expect.any( Function ),
} ),
} );

Expand Down Expand Up @@ -148,4 +152,48 @@ describe( 'AdaptiveForm', () => {
expect.objectContaining( { submitter: buttonB } )
);
} );

it( 'Should be able to accumulate and reset the validation request count and requested state', async () => {
const inspect = jest.fn();

render(
<AdaptiveForm validate={ alwaysValid }>
{ ( { adapter } ) => {
inspect(
adapter.requestedShowValidation,
adapter.validationRequestCount
);

return (
<>
<button onClick={ adapter.showValidation }>
request
</button>

<button onClick={ adapter.hideValidation }>
reset
</button>
</>
);
} }
</AdaptiveForm>
);

const requestButton = screen.getByRole( 'button', { name: 'request' } );
const resetButton = screen.getByRole( 'button', { name: 'reset' } );

expect( inspect ).toHaveBeenLastCalledWith( false, 0 );

await userEvent.click( requestButton );

expect( inspect ).toHaveBeenLastCalledWith( true, 1 );

await userEvent.click( requestButton );

expect( inspect ).toHaveBeenLastCalledWith( true, 2 );

await userEvent.click( resetButton );

expect( inspect ).toHaveBeenLastCalledWith( false, 0 );
} );
} );
7 changes: 1 addition & 6 deletions js/src/components/paid-ads/campaign-assets-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ export default function CampaignAssetsForm( {
}, [ assetEntityGroup ] );

const [ baseAssetGroup, setBaseAssetGroup ] = useState( initialAssetGroup );
const [ validationRequestCount, setValidationRequestCount ] = useState( 0 );
const [ hasImportedAssets, setHasImportedAssets ] = useState( false );

const extendAdapter = ( formContext ) => {
Expand All @@ -89,7 +88,6 @@ export default function CampaignAssetsForm( {
// provide different special business logic.
isEmptyAssetEntityGroup: ! finalUrl,
baseAssetGroup,
validationRequestCount,
assetGroupErrors,
/*
In order to show a Tip in the UI when assets are imported we created the hasImportedAssets
Expand All @@ -111,10 +109,7 @@ export default function CampaignAssetsForm( {

setHasImportedAssets( hasNonEmptyAssets );
setBaseAssetGroup( nextAssetGroup );
setValidationRequestCount( 0 );
},
showValidation() {
setValidationRequestCount( validationRequestCount + 1 );
formContext.adapter.hideValidation();
},
};
};
Expand Down

0 comments on commit 534657d

Please sign in to comment.