From 16b6f934b9621699954c3a9cb3c228a079f4d874 Mon Sep 17 00:00:00 2001 From: George Mamadashvili Date: Wed, 10 Jul 2024 09:33:23 +0400 Subject: [PATCH] Add unit tests --- packages/core-data/src/resolvers.js | 2 +- packages/core-data/src/test/resolvers.js | 182 +++++++++++++++++++++++ packages/core-data/src/test/selectors.js | 11 ++ 3 files changed, 194 insertions(+), 1 deletion(-) diff --git a/packages/core-data/src/resolvers.js b/packages/core-data/src/resolvers.js index a6a6a86a732af8..855439f6589c9c 100644 --- a/packages/core-data/src/resolvers.js +++ b/packages/core-data/src/resolvers.js @@ -374,7 +374,7 @@ export const canUser = const entityConfig = configs.find( ( config ) => config.name === resource.name && - config.kind === resource.name + config.kind === resource.kind ); if ( ! entityConfig ) { return; diff --git a/packages/core-data/src/test/resolvers.js b/packages/core-data/src/test/resolvers.js index 2187f0275593b1..e99f9f2b4e098f 100644 --- a/packages/core-data/src/test/resolvers.js +++ b/packages/core-data/src/test/resolvers.js @@ -283,6 +283,21 @@ describe( 'getEmbedPreview', () => { } ); describe( 'canUser', () => { + const ENTITIES = [ + { + name: 'media', + kind: 'root', + baseURL: '/wp/v2/media', + baseURLParams: { context: 'edit' }, + }, + { + name: 'wp_block', + kind: 'postType', + baseURL: '/wp/v2/blocks', + baseURLParams: { context: 'edit' }, + }, + ]; + let dispatch, registry; beforeEach( async () => { registry = { @@ -294,6 +309,7 @@ describe( 'canUser', () => { dispatch = Object.assign( jest.fn(), { receiveUserPermission: jest.fn(), } ); + dispatch.mockReturnValue( ENTITIES ); triggerFetch.mockReset(); } ); @@ -303,6 +319,10 @@ describe( 'canUser', () => { ); await canUser( 'create', 'media' )( { dispatch, registry } ); + await canUser( 'create', { kind: 'root', name: 'media' } )( { + dispatch, + registry, + } ); expect( triggerFetch ).toHaveBeenCalledWith( { path: '/wp/v2/media', @@ -332,6 +352,28 @@ describe( 'canUser', () => { ); } ); + it( 'receives false when the user is not allowed to perform an action on entities', async () => { + triggerFetch.mockImplementation( () => ( { + headers: new Map( [ [ 'allow', 'GET' ] ] ), + } ) ); + + await canUser( 'create', { kind: 'root', name: 'media' } )( { + dispatch, + registry, + } ); + + expect( triggerFetch ).toHaveBeenCalledWith( { + path: '/wp/v2/media', + method: 'OPTIONS', + parse: false, + } ); + + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'create/root/media', + false + ); + } ); + it( 'receives true when the user is allowed to perform an action', async () => { triggerFetch.mockImplementation( () => ( { headers: new Map( [ [ 'allow', 'POST, GET, PUT, DELETE' ] ] ), @@ -351,6 +393,28 @@ describe( 'canUser', () => { ); } ); + it( 'receives true when the user is allowed to perform an action on entities', async () => { + triggerFetch.mockImplementation( () => ( { + headers: new Map( [ [ 'allow', 'POST, GET, PUT, DELETE' ] ] ), + } ) ); + + await canUser( 'create', { kind: 'root', name: 'media' } )( { + dispatch, + registry, + } ); + + expect( triggerFetch ).toHaveBeenCalledWith( { + path: '/wp/v2/media', + method: 'OPTIONS', + parse: false, + } ); + + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'create/root/media', + true + ); + } ); + it( 'receives true when the user is allowed to perform an action on a specific resource', async () => { triggerFetch.mockImplementation( () => ( { headers: new Map( [ [ 'allow', 'POST, GET, PUT, DELETE' ] ] ), @@ -370,6 +434,32 @@ describe( 'canUser', () => { ); } ); + it( 'receives true when the user is allowed to perform an action on a specific entity', async () => { + triggerFetch.mockImplementation( () => ( { + headers: new Map( [ [ 'allow', 'POST, GET, PUT, DELETE' ] ] ), + } ) ); + + await canUser( 'create', { + kind: 'postType', + name: 'wp_block', + id: 123, + } )( { + dispatch, + registry, + } ); + + expect( triggerFetch ).toHaveBeenCalledWith( { + path: '/wp/v2/blocks/123', + method: 'OPTIONS', + parse: false, + } ); + + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'create/postType/wp_block/123', + true + ); + } ); + it( 'runs apiFetch only once per resource', async () => { registry = { ...registry, @@ -397,6 +487,45 @@ describe( 'canUser', () => { ); } ); + it( 'runs apiFetch only once per entity', async () => { + registry = { + ...registry, + select: () => ( { + hasStartedResolution: ( _, [ action ] ) => action === 'read', + } ), + }; + + triggerFetch.mockImplementation( () => ( { + headers: new Map( [ [ 'allow', 'POST, GET' ] ] ), + } ) ); + + await canUser( 'create', { + kind: 'postType', + name: 'wp_block', + } )( { + dispatch, + registry, + } ); + await canUser( 'read', { + kind: 'postType', + name: 'wp_block', + } )( { + dispatch, + registry, + } ); + + expect( triggerFetch ).toHaveBeenCalledTimes( 1 ); + + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'create/postType/wp_block', + true + ); + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'read/postType/wp_block', + true + ); + } ); + it( 'retrieves all permissions even when ID is not given', async () => { registry = { ...registry, @@ -468,6 +597,59 @@ describe( 'canUser', () => { true ); } ); + + it( 'runs apiFetch only once per entity ID', async () => { + registry = { + ...registry, + select: () => ( { + hasStartedResolution: ( _, [ action ] ) => action === 'create', + } ), + }; + + triggerFetch.mockImplementation( () => ( { + headers: new Map( [ [ 'allow', 'POST, GET, PUT, DELETE' ] ] ), + } ) ); + + await canUser( 'create', { + kind: 'postType', + name: 'wp_block', + id: 123, + } )( { dispatch, registry } ); + await canUser( 'read', { + kind: 'postType', + name: 'wp_block', + id: 123, + } )( { dispatch, registry } ); + await canUser( 'update', { + kind: 'postType', + name: 'wp_block', + id: 123, + } )( { dispatch, registry } ); + await canUser( 'delete', { + kind: 'postType', + name: 'wp_block', + id: 123, + } )( { dispatch, registry } ); + + expect( triggerFetch ).toHaveBeenCalledTimes( 1 ); + + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'create/postType/wp_block/123', + true + ); + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'read/postType/wp_block/123', + true + ); + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'update/postType/wp_block/123', + true + ); + expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith( + 'delete/postType/wp_block/123', + true + ); + } ); } ); describe( 'getAutosaves', () => { diff --git a/packages/core-data/src/test/selectors.js b/packages/core-data/src/test/selectors.js index 43c84a3e978917..841bccd2ce413d 100644 --- a/packages/core-data/src/test/selectors.js +++ b/packages/core-data/src/test/selectors.js @@ -690,24 +690,35 @@ describe( 'canUser', () => { userPermissions: {}, } ); expect( canUser( state, 'create', 'media' ) ).toBe( undefined ); + expect( + canUser( state, 'create', { kind: 'root', name: 'media' } ) + ).toBe( undefined ); } ); it( 'returns whether an action can be performed', () => { const state = deepFreeze( { userPermissions: { 'create/media': false, + 'create/root/media': false, }, } ); expect( canUser( state, 'create', 'media' ) ).toBe( false ); + expect( + canUser( state, 'create', { kind: 'root', name: 'media' } ) + ).toBe( false ); } ); it( 'returns whether an action can be performed for a given resource', () => { const state = deepFreeze( { userPermissions: { 'create/media/123': false, + 'create/root/media/123': false, }, } ); expect( canUser( state, 'create', 'media', 123 ) ).toBe( false ); + expect( + canUser( state, 'create', { kind: 'root', name: 'media', id: 123 } ) + ).toBe( false ); } ); } );