update manage token model to work on load (#29022)
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
4d4af7dc39
Коммит
311381940d
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx should match snapshot 1`] = `
|
||||
exports[`components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx initial call should match snapshot 1`] = `
|
||||
<Modal
|
||||
animation={true}
|
||||
aria-labelledby="manageTokensModalLabel"
|
||||
@@ -95,3 +95,271 @@ exports[`components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx sh
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
`;
|
||||
|
||||
exports[`components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx should display list of tokens 1`] = `
|
||||
<Modal
|
||||
animation={true}
|
||||
aria-labelledby="manageTokensModalLabel"
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
dialogClassName="a11y__modal manage-teams"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[MockFunction]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
role="dialog"
|
||||
show={true}
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
>
|
||||
<ModalTitle
|
||||
bsClass="modal-title"
|
||||
componentClass="h1"
|
||||
id="manageTokensModalLabel"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Manage Personal Access Tokens"
|
||||
id="admin.manage_tokens.manageTokensTitle"
|
||||
/>
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="manage-teams__user"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
size="lg"
|
||||
url="/api/v4/users/defaultuser/image"
|
||||
username="some-user"
|
||||
/>
|
||||
<div
|
||||
className="manage-teams__info"
|
||||
>
|
||||
<div
|
||||
className="manage-teams__name"
|
||||
>
|
||||
@some-user
|
||||
</div>
|
||||
<div
|
||||
className="manage-teams__email"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="pt-3"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Personal access tokens function similarly to session tokens and can be used by integrations to <linkAuthentication>interact with this Mattermost server</linkAuthentication>. Tokens are disabled if the user is deactivated. Learn more about <linkPersonalAccessTokens>personal access tokens</linkPersonalAccessTokens>."
|
||||
id="admin.manage_tokens.userAccessTokensDescription"
|
||||
values={
|
||||
Object {
|
||||
"linkAuthentication": [Function],
|
||||
"linkPersonalAccessTokens": [Function],
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="manage-teams__teams"
|
||||
>
|
||||
<div
|
||||
className="manage-teams__team"
|
||||
key="id1"
|
||||
>
|
||||
<div
|
||||
className="manage-teams__team-name"
|
||||
>
|
||||
<div
|
||||
className="whitespace--nowrap overflow--ellipsis"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Token Description: "
|
||||
id="admin.manage_tokens.userAccessTokensNameLabel"
|
||||
/>
|
||||
description
|
||||
</div>
|
||||
<div
|
||||
className="whitespace--nowrap overflow--ellipsis"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Token ID: "
|
||||
id="admin.manage_tokens.userAccessTokensIdLabel"
|
||||
/>
|
||||
id1
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="manage-teams__team-actions"
|
||||
>
|
||||
<Connect(Component)
|
||||
onError={[Function]}
|
||||
tokenId="id1"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="manage-teams__team"
|
||||
key="id2"
|
||||
>
|
||||
<div
|
||||
className="manage-teams__team-name"
|
||||
>
|
||||
<div
|
||||
className="whitespace--nowrap overflow--ellipsis"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Token Description: "
|
||||
id="admin.manage_tokens.userAccessTokensNameLabel"
|
||||
/>
|
||||
description
|
||||
</div>
|
||||
<div
|
||||
className="whitespace--nowrap overflow--ellipsis"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Token ID: "
|
||||
id="admin.manage_tokens.userAccessTokensIdLabel"
|
||||
/>
|
||||
id2
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="manage-teams__team-actions"
|
||||
>
|
||||
<Connect(Component)
|
||||
onError={[Function]}
|
||||
tokenId="id2"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
`;
|
||||
|
||||
exports[`components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx should replace loading screen on update 1`] = `
|
||||
<Modal
|
||||
animation={true}
|
||||
aria-labelledby="manageTokensModalLabel"
|
||||
autoFocus={true}
|
||||
backdrop={true}
|
||||
bsClass="modal"
|
||||
dialogClassName="a11y__modal manage-teams"
|
||||
dialogComponentClass={[Function]}
|
||||
enforceFocus={true}
|
||||
keyboard={true}
|
||||
manager={
|
||||
ModalManager {
|
||||
"add": [Function],
|
||||
"containers": Array [],
|
||||
"data": Array [],
|
||||
"handleContainerOverflow": true,
|
||||
"hideSiblingNodes": true,
|
||||
"isTopModal": [Function],
|
||||
"modals": Array [],
|
||||
"remove": [Function],
|
||||
}
|
||||
}
|
||||
onExited={[MockFunction]}
|
||||
onHide={[Function]}
|
||||
renderBackdrop={[Function]}
|
||||
restoreFocus={true}
|
||||
role="dialog"
|
||||
show={true}
|
||||
>
|
||||
<ModalHeader
|
||||
bsClass="modal-header"
|
||||
closeButton={true}
|
||||
closeLabel="Close"
|
||||
>
|
||||
<ModalTitle
|
||||
bsClass="modal-title"
|
||||
componentClass="h1"
|
||||
id="manageTokensModalLabel"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Manage Personal Access Tokens"
|
||||
id="admin.manage_tokens.manageTokensTitle"
|
||||
/>
|
||||
</ModalTitle>
|
||||
</ModalHeader>
|
||||
<ModalBody
|
||||
bsClass="modal-body"
|
||||
componentClass="div"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="manage-teams__user"
|
||||
>
|
||||
<Memo(Avatar)
|
||||
size="lg"
|
||||
url="/api/v4/users/defaultuser/image"
|
||||
username="some-user"
|
||||
/>
|
||||
<div
|
||||
className="manage-teams__info"
|
||||
>
|
||||
<div
|
||||
className="manage-teams__name"
|
||||
>
|
||||
@some-user
|
||||
</div>
|
||||
<div
|
||||
className="manage-teams__email"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="pt-3"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="Personal access tokens function similarly to session tokens and can be used by integrations to <linkAuthentication>interact with this Mattermost server</linkAuthentication>. Tokens are disabled if the user is deactivated. Learn more about <linkPersonalAccessTokens>personal access tokens</linkPersonalAccessTokens>."
|
||||
id="admin.manage_tokens.userAccessTokensDescription"
|
||||
values={
|
||||
Object {
|
||||
"linkAuthentication": [Function],
|
||||
"linkPersonalAccessTokens": [Function],
|
||||
}
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className="manage-teams__teams"
|
||||
>
|
||||
<div
|
||||
className="manage-row__empty"
|
||||
>
|
||||
<MemoizedFormattedMessage
|
||||
defaultMessage="No personal access tokens."
|
||||
id="admin.manage_tokens.userAccessTokensNone"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
`;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
import {shallow} from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import LoadingScreen from 'components/loading_screen';
|
||||
|
||||
import {TestHelper} from 'utils/test_helper';
|
||||
|
||||
import ManageTokensModal from './manage_tokens_modal';
|
||||
@@ -20,36 +22,51 @@ describe('components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx',
|
||||
onExited: jest.fn(),
|
||||
};
|
||||
|
||||
test('should match snapshot', () => {
|
||||
test('initial call should match snapshot', () => {
|
||||
const wrapper = shallow(
|
||||
<ManageTokensModal {...baseProps}/>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(baseProps.actions.getUserAccessTokensForUser).toHaveBeenCalledTimes(1);
|
||||
expect(wrapper.find('.manage-teams__teams').exists()).toBe(true);
|
||||
expect(wrapper.find(LoadingScreen).exists()).toBe(true);
|
||||
});
|
||||
|
||||
test('should not call getUserAccessTokensForUser on mount', () => {
|
||||
test('should replace loading screen on update', () => {
|
||||
const wrapper = shallow(
|
||||
<ManageTokensModal {...baseProps}/>,
|
||||
);
|
||||
expect(baseProps.actions.getUserAccessTokensForUser).toHaveBeenCalledTimes(0);
|
||||
expect(wrapper.state('userAccessTokens')).toBeUndefined();
|
||||
});
|
||||
|
||||
test('should call getUserAccessTokensForUser on user change', () => {
|
||||
// create new user as only by then the update method triggers token retrieval
|
||||
const newProps = {
|
||||
...baseProps,
|
||||
user: TestHelper.getUserMock({
|
||||
id: 'newuser',
|
||||
}),
|
||||
userAccessTokens: {},
|
||||
};
|
||||
wrapper.setProps(newProps);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('.manage-teams__teams').exists()).toBe(true);
|
||||
expect(wrapper.find('.manage-row__empty').exists()).toBe(true);
|
||||
});
|
||||
|
||||
test('should display list of tokens', () => {
|
||||
const wrapper = shallow(
|
||||
<ManageTokensModal {...baseProps}/>,
|
||||
);
|
||||
const newProps = {
|
||||
...baseProps,
|
||||
userAccessTokens: [
|
||||
{
|
||||
id: 'id1',
|
||||
description: 'description',
|
||||
},
|
||||
{
|
||||
id: 'id2',
|
||||
description: 'description',
|
||||
},
|
||||
],
|
||||
};
|
||||
wrapper.setProps(newProps);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
wrapper.instance().componentDidUpdate(baseProps, newProps);
|
||||
expect(newProps.actions.getUserAccessTokensForUser).toHaveBeenCalledTimes(2);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
expect(wrapper.find('.manage-teams__teams').exists()).toBe(true);
|
||||
expect(wrapper.find('.manage-teams__team').length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,7 +22,7 @@ export type Props = {
|
||||
/**
|
||||
* The user the roles are being managed for
|
||||
*/
|
||||
user?: UserProfile;
|
||||
user: UserProfile;
|
||||
|
||||
/**
|
||||
* The personal access tokens for a user, object with token ids as keys
|
||||
@@ -53,10 +53,9 @@ export default class ManageTokensModal extends React.PureComponent<Props, State>
|
||||
};
|
||||
}
|
||||
|
||||
public componentDidUpdate(prevProps: Props): void {
|
||||
public componentDidMount(): void {
|
||||
const userId = this.props.user ? this.props.user.id : null;
|
||||
const prevUserId = prevProps.user ? prevProps.user.id : null;
|
||||
if (userId && prevUserId !== userId) {
|
||||
if (userId) {
|
||||
this.props.actions.getUserAccessTokensForUser(userId, 0, 200);
|
||||
}
|
||||
}
|
||||
@@ -74,10 +73,6 @@ export default class ManageTokensModal extends React.PureComponent<Props, State>
|
||||
private renderContents = (): JSX.Element => {
|
||||
const {user, userAccessTokens} = this.props;
|
||||
|
||||
if (!user) {
|
||||
return <LoadingScreen/>;
|
||||
}
|
||||
|
||||
let name = UserUtils.getFullName(user);
|
||||
if (name) {
|
||||
name += ` (@${user.username})`;
|
||||
|
||||
Ссылка в новой задаче
Block a user