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 { class Base {
constructor(http = AxiosHTTP, baseURL) { constructor(http = defaultHttp, baseURL) {
this.http = http; this.http = http;
this.baseUrl = baseURL; this.baseUrl = baseURL;
} }

View File

@@ -1,13 +1,29 @@
import Base from '../Base'; import Base from '../Base';
import RelaunchMixin from '../mixins/Relaunch.mixin'; import RelaunchMixin from '../mixins/Relaunch.mixin';
const BASE_URLS = { const getBaseURL = type => {
playbook: '/jobs/', switch (type) {
project: '/project_updates/', case 'playbook':
system: '/system_jobs/', case 'job':
inventory: '/inventory_updates/', return '/jobs/';
command: '/ad_hoc_commands/', case 'project':
workflow: '/workflow_jobs/', 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) { class Jobs extends RelaunchMixin(Base) {
@@ -16,16 +32,20 @@ class Jobs extends RelaunchMixin(Base) {
this.baseUrl = '/api/v2/jobs/'; this.baseUrl = '/api/v2/jobs/';
} }
cancel(id, type) {
return this.http.post(`/api/v2${getBaseURL(type)}${id}/cancel/`);
}
readDetail(id, type) { 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 = {}) { readEvents(id, type = 'playbook', params = {}) {
let endpoint; let endpoint;
if (type === 'playbook') { if (type === 'playbook') {
endpoint = `/api/v2${BASE_URLS[type]}${id}/job_events/`; endpoint = `/api/v2${getBaseURL(type)}${id}/job_events/`;
} else { } else {
endpoint = `/api/v2${BASE_URLS[type]}${id}/events/`; endpoint = `/api/v2${getBaseURL(type)}${id}/events/`;
} }
return this.http.get(endpoint, { params }); 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, InventoryUpdatesAPI,
JobsAPI, JobsAPI,
ProjectUpdatesAPI, ProjectUpdatesAPI,
RelatedAPI,
SystemJobsAPI, SystemJobsAPI,
UnifiedJobsAPI, UnifiedJobsAPI,
WorkflowJobsAPI, WorkflowJobsAPI,
@@ -103,7 +102,7 @@ function JobList({ i18n, defaultParams, showTypeColumn = false }) {
return Promise.all( return Promise.all(
selected.map(job => { selected.map(job => {
if (['new', 'pending', 'waiting', 'running'].includes(job.status)) { if (['new', 'pending', 'waiting', 'running'].includes(job.status)) {
return RelatedAPI.post(job.related.cancel); return JobsAPI.cancel(job.id, job.type);
} }
return Promise.resolve(); return Promise.resolve();
}) })

View File

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