Skip to content

Commit 19e01ea

Browse files
committed
Add checks when resource is an entity
1 parent a74fd72 commit 19e01ea

6 files changed

Lines changed: 43 additions & 7 deletions

File tree

docs/reference-guides/data/data-core.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ _Parameters_
2323

2424
_Returns_
2525

26-
- `boolean | undefined`: Whether or not the user can perform the action, or `undefined` if the OPTIONS request is still being made.
26+
- `boolean | undefined | null`: Whether or not the user can perform the action, or `undefined` if the OPTIONS request is still being made.
2727

2828
### canUserEditEntityRecord
2929

@@ -42,7 +42,7 @@ _Parameters_
4242

4343
_Returns_
4444

45-
- `boolean | undefined`: Whether or not the user can edit, or `undefined` if the OPTIONS request is still being made.
45+
- `boolean | undefined | null`: Whether or not the user can edit, or `undefined` if the OPTIONS request is still being made.
4646

4747
### getAuthors
4848

packages/core-data/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ _Parameters_
344344

345345
_Returns_
346346

347-
- `boolean | undefined`: Whether or not the user can perform the action, or `undefined` if the OPTIONS request is still being made.
347+
- `boolean | undefined | null`: Whether or not the user can perform the action, or `undefined` if the OPTIONS request is still being made.
348348

349349
### canUserEditEntityRecord
350350

@@ -363,7 +363,7 @@ _Parameters_
363363

364364
_Returns_
365365

366-
- `boolean | undefined`: Whether or not the user can edit, or `undefined` if the OPTIONS request is still being made.
366+
- `boolean | undefined | null`: Whether or not the user can edit, or `undefined` if the OPTIONS request is still being made.
367367

368368
### getAuthors
369369

packages/core-data/src/resolvers.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,10 @@ export const canUser =
368368

369369
let resourcePath = null;
370370
if ( typeof resource === 'object' ) {
371+
if ( ! resource.kind || ! resource.name ) {
372+
return;
373+
}
374+
371375
const configs = await dispatch(
372376
getOrLoadEntitiesConfig( resource.kind, resource.name )
373377
);

packages/core-data/src/selectors.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,9 +1147,14 @@ export function canUser(
11471147
action: string,
11481148
resource: string | Record< string, any >,
11491149
id?: EntityRecordKey
1150-
): boolean | undefined {
1150+
): boolean | undefined | null {
1151+
const isEntity = typeof resource === 'object';
1152+
if ( isEntity && ( ! resource.kind || ! resource.name ) ) {
1153+
return null;
1154+
}
1155+
11511156
const key = (
1152-
typeof resource === 'object'
1157+
isEntity
11531158
? [ action, resource.kind, resource.name, resource.id ]
11541159
: [ action, resource, id ]
11551160
)
@@ -1179,7 +1184,7 @@ export function canUserEditEntityRecord(
11791184
kind: string,
11801185
name: string,
11811186
recordId: EntityRecordKey
1182-
): boolean | undefined {
1187+
): boolean | undefined | null {
11831188
return canUser( state, 'update', { kind, name, id: recordId } );
11841189
}
11851190

packages/core-data/src/test/resolvers.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,25 @@ describe( 'canUser', () => {
333333
expect( dispatch.receiveUserPermission ).not.toHaveBeenCalled();
334334
} );
335335

336+
it( 'does nothing when entity kind or name is missing', async () => {
337+
triggerFetch.mockImplementation( () =>
338+
Promise.reject( { status: 404 } )
339+
);
340+
341+
await canUser( 'create', { kind: 'root', name: 'media' } )( {
342+
dispatch,
343+
registry,
344+
} );
345+
await canUser( 'create', { name: 'wp_block' } )( {
346+
dispatch,
347+
registry,
348+
} );
349+
350+
expect( triggerFetch ).not.toHaveBeenCalledWith();
351+
352+
expect( dispatch.receiveUserPermission ).not.toHaveBeenCalled();
353+
} );
354+
336355
it( 'receives false when the user is not allowed to perform an action', async () => {
337356
triggerFetch.mockImplementation( () => ( {
338357
headers: new Map( [ [ 'allow', 'GET' ] ] ),

packages/core-data/src/test/selectors.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,14 @@ describe( 'canUser', () => {
694694
).toBe( undefined );
695695
} );
696696

697+
it( 'returns null when entity kind or name is missing', () => {
698+
const state = deepFreeze( {
699+
userPermissions: {},
700+
} );
701+
expect( canUser( state, 'create', { name: 'media' } ) ).toBe( null );
702+
expect( canUser( state, 'create', { kind: 'root' } ) ).toBe( null );
703+
} );
704+
697705
it( 'returns whether an action can be performed', () => {
698706
const state = deepFreeze( {
699707
userPermissions: {

0 commit comments

Comments
 (0)