From 38156586763680fbe14fa6320aba33ced4512251 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Wed, 13 May 2026 21:20:28 -0400 Subject: [PATCH] Core Data: Avoid duplicate id-less entity permission requests --- .../navigation/test/use-navigation-menu.js | 10 +++- .../hooks/test/use-resource-permissions.js | 57 +++++++++++++++++++ .../src/hooks/use-resource-permissions.ts | 12 ++-- 3 files changed, 70 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/navigation/test/use-navigation-menu.js b/packages/block-library/src/navigation/test/use-navigation-menu.js index 7eaf648fab936e..85bb28d0c5a49e 100644 --- a/packages/block-library/src/navigation/test/use-navigation-menu.js +++ b/packages/block-library/src/navigation/test/use-navigation-menu.js @@ -70,8 +70,14 @@ function resolveRecords( registry, menus ) { function resolveReadPermission( registry, allowed ) { const dispatch = registry.dispatch( coreStore ); dispatch.receiveUserPermission( 'read/postType/wp_navigation', allowed ); - dispatch.startResolution( 'canUser', [ 'read', BASE_ENTITY ] ); - dispatch.finishResolution( 'canUser', [ 'read', BASE_ENTITY ] ); + dispatch.startResolution( 'canUser', [ + 'read', + { kind: 'postType', name: 'wp_navigation' }, + ] ); + dispatch.finishResolution( 'canUser', [ + 'read', + { kind: 'postType', name: 'wp_navigation' }, + ] ); } function resolveReadRecordPermission( registry, ref, allowed ) { diff --git a/packages/core-data/src/hooks/test/use-resource-permissions.js b/packages/core-data/src/hooks/test/use-resource-permissions.js index 0e7356fb046e82..4ecde978537329 100644 --- a/packages/core-data/src/hooks/test/use-resource-permissions.js +++ b/packages/core-data/src/hooks/test/use-resource-permissions.js @@ -127,6 +127,63 @@ describe( 'useResourcePermissions', () => { ); } ); + it( 'normalizes id-less entity resources before resolving permissions', async () => { + let data; + triggerFetch.mockImplementation( ( options ) => { + if ( options.path === '/wp/v2/types?context=view' ) { + return { + wp_navigation: { + name: 'Navigation Menus', + slug: 'wp_navigation', + rest_base: 'navigation', + rest_namespace: 'wp/v2', + }, + }; + } + if ( + options.path === '/wp/v2/navigation' && + options.method === 'OPTIONS' + ) { + return { + headers: new Headers( { allow: 'GET, POST' } ), + }; + } + throw new Error( + `Unexpected request: ${ JSON.stringify( options ) }` + ); + } ); + + const TestComponent = () => { + data = useResourcePermissions( { + kind: 'postType', + name: 'wp_navigation', + id: undefined, + } ); + return
; + }; + render( + + + + ); + + await waitFor( () => + expect( data ).toEqual( { + status: 'SUCCESS', + isResolving: false, + hasResolved: true, + canCreate: true, + canRead: true, + } ) + ); + + expect( + triggerFetch.mock.calls.filter( + ( [ options ] ) => options.path === '/wp/v2/navigation' + ) + ).toHaveLength( 1 ); + } ); + it( 'retrieves the relevant permissions for an entity', async () => { let data; const TestComponent = () => { diff --git a/packages/core-data/src/hooks/use-resource-permissions.ts b/packages/core-data/src/hooks/use-resource-permissions.ts index 129c20682a1613..f3c2b246f0399c 100644 --- a/packages/core-data/src/hooks/use-resource-permissions.ts +++ b/packages/core-data/src/hooks/use-resource-permissions.ts @@ -145,15 +145,13 @@ function useResourcePermissions< IdType = void >( ( resolve ) => { const hasId = isEntity ? !! resource.id : !! id; const { canUser } = resolve( coreStore ); - const create = canUser( - 'create', - isEntity - ? { kind: resource.kind, name: resource.name } - : resource - ); + const collectionResource = isEntity + ? { kind: resource.kind, name: resource.name } + : resource; + const create = canUser( 'create', collectionResource ); if ( ! hasId ) { - const read = canUser( 'read', resource ); + const read = canUser( 'read', collectionResource ); const isResolving = create.isResolving || read.isResolving; const hasResolved = create.hasResolved && read.hasResolved;