Skip to content

Commit

Permalink
Migrate canUser
Browse files Browse the repository at this point in the history
  • Loading branch information
adamziel committed Sep 6, 2021
1 parent e8a4228 commit 883c314
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 85 deletions.
20 changes: 11 additions & 9 deletions packages/core-data/src/resolvers.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { find, includes, get, hasIn, compact, uniq } from 'lodash';
import { addQueryArgs } from '@wordpress/url';
import { controls } from '@wordpress/data';
import { apiFetch } from '@wordpress/data-controls';
import triggerFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
Expand All @@ -25,7 +26,6 @@ import {
receiveEntityRecords,
receiveThemeSupports,
receiveEmbedPreview,
receiveUserPermission,
receiveAutosaves,
} from './actions';
import { getKindEntities, DEFAULT_ENTITY_KEY } from './entities';
Expand Down Expand Up @@ -294,7 +294,7 @@ export function* getEmbedPreview( url ) {
* @param {string} resource REST resource to check, e.g. 'media' or 'posts'.
* @param {?string} id ID of the rest resource to check.
*/
export function* canUser( action, resource, id ) {
export const canUser = ( action, resource, id ) => async ( { dispatch } ) => {
const methods = {
create: 'POST',
read: 'GET',
Expand All @@ -311,7 +311,7 @@ export function* canUser( action, resource, id ) {

let response;
try {
response = yield apiFetch( {
response = await triggerFetch( {
path,
// Ideally this would always be an OPTIONS request, but unfortunately there's
// a bug in the REST API which causes the Allow header to not be sent on
Expand Down Expand Up @@ -339,8 +339,8 @@ export function* canUser( action, resource, id ) {

const key = compact( [ action, resource, id ] ).join( '/' );
const isAllowed = includes( allowHeader, method );
yield receiveUserPermission( key, isAllowed );
}
dispatch.receiveUserPermission( key, isAllowed );
};

/**
* Checks whether the current user can perform the given action on the given
Expand All @@ -350,16 +350,18 @@ export function* canUser( action, resource, id ) {
* @param {string} name Entity name.
* @param {string} recordId Record's id.
*/
export function* canUserEditEntityRecord( kind, name, recordId ) {
const entities = yield getKindEntities( kind );
export const canUserEditEntityRecord = ( kind, name, recordId ) => async ( {
dispatch,
} ) => {
const entities = await dispatch( getKindEntities( kind ) );
const entity = find( entities, { kind, name } );
if ( ! entity ) {
return;
}

const resource = entity.__unstable_rest_base;
yield canUser( 'update', resource, recordId );
}
await dispatch( canUser( 'update', resource, recordId ) );
};

/**
* Request autosave data from the REST API.
Expand Down
150 changes: 74 additions & 76 deletions packages/core-data/src/test/resolvers.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/**
* WordPress dependencies
*/
import { apiFetch } from '@wordpress/data-controls';
import triggerFetch from '@wordpress/api-fetch';

jest.mock( '@wordpress/api-fetch' );

/**
* Internal dependencies
Expand All @@ -17,7 +19,6 @@ import {
import {
receiveEntityRecords,
receiveEmbedPreview,
receiveUserPermission,
receiveAutosaves,
receiveCurrentUser,
} from '../actions';
Expand Down Expand Up @@ -218,106 +219,103 @@ describe( 'getEmbedPreview', () => {
} );

describe( 'canUser', () => {
it( 'does nothing when there is an API error', () => {
const generator = canUser( 'create', 'media' );

let received = generator.next();
expect( received.done ).toBe( false );
expect( received.value ).toEqual(
apiFetch( {
path: '/wp/v2/media',
method: 'OPTIONS',
parse: false,
} )
beforeEach( async () => {
triggerFetch.mockReset();
} );

it( 'does nothing when there is an API error', async () => {
const dispatch = Object.assign( jest.fn(), {
receiveUserPermission: jest.fn(),
} );

triggerFetch.mockImplementation( () =>
Promise.reject( { status: 404 } )
);

received = generator.throw( { status: 404 } );
expect( received.done ).toBe( true );
expect( received.value ).toBeUndefined();
await canUser( 'create', 'media' )( { dispatch } );

expect( triggerFetch ).toHaveBeenCalledWith( {
path: '/wp/v2/media',
method: 'OPTIONS',
parse: false,
} );

expect( dispatch.receiveUserPermission ).not.toHaveBeenCalled();
} );

it( 'receives false when the user is not allowed to perform an action', () => {
const generator = canUser( 'create', 'media' );

let received = generator.next();
expect( received.done ).toBe( false );
expect( received.value ).toEqual(
apiFetch( {
path: '/wp/v2/media',
method: 'OPTIONS',
parse: false,
} )
);
it( 'receives false when the user is not allowed to perform an action', async () => {
const dispatch = Object.assign( jest.fn(), {
receiveUserPermission: jest.fn(),
} );

received = generator.next( {
triggerFetch.mockImplementation( () => ( {
headers: {
Allow: 'GET',
},
} ) );

await canUser( 'create', 'media' )( { dispatch } );

expect( triggerFetch ).toHaveBeenCalledWith( {
path: '/wp/v2/media',
method: 'OPTIONS',
parse: false,
} );
expect( received.done ).toBe( false );
expect( received.value ).toEqual(
receiveUserPermission( 'create/media', false )
);

received = generator.next();
expect( received.done ).toBe( true );
expect( received.value ).toBeUndefined();
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
'create/media',
false
);
} );

it( 'receives true when the user is allowed to perform an action', () => {
const generator = canUser( 'create', 'media' );

let received = generator.next();
expect( received.done ).toBe( false );
expect( received.value ).toEqual(
apiFetch( {
path: '/wp/v2/media',
method: 'OPTIONS',
parse: false,
} )
);
it( 'receives true when the user is allowed to perform an action', async () => {
const dispatch = Object.assign( jest.fn(), {
receiveUserPermission: jest.fn(),
} );

received = generator.next( {
triggerFetch.mockImplementation( () => ( {
headers: {
Allow: 'POST, GET, PUT, DELETE',
},
} ) );

await canUser( 'create', 'media' )( { dispatch } );

expect( triggerFetch ).toHaveBeenCalledWith( {
path: '/wp/v2/media',
method: 'OPTIONS',
parse: false,
} );
expect( received.done ).toBe( false );
expect( received.value ).toEqual(
receiveUserPermission( 'create/media', true )
);

received = generator.next();
expect( received.done ).toBe( true );
expect( received.value ).toBeUndefined();
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
'create/media',
true
);
} );

it( 'receives true when the user is allowed to perform an action on a specific resource', () => {
const generator = canUser( 'update', 'blocks', 123 );

let received = generator.next();
expect( received.done ).toBe( false );
expect( received.value ).toEqual(
apiFetch( {
path: '/wp/v2/blocks/123',
method: 'GET',
parse: false,
} )
);
it( 'receives true when the user is allowed to perform an action on a specific resource', async () => {
const dispatch = Object.assign( jest.fn(), {
receiveUserPermission: jest.fn(),
} );

received = generator.next( {
triggerFetch.mockImplementation( () => ( {
headers: {
Allow: 'POST, GET, PUT, DELETE',
},
} ) );

await canUser( 'create', 'blocks', 123 )( { dispatch } );

expect( triggerFetch ).toHaveBeenCalledWith( {
path: '/wp/v2/blocks/123',
method: 'GET',
parse: false,
} );
expect( received.done ).toBe( false );
expect( received.value ).toEqual(
receiveUserPermission( 'update/blocks/123', true )
);

received = generator.next();
expect( received.done ).toBe( true );
expect( received.value ).toBeUndefined();
expect( dispatch.receiveUserPermission ).toHaveBeenCalledWith(
'create/blocks/123',
true
);
} );
} );

Expand Down

0 comments on commit 883c314

Please sign in to comment.