Switch issue_show to Axios

This commit is contained in:
Eric Eastwood 2017-12-14 22:52:18 -06:00
parent b7da615c0d
commit d2e5313ad8
5 changed files with 67 additions and 99 deletions

View file

@ -172,8 +172,8 @@ export default {
},
updateIssuable() {
this.service.updateIssuable(this.store.formState)
.then(res => res.json())
return this.service.updateIssuable(this.store.formState)
.then(res => res.data)
.then(data => this.checkForSpam(data))
.then((data) => {
if (location.pathname !== data.web_url) {
@ -182,7 +182,7 @@ export default {
return this.service.getData();
})
.then(res => res.json())
.then(res => res.data)
.then((data) => {
this.store.updateState(data);
eventHub.$emit('close.form');
@ -207,7 +207,7 @@ export default {
deleteIssuable() {
this.service.deleteIssuable()
.then(res => res.json())
.then(res => res.data)
.then((data) => {
// Stop the poll so we don't get 404's with the issuable not existing
this.poll.stop();
@ -225,7 +225,7 @@ export default {
this.poll = new Poll({
resource: this.service,
method: 'getData',
successCallback: res => res.json().then(data => this.store.updateState(data)),
successCallback: res => this.store.updateState(res.data),
errorCallback(err) {
throw new Error(err);
},

View file

@ -1,29 +1,20 @@
import Vue from 'vue';
import VueResource from 'vue-resource';
Vue.use(VueResource);
import axios from '../../lib/utils/axios_utils';
export default class Service {
constructor(endpoint) {
this.endpoint = endpoint;
this.resource = Vue.resource(`${this.endpoint}.json`, {}, {
realtimeChanges: {
method: 'GET',
url: `${this.endpoint}/realtime_changes`,
},
});
this.endpoint = `${endpoint}.json`;
this.realtimeEndpoint = `${endpoint}/realtime_changes`;
}
getData() {
return this.resource.realtimeChanges();
return axios.get(this.realtimeEndpoint);
}
deleteIssuable() {
return this.resource.delete();
return axios.delete(this.endpoint);
}
updateIssuable(data) {
return this.resource.update(data);
return axios.put(this.endpoint, data);
}
}

View file

@ -232,7 +232,7 @@ export const nodeMatchesSelector = (node, selector) => {
export const normalizeHeaders = (headers) => {
const upperCaseHeaders = {};
Object.keys(headers).forEach((e) => {
Object.keys(headers || {}).forEach((e) => {
upperCaseHeaders[e.toUpperCase()] = headers[e];
});

View file

@ -1,4 +1,6 @@
import Vue from 'vue';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import '~/render_math';
import '~/render_gfm';
import * as urlUtils from '~/lib/utils/url_utility';
@ -11,26 +13,29 @@ function formatText(text) {
return text.trim().replace(/\s\s+/g, ' ');
}
const REALTIME_REQUEST_STACK = [
issueShowData.initialRequest,
issueShowData.secondRequest,
];
describe('Issuable output', () => {
let requestData = issueShowData.initialRequest;
let mock;
let realtimeRequestCount = 0;
let vm;
document.body.innerHTML = '<span id="task_status"></span>';
const interceptor = (request, next) => {
next(request.respondWith(JSON.stringify(requestData), {
status: 200,
}));
};
let vm;
beforeEach((done) => {
spyOn(eventHub, '$emit');
const IssuableDescriptionComponent = Vue.extend(issuableApp);
requestData = issueShowData.initialRequest;
Vue.http.interceptors.push(interceptor);
mock = new MockAdapter(axios);
mock.onGet('/gitlab-org/gitlab-shell/issues/9/realtime_changes/realtime_changes').reply(() => {
const res = Promise.resolve([200, REALTIME_REQUEST_STACK[realtimeRequestCount]]);
realtimeRequestCount += 1;
return res;
});
vm = new IssuableDescriptionComponent({
propsData: {
@ -54,10 +59,10 @@ describe('Issuable output', () => {
});
afterEach(() => {
Vue.http.interceptors = _.without(Vue.http.interceptors, interceptor);
mock.reset();
realtimeRequestCount = 0;
vm.poll.stop();
vm.$destroy();
});
@ -77,7 +82,6 @@ describe('Issuable output', () => {
expect(editedText.querySelector('time')).toBeTruthy();
})
.then(() => {
requestData = issueShowData.secondRequest;
vm.poll.makeRequest();
})
.then(() => new Promise(resolve => setTimeout(resolve)))
@ -141,24 +145,19 @@ describe('Issuable output', () => {
spyOn(vm.service, 'getData').and.callThrough();
spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => {
resolve({
json() {
return {
confidential: false,
web_url: location.pathname,
};
data: {
confidential: false,
web_url: location.pathname,
},
});
}));
vm.updateIssuable();
setTimeout(() => {
expect(
vm.service.getData,
).toHaveBeenCalled();
done();
});
vm.updateIssuable()
.then(() => {
expect(vm.service.getData).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
it('correctly updates issuable data', (done) => {
@ -166,29 +165,22 @@ describe('Issuable output', () => {
resolve();
}));
vm.updateIssuable();
setTimeout(() => {
expect(
vm.service.updateIssuable,
).toHaveBeenCalledWith(vm.formState);
expect(
eventHub.$emit,
).toHaveBeenCalledWith('close.form');
done();
});
vm.updateIssuable()
.then(() => {
expect(vm.service.updateIssuable).toHaveBeenCalledWith(vm.formState);
expect(eventHub.$emit).toHaveBeenCalledWith('close.form');
})
.then(done)
.catch(done.fail);
});
it('does not redirect if issue has not moved', (done) => {
spyOn(urlUtils, 'visitUrl');
spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => {
resolve({
json() {
return {
web_url: location.pathname,
confidential: vm.isConfidential,
};
data: {
web_url: location.pathname,
confidential: vm.isConfidential,
},
});
}));
@ -208,11 +200,9 @@ describe('Issuable output', () => {
spyOn(urlUtils, 'visitUrl');
spyOn(vm.service, 'updateIssuable').and.callFake(() => new Promise((resolve) => {
resolve({
json() {
return {
web_url: '/testing-issue-move',
confidential: vm.isConfidential,
};
data: {
web_url: '/testing-issue-move',
confidential: vm.isConfidential,
},
});
}));
@ -283,10 +273,8 @@ describe('Issuable output', () => {
let modal;
const promise = new Promise((resolve) => {
resolve({
json() {
return {
recaptcha_html: '<div class="g-recaptcha">recaptcha_html</div>',
};
data: {
recaptcha_html: '<div class="g-recaptcha">recaptcha_html</div>',
},
});
});
@ -323,8 +311,8 @@ describe('Issuable output', () => {
spyOn(urlUtils, 'visitUrl');
spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve) => {
resolve({
json() {
return { web_url: '/test' };
data: {
web_url: '/test',
},
});
}));
@ -345,8 +333,8 @@ describe('Issuable output', () => {
spyOn(vm.poll, 'stop').and.callThrough();
spyOn(vm.service, 'deleteIssuable').and.callFake(() => new Promise((resolve) => {
resolve({
json() {
return { web_url: '/test' };
data: {
web_url: '/test',
},
});
}));
@ -385,22 +373,21 @@ describe('Issuable output', () => {
describe('open form', () => {
it('shows locked warning if form is open & data is different', (done) => {
Vue.nextTick()
vm.$nextTick()
.then(() => {
vm.openForm();
requestData = issueShowData.secondRequest;
vm.poll.makeRequest();
})
.then(() => new Promise(resolve => setTimeout(resolve)))
// Wait for the request
.then(vm.$nextTick)
// Wait for the successCallback to update the store state
.then(vm.$nextTick)
// Wait for the new state to flow to the Vue components
.then(vm.$nextTick)
.then(() => {
expect(
vm.formState.lockedWarningVisible,
).toBeTruthy();
expect(
vm.$el.querySelector('.alert'),
).not.toBeNull();
expect(vm.formState.lockedWarningVisible).toEqual(true);
expect(vm.$el.querySelector('.alert')).not.toBeNull();
})
.then(done)
.catch(done.fail);

View file

@ -19,14 +19,4 @@ export default {
updated_by_name: 'Other User',
updated_by_path: '/other_user',
},
issueSpecRequest: {
title: '<p>this is a title</p>',
title_text: 'this is a title',
description: '<li class="task-list-item enabled"><input type="checkbox" class="task-list-item-checkbox">Task List Item</li>',
description_text: '- [ ] Task List Item',
task_status: '0 of 1 completed',
updated_at: '2017-05-15T12:31:04.428Z',
updated_by_name: 'Last User',
updated_by_path: '/last_user',
},
};