Remove RelatedAPI model in favor of JobsAPI. Adds cancel method to JobsAPI and uses that on the jobs list.

This commit is contained in:
mabashian 2020-08-26 16:03:24 -04:00
parent f27b541396
commit bae10718d5
6 changed files with 53 additions and 78 deletions

View File

@ -1,13 +0,0 @@
import axios from 'axios';
import { encodeQueryString } from '../util/qs';
const AxiosHTTP = axios.create({
xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'X-CSRFToken',
paramsSerializer(params) {
return encodeQueryString(params);
},
});
export default AxiosHTTP;

View File

@ -1,7 +1,17 @@
import AxiosHTTP from './AxiosHTTP';
import axios from 'axios';
import { encodeQueryString } from '../util/qs';
const defaultHttp = axios.create({
xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'X-CSRFToken',
paramsSerializer(params) {
return encodeQueryString(params);
},
});
class Base {
constructor(http = AxiosHTTP, baseURL) {
constructor(http = defaultHttp, baseURL) {
this.http = http;
this.baseUrl = baseURL;
}

View File

@ -1,13 +1,29 @@
import Base from '../Base';
import RelaunchMixin from '../mixins/Relaunch.mixin';
const BASE_URLS = {
playbook: '/jobs/',
project: '/project_updates/',
system: '/system_jobs/',
inventory: '/inventory_updates/',
command: '/ad_hoc_commands/',
workflow: '/workflow_jobs/',
const getBaseURL = type => {
switch (type) {
case 'playbook':
case 'job':
return '/jobs/';
case 'project':
case 'project_update':
return '/project_updates/';
case 'system':
case 'system_job':
return '/system_jobs/';
case 'inventory':
case 'inventory_update':
return '/inventory_updates/';
case 'command':
case 'ad_hoc_command':
return '/ad_hoc_commands/';
case 'workflow':
case 'workflow_job':
return '/workflow_jobs/';
default:
throw new Error('Unable to find matching job type');
}
};
class Jobs extends RelaunchMixin(Base) {
@ -16,16 +32,20 @@ class Jobs extends RelaunchMixin(Base) {
this.baseUrl = '/api/v2/jobs/';
}
cancel(id, type) {
return this.http.post(`/api/v2${getBaseURL(type)}${id}/cancel/`);
}
readDetail(id, type) {
return this.http.get(`/api/v2${BASE_URLS[type]}${id}/`);
return this.http.get(`/api/v2${getBaseURL(type)}${id}/`);
}
readEvents(id, type = 'playbook', params = {}) {
let endpoint;
if (type === 'playbook') {
endpoint = `/api/v2${BASE_URLS[type]}${id}/job_events/`;
endpoint = `/api/v2${getBaseURL(type)}${id}/job_events/`;
} else {
endpoint = `/api/v2${BASE_URLS[type]}${id}/events/`;
endpoint = `/api/v2${getBaseURL(type)}${id}/events/`;
}
return this.http.get(endpoint, { params });
}

View File

@ -1,31 +0,0 @@
import AxiosHTTP from '../AxiosHTTP';
class Related {
constructor(http = AxiosHTTP) {
this.http = http;
}
delete(relatedEndpoint) {
return this.http.delete(relatedEndpoint);
}
get(relatedEndpoint, params) {
return this.http.get(relatedEndpoint, {
params,
});
}
patch(relatedEndpoint, data) {
return this.http.patch(relatedEndpoint, data);
}
post(relatedEndpoint, data) {
return this.http.post(relatedEndpoint, data);
}
put(relatedEndpoint, data) {
return this.http.put(relatedEndpoint, data);
}
}
export default Related;

View File

@ -21,7 +21,6 @@ import {
InventoryUpdatesAPI,
JobsAPI,
ProjectUpdatesAPI,
RelatedAPI,
SystemJobsAPI,
UnifiedJobsAPI,
WorkflowJobsAPI,
@ -103,7 +102,7 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
return Promise.all(
selected.map(job => {
if (['new', 'pending', 'waiting', 'running'].includes(job.status)) {
return RelatedAPI.post(job.related.cancel);
return JobsAPI.cancel(job.id, job.type);
}
return Promise.resolve();
})

View File

@ -9,7 +9,6 @@ import {
InventoryUpdatesAPI,
JobsAPI,
ProjectUpdatesAPI,
RelatedAPI,
SystemJobsAPI,
UnifiedJobsAPI,
WorkflowJobsAPI,
@ -300,7 +299,7 @@ describe('<JobList />', () => {
});
test('should send all corresponding delete API requests', async () => {
RelatedAPI.post = jest.fn();
JobsAPI.cancel = jest.fn();
let wrapper;
await act(async () => {
wrapper = mountWithContexts(<JobList />);
@ -319,29 +318,20 @@ describe('<JobList />', () => {
await act(async () => {
wrapper.find('JobListCancelButton').invoke('onCancel')();
});
expect(RelatedAPI.post).toHaveBeenCalledTimes(6);
expect(RelatedAPI.post).toHaveBeenCalledWith(
'/api/v2/project_updates/1/cancel'
);
expect(RelatedAPI.post).toHaveBeenCalledWith('/api/v2/jobs/2/cancel');
expect(RelatedAPI.post).toHaveBeenCalledWith(
'/api/v2/inventory_updates/3/cancel'
);
expect(RelatedAPI.post).toHaveBeenCalledWith(
'/api/v2/workflow_jobs/4/cancel'
);
expect(RelatedAPI.post).toHaveBeenCalledWith(
'/api/v2/system_jobs/5/cancel'
);
expect(RelatedAPI.post).toHaveBeenCalledWith(
'/api/v2/ad_hoc_commands/6/cancel'
);
expect(JobsAPI.cancel).toHaveBeenCalledTimes(6);
expect(JobsAPI.cancel).toHaveBeenCalledWith(1, 'project_update');
expect(JobsAPI.cancel).toHaveBeenCalledWith(2, 'job');
expect(JobsAPI.cancel).toHaveBeenCalledWith(3, 'inventory_update');
expect(JobsAPI.cancel).toHaveBeenCalledWith(4, 'workflow_job');
expect(JobsAPI.cancel).toHaveBeenCalledWith(5, 'system_job');
expect(JobsAPI.cancel).toHaveBeenCalledWith(6, 'ad_hoc_command');
jest.restoreAllMocks();
});
test('error is shown when job not successfully cancelled', async () => {
RelatedAPI.post.mockImplementation(() => {
JobsAPI.cancel.mockImplementation(() => {
throw new Error({
response: {
config: {