Skip to content

Commit

Permalink
Refactor deleteEntityRecord to use thunks instead of generators (#34386)
Browse files Browse the repository at this point in the history
* Refactor deleteEntityRecord to use thunks instead of generators

* Remove await from two synchronous dispatch calls

* Adjust tests
  • Loading branch information
adamziel authored Sep 1, 2021
1 parent 412b015 commit 06f2447
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 57 deletions.
2 changes: 1 addition & 1 deletion docs/reference-guides/data/data-core.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ _Parameters_
- _recordId_ `string`: Record ID of the deleted entity.
- _query_ `?Object`: Special query parameters for the DELETE API call.
- _options_ `[Object]`: Delete options.
- _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a control descriptor.
- _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a promise.

### editEntityRecord

Expand Down
2 changes: 1 addition & 1 deletion packages/core-data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ _Parameters_
- _recordId_ `string`: Record ID of the deleted entity.
- _query_ `?Object`: Special query parameters for the DELETE API call.
- _options_ `[Object]`: Delete options.
- _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a control descriptor.
- _options.\_\_unstableFetch_ `[Function]`: Internal use only. Function to call instead of `apiFetch()`. Must return a promise.

### editEntityRecord

Expand Down
45 changes: 16 additions & 29 deletions packages/core-data/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { v4 as uuid } from 'uuid';
* WordPress dependencies
*/
import { controls } from '@wordpress/data';
import { apiFetch, __unstableAwaitPromise } from '@wordpress/data-controls';
import { __unstableAwaitPromise } from '@wordpress/data-controls';
import triggerFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';

Expand Down Expand Up @@ -162,38 +162,36 @@ export function receiveEmbedPreview( url, preview ) {
* @param {Object} [options] Delete options.
* @param {Function} [options.__unstableFetch] Internal use only. Function to
* call instead of `apiFetch()`.
* Must return a control descriptor.
* Must return a promise.
*/
export function* deleteEntityRecord(
export const deleteEntityRecord = (
kind,
name,
recordId,
query,
{ __unstableFetch = null } = {}
) {
const entities = yield getKindEntities( kind );
{ __unstableFetch = triggerFetch } = {}
) => async ( { dispatch } ) => {
const entities = await dispatch( getKindEntities( kind ) );
const entity = find( entities, { kind, name } );
let error;
let deletedRecord = false;
if ( ! entity ) {
return;
}

const lock = yield controls.dispatch(
STORE_NAME,
'__unstableAcquireStoreLock',
const lock = await dispatch.__unstableAcquireStoreLock(
STORE_NAME,
[ 'entities', 'data', kind, name, recordId ],
{ exclusive: true }
);

try {
yield {
dispatch( {
type: 'DELETE_ENTITY_RECORD_START',
kind,
name,
recordId,
};
} );

try {
let path = `${ entity.baseURL }/${ recordId }`;
Expand All @@ -202,40 +200,29 @@ export function* deleteEntityRecord(
path = addQueryArgs( path, query );
}

const options = {
deletedRecord = await __unstableFetch( {
path,
method: 'DELETE',
};
if ( __unstableFetch ) {
deletedRecord = yield __unstableAwaitPromise(
__unstableFetch( options )
);
} else {
deletedRecord = yield apiFetch( options );
}
} );

yield removeItems( kind, name, recordId, true );
await dispatch( removeItems( kind, name, recordId, true ) );
} catch ( _error ) {
error = _error;
}

yield {
dispatch( {
type: 'DELETE_ENTITY_RECORD_FINISH',
kind,
name,
recordId,
error,
};
} );

return deletedRecord;
} finally {
yield controls.dispatch(
STORE_NAME,
'__unstableReleaseStoreLock',
lock
);
dispatch.__unstableReleaseStoreLock( lock );
}
}
};

/**
* Returns an action object that triggers an
Expand Down
68 changes: 42 additions & 26 deletions packages/core-data/src/test/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,46 +49,62 @@ describe( 'editEntityRecord', () => {
} );

describe( 'deleteEntityRecord', () => {
beforeEach( async () => {
apiFetch.mockReset();
jest.useFakeTimers();
} );

it( 'triggers a DELETE request for an existing record', async () => {
const post = 10;
const deletedRecord = { title: 'new post', id: 10 };
const entities = [
{ name: 'post', kind: 'postType', baseURL: '/wp/v2/posts' },
];
const fulfillment = deleteEntityRecord( 'postType', 'post', post );

// Trigger generator
fulfillment.next();
const dispatch = Object.assign( jest.fn(), {
receiveEntityRecords: jest.fn(),
__unstableAcquireStoreLock: jest.fn(),
__unstableReleaseStoreLock: jest.fn(),
} );
// Provide entities
dispatch.mockReturnValueOnce( entities );

// Acquire lock
expect( fulfillment.next( entities ).value.type ).toBe(
'@@data/DISPATCH'
);
// Provide response
apiFetch.mockImplementation( () => deletedRecord );

// Start
expect( fulfillment.next().value.type ).toEqual(
'DELETE_ENTITY_RECORD_START'
);
const result = await deleteEntityRecord(
'postType',
'post',
deletedRecord.id
)( { dispatch } );

// delete api call
const { value: apiFetchAction } = fulfillment.next();
expect( apiFetchAction.request ).toEqual( {
expect( apiFetch ).toHaveBeenCalledTimes( 1 );
expect( apiFetch ).toHaveBeenCalledWith( {
path: '/wp/v2/posts/10',
method: 'DELETE',
} );

expect( fulfillment.next().value.type ).toBe( 'REMOVE_ITEMS' );

expect( fulfillment.next().value.type ).toBe(
'DELETE_ENTITY_RECORD_FINISH'
expect( dispatch ).toHaveBeenCalledTimes( 4 );
expect( dispatch ).toHaveBeenCalledWith( {
type: 'DELETE_ENTITY_RECORD_START',
kind: 'postType',
name: 'post',
recordId: 10,
} );
expect( dispatch ).toHaveBeenCalledWith( {
type: 'DELETE_ENTITY_RECORD_FINISH',
kind: 'postType',
name: 'post',
recordId: 10,
error: undefined,
} );
expect( dispatch.__unstableAcquireStoreLock ).toHaveBeenCalledTimes(
1
);
expect( dispatch.__unstableReleaseStoreLock ).toHaveBeenCalledTimes(
1
);

// Release lock
expect( fulfillment.next().value.type ).toEqual( '@@data/DISPATCH' );

expect( fulfillment.next() ).toMatchObject( {
done: true,
value: undefined,
} );
expect( result ).toBe( deletedRecord );
} );
} );

Expand Down

0 comments on commit 06f2447

Please sign in to comment.