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
|
// 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
|
<Modal
|
||||||
animation={true}
|
animation={true}
|
||||||
aria-labelledby="manageTokensModalLabel"
|
aria-labelledby="manageTokensModalLabel"
|
||||||
@@ -95,3 +95,271 @@ exports[`components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx sh
|
|||||||
</ModalBody>
|
</ModalBody>
|
||||||
</Modal>
|
</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 {shallow} from 'enzyme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import LoadingScreen from 'components/loading_screen';
|
||||||
|
|
||||||
import {TestHelper} from 'utils/test_helper';
|
import {TestHelper} from 'utils/test_helper';
|
||||||
|
|
||||||
import ManageTokensModal from './manage_tokens_modal';
|
import ManageTokensModal from './manage_tokens_modal';
|
||||||
@@ -20,36 +22,51 @@ describe('components/admin_console/manage_tokens_modal/manage_tokens_modal.tsx',
|
|||||||
onExited: jest.fn(),
|
onExited: jest.fn(),
|
||||||
};
|
};
|
||||||
|
|
||||||
test('should match snapshot', () => {
|
test('initial call should match snapshot', () => {
|
||||||
const wrapper = shallow(
|
const wrapper = shallow(
|
||||||
<ManageTokensModal {...baseProps}/>,
|
<ManageTokensModal {...baseProps}/>,
|
||||||
);
|
);
|
||||||
expect(wrapper).toMatchSnapshot();
|
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(
|
const wrapper = shallow(
|
||||||
<ManageTokensModal {...baseProps}/>,
|
<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 = {
|
const newProps = {
|
||||||
...baseProps,
|
...baseProps,
|
||||||
user: TestHelper.getUserMock({
|
userAccessTokens: {},
|
||||||
id: 'newuser',
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
|
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(
|
const wrapper = shallow(
|
||||||
<ManageTokensModal {...baseProps}/>,
|
<ManageTokensModal {...baseProps}/>,
|
||||||
);
|
);
|
||||||
|
const newProps = {
|
||||||
|
...baseProps,
|
||||||
|
userAccessTokens: [
|
||||||
|
{
|
||||||
|
id: 'id1',
|
||||||
|
description: 'description',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'id2',
|
||||||
|
description: 'description',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
wrapper.setProps(newProps);
|
wrapper.setProps(newProps);
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
expect(wrapper).toMatchSnapshot();
|
||||||
// @ts-ignore
|
expect(wrapper.find('.manage-teams__teams').exists()).toBe(true);
|
||||||
wrapper.instance().componentDidUpdate(baseProps, newProps);
|
expect(wrapper.find('.manage-teams__team').length).toBe(2);
|
||||||
expect(newProps.actions.getUserAccessTokensForUser).toHaveBeenCalledTimes(2);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export type Props = {
|
|||||||
/**
|
/**
|
||||||
* The user the roles are being managed for
|
* 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
|
* 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 userId = this.props.user ? this.props.user.id : null;
|
||||||
const prevUserId = prevProps.user ? prevProps.user.id : null;
|
if (userId) {
|
||||||
if (userId && prevUserId !== userId) {
|
|
||||||
this.props.actions.getUserAccessTokensForUser(userId, 0, 200);
|
this.props.actions.getUserAccessTokensForUser(userId, 0, 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,10 +73,6 @@ export default class ManageTokensModal extends React.PureComponent<Props, State>
|
|||||||
private renderContents = (): JSX.Element => {
|
private renderContents = (): JSX.Element => {
|
||||||
const {user, userAccessTokens} = this.props;
|
const {user, userAccessTokens} = this.props;
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return <LoadingScreen/>;
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = UserUtils.getFullName(user);
|
let name = UserUtils.getFullName(user);
|
||||||
if (name) {
|
if (name) {
|
||||||
name += ` (@${user.username})`;
|
name += ` (@${user.username})`;
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user