mirror of
https://github.com/ansible/awx.git
synced 2026-02-26 07:26:03 -03:30
Merge pull request #7772 from mabashian/convert-ResourceAccessList-functional
Converts ResourceAccessList to functional component Reviewed-by: https://github.com/apps/softwarefactory-project-zuul
This commit is contained in:
@@ -1,19 +1,14 @@
|
|||||||
import React, { Fragment } from 'react';
|
import React, { useCallback, useEffect, useState } from 'react';
|
||||||
import { withRouter } from 'react-router-dom';
|
import { useLocation } 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 { TeamsAPI, UsersAPI } from '../../api';
|
import { TeamsAPI, UsersAPI } from '../../api';
|
||||||
import AddResourceRole from '../AddRole/AddResourceRole';
|
import AddResourceRole from '../AddRole/AddResourceRole';
|
||||||
import AlertModal from '../AlertModal';
|
import AlertModal from '../AlertModal';
|
||||||
import DataListToolbar from '../DataListToolbar';
|
import DataListToolbar from '../DataListToolbar';
|
||||||
import PaginatedDataList, { ToolbarAddButton } from '../PaginatedDataList';
|
import PaginatedDataList, { ToolbarAddButton } from '../PaginatedDataList';
|
||||||
import {
|
import { getQSConfig, parseQueryString } from '../../util/qs';
|
||||||
getQSConfig,
|
import useRequest, { useDeleteItems } from '../../util/useRequest';
|
||||||
encodeQueryString,
|
|
||||||
parseQueryString,
|
|
||||||
} from '../../util/qs';
|
|
||||||
|
|
||||||
import DeleteRoleConfirmationModal from './DeleteRoleConfirmationModal';
|
import DeleteRoleConfirmationModal from './DeleteRoleConfirmationModal';
|
||||||
import ResourceAccessListItem from './ResourceAccessListItem';
|
import ResourceAccessListItem from './ResourceAccessListItem';
|
||||||
|
|
||||||
@@ -23,227 +18,160 @@ const QS_CONFIG = getQSConfig('access', {
|
|||||||
order_by: 'first_name',
|
order_by: 'first_name',
|
||||||
});
|
});
|
||||||
|
|
||||||
class ResourceAccessList extends React.Component {
|
function ResourceAccessList({ i18n, apiModel, resource }) {
|
||||||
constructor(props) {
|
const [deletionRecord, setDeletionRecord] = useState(null);
|
||||||
super(props);
|
const [deletionRole, setDeletionRole] = useState(null);
|
||||||
this.state = {
|
const [showAddModal, setShowAddModal] = useState(false);
|
||||||
|
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||||
|
const location = useLocation();
|
||||||
|
|
||||||
|
const {
|
||||||
|
result: { accessRecords, itemCount },
|
||||||
|
error: contentError,
|
||||||
|
isLoading,
|
||||||
|
request: fetchAccessRecords,
|
||||||
|
} = useRequest(
|
||||||
|
useCallback(async () => {
|
||||||
|
const params = parseQueryString(QS_CONFIG, location.search);
|
||||||
|
const response = await apiModel.readAccessList(resource.id, params);
|
||||||
|
return {
|
||||||
|
accessRecords: response.data.results,
|
||||||
|
itemCount: response.data.count,
|
||||||
|
};
|
||||||
|
}, [apiModel, location, resource.id]),
|
||||||
|
{
|
||||||
accessRecords: [],
|
accessRecords: [],
|
||||||
contentError: null,
|
|
||||||
hasContentLoading: true,
|
|
||||||
hasDeletionError: false,
|
|
||||||
deletionRecord: null,
|
|
||||||
deletionRole: null,
|
|
||||||
isAddModalOpen: false,
|
|
||||||
itemCount: 0,
|
itemCount: 0,
|
||||||
};
|
|
||||||
this.loadAccessList = this.loadAccessList.bind(this);
|
|
||||||
this.handleAddClose = this.handleAddClose.bind(this);
|
|
||||||
this.handleAddOpen = this.handleAddOpen.bind(this);
|
|
||||||
this.handleAddSuccess = this.handleAddSuccess.bind(this);
|
|
||||||
this.handleDeleteCancel = this.handleDeleteCancel.bind(this);
|
|
||||||
this.handleDeleteConfirm = this.handleDeleteConfirm.bind(this);
|
|
||||||
this.handleDeleteErrorClose = this.handleDeleteErrorClose.bind(this);
|
|
||||||
this.handleDeleteOpen = this.handleDeleteOpen.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.loadAccessList();
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
|
||||||
const { location } = this.props;
|
|
||||||
|
|
||||||
const prevParams = parseQueryString(QS_CONFIG, prevProps.location.search);
|
|
||||||
const currentParams = parseQueryString(QS_CONFIG, location.search);
|
|
||||||
|
|
||||||
if (encodeQueryString(currentParams) !== encodeQueryString(prevParams)) {
|
|
||||||
this.loadAccessList();
|
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
async loadAccessList() {
|
useEffect(() => {
|
||||||
const { apiModel, resource, location } = this.props;
|
fetchAccessRecords();
|
||||||
const params = parseQueryString(QS_CONFIG, location.search);
|
}, [fetchAccessRecords]);
|
||||||
|
|
||||||
this.setState({ contentError: null, hasContentLoading: true });
|
const {
|
||||||
try {
|
isLoading: isDeleteLoading,
|
||||||
const {
|
deleteItems: deleteRole,
|
||||||
data: { results: accessRecords = [], count: itemCount = 0 },
|
deletionError,
|
||||||
} = await apiModel.readAccessList(resource.id, params);
|
clearDeletionError,
|
||||||
this.setState({ itemCount, accessRecords });
|
} = useDeleteItems(
|
||||||
} catch (err) {
|
useCallback(async () => {
|
||||||
this.setState({ contentError: err });
|
if (typeof deletionRole.team_id !== 'undefined') {
|
||||||
} finally {
|
return TeamsAPI.disassociateRole(deletionRole.team_id, deletionRole.id);
|
||||||
this.setState({ hasContentLoading: false });
|
}
|
||||||
|
return UsersAPI.disassociateRole(deletionRecord.id, deletionRole.id);
|
||||||
|
/* eslint-disable-next-line react-hooks/exhaustive-deps */
|
||||||
|
}, [deletionRole]),
|
||||||
|
{
|
||||||
|
qsConfig: QS_CONFIG,
|
||||||
|
fetchItems: fetchAccessRecords,
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
handleDeleteOpen(deletionRole, deletionRecord) {
|
return (
|
||||||
this.setState({ deletionRole, deletionRecord });
|
<>
|
||||||
}
|
<PaginatedDataList
|
||||||
|
error={contentError}
|
||||||
handleDeleteCancel() {
|
hasContentLoading={isLoading || isDeleteLoading}
|
||||||
this.setState({ deletionRole: null, deletionRecord: null });
|
items={accessRecords}
|
||||||
}
|
itemCount={itemCount}
|
||||||
|
pluralizedItemName={i18n._(t`Roles`)}
|
||||||
handleDeleteErrorClose() {
|
qsConfig={QS_CONFIG}
|
||||||
this.setState({
|
toolbarSearchColumns={[
|
||||||
hasDeletionError: false,
|
{
|
||||||
deletionRecord: null,
|
name: i18n._(t`Username`),
|
||||||
deletionRole: null,
|
key: 'username',
|
||||||
});
|
isDefault: true,
|
||||||
}
|
},
|
||||||
|
{
|
||||||
async handleDeleteConfirm() {
|
name: i18n._(t`First name`),
|
||||||
const { deletionRole, deletionRecord } = this.state;
|
key: 'first_name',
|
||||||
|
},
|
||||||
if (!deletionRole || !deletionRecord) {
|
{
|
||||||
return;
|
name: i18n._(t`Last name`),
|
||||||
}
|
key: 'last_name',
|
||||||
|
},
|
||||||
let promise;
|
]}
|
||||||
if (typeof deletionRole.team_id !== 'undefined') {
|
toolbarSortColumns={[
|
||||||
promise = TeamsAPI.disassociateRole(
|
{
|
||||||
deletionRole.team_id,
|
name: i18n._(t`Username`),
|
||||||
deletionRole.id
|
key: 'username',
|
||||||
);
|
},
|
||||||
} else {
|
{
|
||||||
promise = UsersAPI.disassociateRole(deletionRecord.id, deletionRole.id);
|
name: i18n._(t`First name`),
|
||||||
}
|
key: 'first_name',
|
||||||
|
},
|
||||||
this.setState({ hasContentLoading: true });
|
{
|
||||||
try {
|
name: i18n._(t`Last name`),
|
||||||
await promise.then(this.loadAccessList);
|
key: 'last_name',
|
||||||
this.setState({
|
},
|
||||||
deletionRole: null,
|
]}
|
||||||
deletionRecord: null,
|
renderToolbar={props => (
|
||||||
});
|
<DataListToolbar
|
||||||
} catch (error) {
|
{...props}
|
||||||
this.setState({
|
qsConfig={QS_CONFIG}
|
||||||
hasContentLoading: false,
|
additionalControls={
|
||||||
hasDeletionError: true,
|
resource?.summary_fields?.user_capabilities?.edit
|
||||||
});
|
? [
|
||||||
}
|
<ToolbarAddButton
|
||||||
}
|
key="add"
|
||||||
|
onClick={() => setShowAddModal(true)}
|
||||||
handleAddClose() {
|
/>,
|
||||||
this.setState({ isAddModalOpen: false });
|
]
|
||||||
}
|
: []
|
||||||
|
}
|
||||||
handleAddOpen() {
|
/>
|
||||||
this.setState({ isAddModalOpen: true });
|
)}
|
||||||
}
|
renderItem={accessRecord => (
|
||||||
|
<ResourceAccessListItem
|
||||||
handleAddSuccess() {
|
key={accessRecord.id}
|
||||||
this.setState({ isAddModalOpen: false });
|
accessRecord={accessRecord}
|
||||||
this.loadAccessList();
|
onRoleDelete={(role, record) => {
|
||||||
}
|
setDeletionRecord(record);
|
||||||
|
setDeletionRole(role);
|
||||||
render() {
|
setShowDeleteModal(true);
|
||||||
const { resource, i18n } = this.props;
|
}}
|
||||||
const {
|
/>
|
||||||
accessRecords,
|
)}
|
||||||
contentError,
|
/>
|
||||||
hasContentLoading,
|
{showAddModal && (
|
||||||
deletionRole,
|
<AddResourceRole
|
||||||
deletionRecord,
|
onClose={() => setShowAddModal(false)}
|
||||||
hasDeletionError,
|
onSave={() => {
|
||||||
itemCount,
|
setShowAddModal(false);
|
||||||
isAddModalOpen,
|
fetchAccessRecords();
|
||||||
} = this.state;
|
}}
|
||||||
const canEdit = resource.summary_fields.user_capabilities.edit;
|
roles={resource.summary_fields.object_roles}
|
||||||
const isDeleteModalOpen =
|
|
||||||
!hasContentLoading && !hasDeletionError && deletionRole;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Fragment>
|
|
||||||
<PaginatedDataList
|
|
||||||
error={contentError}
|
|
||||||
hasContentLoading={hasContentLoading}
|
|
||||||
items={accessRecords}
|
|
||||||
itemCount={itemCount}
|
|
||||||
pluralizedItemName={i18n._(t`Roles`)}
|
|
||||||
qsConfig={QS_CONFIG}
|
|
||||||
toolbarSearchColumns={[
|
|
||||||
{
|
|
||||||
name: i18n._(t`Username`),
|
|
||||||
key: 'username',
|
|
||||||
isDefault: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n._(t`First Name`),
|
|
||||||
key: 'first_name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n._(t`Last Name`),
|
|
||||||
key: 'last_name',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
toolbarSortColumns={[
|
|
||||||
{
|
|
||||||
name: i18n._(t`Username`),
|
|
||||||
key: 'username',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n._(t`First Name`),
|
|
||||||
key: 'first_name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n._(t`Last Name`),
|
|
||||||
key: 'last_name',
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
renderToolbar={props => (
|
|
||||||
<DataListToolbar
|
|
||||||
{...props}
|
|
||||||
qsConfig={QS_CONFIG}
|
|
||||||
additionalControls={
|
|
||||||
canEdit
|
|
||||||
? [
|
|
||||||
<ToolbarAddButton
|
|
||||||
key="add"
|
|
||||||
onClick={this.handleAddOpen}
|
|
||||||
/>,
|
|
||||||
]
|
|
||||||
: []
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
renderItem={accessRecord => (
|
|
||||||
<ResourceAccessListItem
|
|
||||||
key={accessRecord.id}
|
|
||||||
accessRecord={accessRecord}
|
|
||||||
onRoleDelete={this.handleDeleteOpen}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
/>
|
/>
|
||||||
{isAddModalOpen && (
|
)}
|
||||||
<AddResourceRole
|
{showDeleteModal && (
|
||||||
onClose={this.handleAddClose}
|
<DeleteRoleConfirmationModal
|
||||||
onSave={this.handleAddSuccess}
|
role={deletionRole}
|
||||||
roles={resource.summary_fields.object_roles}
|
username={deletionRecord.username}
|
||||||
/>
|
onCancel={() => {
|
||||||
)}
|
setDeletionRecord(null);
|
||||||
{isDeleteModalOpen && (
|
setDeletionRole(null);
|
||||||
<DeleteRoleConfirmationModal
|
setShowDeleteModal(false);
|
||||||
role={deletionRole}
|
}}
|
||||||
username={deletionRecord.username}
|
onConfirm={async () => {
|
||||||
onCancel={this.handleDeleteCancel}
|
await deleteRole();
|
||||||
onConfirm={this.handleDeleteConfirm}
|
setShowDeleteModal(false);
|
||||||
/>
|
setDeletionRecord(null);
|
||||||
)}
|
setDeletionRole(null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{deletionError && (
|
||||||
<AlertModal
|
<AlertModal
|
||||||
isOpen={hasDeletionError}
|
isOpen={deletionError}
|
||||||
variant="error"
|
variant="error"
|
||||||
title={i18n._(t`Error!`)}
|
title={i18n._(t`Error!`)}
|
||||||
onClose={this.handleDeleteErrorClose}
|
onClose={clearDeletionError}
|
||||||
>
|
>
|
||||||
{i18n._(t`Failed to delete role`)}
|
{i18n._(t`Failed to delete role`)}
|
||||||
</AlertModal>
|
</AlertModal>
|
||||||
</Fragment>
|
)}
|
||||||
);
|
</>
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
export default withI18n()(ResourceAccessList);
|
||||||
export { ResourceAccessList as _ResourceAccessList };
|
|
||||||
export default withI18n()(withRouter(ResourceAccessList));
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { act } from 'react-dom/test-utils';
|
||||||
import { sleep } from '../../../testUtils/testUtils';
|
|
||||||
import {
|
import {
|
||||||
mountWithContexts,
|
mountWithContexts,
|
||||||
waitForElement,
|
waitForElement,
|
||||||
@@ -13,6 +12,7 @@ import ResourceAccessList from './ResourceAccessList';
|
|||||||
jest.mock('../../api');
|
jest.mock('../../api');
|
||||||
|
|
||||||
describe('<ResourceAccessList />', () => {
|
describe('<ResourceAccessList />', () => {
|
||||||
|
let wrapper;
|
||||||
const organization = {
|
const organization = {
|
||||||
id: 1,
|
id: 1,
|
||||||
name: 'Default',
|
name: 'Default',
|
||||||
@@ -74,108 +74,68 @@ describe('<ResourceAccessList />', () => {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
OrganizationsAPI.readAccessList.mockResolvedValue({ data });
|
OrganizationsAPI.readAccessList.mockResolvedValue({ data });
|
||||||
TeamsAPI.disassociateRole.mockResolvedValue({});
|
TeamsAPI.disassociateRole.mockResolvedValue({});
|
||||||
UsersAPI.disassociateRole.mockResolvedValue({});
|
UsersAPI.disassociateRole.mockResolvedValue({});
|
||||||
|
await act(async () => {
|
||||||
|
wrapper = mountWithContexts(
|
||||||
|
<ResourceAccessList
|
||||||
|
resource={organization}
|
||||||
|
apiModel={OrganizationsAPI}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
wrapper.update();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
wrapper.unmount();
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('initially renders succesfully', () => {
|
test('initially renders succesfully', () => {
|
||||||
const wrapper = mountWithContexts(
|
|
||||||
<ResourceAccessList resource={organization} apiModel={OrganizationsAPI} />
|
|
||||||
);
|
|
||||||
expect(wrapper.find('PaginatedDataList')).toHaveLength(1);
|
expect(wrapper.find('PaginatedDataList')).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should fetch and display access records on mount', async done => {
|
test('should fetch and display access records on mount', async done => {
|
||||||
const wrapper = mountWithContexts(
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
<ResourceAccessList resource={organization} apiModel={OrganizationsAPI} />
|
expect(OrganizationsAPI.readAccessList).toHaveBeenCalled();
|
||||||
);
|
expect(wrapper.find('ResourceAccessListItem').length).toBe(2);
|
||||||
await waitForElement(
|
|
||||||
wrapper,
|
|
||||||
'ResourceAccessListItem',
|
|
||||||
el => el.length === 2
|
|
||||||
);
|
|
||||||
expect(wrapper.find('PaginatedDataList').prop('items')).toEqual(
|
|
||||||
data.results
|
|
||||||
);
|
|
||||||
expect(wrapper.find('ResourceAccessList').state('hasContentLoading')).toBe(
|
|
||||||
false
|
|
||||||
);
|
|
||||||
expect(wrapper.find('ResourceAccessList').state('contentError')).toBe(null);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should open confirmation dialog when deleting role', async done => {
|
test('should open and close confirmation dialog when deleting role', async done => {
|
||||||
const wrapper = mountWithContexts(
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
<ResourceAccessList resource={organization} apiModel={OrganizationsAPI} />
|
expect(wrapper.find('DeleteRoleConfirmationModal')).toHaveLength(0);
|
||||||
);
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
|
||||||
|
|
||||||
const button = wrapper.find('Chip Button').at(0);
|
const button = wrapper.find('Chip Button').at(0);
|
||||||
button.prop('onClick')();
|
await act(async () => {
|
||||||
|
button.prop('onClick')();
|
||||||
|
});
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
expect(wrapper.find('DeleteRoleConfirmationModal')).toHaveLength(1);
|
||||||
const component = wrapper.find('ResourceAccessList');
|
await act(async () => {
|
||||||
expect(component.state('deletionRole')).toEqual(
|
wrapper.find('DeleteRoleConfirmationModal').prop('onCancel')();
|
||||||
data.results[0].summary_fields.direct_access[0].role
|
});
|
||||||
);
|
|
||||||
expect(component.state('deletionRecord')).toEqual(data.results[0]);
|
|
||||||
expect(component.find('DeleteRoleConfirmationModal')).toHaveLength(1);
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should close dialog when cancel button clicked', async done => {
|
|
||||||
const wrapper = mountWithContexts(
|
|
||||||
<ResourceAccessList resource={organization} apiModel={OrganizationsAPI} />
|
|
||||||
);
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
const button = wrapper.find('Chip Button').at(0);
|
expect(wrapper.find('DeleteRoleConfirmationModal')).toHaveLength(0);
|
||||||
button.prop('onClick')();
|
|
||||||
wrapper.update();
|
|
||||||
|
|
||||||
wrapper.find('DeleteRoleConfirmationModal').prop('onCancel')();
|
|
||||||
const component = wrapper.find('ResourceAccessList');
|
|
||||||
expect(component.state('deletionRole')).toBeNull();
|
|
||||||
expect(component.state('deletionRecord')).toBeNull();
|
|
||||||
expect(TeamsAPI.disassociateRole).not.toHaveBeenCalled();
|
expect(TeamsAPI.disassociateRole).not.toHaveBeenCalled();
|
||||||
expect(UsersAPI.disassociateRole).not.toHaveBeenCalled();
|
expect(UsersAPI.disassociateRole).not.toHaveBeenCalled();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should delete user role', async done => {
|
it('should delete user role', async done => {
|
||||||
const wrapper = mountWithContexts(
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
<ResourceAccessList resource={organization} apiModel={OrganizationsAPI} />
|
const button = wrapper.find('Chip Button').at(0);
|
||||||
);
|
await act(async () => {
|
||||||
const button = await waitForElement(
|
button.prop('onClick')();
|
||||||
wrapper,
|
});
|
||||||
'Chip Button',
|
|
||||||
el => el.length === 2
|
|
||||||
);
|
|
||||||
button.at(0).prop('onClick')();
|
|
||||||
|
|
||||||
const confirmation = await waitForElement(
|
|
||||||
wrapper,
|
|
||||||
'DeleteRoleConfirmationModal'
|
|
||||||
);
|
|
||||||
confirmation.prop('onConfirm')();
|
|
||||||
await waitForElement(
|
|
||||||
wrapper,
|
|
||||||
'DeleteRoleConfirmationModal',
|
|
||||||
el => el.length === 0
|
|
||||||
);
|
|
||||||
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
const component = wrapper.find('ResourceAccessList');
|
await act(async () => {
|
||||||
expect(component.state('deletionRole')).toBeNull();
|
wrapper.find('DeleteRoleConfirmationModal').prop('onConfirm')();
|
||||||
expect(component.state('deletionRecord')).toBeNull();
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(wrapper.find('DeleteRoleConfirmationModal')).toHaveLength(0);
|
||||||
expect(TeamsAPI.disassociateRole).not.toHaveBeenCalled();
|
expect(TeamsAPI.disassociateRole).not.toHaveBeenCalled();
|
||||||
expect(UsersAPI.disassociateRole).toHaveBeenCalledWith(1, 1);
|
expect(UsersAPI.disassociateRole).toHaveBeenCalledWith(1, 1);
|
||||||
expect(OrganizationsAPI.readAccessList).toHaveBeenCalledTimes(2);
|
expect(OrganizationsAPI.readAccessList).toHaveBeenCalledTimes(2);
|
||||||
@@ -183,32 +143,17 @@ describe('<ResourceAccessList />', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should delete team role', async done => {
|
it('should delete team role', async done => {
|
||||||
const wrapper = mountWithContexts(
|
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
|
||||||
<ResourceAccessList resource={organization} apiModel={OrganizationsAPI} />
|
const button = wrapper.find('Chip Button').at(1);
|
||||||
);
|
await act(async () => {
|
||||||
const button = await waitForElement(
|
button.prop('onClick')();
|
||||||
wrapper,
|
});
|
||||||
'Chip Button',
|
|
||||||
el => el.length === 2
|
|
||||||
);
|
|
||||||
button.at(1).prop('onClick')();
|
|
||||||
|
|
||||||
const confirmation = await waitForElement(
|
|
||||||
wrapper,
|
|
||||||
'DeleteRoleConfirmationModal'
|
|
||||||
);
|
|
||||||
confirmation.prop('onConfirm')();
|
|
||||||
await waitForElement(
|
|
||||||
wrapper,
|
|
||||||
'DeleteRoleConfirmationModal',
|
|
||||||
el => el.length === 0
|
|
||||||
);
|
|
||||||
|
|
||||||
await sleep(0);
|
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
const component = wrapper.find('ResourceAccessList');
|
await act(async () => {
|
||||||
expect(component.state('deletionRole')).toBeNull();
|
wrapper.find('DeleteRoleConfirmationModal').prop('onConfirm')();
|
||||||
expect(component.state('deletionRecord')).toBeNull();
|
});
|
||||||
|
wrapper.update();
|
||||||
|
expect(wrapper.find('DeleteRoleConfirmationModal')).toHaveLength(0);
|
||||||
expect(TeamsAPI.disassociateRole).toHaveBeenCalledWith(5, 3);
|
expect(TeamsAPI.disassociateRole).toHaveBeenCalledWith(5, 3);
|
||||||
expect(UsersAPI.disassociateRole).not.toHaveBeenCalled();
|
expect(UsersAPI.disassociateRole).not.toHaveBeenCalled();
|
||||||
expect(OrganizationsAPI.readAccessList).toHaveBeenCalledTimes(2);
|
expect(OrganizationsAPI.readAccessList).toHaveBeenCalledTimes(2);
|
||||||
|
|||||||
Reference in New Issue
Block a user