Skip to content

Commit

Permalink
Propose useResourcePermissions hook
Browse files Browse the repository at this point in the history
  • Loading branch information
adamziel committed Feb 15, 2022
1 parent 2d5e270 commit 0db7bd2
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
71 changes: 71 additions & 0 deletions packages/core-data/src/hooks/test/use-resource-permissions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* WordPress dependencies
*/
import triggerFetch from '@wordpress/api-fetch';
import { createRegistry, RegistryProvider } from '@wordpress/data';

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

/**
* External dependencies
*/
import { act, render } from '@testing-library/react';

/**
* Internal dependencies
*/
import { store as coreDataStore } from '../../index';
import useResourcePermissions from '../use-resource-permissions';

describe( 'useEntityRecord', () => {
let registry;
beforeEach( () => {
jest.useFakeTimers();

registry = createRegistry();
registry.register( coreDataStore );
} );

afterEach( () => {
jest.runOnlyPendingTimers();
jest.useRealTimers();
} );

it( 'retrieves the relevant permissions for a key-less resource', async () => {
triggerFetch.mockImplementation( () => ( {
headers: {
Allow: 'POST',
},
} ) );
let data;
const TestComponent = () => {
data = useResourcePermissions( 'widgets' );
return <div />;
};
render(
<RegistryProvider value={ registry }>
<TestComponent />
</RegistryProvider>
);
expect( data ).toEqual( {
status: 'IDLE',
isResolving: false,
hasResolved: false,
canCreate: false,
} );

// Required to make sure no updates happen outside of act()
await act( async () => {
jest.advanceTimersByTime( 1 );
} );

expect( data ).toEqual( {
status: 'SUCCESS',
isResolving: false,
hasResolved: true,
canCreate: true,
canUpdate: false,
canDelete: false,
} );
} );
} );
46 changes: 46 additions & 0 deletions packages/core-data/src/hooks/use-resource-permissions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Internal dependencies
*/
import { store as coreStore } from '../';
import { Status } from './constants';
import useQuerySelect from './use-query-select';

export default function __experimentalUseResourcePermissions( resource, id ) {
return useQuerySelect(
( resolve ) => {
const { canUser } = resolve( coreStore );
const create = canUser( 'create', resource );
if ( ! id ) {
return {
status: create.status,
isResolving: create.isResolving,
hasResolved: create.hasResolved,
canCreate: create.hasResolved && create.data,
};
}

const update = canUser( 'update', resource, id );
const _delete = canUser( 'delete', resource, id );
const isResolving =
create.isResolving || update.isResolving || _delete.isResolving;
const hasResolved =
create.hasResolved && update.hasResolved && _delete.hasResolved;

let status = Status.Idle;
if ( isResolving ) {
status = Status.Resolving;
} else if ( hasResolved ) {
status = Status.Success;
}
return {
status,
isResolving,
hasResolved,
canCreate: hasResolved && create.data,
canUpdate: hasResolved && update.data,
canDelete: hasResolved && _delete.data,
};
},
[ resource, id ]
);
}

0 comments on commit 0db7bd2

Please sign in to comment.