Removes token edit button from details. Removes unnecessary request/props that were used to determine whether a user could delete a token.

This commit is contained in:
mabashian
2020-12-08 13:38:55 -05:00
parent f7a51fe658
commit 1a270bfc8b
3 changed files with 20 additions and 57 deletions

View File

@@ -24,20 +24,16 @@ function UserToken({ i18n, setBreadcrumb, user }) {
isLoading, isLoading,
error, error,
request: fetchToken, request: fetchToken,
result: { token, actions }, result: { token },
} = useRequest( } = useRequest(
useCallback(async () => { useCallback(async () => {
const [response, actionsResponse] = await Promise.all([ const response = await TokensAPI.readDetail(tokenId);
TokensAPI.readDetail(tokenId),
TokensAPI.readOptions(),
]);
setBreadcrumb(user, response.data); setBreadcrumb(user, response.data);
return { return {
token: response.data, token: response.data,
actions: actionsResponse.data.actions.POST,
}; };
}, [setBreadcrumb, user, tokenId]), }, [setBreadcrumb, user, tokenId]),
{ token: null, actions: null } { token: null }
); );
useEffect(() => { useEffect(() => {
fetchToken(); fetchToken();
@@ -97,7 +93,7 @@ function UserToken({ i18n, setBreadcrumb, user }) {
/> />
{token && ( {token && (
<Route path="/users/:id/tokens/:tokenId/details"> <Route path="/users/:id/tokens/:tokenId/details">
<UserTokenDetail canEditOrDelete={actions} token={token} /> <UserTokenDetail token={token} />
</Route> </Route>
)} )}
<Route key="not-found" path="*"> <Route key="not-found" path="*">

View File

@@ -1,8 +1,7 @@
import React, { useCallback } from 'react'; import React, { useCallback } from 'react';
import { Link, useHistory, useParams } from 'react-router-dom'; import { useHistory, useParams } from 'react-router-dom';
import { withI18n } from '@lingui/react'; import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro'; import { t } from '@lingui/macro';
import { Button } from '@patternfly/react-core';
import AlertModal from '../../../components/AlertModal'; import AlertModal from '../../../components/AlertModal';
import { CardBody, CardActionsRow } from '../../../components/Card'; import { CardBody, CardActionsRow } from '../../../components/Card';
@@ -18,7 +17,7 @@ import { formatDateString } from '../../../util/dates';
import useRequest, { useDismissableError } from '../../../util/useRequest'; import useRequest, { useDismissableError } from '../../../util/useRequest';
import { toTitleCase } from '../../../util/strings'; import { toTitleCase } from '../../../util/strings';
function UserTokenDetail({ token, canEditOrDelete, i18n }) { function UserTokenDetail({ token, i18n }) {
const { const {
scope, scope,
description, description,
@@ -60,25 +59,14 @@ function UserTokenDetail({ token, canEditOrDelete, i18n }) {
/> />
</DetailList> </DetailList>
<CardActionsRow> <CardActionsRow>
{canEditOrDelete && ( <DeleteButton
<> name={summary_fields?.application?.name}
<Button modalTitle={i18n._(t`Delete User Token`)}
aria-label={i18n._(t`Edit`)} onConfirm={deleteToken}
component={Link} isDisabled={isLoading}
to={`/users/${id}/tokens/${tokenId}/details`} >
> {i18n._(t`Delete`)}
{i18n._(t`Edit`)} </DeleteButton>
</Button>
<DeleteButton
name={summary_fields?.application?.name}
modalTitle={i18n._(t`Delete User Token`)}
onConfirm={deleteToken}
isDisabled={isLoading}
>
{i18n._(t`Delete`)}
</DeleteButton>
</>
)}
</CardActionsRow> </CardActionsRow>
{error && ( {error && (
<AlertModal <AlertModal

View File

@@ -37,20 +37,12 @@ describe('<UserTokenDetail/>', () => {
description: 'cdfsg', description: 'cdfsg',
scope: 'read', scope: 'read',
}; };
test('should call api for token details and actions', async () => { test('should render properly', async () => {
await act(async () => { await act(async () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(<UserTokenDetail token={token} />);
<UserTokenDetail canEditOrDelete token={token} />
);
}); });
expect(wrapper.find('UserTokenDetail').length).toBe(1); expect(wrapper.find('UserTokenDetail').length).toBe(1);
});
test('should call api for token details and actions', async () => {
await act(async () => {
wrapper = mountWithContexts(
<UserTokenDetail canEditOrDelete token={token} />
);
});
expect(wrapper.find('Detail[label="Application"]').prop('value')).toBe( expect(wrapper.find('Detail[label="Application"]').prop('value')).toBe(
'hg' 'hg'
@@ -68,20 +60,9 @@ describe('<UserTokenDetail/>', () => {
expect(wrapper.find('Button[aria-label="Edit"]').length).toBe(1); expect(wrapper.find('Button[aria-label="Edit"]').length).toBe(1);
expect(wrapper.find('Button[aria-label="Delete"]').length).toBe(1); expect(wrapper.find('Button[aria-label="Delete"]').length).toBe(1);
}); });
test('should not render edit or delete buttons', async () => {
await act(async () => {
wrapper = mountWithContexts(
<UserTokenDetail canEditOrDelete={false} token={token} />
);
});
expect(wrapper.find('Button[aria-label="Edit"]').length).toBe(0);
expect(wrapper.find('Button[aria-label="Delete"]').length).toBe(0);
});
test('should delete token properly', async () => { test('should delete token properly', async () => {
await act(async () => { await act(async () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(<UserTokenDetail token={token} />);
<UserTokenDetail canEditOrDelete token={token} />
);
}); });
await act(async () => await act(async () =>
wrapper.find('Button[aria-label="Delete"]').prop('onClick')() wrapper.find('Button[aria-label="Delete"]').prop('onClick')()
@@ -90,7 +71,7 @@ describe('<UserTokenDetail/>', () => {
await act(async () => wrapper.find('DeleteButton').prop('onConfirm')()); await act(async () => wrapper.find('DeleteButton').prop('onConfirm')());
expect(TokensAPI.destroy).toBeCalledWith(2); expect(TokensAPI.destroy).toBeCalledWith(2);
}); });
test('should throw deletion error', async () => { test('should display error on failed deletion', async () => {
TokensAPI.destroy.mockRejectedValue( TokensAPI.destroy.mockRejectedValue(
new Error({ new Error({
response: { response: {
@@ -104,9 +85,7 @@ describe('<UserTokenDetail/>', () => {
}) })
); );
await act(async () => { await act(async () => {
wrapper = mountWithContexts( wrapper = mountWithContexts(<UserTokenDetail token={token} />);
<UserTokenDetail canEditOrDelete token={token} />
);
}); });
await act(async () => await act(async () =>
wrapper.find('Button[aria-label="Delete"]').prop('onClick')() wrapper.find('Button[aria-label="Delete"]').prop('onClick')()