diff --git a/bin/update-readmes.js b/bin/update-readmes.js index 63d041e7ab509..7d96e68adce03 100755 --- a/bin/update-readmes.js +++ b/bin/update-readmes.js @@ -17,6 +17,7 @@ const packages = [ 'Autogenerated selectors': 'src/selectors.js', } ], 'data', + 'data-controls', 'date', 'deprecated', 'dom', diff --git a/docs/manifest-devhub.json b/docs/manifest-devhub.json index 09544a23854c3..2095e773664bb 100644 --- a/docs/manifest-devhub.json +++ b/docs/manifest-devhub.json @@ -1079,6 +1079,12 @@ "markdown_source": "../packages/custom-templated-path-webpack-plugin/README.md", "parent": "packages" }, + { + "title": "@wordpress/data-controls", + "slug": "packages-data-controls", + "markdown_source": "../packages/data-controls/README.md", + "parent": "packages" + }, { "title": "@wordpress/data", "slug": "packages-data", diff --git a/docs/manifest.json b/docs/manifest.json index 594d3504a50dc..429fd5bc835ae 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -287,6 +287,12 @@ "markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/packages/custom-templated-path-webpack-plugin/README.md", "parent": "packages" }, + { + "title": "@wordpress/data-controls", + "slug": "packages-data-controls", + "markdown_source": "https://raw.githubusercontent.com/WordPress/gutenberg/master/packages/data-controls/README.md", + "parent": "packages" + }, { "title": "@wordpress/data", "slug": "packages-data", diff --git a/package-lock.json b/package-lock.json index 787fab54e81be..2b1826f94d929 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3107,6 +3107,13 @@ "turbo-combine-reducers": "^1.0.2" } }, + "@wordpress/data-controls": { + "version": "file:packages/data-controls", + "requires": { + "@wordpress/api-fetch": "file:packages/api-fetch", + "@wordpress/data": "file:packages/data" + } + }, "@wordpress/date": { "version": "file:packages/date", "requires": { @@ -3245,6 +3252,7 @@ "@wordpress/compose": "file:packages/compose", "@wordpress/core-data": "file:packages/core-data", "@wordpress/data": "file:packages/data", + "@wordpress/data-controls": "file:packages/data-controls", "@wordpress/date": "file:packages/date", "@wordpress/deprecated": "file:packages/deprecated", "@wordpress/element": "file:packages/element", diff --git a/package.json b/package.json index c9474bcfdc3e5..f43c1e4cf0864 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@wordpress/compose": "file:packages/compose", "@wordpress/core-data": "file:packages/core-data", "@wordpress/data": "file:packages/data", + "@wordpress/data-controls": "file:packages/data-controls", "@wordpress/date": "file:packages/date", "@wordpress/deprecated": "file:packages/deprecated", "@wordpress/dom": "file:packages/dom", diff --git a/packages/data-controls/CHANGELOG.md b/packages/data-controls/CHANGELOG.md new file mode 100644 index 0000000000000..dff204f06c92d --- /dev/null +++ b/packages/data-controls/CHANGELOG.md @@ -0,0 +1,3 @@ +# Master + +Initial release of the @wordpress/data-controls package. diff --git a/packages/data-controls/README.md b/packages/data-controls/README.md new file mode 100644 index 0000000000000..08b822fe67967 --- /dev/null +++ b/packages/data-controls/README.md @@ -0,0 +1,136 @@ +# Data Controls + +The data controls module is a module intended to simplify implementation of common controls used with the [`@wordpress/data`](/packages/data/README.md) package. + +**Note:** It is assumed that the registry being used has the controls plugin enabled on it (see [more details on controls here](https://github.com/WordPress/gutenberg/tree/master/packages/data#controls)) + +## Installation + +Install the module + +```bash +npm install @wordpress/data-controls --save +``` + + _This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. Learn more about it in [Babel docs](https://babeljs.io/docs/en/next/caveats)._ + +The following controls are available on the object returned by the module: + +## API + + + +# **apiFetch** + +Dispatches a control action for triggering an api fetch call. + +_Usage_ + +```js +import { apiFetch } from '@wordpress/data-controls'; + +// Action generator using apiFetch +export function* myAction { + const path = '/v2/my-api/items'; + const items = yield apiFetch( { path } ); + // do something with the items. +} +``` + +_Parameters_ + +- _request_ `Object`: Arguments for the fetch request. + +_Returns_ + +- `Object`: The control descriptor. + +# **controls** + +The default export is what you use to register the controls with your custom +store. + +_Usage_ + +```js +// WordPress dependencies +import { controls } from '@wordpress/data-controls'; +import { registerStore } from '@wordpress/data'; + +// Internal dependencies +import reducer from './reducer'; +import * as selectors from './selectors'; +import * as actions from './actions'; +import * as resolvers from './resolvers'; + +registerStore ( 'my-custom-store', { + reducer, + controls, + actions, + selectors, + resolvers, +} ); +``` + +_Returns_ + +- `Object`: An object for registering the default controls with the store. + +# **dispatch** + +Dispatches a control action for triggering a registry dispatch. + +_Usage_ + +```js +import { dispatch } from '@wordpress/data-controls'; + +// Action generator using dispatch +export function* myAction { + yield dispatch( 'core/edit-post' ).togglePublishSidebar(); + // do some other things. +} +``` + +_Parameters_ + +- _storeKey_ `string`: The key for the store the action belongs to +- _actionName_ `string`: The name of the action to dispatch +- _args_ `Array`: Arguments for the dispatch action. + +_Returns_ + +- `Object`: The control descriptor. + +# **select** + +Dispatches a control action for triggering a registry select. + +Note: when this control action is handled, it automatically considers +selectors that may have a resolver. It will await and return the resolved +value when the selector has not been resolved yet. + +_Usage_ + +```js +import { select } from '@wordpress/data-controls'; + +// Action generator using select +export function* myAction { + const isSidebarOpened = yield select( 'core/edit-post', 'isEditorSideBarOpened' ); + // do stuff with the result from the select. +} +``` + +_Parameters_ + +- _storeKey_ `string`: The key for the store the selector belongs to +- _selectorName_ `string`: The name of the selector +- _args_ `Array`: Arguments for the select. + +_Returns_ + +- `Object`: The control descriptor. + + + diff --git a/packages/data-controls/package.json b/packages/data-controls/package.json new file mode 100644 index 0000000000000..9ffbf80cd5165 --- /dev/null +++ b/packages/data-controls/package.json @@ -0,0 +1,31 @@ +{ + "name": "@wordpress/data-controls", + "version": "1.0.0-beta.1", + "description": "A set of common controls for the @wordpress/data api.", + "author": "The WordPress Contributors", + "license": "GPL-2.0-or-later", + "keywords": [ + "wordpress", + "data", + "controls" + ], + "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/data-controls/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/data-controls" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "main": "build/index.js", + "module": "build-module/index.js", + "react-native": "src/index", + "dependencies": { + "@wordpress/api-fetch": "file:../api-fetch", + "@wordpress/data": "file:../data" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/data-controls/src/index.js b/packages/data-controls/src/index.js new file mode 100644 index 0000000000000..c209b3397b4fa --- /dev/null +++ b/packages/data-controls/src/index.js @@ -0,0 +1,171 @@ +/** + * WordPress dependencies + */ +import triggerFetch from '@wordpress/api-fetch'; +import { createRegistryControl } from '@wordpress/data'; + +/** + * Dispatches a control action for triggering an api fetch call. + * + * @param {Object} request Arguments for the fetch request. + * + * @example + * ```js + * import { apiFetch } from '@wordpress/data-controls'; + * + * // Action generator using apiFetch + * export function* myAction { + * const path = '/v2/my-api/items'; + * const items = yield apiFetch( { path } ); + * // do something with the items. + * } + * ``` + * + * @return {Object} The control descriptor. + */ +export const apiFetch = ( request ) => { + return { + type: 'API_FETCH', + request, + }; +}; + +/** + * Dispatches a control action for triggering a registry select. + * + * Note: when this control action is handled, it automatically considers + * selectors that may have a resolver. It will await and return the resolved + * value when the selector has not been resolved yet. + * + * @param {string} storeKey The key for the store the selector belongs to + * @param {string} selectorName The name of the selector + * @param {Array} args Arguments for the select. + * + * @example + * ```js + * import { select } from '@wordpress/data-controls'; + * + * // Action generator using select + * export function* myAction { + * const isSidebarOpened = yield select( 'core/edit-post', 'isEditorSideBarOpened' ); + * // do stuff with the result from the select. + * } + * ``` + * + * @return {Object} The control descriptor. + */ +export function select( storeKey, selectorName, ...args ) { + return { + type: 'SELECT', + storeKey, + selectorName, + args, + }; +} + +/** + * Dispatches a control action for triggering a registry dispatch. + * + * @param {string} storeKey The key for the store the action belongs to + * @param {string} actionName The name of the action to dispatch + * @param {Array} args Arguments for the dispatch action. + * + * @example + * ```js + * import { dispatch } from '@wordpress/data-controls'; + * + * // Action generator using dispatch + * export function* myAction { + * yield dispatch( 'core/edit-post' ).togglePublishSidebar(); + * // do some other things. + * } + * ``` + * + * @return {Object} The control descriptor. + */ +export function dispatch( storeKey, actionName, ...args ) { + return { + type: 'DISPATCH', + storeKey, + actionName, + args, + }; +} + +/** + * Utility for returning a promise that handles a selector with a resolver. + * + * @param {Object} registry The data registry. + * @param {string} storeKey The store the selector belongs to + * @param {string} selectorName The selector name + * @param {Array} args The arguments fed to the selector + * + * @return {Promise} A promise for resolving the given selector. + */ +const resolveSelect = ( registry, { storeKey, selectorName, args } ) => { + return new Promise( ( resolve ) => { + const hasFinished = () => registry.select( 'core/data' ) + .hasFinishedResolution( storeKey, selectorName, args ); + const getResult = () => registry.select( storeKey )[ selectorName ] + .apply( null, args ); + + // trigger the selector (to trigger the resolver) + const result = getResult(); + if ( hasFinished() ) { + return resolve( result ); + } + + const unsubscribe = registry.subscribe( () => { + if ( hasFinished() ) { + unsubscribe(); + resolve( getResult() ); + } + } ); + } ); +}; + +/** + * The default export is what you use to register the controls with your custom + * store. + * + * @example + * ```js + * // WordPress dependencies + * import { controls } from '@wordpress/data-controls'; + * import { registerStore } from '@wordpress/data'; + * + * // Internal dependencies + * import reducer from './reducer'; + * import * as selectors from './selectors'; + * import * as actions from './actions'; + * import * as resolvers from './resolvers'; + * + * registerStore ( 'my-custom-store', { + * reducer, + * controls, + * actions, + * selectors, + * resolvers, + * } ); + * ``` + * + * @return {Object} An object for registering the default controls with the + * store. + */ +export const controls = { + API_FETCH( { request } ) { + return triggerFetch( request ); + }, + SELECT: createRegistryControl( + ( registry ) => ( { storeKey, selectorName, args } ) => { + return registry.select( storeKey )[ selectorName ].hasResolver ? + resolveSelect( registry, { storeKey, selectorName, args } ) : + registry.select( storeKey )[ selectorName ]( ...args ); + } + ), + DISPATCH: createRegistryControl( + ( registry ) => ( { storeKey, actionName, args } ) => { + return registry.dispatch( storeKey )[ actionName ]( ...args ); + } + ), +}; diff --git a/packages/data-controls/src/test/index.js b/packages/data-controls/src/test/index.js new file mode 100644 index 0000000000000..fcd6650352af1 --- /dev/null +++ b/packages/data-controls/src/test/index.js @@ -0,0 +1,146 @@ +/** + * WordPress dependencies + */ +import triggerFetch from '@wordpress/api-fetch'; + +jest.mock( '@wordpress/api-fetch' ); + +/** + * Internal dependencies + */ +import { controls } from '../index'; + +describe( 'controls', () => { + describe( 'API_FETCH', () => { + afterEach( () => { + triggerFetch.mockClear(); + } ); + it( 'invokes the triggerFetch function', () => { + controls.API_FETCH( { request: '' } ); + expect( triggerFetch ).toHaveBeenCalledTimes( 1 ); + } ); + it( 'invokes the triggerFetch funcion with the passed in request', () => { + controls.API_FETCH( { request: 'foo' } ); + expect( triggerFetch ).toHaveBeenCalledWith( 'foo' ); + } ); + } ); + describe( 'SELECT', () => { + const selectorWithUndefinedResolver = jest.fn(); + const selectorWithResolver = jest.fn(); + selectorWithResolver.hasResolver = true; + const selectorWithFalseResolver = jest.fn(); + selectorWithFalseResolver.hasResolver = false; + const hasFinishedResolution = jest.fn(); + const unsubscribe = jest.fn(); + let subscribedCallback; + const registryMock = { + select: ( storeKey ) => { + const stores = { + mockStore: { + selectorWithResolver, + selectorWithUndefinedResolver, + selectorWithFalseResolver, + }, + 'core/data': { + hasFinishedResolution, + }, + }; + return stores[ storeKey ]; + }, + subscribe: jest.fn( + ( subscribeCallback ) => { + subscribedCallback = subscribeCallback; + return unsubscribe; + } + ), + }; + const getSelectorArgs = ( storeKey, selectorName, ...args ) => ( + { storeKey, selectorName, args } + ); + beforeEach( () => { + selectorWithUndefinedResolver.mockReturnValue( 'foo' ); + selectorWithFalseResolver.mockReturnValue( 'bar' ); + selectorWithResolver.mockReturnValue( 'resolved' ); + hasFinishedResolution.mockReturnValue( false ); + } ); + afterEach( () => { + selectorWithUndefinedResolver.mockClear(); + selectorWithResolver.mockClear(); + selectorWithFalseResolver.mockClear(); + hasFinishedResolution.mockClear(); + unsubscribe.mockClear(); + } ); + it( 'invokes selector with undefined resolver', () => { + const testControl = controls.SELECT( registryMock ); + const value = testControl( getSelectorArgs( + 'mockStore', + 'selectorWithUndefinedResolver' + ) ); + expect( value ).toBe( 'foo' ); + expect( selectorWithUndefinedResolver ).toHaveBeenCalled(); + expect( hasFinishedResolution ).not.toHaveBeenCalled(); + } ); + it( 'invokes selector with resolver set to false', () => { + const testControl = controls.SELECT( registryMock ); + const value = testControl( getSelectorArgs( + 'mockStore', + 'selectorWithFalseResolver' + ) ); + expect( value ).toBe( 'bar' ); + expect( selectorWithFalseResolver ).toHaveBeenCalled(); + expect( hasFinishedResolution ).not.toHaveBeenCalled(); + } ); + describe( 'invokes selector with resolver set to true', () => { + const testControl = controls.SELECT( registryMock ); + it( 'returns a promise', () => { + const value = testControl( getSelectorArgs( + 'mockStore', + 'selectorWithResolver' + ) ); + expect( value ).toBeInstanceOf( Promise ); + expect( hasFinishedResolution ).toHaveBeenCalled(); + expect( registryMock.subscribe ).toHaveBeenCalled(); + } ); + it( 'selector with resolver resolves to expected result when ' + + 'finished', async () => { + const value = testControl( getSelectorArgs( + 'mockStore', + 'selectorWithResolver' + ) ); + hasFinishedResolution.mockReturnValue( true ); + subscribedCallback(); + await expect( value ).resolves.toBe( 'resolved' ); + expect( unsubscribe ).toHaveBeenCalled(); + } ); + } ); + } ); + describe( 'DISPATCH', () => { + const mockDispatch = jest.fn(); + const registryMock = { + dispatch: ( storeKey ) => { + const stores = { + mockStore: { + mockDispatch, + }, + }; + return stores[ storeKey ]; + }, + }; + beforeEach( () => { + mockDispatch.mockReturnValue( 'foo' ); + } ); + afterEach( () => { + mockDispatch.mockClear(); + } ); + it( 'invokes dispatch action', () => { + const testControl = controls.DISPATCH( registryMock ); + const value = testControl( { + storeKey: 'mockStore', + actionName: 'mockDispatch', + args: [], + } ); + expect( value ).toBe( 'foo' ); + expect( mockDispatch ).toHaveBeenCalled(); + } ); + } ); +} ); diff --git a/packages/editor/CHANGELOG.md b/packages/editor/CHANGELOG.md index da86f36a1209a..d37f22323ec95 100644 --- a/packages/editor/CHANGELOG.md +++ b/packages/editor/CHANGELOG.md @@ -8,6 +8,7 @@ - Refactor setupEditor effects to action-generator using controls ([#14513](https://github.com/WordPress/gutenberg/pull/14513)) - Remove redux-multi dependency (no longer needed/used with above refactor) +- Replace internal controls definitions with usage of new @wordpress/data-controls package (see [#15435](https://github.com/WordPress/gutenberg/pull/15435) ## 9.1.0 (2019-03-06) diff --git a/packages/editor/package.json b/packages/editor/package.json index af327112ade9e..74384ff0ce390 100644 --- a/packages/editor/package.json +++ b/packages/editor/package.json @@ -30,6 +30,7 @@ "@wordpress/compose": "file:../compose", "@wordpress/core-data": "file:../core-data", "@wordpress/data": "file:../data", + "@wordpress/data-controls": "file:../data-controls", "@wordpress/date": "file:../date", "@wordpress/deprecated": "file:../deprecated", "@wordpress/element": "file:../element", diff --git a/packages/editor/src/store/actions.js b/packages/editor/src/store/actions.js index 52f021d1a2f83..4c340057c6471 100644 --- a/packages/editor/src/store/actions.js +++ b/packages/editor/src/store/actions.js @@ -8,16 +8,15 @@ import { BEGIN, COMMIT, REVERT } from 'redux-optimist'; * WordPress dependencies */ import deprecated from '@wordpress/deprecated'; +import { dispatch, select, apiFetch } from '@wordpress/data-controls'; +import { + parse, + synchronizeBlocksWithTemplate, +} from '@wordpress/blocks'; /** * Internal dependencies */ -import { - dispatch, - select, - resolveSelect, - apiFetch, -} from './controls'; import { getPostRawValue, } from './reducer'; @@ -34,14 +33,6 @@ import { getNotificationArgumentsForTrashFail, } from './utils/notice-builder'; -/** - * WordPress dependencies - */ -import { - parse, - synchronizeBlocksWithTemplate, -} from '@wordpress/blocks'; - /** * Returns an action generator used in signalling that editor has initialized with * the specified post object and editor settings. @@ -323,7 +314,7 @@ export function* savePost( options = {} ) { 'getCurrentPostType' ); - const postType = yield resolveSelect( + const postType = yield select( 'core', 'getPostType', currentPostType @@ -347,9 +338,9 @@ export function* savePost( options = {} ) { let path = `/wp/v2/${ postType.rest_base }/${ post.id }`; let method = 'PUT'; if ( isAutosave ) { - const currentUser = yield resolveSelect( 'core', 'getCurrentUser' ); + const currentUser = yield select( 'core', 'getCurrentUser' ); const currentUserId = currentUser ? currentUser.id : undefined; - const autosavePost = yield resolveSelect( 'core', 'getAutosave', post.type, post.id, currentUserId ); + const autosavePost = yield select( 'core', 'getAutosave', post.type, post.id, currentUserId ); const mappedAutosavePost = mapValues( pick( autosavePost, AUTOSAVE_PROPERTIES ), getPostRawValue ); // Ensure autosaves contain all expected fields, using autosave or @@ -448,7 +439,7 @@ export function* refreshPost() { STORE_KEY, 'getCurrentPostType' ); - const postType = yield resolveSelect( + const postType = yield select( 'core', 'getPostType', postTypeSlug @@ -476,7 +467,7 @@ export function* trashPost() { STORE_KEY, 'getCurrentPostType' ); - const postType = yield resolveSelect( + const postType = yield select( 'core', 'getPostType', postTypeSlug diff --git a/packages/editor/src/store/controls.js b/packages/editor/src/store/controls.js deleted file mode 100644 index 597a5f726145b..0000000000000 --- a/packages/editor/src/store/controls.js +++ /dev/null @@ -1,113 +0,0 @@ -/** - * WordPress dependencies - */ -import triggerFetch from '@wordpress/api-fetch'; -import { createRegistryControl } from '@wordpress/data'; - -/** - * Dispatches a control action for triggering an api fetch call. - * - * @param {Object} request Arguments for the fetch request. - * - * @return {Object} control descriptor. - */ -export function apiFetch( request ) { - return { - type: 'API_FETCH', - request, - }; -} - -/** - * Dispatches a control action for triggering a registry select. - * - * @param {string} storeKey - * @param {string} selectorName - * @param {Array} args Arguments for the select. - * - * @return {Object} control descriptor. - */ -export function select( storeKey, selectorName, ...args ) { - return { - type: 'SELECT', - storeKey, - selectorName, - args, - }; -} - -/** - * Dispatches a control action for triggering a registry select that has a - * resolver. - * - * @param {string} storeKey - * @param {string} selectorName - * @param {Array} args Arguments for the select. - * - * @return {Object} control descriptor. - */ -export function resolveSelect( storeKey, selectorName, ...args ) { - return { - type: 'RESOLVE_SELECT', - storeKey, - selectorName, - args, - }; -} - -/** - * Dispatches a control action for triggering a registry dispatch. - * - * @param {string} storeKey - * @param {string} actionName - * @param {Array} args Arguments for the dispatch action. - * - * @return {Object} control descriptor. - */ -export function dispatch( storeKey, actionName, ...args ) { - return { - type: 'DISPATCH', - storeKey, - actionName, - args, - }; -} - -export default { - API_FETCH( { request } ) { - return triggerFetch( request ); - }, - SELECT: createRegistryControl( - ( registry ) => ( { storeKey, selectorName, args } ) => { - return registry.select( storeKey )[ selectorName ]( ...args ); - } - ), - DISPATCH: createRegistryControl( - ( registry ) => ( { storeKey, actionName, args } ) => { - return registry.dispatch( storeKey )[ actionName ]( ...args ); - } - ), - RESOLVE_SELECT: createRegistryControl( - ( registry ) => ( { storeKey, selectorName, args } ) => { - return new Promise( ( resolve ) => { - const hasFinished = () => registry.select( 'core/data' ) - .hasFinishedResolution( storeKey, selectorName, args ); - const getResult = () => registry.select( storeKey )[ selectorName ] - .apply( null, args ); - - // trigger the selector (to trigger the resolver) - const result = getResult(); - if ( hasFinished() ) { - return resolve( result ); - } - - const unsubscribe = registry.subscribe( () => { - if ( hasFinished() ) { - unsubscribe(); - resolve( getResult() ); - } - } ); - } ); - } - ), -}; diff --git a/packages/editor/src/store/index.js b/packages/editor/src/store/index.js index 42af629bcce0d..1ba136aaab722 100644 --- a/packages/editor/src/store/index.js +++ b/packages/editor/src/store/index.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { registerStore } from '@wordpress/data'; +import { controls } from '@wordpress/data-controls'; /** * Internal dependencies @@ -10,7 +11,6 @@ import reducer from './reducer'; import applyMiddlewares from './middlewares'; import * as selectors from './selectors'; import * as actions from './actions'; -import controls from './controls'; import { STORE_KEY } from './constants'; const store = registerStore( STORE_KEY, { diff --git a/packages/editor/src/store/test/actions.js b/packages/editor/src/store/test/actions.js index af7e7f60a2210..f0ec7c84dab15 100644 --- a/packages/editor/src/store/test/actions.js +++ b/packages/editor/src/store/test/actions.js @@ -3,11 +3,15 @@ */ import { BEGIN, COMMIT, REVERT } from 'redux-optimist'; +/** + * WordPress dependencies + */ +import { select, dispatch, apiFetch } from '@wordpress/data-controls'; + /** * Internal dependencies */ import * as actions from '../actions'; -import { select, dispatch, apiFetch, resolveSelect } from '../controls'; import { STORE_KEY, SAVE_POST_NOTICE_ID, @@ -15,24 +19,20 @@ import { POST_UPDATE_TRANSACTION_ID, } from '../constants'; -jest.mock( '../controls' ); +jest.mock( '@wordpress/data-controls' ); select.mockImplementation( ( ...args ) => { - const { select: actualSelect } = jest.requireActual( '../controls' ); + const { select: actualSelect } = jest + .requireActual( '@wordpress/data-controls' ); return actualSelect( ...args ); } ); dispatch.mockImplementation( ( ...args ) => { - const { dispatch: actualDispatch } = jest.requireActual( '../controls' ); + const { dispatch: actualDispatch } = jest + .requireActual( '@wordpress/data-controls' ); return actualDispatch( ...args ); } ); -resolveSelect.mockImplementation( ( ...args ) => { - const { resolveSelect: selectResolver } = jest - .requireActual( '../controls' ); - return selectResolver( ...args ); -} ); - const apiFetchThrowError = ( error ) => { apiFetch.mockClear(); apiFetch.mockImplementation( () => { @@ -43,7 +43,8 @@ const apiFetchThrowError = ( error ) => { const apiFetchDoActual = () => { apiFetch.mockClear(); apiFetch.mockImplementation( ( ...args ) => { - const { apiFetch: fetch } = jest.requireActual( '../controls' ); + const { apiFetch: fetch } = jest + .requireActual( '@wordpress/data-controls' ); return fetch( ...args ); } ); }; @@ -212,7 +213,7 @@ describe( 'Post generator actions', () => { () => { const { value } = fulfillment.next( postTypeSlug ); expect( value ).toEqual( - resolveSelect( 'core', 'getPostType', postTypeSlug ) + select( 'core', 'getPostType', postTypeSlug ) ); }, ], @@ -278,7 +279,7 @@ describe( 'Post generator actions', () => { () => { const { value } = fulfillment.next(); expect( value ).toEqual( - resolveSelect( 'core', 'getCurrentUser' ) + select( 'core', 'getCurrentUser' ) ); }, ], @@ -288,7 +289,7 @@ describe( 'Post generator actions', () => { () => { const { value } = fulfillment.next( currentUser ); expect( value ).toEqual( - resolveSelect( + select( 'core', 'getAutosave', postTypeSlug, @@ -533,7 +534,7 @@ describe( 'Post generator actions', () => { ); it( 'yields expected action for selecting the post type object', () => { const { value } = fulfillment.next( postTypeSlug ); - expect( value ).toEqual( resolveSelect( + expect( value ).toEqual( select( 'core', 'getPostType', postTypeSlug @@ -611,7 +612,7 @@ describe( 'Post generator actions', () => { } ); it( 'yields expected action for selecting the post type object', () => { const { value } = fulfillment.next( postTypeSlug ); - expect( value ).toEqual( resolveSelect( + expect( value ).toEqual( select( 'core', 'getPostType', postTypeSlug