Do not allow user to attempt to delete a running job

Do not allow user to attempt to delete a running job

See: https://github.com/ansible/awx/issues/9187
This commit is contained in:
nixocio
2021-03-30 15:31:32 -04:00
parent 775c0b02ee
commit e843872b98
2 changed files with 84 additions and 2 deletions

View File

@@ -152,6 +152,8 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
} }
}; };
const cannotDeleteItems = selected.filter(job => isJobRunning(job.status));
return ( return (
<> <>
<Card> <Card>
@@ -238,6 +240,17 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
onDelete={handleJobDelete} onDelete={handleJobDelete}
itemsToDelete={selected} itemsToDelete={selected}
pluralizedItemName={i18n._(t`Jobs`)} pluralizedItemName={i18n._(t`Jobs`)}
cannotDelete={item =>
isJobRunning(item.status) ||
!item.summary_fields.user_capabilities.delete
}
errorMessage={i18n.plural({
value: cannotDeleteItems.length,
one:
'The selected job cannot be deleted due to insufficient permission or a running job status',
other:
'The selected jobs cannot be deleted due to insufficient permissions or a running job status',
})}
/>, />,
<JobListCancelButton <JobListCancelButton
key="cancel" key="cancel"

View File

@@ -117,7 +117,7 @@ const mockResults = [
]; ];
UnifiedJobsAPI.read.mockResolvedValue({ UnifiedJobsAPI.read.mockResolvedValue({
data: { count: 3, results: mockResults }, data: { count: 6, results: mockResults },
}); });
UnifiedJobsAPI.readOptions.mockResolvedValue({ UnifiedJobsAPI.readOptions.mockResolvedValue({
@@ -141,6 +141,9 @@ function waitForLoaded(wrapper) {
describe('<JobList />', () => { describe('<JobList />', () => {
let debug; let debug;
beforeEach(() => { beforeEach(() => {
UnifiedJobsAPI.read.mockResolvedValue({
data: { count: 6, results: mockResults },
});
debug = global.console.debug; // eslint-disable-line prefer-destructuring debug = global.console.debug; // eslint-disable-line prefer-destructuring
global.console.debug = () => {}; global.console.debug = () => {};
}); });
@@ -262,6 +265,72 @@ describe('<JobList />', () => {
jest.restoreAllMocks(); jest.restoreAllMocks();
}); });
test('should display message about job running status', async () => {
UnifiedJobsAPI.read.mockResolvedValue({
data: {
count: 2,
results: [
{
id: 1,
url: '/api/v2/project_updates/1',
name: 'job 1',
type: 'project_update',
status: 'running',
related: {
cancel: '/api/v2/project_updates/1/cancel',
},
summary_fields: {
user_capabilities: {
delete: true,
start: true,
},
},
},
{
id: 2,
url: '/api/v2/jobs/2',
name: 'job 2',
type: 'job',
status: 'running',
related: {
cancel: '/api/v2/jobs/2/cancel',
},
summary_fields: {
user_capabilities: {
delete: true,
start: true,
},
},
},
],
},
});
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<JobList />);
});
await waitForLoaded(wrapper);
act(() => {
wrapper.find('DataListToolbar').invoke('onSelectAll')(true);
});
wrapper.update();
wrapper.find('JobListItem');
expect(
wrapper.find('ToolbarDeleteButton').prop('itemsToDelete')
).toHaveLength(2);
wrapper.update();
const deleteButton = wrapper.find('ToolbarDeleteButton');
expect(deleteButton.find('Tooltip').prop('content').props.children).toEqual(
'The selected jobs cannot be deleted due to insufficient permissions or a running job status: job 1, job 2'
);
jest.restoreAllMocks();
});
test('error is shown when job not successfully deleted from api', async () => { test('error is shown when job not successfully deleted from api', async () => {
JobsAPI.destroy.mockImplementation(() => { JobsAPI.destroy.mockImplementation(() => {
throw new Error({ throw new Error({
@@ -298,7 +367,7 @@ describe('<JobList />', () => {
); );
}); });
test('should send all corresponding delete API requests', async () => { test('should send all corresponding cancel API requests', async () => {
JobsAPI.cancel = jest.fn(); JobsAPI.cancel = jest.fn();
let wrapper; let wrapper;
await act(async () => { await act(async () => {