MM-53855 - Handle serverError undefined or null (#24630)
* handle serverError undefined or null * exclude bots from list and search for adding users to roles * add import, fix lint * add unit tests * update test, team/channel admin based on membership, not user roles --------- Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
bd982356a7
Коммит
f4b4afdae6
@@ -1,6 +1,395 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`admin_console/add_users_to_role_modal should match snapshot 1`] = `
|
exports[`admin_console/add_users_to_role_modal search should not include bot user 1`] = `
|
||||||
|
<Modal
|
||||||
|
animation={true}
|
||||||
|
autoFocus={true}
|
||||||
|
backdrop={true}
|
||||||
|
bsClass="modal"
|
||||||
|
dialogClassName="a11y__modal more-modal more-direct-channels"
|
||||||
|
dialogComponentClass={[Function]}
|
||||||
|
enforceFocus={true}
|
||||||
|
id="addUsersToRoleModal"
|
||||||
|
keyboard={true}
|
||||||
|
manager={
|
||||||
|
ModalManager {
|
||||||
|
"add": [Function],
|
||||||
|
"containers": Array [],
|
||||||
|
"data": Array [],
|
||||||
|
"handleContainerOverflow": true,
|
||||||
|
"hideSiblingNodes": true,
|
||||||
|
"isTopModal": [Function],
|
||||||
|
"modals": Array [],
|
||||||
|
"remove": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited={[Function]}
|
||||||
|
onHide={[Function]}
|
||||||
|
renderBackdrop={[Function]}
|
||||||
|
restoreFocus={true}
|
||||||
|
show={true}
|
||||||
|
>
|
||||||
|
<ModalHeader
|
||||||
|
bsClass="modal-header"
|
||||||
|
closeButton={true}
|
||||||
|
closeLabel="Close"
|
||||||
|
>
|
||||||
|
<ModalTitle
|
||||||
|
bsClass="modal-title"
|
||||||
|
componentClass="h1"
|
||||||
|
>
|
||||||
|
<MemoizedFormattedMessage
|
||||||
|
defaultMessage="Add users to {roleName}"
|
||||||
|
id="add_users_to_role.title"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"roleName": <strong>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="role_name"
|
||||||
|
id="admin.permissions.roles.role_name.name"
|
||||||
|
/>
|
||||||
|
</strong>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ModalTitle>
|
||||||
|
</ModalHeader>
|
||||||
|
<ModalBody
|
||||||
|
bsClass="modal-body"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<MultiSelect
|
||||||
|
ariaLabelRenderer={[Function]}
|
||||||
|
buttonSubmitLoadingText="Adding..."
|
||||||
|
buttonSubmitText="Add"
|
||||||
|
focusOnLoad={true}
|
||||||
|
handleAdd={[Function]}
|
||||||
|
handleDelete={[Function]}
|
||||||
|
handleInput={[Function]}
|
||||||
|
handlePageChange={[Function]}
|
||||||
|
handleSubmit={[Function]}
|
||||||
|
key="addUsersToRoleKey"
|
||||||
|
loading={true}
|
||||||
|
maxValues={20}
|
||||||
|
numRemainingText={
|
||||||
|
<div
|
||||||
|
id="numPeopleRemaining"
|
||||||
|
>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="Use ↑↓ to browse, ↵ to select. You can add {num, number} more {num, plural, one {person} other {people}}. "
|
||||||
|
id="multiselect.numPeopleRemaining"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"num": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
optionRenderer={[Function]}
|
||||||
|
options={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"auth_service": "",
|
||||||
|
"bot_description": "",
|
||||||
|
"create_at": 0,
|
||||||
|
"delete_at": 0,
|
||||||
|
"email": "",
|
||||||
|
"first_name": "",
|
||||||
|
"id": "user_id",
|
||||||
|
"is_bot": false,
|
||||||
|
"label": "some-user",
|
||||||
|
"last_activity_at": 0,
|
||||||
|
"last_name": "",
|
||||||
|
"last_password_update": 0,
|
||||||
|
"last_picture_update": 0,
|
||||||
|
"locale": "",
|
||||||
|
"mfa_active": false,
|
||||||
|
"nickname": "",
|
||||||
|
"notify_props": Object {
|
||||||
|
"calls_desktop_sound": "true",
|
||||||
|
"channel": "false",
|
||||||
|
"comments": "never",
|
||||||
|
"desktop": "default",
|
||||||
|
"desktop_sound": "false",
|
||||||
|
"email": "false",
|
||||||
|
"first_name": "false",
|
||||||
|
"mark_unread": "mention",
|
||||||
|
"mention_keys": "",
|
||||||
|
"push": "none",
|
||||||
|
"push_status": "offline",
|
||||||
|
},
|
||||||
|
"password": "",
|
||||||
|
"position": "",
|
||||||
|
"props": Object {},
|
||||||
|
"roles": "",
|
||||||
|
"terms_of_service_create_at": 0,
|
||||||
|
"terms_of_service_id": "",
|
||||||
|
"update_at": 0,
|
||||||
|
"username": "some-user",
|
||||||
|
"value": "user_id",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
perPage={50}
|
||||||
|
placeholderText="Search and add members"
|
||||||
|
saveButtonPosition="top"
|
||||||
|
saving={false}
|
||||||
|
savingEnabled={true}
|
||||||
|
valueRenderer={[Function]}
|
||||||
|
valueWithImage={false}
|
||||||
|
values={Array []}
|
||||||
|
/>
|
||||||
|
</ModalBody>
|
||||||
|
</Modal>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`admin_console/add_users_to_role_modal should exclude user 1`] = `
|
||||||
|
<Modal
|
||||||
|
animation={true}
|
||||||
|
autoFocus={true}
|
||||||
|
backdrop={true}
|
||||||
|
bsClass="modal"
|
||||||
|
dialogClassName="a11y__modal more-modal more-direct-channels"
|
||||||
|
dialogComponentClass={[Function]}
|
||||||
|
enforceFocus={true}
|
||||||
|
id="addUsersToRoleModal"
|
||||||
|
keyboard={true}
|
||||||
|
manager={
|
||||||
|
ModalManager {
|
||||||
|
"add": [Function],
|
||||||
|
"containers": Array [],
|
||||||
|
"data": Array [],
|
||||||
|
"handleContainerOverflow": true,
|
||||||
|
"hideSiblingNodes": true,
|
||||||
|
"isTopModal": [Function],
|
||||||
|
"modals": Array [],
|
||||||
|
"remove": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited={[Function]}
|
||||||
|
onHide={[Function]}
|
||||||
|
renderBackdrop={[Function]}
|
||||||
|
restoreFocus={true}
|
||||||
|
show={true}
|
||||||
|
>
|
||||||
|
<ModalHeader
|
||||||
|
bsClass="modal-header"
|
||||||
|
closeButton={true}
|
||||||
|
closeLabel="Close"
|
||||||
|
>
|
||||||
|
<ModalTitle
|
||||||
|
bsClass="modal-title"
|
||||||
|
componentClass="h1"
|
||||||
|
>
|
||||||
|
<MemoizedFormattedMessage
|
||||||
|
defaultMessage="Add users to {roleName}"
|
||||||
|
id="add_users_to_role.title"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"roleName": <strong>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="role_name"
|
||||||
|
id="admin.permissions.roles.role_name.name"
|
||||||
|
/>
|
||||||
|
</strong>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ModalTitle>
|
||||||
|
</ModalHeader>
|
||||||
|
<ModalBody
|
||||||
|
bsClass="modal-body"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<MultiSelect
|
||||||
|
ariaLabelRenderer={[Function]}
|
||||||
|
buttonSubmitLoadingText="Adding..."
|
||||||
|
buttonSubmitText="Add"
|
||||||
|
focusOnLoad={true}
|
||||||
|
handleAdd={[Function]}
|
||||||
|
handleDelete={[Function]}
|
||||||
|
handleInput={[Function]}
|
||||||
|
handlePageChange={[Function]}
|
||||||
|
handleSubmit={[Function]}
|
||||||
|
key="addUsersToRoleKey"
|
||||||
|
loading={true}
|
||||||
|
maxValues={20}
|
||||||
|
numRemainingText={
|
||||||
|
<div
|
||||||
|
id="numPeopleRemaining"
|
||||||
|
>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="Use ↑↓ to browse, ↵ to select. You can add {num, number} more {num, plural, one {person} other {people}}. "
|
||||||
|
id="multiselect.numPeopleRemaining"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"num": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
optionRenderer={[Function]}
|
||||||
|
options={Array []}
|
||||||
|
perPage={50}
|
||||||
|
placeholderText="Search and add members"
|
||||||
|
saveButtonPosition="top"
|
||||||
|
saving={false}
|
||||||
|
savingEnabled={true}
|
||||||
|
valueRenderer={[Function]}
|
||||||
|
valueWithImage={false}
|
||||||
|
values={Array []}
|
||||||
|
/>
|
||||||
|
</ModalBody>
|
||||||
|
</Modal>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`admin_console/add_users_to_role_modal should have single passed value 1`] = `
|
||||||
|
<Modal
|
||||||
|
animation={true}
|
||||||
|
autoFocus={true}
|
||||||
|
backdrop={true}
|
||||||
|
bsClass="modal"
|
||||||
|
dialogClassName="a11y__modal more-modal more-direct-channels"
|
||||||
|
dialogComponentClass={[Function]}
|
||||||
|
enforceFocus={true}
|
||||||
|
id="addUsersToRoleModal"
|
||||||
|
keyboard={true}
|
||||||
|
manager={
|
||||||
|
ModalManager {
|
||||||
|
"add": [Function],
|
||||||
|
"containers": Array [],
|
||||||
|
"data": Array [],
|
||||||
|
"handleContainerOverflow": true,
|
||||||
|
"hideSiblingNodes": true,
|
||||||
|
"isTopModal": [Function],
|
||||||
|
"modals": Array [],
|
||||||
|
"remove": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited={[Function]}
|
||||||
|
onHide={[Function]}
|
||||||
|
renderBackdrop={[Function]}
|
||||||
|
restoreFocus={true}
|
||||||
|
show={true}
|
||||||
|
>
|
||||||
|
<ModalHeader
|
||||||
|
bsClass="modal-header"
|
||||||
|
closeButton={true}
|
||||||
|
closeLabel="Close"
|
||||||
|
>
|
||||||
|
<ModalTitle
|
||||||
|
bsClass="modal-title"
|
||||||
|
componentClass="h1"
|
||||||
|
>
|
||||||
|
<MemoizedFormattedMessage
|
||||||
|
defaultMessage="Add users to {roleName}"
|
||||||
|
id="add_users_to_role.title"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"roleName": <strong>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="role_name"
|
||||||
|
id="admin.permissions.roles.role_name.name"
|
||||||
|
/>
|
||||||
|
</strong>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ModalTitle>
|
||||||
|
</ModalHeader>
|
||||||
|
<ModalBody
|
||||||
|
bsClass="modal-body"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<MultiSelect
|
||||||
|
ariaLabelRenderer={[Function]}
|
||||||
|
buttonSubmitLoadingText="Adding..."
|
||||||
|
buttonSubmitText="Add"
|
||||||
|
focusOnLoad={true}
|
||||||
|
handleAdd={[Function]}
|
||||||
|
handleDelete={[Function]}
|
||||||
|
handleInput={[Function]}
|
||||||
|
handlePageChange={[Function]}
|
||||||
|
handleSubmit={[Function]}
|
||||||
|
key="addUsersToRoleKey"
|
||||||
|
loading={true}
|
||||||
|
maxValues={20}
|
||||||
|
numRemainingText={
|
||||||
|
<div
|
||||||
|
id="numPeopleRemaining"
|
||||||
|
>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="Use ↑↓ to browse, ↵ to select. You can add {num, number} more {num, plural, one {person} other {people}}. "
|
||||||
|
id="multiselect.numPeopleRemaining"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"num": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
optionRenderer={[Function]}
|
||||||
|
options={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"auth_service": "",
|
||||||
|
"bot_description": "",
|
||||||
|
"create_at": 0,
|
||||||
|
"delete_at": 0,
|
||||||
|
"email": "",
|
||||||
|
"first_name": "",
|
||||||
|
"id": "user_id",
|
||||||
|
"is_bot": false,
|
||||||
|
"label": "some-user",
|
||||||
|
"last_activity_at": 0,
|
||||||
|
"last_name": "",
|
||||||
|
"last_password_update": 0,
|
||||||
|
"last_picture_update": 0,
|
||||||
|
"locale": "",
|
||||||
|
"mfa_active": false,
|
||||||
|
"nickname": "",
|
||||||
|
"notify_props": Object {
|
||||||
|
"calls_desktop_sound": "true",
|
||||||
|
"channel": "false",
|
||||||
|
"comments": "never",
|
||||||
|
"desktop": "default",
|
||||||
|
"desktop_sound": "false",
|
||||||
|
"email": "false",
|
||||||
|
"first_name": "false",
|
||||||
|
"mark_unread": "mention",
|
||||||
|
"mention_keys": "",
|
||||||
|
"push": "none",
|
||||||
|
"push_status": "offline",
|
||||||
|
},
|
||||||
|
"password": "",
|
||||||
|
"position": "",
|
||||||
|
"props": Object {},
|
||||||
|
"roles": "",
|
||||||
|
"terms_of_service_create_at": 0,
|
||||||
|
"terms_of_service_id": "",
|
||||||
|
"update_at": 0,
|
||||||
|
"username": "some-user",
|
||||||
|
"value": "user_id",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
perPage={50}
|
||||||
|
placeholderText="Search and add members"
|
||||||
|
saveButtonPosition="top"
|
||||||
|
saving={false}
|
||||||
|
savingEnabled={true}
|
||||||
|
valueRenderer={[Function]}
|
||||||
|
valueWithImage={false}
|
||||||
|
values={Array []}
|
||||||
|
/>
|
||||||
|
</ModalBody>
|
||||||
|
</Modal>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`admin_console/add_users_to_role_modal should include additional user 1`] = `
|
||||||
<Modal
|
<Modal
|
||||||
animation={true}
|
animation={true}
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
@@ -183,3 +572,331 @@ exports[`admin_console/add_users_to_role_modal should match snapshot 1`] = `
|
|||||||
</ModalBody>
|
</ModalBody>
|
||||||
</Modal>
|
</Modal>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`admin_console/add_users_to_role_modal should include additional user 2`] = `
|
||||||
|
<Modal
|
||||||
|
animation={true}
|
||||||
|
autoFocus={true}
|
||||||
|
backdrop={true}
|
||||||
|
bsClass="modal"
|
||||||
|
dialogClassName="a11y__modal more-modal more-direct-channels"
|
||||||
|
dialogComponentClass={[Function]}
|
||||||
|
enforceFocus={true}
|
||||||
|
id="addUsersToRoleModal"
|
||||||
|
keyboard={true}
|
||||||
|
manager={
|
||||||
|
ModalManager {
|
||||||
|
"add": [Function],
|
||||||
|
"containers": Array [],
|
||||||
|
"data": Array [],
|
||||||
|
"handleContainerOverflow": true,
|
||||||
|
"hideSiblingNodes": true,
|
||||||
|
"isTopModal": [Function],
|
||||||
|
"modals": Array [],
|
||||||
|
"remove": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited={[Function]}
|
||||||
|
onHide={[Function]}
|
||||||
|
renderBackdrop={[Function]}
|
||||||
|
restoreFocus={true}
|
||||||
|
show={true}
|
||||||
|
>
|
||||||
|
<ModalHeader
|
||||||
|
bsClass="modal-header"
|
||||||
|
closeButton={true}
|
||||||
|
closeLabel="Close"
|
||||||
|
>
|
||||||
|
<ModalTitle
|
||||||
|
bsClass="modal-title"
|
||||||
|
componentClass="h1"
|
||||||
|
>
|
||||||
|
<MemoizedFormattedMessage
|
||||||
|
defaultMessage="Add users to {roleName}"
|
||||||
|
id="add_users_to_role.title"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"roleName": <strong>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="role_name"
|
||||||
|
id="admin.permissions.roles.role_name.name"
|
||||||
|
/>
|
||||||
|
</strong>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ModalTitle>
|
||||||
|
</ModalHeader>
|
||||||
|
<ModalBody
|
||||||
|
bsClass="modal-body"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<MultiSelect
|
||||||
|
ariaLabelRenderer={[Function]}
|
||||||
|
buttonSubmitLoadingText="Adding..."
|
||||||
|
buttonSubmitText="Add"
|
||||||
|
focusOnLoad={true}
|
||||||
|
handleAdd={[Function]}
|
||||||
|
handleDelete={[Function]}
|
||||||
|
handleInput={[Function]}
|
||||||
|
handlePageChange={[Function]}
|
||||||
|
handleSubmit={[Function]}
|
||||||
|
key="addUsersToRoleKey"
|
||||||
|
loading={true}
|
||||||
|
maxValues={20}
|
||||||
|
numRemainingText={
|
||||||
|
<div
|
||||||
|
id="numPeopleRemaining"
|
||||||
|
>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="Use ↑↓ to browse, ↵ to select. You can add {num, number} more {num, plural, one {person} other {people}}. "
|
||||||
|
id="multiselect.numPeopleRemaining"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"num": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
optionRenderer={[Function]}
|
||||||
|
options={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"auth_service": "",
|
||||||
|
"bot_description": "",
|
||||||
|
"create_at": 0,
|
||||||
|
"delete_at": 0,
|
||||||
|
"email": "",
|
||||||
|
"first_name": "",
|
||||||
|
"id": "user_id",
|
||||||
|
"is_bot": false,
|
||||||
|
"label": "some-user",
|
||||||
|
"last_activity_at": 0,
|
||||||
|
"last_name": "",
|
||||||
|
"last_password_update": 0,
|
||||||
|
"last_picture_update": 0,
|
||||||
|
"locale": "",
|
||||||
|
"mfa_active": false,
|
||||||
|
"nickname": "",
|
||||||
|
"notify_props": Object {
|
||||||
|
"calls_desktop_sound": "true",
|
||||||
|
"channel": "false",
|
||||||
|
"comments": "never",
|
||||||
|
"desktop": "default",
|
||||||
|
"desktop_sound": "false",
|
||||||
|
"email": "false",
|
||||||
|
"first_name": "false",
|
||||||
|
"mark_unread": "mention",
|
||||||
|
"mention_keys": "",
|
||||||
|
"push": "none",
|
||||||
|
"push_status": "offline",
|
||||||
|
},
|
||||||
|
"password": "",
|
||||||
|
"position": "",
|
||||||
|
"props": Object {},
|
||||||
|
"roles": "",
|
||||||
|
"terms_of_service_create_at": 0,
|
||||||
|
"terms_of_service_id": "",
|
||||||
|
"update_at": 0,
|
||||||
|
"username": "some-user",
|
||||||
|
"value": "user_id",
|
||||||
|
},
|
||||||
|
Object {
|
||||||
|
"auth_service": "",
|
||||||
|
"bot_description": "",
|
||||||
|
"create_at": 0,
|
||||||
|
"delete_at": 0,
|
||||||
|
"email": "",
|
||||||
|
"first_name": "",
|
||||||
|
"id": "user_id",
|
||||||
|
"is_bot": false,
|
||||||
|
"label": "some-user",
|
||||||
|
"last_activity_at": 0,
|
||||||
|
"last_name": "",
|
||||||
|
"last_password_update": 0,
|
||||||
|
"last_picture_update": 0,
|
||||||
|
"locale": "",
|
||||||
|
"mfa_active": false,
|
||||||
|
"nickname": "",
|
||||||
|
"notify_props": Object {
|
||||||
|
"calls_desktop_sound": "true",
|
||||||
|
"channel": "false",
|
||||||
|
"comments": "never",
|
||||||
|
"desktop": "default",
|
||||||
|
"desktop_sound": "false",
|
||||||
|
"email": "false",
|
||||||
|
"first_name": "false",
|
||||||
|
"mark_unread": "mention",
|
||||||
|
"mention_keys": "",
|
||||||
|
"push": "none",
|
||||||
|
"push_status": "offline",
|
||||||
|
},
|
||||||
|
"password": "",
|
||||||
|
"position": "",
|
||||||
|
"props": Object {},
|
||||||
|
"roles": "",
|
||||||
|
"terms_of_service_create_at": 0,
|
||||||
|
"terms_of_service_id": "",
|
||||||
|
"update_at": 0,
|
||||||
|
"username": "some-user",
|
||||||
|
"value": "user_id",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
perPage={50}
|
||||||
|
placeholderText="Search and add members"
|
||||||
|
saveButtonPosition="top"
|
||||||
|
saving={false}
|
||||||
|
savingEnabled={true}
|
||||||
|
valueRenderer={[Function]}
|
||||||
|
valueWithImage={false}
|
||||||
|
values={Array []}
|
||||||
|
/>
|
||||||
|
</ModalBody>
|
||||||
|
</Modal>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`admin_console/add_users_to_role_modal should not include bot user 1`] = `
|
||||||
|
<Modal
|
||||||
|
animation={true}
|
||||||
|
autoFocus={true}
|
||||||
|
backdrop={true}
|
||||||
|
bsClass="modal"
|
||||||
|
dialogClassName="a11y__modal more-modal more-direct-channels"
|
||||||
|
dialogComponentClass={[Function]}
|
||||||
|
enforceFocus={true}
|
||||||
|
id="addUsersToRoleModal"
|
||||||
|
keyboard={true}
|
||||||
|
manager={
|
||||||
|
ModalManager {
|
||||||
|
"add": [Function],
|
||||||
|
"containers": Array [],
|
||||||
|
"data": Array [],
|
||||||
|
"handleContainerOverflow": true,
|
||||||
|
"hideSiblingNodes": true,
|
||||||
|
"isTopModal": [Function],
|
||||||
|
"modals": Array [],
|
||||||
|
"remove": [Function],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onExited={[Function]}
|
||||||
|
onHide={[Function]}
|
||||||
|
renderBackdrop={[Function]}
|
||||||
|
restoreFocus={true}
|
||||||
|
show={true}
|
||||||
|
>
|
||||||
|
<ModalHeader
|
||||||
|
bsClass="modal-header"
|
||||||
|
closeButton={true}
|
||||||
|
closeLabel="Close"
|
||||||
|
>
|
||||||
|
<ModalTitle
|
||||||
|
bsClass="modal-title"
|
||||||
|
componentClass="h1"
|
||||||
|
>
|
||||||
|
<MemoizedFormattedMessage
|
||||||
|
defaultMessage="Add users to {roleName}"
|
||||||
|
id="add_users_to_role.title"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"roleName": <strong>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="role_name"
|
||||||
|
id="admin.permissions.roles.role_name.name"
|
||||||
|
/>
|
||||||
|
</strong>,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ModalTitle>
|
||||||
|
</ModalHeader>
|
||||||
|
<ModalBody
|
||||||
|
bsClass="modal-body"
|
||||||
|
componentClass="div"
|
||||||
|
>
|
||||||
|
<MultiSelect
|
||||||
|
ariaLabelRenderer={[Function]}
|
||||||
|
buttonSubmitLoadingText="Adding..."
|
||||||
|
buttonSubmitText="Add"
|
||||||
|
focusOnLoad={true}
|
||||||
|
handleAdd={[Function]}
|
||||||
|
handleDelete={[Function]}
|
||||||
|
handleInput={[Function]}
|
||||||
|
handlePageChange={[Function]}
|
||||||
|
handleSubmit={[Function]}
|
||||||
|
key="addUsersToRoleKey"
|
||||||
|
loading={true}
|
||||||
|
maxValues={20}
|
||||||
|
numRemainingText={
|
||||||
|
<div
|
||||||
|
id="numPeopleRemaining"
|
||||||
|
>
|
||||||
|
<Memo(MemoizedFormattedMessage)
|
||||||
|
defaultMessage="Use ↑↓ to browse, ↵ to select. You can add {num, number} more {num, plural, one {person} other {people}}. "
|
||||||
|
id="multiselect.numPeopleRemaining"
|
||||||
|
values={
|
||||||
|
Object {
|
||||||
|
"num": 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
optionRenderer={[Function]}
|
||||||
|
options={
|
||||||
|
Array [
|
||||||
|
Object {
|
||||||
|
"auth_service": "",
|
||||||
|
"bot_description": "",
|
||||||
|
"create_at": 0,
|
||||||
|
"delete_at": 0,
|
||||||
|
"email": "",
|
||||||
|
"first_name": "",
|
||||||
|
"id": "user_id",
|
||||||
|
"is_bot": false,
|
||||||
|
"label": "some-user",
|
||||||
|
"last_activity_at": 0,
|
||||||
|
"last_name": "",
|
||||||
|
"last_password_update": 0,
|
||||||
|
"last_picture_update": 0,
|
||||||
|
"locale": "",
|
||||||
|
"mfa_active": false,
|
||||||
|
"nickname": "",
|
||||||
|
"notify_props": Object {
|
||||||
|
"calls_desktop_sound": "true",
|
||||||
|
"channel": "false",
|
||||||
|
"comments": "never",
|
||||||
|
"desktop": "default",
|
||||||
|
"desktop_sound": "false",
|
||||||
|
"email": "false",
|
||||||
|
"first_name": "false",
|
||||||
|
"mark_unread": "mention",
|
||||||
|
"mention_keys": "",
|
||||||
|
"push": "none",
|
||||||
|
"push_status": "offline",
|
||||||
|
},
|
||||||
|
"password": "",
|
||||||
|
"position": "",
|
||||||
|
"props": Object {},
|
||||||
|
"roles": "",
|
||||||
|
"terms_of_service_create_at": 0,
|
||||||
|
"terms_of_service_id": "",
|
||||||
|
"update_at": 0,
|
||||||
|
"username": "some-user",
|
||||||
|
"value": "user_id",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
perPage={50}
|
||||||
|
placeholderText="Search and add members"
|
||||||
|
saveButtonPosition="top"
|
||||||
|
saving={false}
|
||||||
|
savingEnabled={true}
|
||||||
|
valueRenderer={[Function]}
|
||||||
|
valueWithImage={false}
|
||||||
|
values={Array []}
|
||||||
|
/>
|
||||||
|
</ModalBody>
|
||||||
|
</Modal>
|
||||||
|
`;
|
||||||
|
|||||||
@@ -9,15 +9,11 @@ import {TestHelper} from 'utils/test_helper';
|
|||||||
import AddUsersToRoleModal from './add_users_to_role_modal';
|
import AddUsersToRoleModal from './add_users_to_role_modal';
|
||||||
|
|
||||||
describe('admin_console/add_users_to_role_modal', () => {
|
describe('admin_console/add_users_to_role_modal', () => {
|
||||||
const props = {
|
const baseProps = {
|
||||||
role: TestHelper.getRoleMock(),
|
role: TestHelper.getRoleMock(),
|
||||||
users: [TestHelper.getUserMock()],
|
users: [TestHelper.getUserMock()],
|
||||||
excludeUsers: {
|
excludeUsers: {},
|
||||||
asdf123: TestHelper.getUserMock(),
|
includeUsers: {},
|
||||||
},
|
|
||||||
includeUsers: {
|
|
||||||
asdf123: TestHelper.getUserMock(),
|
|
||||||
},
|
|
||||||
onAddCallback: jest.fn(),
|
onAddCallback: jest.fn(),
|
||||||
onExited: jest.fn(),
|
onExited: jest.fn(),
|
||||||
actions: {
|
actions: {
|
||||||
@@ -26,12 +22,76 @@ describe('admin_console/add_users_to_role_modal', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
test('should match snapshot', () => {
|
test('should have single passed value', () => {
|
||||||
|
const wrapper = shallow(
|
||||||
|
<AddUsersToRoleModal
|
||||||
|
{...baseProps}
|
||||||
|
/>);
|
||||||
|
expect(wrapper.find('MultiSelect').prop('options')).toHaveLength(1);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should exclude user', () => {
|
||||||
|
const props = {...baseProps, excludeUsers: {user_id: TestHelper.getUserMock()}};
|
||||||
const wrapper = shallow(
|
const wrapper = shallow(
|
||||||
<AddUsersToRoleModal
|
<AddUsersToRoleModal
|
||||||
{...props}
|
{...props}
|
||||||
/>);
|
/>);
|
||||||
|
expect(wrapper.find('MultiSelect').prop('options')).toHaveLength(0);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should include additional user', () => {
|
||||||
|
const props = {...baseProps, includeUsers: {user_id1: TestHelper.getUserMock()}};
|
||||||
|
const wrapper = shallow(
|
||||||
|
<AddUsersToRoleModal
|
||||||
|
{...props}
|
||||||
|
/>);
|
||||||
|
expect(wrapper.find('MultiSelect').prop('options')).toHaveLength(2);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should include additional user', () => {
|
||||||
|
const props = {...baseProps, includeUsers: {user_id1: TestHelper.getUserMock()}};
|
||||||
|
const wrapper = shallow(
|
||||||
|
<AddUsersToRoleModal
|
||||||
|
{...props}
|
||||||
|
/>);
|
||||||
|
expect(wrapper.find('MultiSelect').prop('options')).toHaveLength(2);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not include bot user', () => {
|
||||||
|
const botUser = TestHelper.getUserMock();
|
||||||
|
botUser.is_bot = true;
|
||||||
|
const props = {...baseProps,
|
||||||
|
actions: {
|
||||||
|
getProfiles: jest.fn().mockResolvedValue({data: [TestHelper.getUserMock(), botUser]}),
|
||||||
|
searchProfiles: jest.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const wrapper = shallow(
|
||||||
|
<AddUsersToRoleModal
|
||||||
|
{...props}
|
||||||
|
/>);
|
||||||
|
expect(wrapper.find('MultiSelect').prop('options')).toHaveLength(1);
|
||||||
|
expect(wrapper).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('search should not include bot user', () => {
|
||||||
|
const botUser = TestHelper.getUserMock();
|
||||||
|
botUser.is_bot = true;
|
||||||
|
const props = {...baseProps,
|
||||||
|
actions: {
|
||||||
|
searchProfiles: jest.fn().mockResolvedValue({data: [TestHelper.getUserMock(), botUser]}),
|
||||||
|
getProfiles: jest.fn(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const wrapper = shallow(
|
||||||
|
<AddUsersToRoleModal
|
||||||
|
{...props}
|
||||||
|
/>);
|
||||||
|
expect(wrapper.find('MultiSelect').prop('options')).toHaveLength(1);
|
||||||
expect(wrapper).toMatchSnapshot();
|
expect(wrapper).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -82,11 +82,15 @@ export default class AddUsersToRoleModal extends React.PureComponent<Props, Stat
|
|||||||
|
|
||||||
search = async (term: string) => {
|
search = async (term: string) => {
|
||||||
this.setUsersLoadingState(true);
|
this.setUsersLoadingState(true);
|
||||||
let searchResults: UserProfile[] = [];
|
const searchResults: UserProfile[] = [];
|
||||||
const search = term !== '';
|
const search = term !== '';
|
||||||
if (search) {
|
if (search) {
|
||||||
const {data} = await this.props.actions.searchProfiles(term, {replace: true});
|
const {data} = await this.props.actions.searchProfiles(term, {replace: true});
|
||||||
searchResults = data;
|
data.forEach((user) => {
|
||||||
|
if (!user.is_bot) {
|
||||||
|
searchResults.push(user);
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
await this.props.actions.getProfiles(0, USERS_PER_PAGE * 2);
|
await this.props.actions.getProfiles(0, USERS_PER_PAGE * 2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import AddUsersToRoleModal from './add_users_to_role_modal';
|
|||||||
import type {Props} from './add_users_to_role_modal';
|
import type {Props} from './add_users_to_role_modal';
|
||||||
|
|
||||||
function mapStateToProps(state: GlobalState, props: Props) {
|
function mapStateToProps(state: GlobalState, props: Props) {
|
||||||
const filterOptions: {[key: string]: any} = {active: true, exclude_roles: [props.role.name]};
|
const filterOptions: {[key: string]: any} = {active: true, exclude_roles: [props.role.name], exclude_bots: true};
|
||||||
const users: UserProfile[] = selectProfiles(state, filterOptions);
|
const users: UserProfile[] = selectProfiles(state, filterOptions);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ export default class SystemRole extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const userIdsToAdd = Object.keys(usersToAdd);
|
const userIdsToAdd = Object.keys(usersToAdd);
|
||||||
if (userIdsToAdd.length > 0 && serverError == null) {
|
if (userIdsToAdd.length > 0 && !serverError) {
|
||||||
const addUserPromises: Array<Promise<ActionResult>> = [];
|
const addUserPromises: Array<Promise<ActionResult>> = [];
|
||||||
userIdsToAdd.forEach((userId) => {
|
userIdsToAdd.forEach((userId) => {
|
||||||
const user = usersToAdd[userId];
|
const user = usersToAdd[userId];
|
||||||
@@ -174,16 +174,16 @@ export default class SystemRole extends React.PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let {saveKey} = this.state;
|
let {saveKey} = this.state;
|
||||||
if (serverError === null) {
|
if (!serverError) {
|
||||||
saveKey += 1;
|
saveKey += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverError === null) {
|
if (!serverError) {
|
||||||
getHistory().push('/admin_console/user_management/system_roles');
|
getHistory().push('/admin_console/user_management/system_roles');
|
||||||
}
|
}
|
||||||
setNavigationBlocked(serverError !== null);
|
setNavigationBlocked(Boolean(serverError));
|
||||||
this.setState({
|
this.setState({
|
||||||
saveNeeded: (serverError !== null),
|
saveNeeded: Boolean(serverError),
|
||||||
saving: false,
|
saving: false,
|
||||||
serverError,
|
serverError,
|
||||||
usersToAdd: {},
|
usersToAdd: {},
|
||||||
|
|||||||
@@ -819,4 +819,70 @@ describe('Selectors.Users', () => {
|
|||||||
expect(Selectors.currentUserHasAnAdminRole(state)).toEqual(false);
|
expect(Selectors.currentUserHasAnAdminRole(state)).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('filterProfiles', () => {
|
||||||
|
it('no filter, return all users', () => {
|
||||||
|
expect(Object.keys(Selectors.filterProfiles(profiles)).length).toEqual(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filter role', () => {
|
||||||
|
const filter = {
|
||||||
|
role: 'system_admin',
|
||||||
|
};
|
||||||
|
expect(Object.keys(Selectors.filterProfiles(profiles, filter)).length).toEqual(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filter roles', () => {
|
||||||
|
const filter = {
|
||||||
|
roles: ['system_admin'],
|
||||||
|
team_roles: ['team_admin'],
|
||||||
|
};
|
||||||
|
|
||||||
|
const membership = TestHelper.fakeTeamMember(user3.id, team1.id);
|
||||||
|
membership.scheme_admin = true;
|
||||||
|
const memberships = {[user3.id]: membership};
|
||||||
|
|
||||||
|
expect(Object.keys(Selectors.filterProfiles(profiles, filter, memberships)).length).toEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exclude_roles', () => {
|
||||||
|
const filter = {
|
||||||
|
exclude_roles: ['system_admin'],
|
||||||
|
};
|
||||||
|
expect(Object.keys(Selectors.filterProfiles(profiles, filter)).length).toEqual(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('exclude bots', () => {
|
||||||
|
const filter = {
|
||||||
|
exclude_bots: true,
|
||||||
|
};
|
||||||
|
const botUser = {
|
||||||
|
...user1,
|
||||||
|
id: 'test_bot_id',
|
||||||
|
username: 'botusername',
|
||||||
|
first_name: '',
|
||||||
|
last_name: '',
|
||||||
|
is_bot: true,
|
||||||
|
};
|
||||||
|
const newProfiles = {
|
||||||
|
...profiles,
|
||||||
|
[botUser.id]: botUser,
|
||||||
|
};
|
||||||
|
expect(Object.keys(Selectors.filterProfiles(newProfiles, filter)).length).toEqual(7);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filter inactive', () => {
|
||||||
|
const filter = {
|
||||||
|
inactive: true,
|
||||||
|
};
|
||||||
|
expect(Object.keys(Selectors.filterProfiles(profiles, filter)).length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('filter active', () => {
|
||||||
|
const filter = {
|
||||||
|
active: true,
|
||||||
|
};
|
||||||
|
expect(Object.keys(Selectors.filterProfiles(profiles, filter)).length).toEqual(5);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ type Filters = {
|
|||||||
exclude_roles?: string[];
|
exclude_roles?: string[];
|
||||||
channel_roles?: string[];
|
channel_roles?: string[];
|
||||||
team_roles?: string[];
|
team_roles?: string[];
|
||||||
|
exclude_bots?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getUserIdsInChannels(state: GlobalState): RelationOneToManyUnique<Channel, UserProfile> {
|
export function getUserIdsInChannels(state: GlobalState): RelationOneToManyUnique<Channel, UserProfile> {
|
||||||
@@ -304,6 +305,10 @@ export function filterProfiles(profiles: IDMappedObjects<UserProfile>, filters?:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filters.exclude_bots) {
|
||||||
|
users = users.filter((user) => !user.is_bot);
|
||||||
|
}
|
||||||
|
|
||||||
if (filters.inactive) {
|
if (filters.inactive) {
|
||||||
users = users.filter((user) => user.delete_at !== 0);
|
users = users.filter((user) => user.delete_at !== 0);
|
||||||
} else if (filters.active) {
|
} else if (filters.active) {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user