diff --git a/packages/core-data/src/actions.js b/packages/core-data/src/actions.js index a79aaba7e33d8f..66fbd292ec3403 100644 --- a/packages/core-data/src/actions.js +++ b/packages/core-data/src/actions.js @@ -136,11 +136,11 @@ export function receiveEmbedPreview( url, preview ) { * @return {Object} Action object. */ export function* editEntityRecord( kind, name, recordId, edits, options = {} ) { - const { transientEdits = {}, mergedEdits = {} } = yield select( - 'getEntity', - kind, - name - ); + const entity = yield select( 'getEntity', kind, name ); + if ( ! entity ) { + throw new Error( `The entity being edited (${ kind }, ${ name }) does not have a loaded config.` ); + } + const { transientEdits = {}, mergedEdits = {} } = entity; const record = yield select( 'getRawEntityRecord', kind, name, recordId ); const editedRecord = yield select( 'getEditedEntityRecord', diff --git a/packages/core-data/src/selectors.js b/packages/core-data/src/selectors.js index 3974d66c83b60b..1475ffd2562f8f 100644 --- a/packages/core-data/src/selectors.js +++ b/packages/core-data/src/selectors.js @@ -183,8 +183,11 @@ export function getEntityRecordEdits( state, kind, name, recordId ) { */ export const getEntityRecordNonTransientEdits = createSelector( ( state, kind, name, recordId ) => { - const { transientEdits = {} } = getEntity( state, kind, name ); - const edits = getEntityRecordEdits( state, kind, name, recordId ) || []; + const { transientEdits } = getEntity( state, kind, name ) || {}; + const edits = getEntityRecordEdits( state, kind, name, recordId ) || {}; + if ( ! transientEdits ) { + return edits; + } return Object.keys( edits ).reduce( ( acc, key ) => { if ( ! transientEdits[ key ] ) { acc[ key ] = edits[ key ]; diff --git a/packages/core-data/src/test/actions.js b/packages/core-data/src/test/actions.js index cf839cf9a3493a..ffcee0efbca504 100644 --- a/packages/core-data/src/test/actions.js +++ b/packages/core-data/src/test/actions.js @@ -1,7 +1,34 @@ /** * Internal dependencies */ -import { saveEntityRecord, receiveEntityRecords, receiveUserPermission, receiveAutosaves, receiveCurrentUser } from '../actions'; +import { + editEntityRecord, + saveEntityRecord, + receiveEntityRecords, + receiveUserPermission, + receiveAutosaves, + receiveCurrentUser, +} from '../actions'; +import { select } from '../controls'; + +describe( 'editEntityRecord', () => { + it( 'throws when the edited entity does not have a loaded config.', () => { + const entity = { kind: 'someKind', name: 'someName', id: 'someId' }; + const fulfillment = editEntityRecord( + entity.kind, + entity.name, + entity.id, + {} + ); + expect( fulfillment.next().value ).toEqual( + select( 'getEntity', entity.kind, entity.name ) + ); + // Don't pass back an entity config. + expect( fulfillment.next.bind( fulfillment ) ).toThrow( + `The entity being edited (${ entity.kind }, ${ entity.name }) does not have a loaded config.` + ); + } ); +} ); describe( 'saveEntityRecord', () => { it( 'triggers a POST request for a new record', async () => { diff --git a/packages/core-data/src/test/selectors.js b/packages/core-data/src/test/selectors.js index a52c13d99c7d16..13e1551f2f1d6e 100644 --- a/packages/core-data/src/test/selectors.js +++ b/packages/core-data/src/test/selectors.js @@ -9,6 +9,7 @@ import deepFreeze from 'deep-freeze'; import { getEntityRecord, getEntityRecords, + getEntityRecordNonTransientEdits, getEmbedPreview, isPreviewEmbedFallback, canUser, @@ -104,6 +105,17 @@ describe( 'getEntityRecords', () => { } ); } ); +describe( 'getEntityRecordNonTransientEdits', () => { + it( 'should return an empty object when the entity does not have a loaded config.', () => { + const state = deepFreeze( { + entities: { config: {}, data: {} }, + } ); + expect( + getEntityRecordNonTransientEdits( state, 'someKind', 'someName', 'someId' ) + ).toEqual( {} ); + } ); +} ); + describe( 'getEmbedPreview()', () => { it( 'returns preview stored for url', () => { let state = deepFreeze( {