Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix navigation editor saving #29749

Merged
merged 2 commits into from
Mar 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions packages/edit-navigation/src/store/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { v4 as uuid } from 'uuid';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { __, sprintf } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';

/**
Expand All @@ -17,6 +17,7 @@ import {
getMenuItemToClientIdMapping,
resolveMenuItems,
dispatch,
select,
apiFetch,
} from './controls';
import {
Expand Down Expand Up @@ -89,23 +90,35 @@ export const saveNavigationPost = serializeProcessing( function* ( post ) {

try {
// Save edits to the menu, like the menu name.
const menuResponse = yield dispatch(
yield dispatch(
'core',
'saveEditedEntityRecord',
'root',
'menu',
menuId
);

const error = yield select(
'core',
'getLastEntitySaveError',
'root',
'menu',
menuId
);

if ( error ) {
throw new Error( error.message );
}

// Save blocks as menu items.
const batchSaveResponse = yield* batchSave(
menuId,
menuItemsByClientId,
post.blocks[ 0 ]
);

if ( ! batchSaveResponse.success || ! menuResponse ) {
throw new Error();
if ( ! batchSaveResponse.success ) {
throw new Error( batchSaveResponse.data.message );
}

yield dispatch(
Expand All @@ -116,15 +129,17 @@ export const saveNavigationPost = serializeProcessing( function* ( post ) {
type: 'snackbar',
}
);
} catch ( e ) {
yield dispatch(
noticesStore,
'createErrorNotice',
__( 'There was an error.' ),
{
type: 'snackbar',
}
);
} catch ( saveError ) {
const errorMessage = saveError
? sprintf(
/* translators: %s: The text of an error message (potentially untranslated). */
__( "Unable to save: '%s'" ),
saveError.message
)
: __( 'Unable to save: An error ocurred.' );
yield dispatch( noticesStore, 'createErrorNotice', errorMessage, {
type: 'snackbar',
} );
}
} );

Expand Down
141 changes: 134 additions & 7 deletions packages/edit-navigation/src/store/test/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
resolveMenuItems,
getMenuItemToClientIdMapping,
dispatch,
select,
apiFetch,
} from '../controls';
import { menuItemsQuery, computeCustomizedAttribute } from '../utils';
Expand All @@ -24,7 +25,7 @@ jest.mock( '../utils', () => {
} );

describe( 'createMissingMenuItems', () => {
it( 'create missing menu for navigation block', () => {
it( 'creates a missing menu for navigation block', () => {
const post = {
id: 'navigation-post-1',
slug: 'navigation-post-1',
Expand Down Expand Up @@ -100,7 +101,7 @@ describe( 'createMissingMenuItems', () => {
expect( action.next( [] ).done ).toBe( true );
} );

it( 'create missing menu for navigation link block', () => {
it( 'creates a missing menu for navigation link block', () => {
const post = {
id: 'navigation-post-1',
slug: 'navigation-post-1',
Expand Down Expand Up @@ -227,7 +228,7 @@ describe( 'createMissingMenuItems', () => {
} );

describe( 'saveNavigationPost', () => {
it( 'should convert all the blocks into menu items and batch save them at once', () => {
it( 'converts all the blocks into menu items and batch save them at once', () => {
const post = {
id: 'navigation-post-1',
slug: 'navigation-post-1',
Expand Down Expand Up @@ -326,8 +327,11 @@ describe( 'saveNavigationPost', () => {
expect( action.next( mapping ).value ).toEqual(
dispatch( 'core', 'saveEditedEntityRecord', 'root', 'menu', 1 )
);

expect( action.next( { id: 1 } ).value ).toEqual(
select( 'core', 'getLastEntitySaveError', 'root', 'menu', 1 )
);

expect( action.next().value ).toEqual(
apiFetch( {
path: '/__experimental/customizer-nonces/get-save-nonce',
} )
Expand Down Expand Up @@ -361,7 +365,7 @@ describe( 'saveNavigationPost', () => {
);
} );

it( 'should handle error and show error notifications', () => {
it( 'handles an error from the batch API and show error notifications', () => {
const post = {
id: 'navigation-post-1',
slug: 'navigation-post-1',
Expand Down Expand Up @@ -461,6 +465,10 @@ describe( 'saveNavigationPost', () => {
dispatch( 'core', 'saveEditedEntityRecord', 'root', 'menu', 1 )
);

expect( action.next( { id: 1 } ).value ).toEqual(
select( 'core', 'getLastEntitySaveError', 'root', 'menu', 1 )
);

expect( action.next().value ).toEqual(
apiFetch( {
path: '/__experimental/customizer-nonces/get-save-nonce',
Expand All @@ -483,11 +491,130 @@ describe( 'saveNavigationPost', () => {
)
);

expect( action.next( { success: false } ).value ).toEqual(
expect(
action.next( { success: false, data: { message: 'Test Message' } } )
.value
).toEqual(
dispatch(
noticesStore,
'createErrorNotice',
__( "Unable to save: 'Test Message'" ),
{
type: 'snackbar',
}
)
);
} );

it( 'handles an error from the entity and show error notifications', () => {
const post = {
id: 'navigation-post-1',
slug: 'navigation-post-1',
type: 'page',
meta: {
menuId: 1,
},
blocks: [
{
attributes: { showSubmenuIcon: true },
clientId: 'navigation-block-client-id',
innerBlocks: [
{
attributes: {
label: 'wp.org',
opensInNewTab: false,
url: 'http://wp.org',
className: '',
rel: '',
description: '',
title: '',
},
clientId: 'navigation-link-block-client-id-1',
innerBlocks: [],
isValid: true,
name: 'core/navigation-link',
},
{
attributes: {
label: 'wp.com',
opensInNewTab: false,
url: 'http://wp.com',
className: '',
rel: '',
description: '',
title: '',
},
clientId: 'navigation-link-block-client-id-2',
innerBlocks: [],
isValid: true,
name: 'core/navigation-link',
},
],
isValid: true,
name: 'core/navigation',
},
],
};

const menuItems = [
{
id: 100,
title: {
raw: 'wp.com',
rendered: 'wp.com',
},
url: 'http://wp.com',
menu_order: 1,
menus: [ 1 ],
classes: [],
xfn: [],
description: '',
attr_title: '',
},
{
id: 101,
title: {
raw: 'wp.org',
rendered: 'wp.org',
},
url: 'http://wp.org',
menu_order: 2,
menus: [ 1 ],
classes: [],
xfn: [],
description: '',
attr_title: '',
},
];

const mapping = {
100: 'navigation-link-block-client-id-1',
101: 'navigation-link-block-client-id-2',
};

const action = saveNavigationPost( post );

expect( action.next().value ).toEqual(
resolveMenuItems( post.meta.menuId )
);

expect( action.next( menuItems ).value ).toEqual(
getMenuItemToClientIdMapping( post.id )
);

expect( action.next( mapping ).value ).toEqual(
dispatch( 'core', 'saveEditedEntityRecord', 'root', 'menu', 1 )
);

expect( action.next().value ).toEqual(
select( 'core', 'getLastEntitySaveError', 'root', 'menu', 1 )
);

expect( action.next( { message: 'Test Message 2' } ).value ).toEqual(
dispatch(
noticesStore,
'createErrorNotice',
__( 'There was an error.' ),
__( "Unable to save: 'Test Message 2'" ),
{
type: 'snackbar',
}
Expand Down