Merge branch 'ph-ajax-to-axios' into 'master'

Converted $.ajax calls in some JS files to axios

See merge request gitlab-org/gitlab-ce!16717
This commit is contained in:
Filipa Lacerda 2018-01-31 09:37:23 +00:00
commit afcd9fc7f4
15 changed files with 231 additions and 285 deletions

View file

@ -1,9 +1,9 @@
import $ from 'jquery'; import _ from 'underscore';
import axios from './lib/utils/axios_utils'; import axios from './lib/utils/axios_utils';
const Api = { const Api = {
groupsPath: '/api/:version/groups.json', groupsPath: '/api/:version/groups.json',
groupPath: '/api/:version/groups/:id.json', groupPath: '/api/:version/groups/:id',
namespacesPath: '/api/:version/namespaces.json', namespacesPath: '/api/:version/namespaces.json',
groupProjectsPath: '/api/:version/groups/:id/projects.json', groupProjectsPath: '/api/:version/groups/:id/projects.json',
projectsPath: '/api/:version/projects.json', projectsPath: '/api/:version/projects.json',
@ -23,42 +23,44 @@ const Api = {
group(groupId, callback) { group(groupId, callback) {
const url = Api.buildUrl(Api.groupPath) const url = Api.buildUrl(Api.groupPath)
.replace(':id', groupId); .replace(':id', groupId);
return $.ajax({ return axios.get(url)
url, .then(({ data }) => {
dataType: 'json', callback(data);
})
.done(group => callback(group)); return data;
});
}, },
// Return groups list. Filtered by query // Return groups list. Filtered by query
groups(query, options, callback) { groups(query, options, callback) {
const url = Api.buildUrl(Api.groupsPath); const url = Api.buildUrl(Api.groupsPath);
return $.ajax({ return axios.get(url, {
url, params: Object.assign({
data: Object.assign({
search: query, search: query,
per_page: 20, per_page: 20,
}, options), }, options),
dataType: 'json',
}) })
.done(groups => callback(groups)); .then(({ data }) => {
callback(data);
return data;
});
}, },
// Return namespaces list. Filtered by query // Return namespaces list. Filtered by query
namespaces(query, callback) { namespaces(query, callback) {
const url = Api.buildUrl(Api.namespacesPath); const url = Api.buildUrl(Api.namespacesPath);
return $.ajax({ return axios.get(url, {
url, params: {
data: {
search: query, search: query,
per_page: 20, per_page: 20,
}, },
dataType: 'json', })
}).done(namespaces => callback(namespaces)); .then(({ data }) => callback(data));
}, },
// Return projects list. Filtered by query // Return projects list. Filtered by query
projects(query, options, callback) { projects(query, options, callback = _.noop) {
const url = Api.buildUrl(Api.projectsPath); const url = Api.buildUrl(Api.projectsPath);
const defaults = { const defaults = {
search: query, search: query,
@ -70,12 +72,14 @@ const Api = {
defaults.membership = true; defaults.membership = true;
} }
return $.ajax({ return axios.get(url, {
url, params: Object.assign(defaults, options),
data: Object.assign(defaults, options),
dataType: 'json',
}) })
.done(projects => callback(projects)); .then(({ data }) => {
callback(data);
return data;
});
}, },
// Return single project // Return single project
@ -97,41 +101,34 @@ const Api = {
url = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespacePath); url = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespacePath);
} }
return $.ajax({ return axios.post(url, {
url, label: data,
type: 'POST',
data: { label: data },
dataType: 'json',
}) })
.done(label => callback(label)) .then(res => callback(res.data))
.fail(message => callback(message.responseJSON)); .catch(e => callback(e.response.data));
}, },
// Return group projects list. Filtered by query // Return group projects list. Filtered by query
groupProjects(groupId, query, callback) { groupProjects(groupId, query, callback) {
const url = Api.buildUrl(Api.groupProjectsPath) const url = Api.buildUrl(Api.groupProjectsPath)
.replace(':id', groupId); .replace(':id', groupId);
return $.ajax({ return axios.get(url, {
url, params: {
data: {
search: query, search: query,
per_page: 20, per_page: 20,
}, },
dataType: 'json',
}) })
.done(projects => callback(projects)); .then(({ data }) => callback(data));
}, },
commitMultiple(id, data) { commitMultiple(id, data) {
// see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions // see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
const url = Api.buildUrl(Api.commitPath) const url = Api.buildUrl(Api.commitPath)
.replace(':id', encodeURIComponent(id)); .replace(':id', encodeURIComponent(id));
return this.wrapAjaxCall({ return axios.post(url, JSON.stringify(data), {
url, headers: {
type: 'POST', 'Content-Type': 'application/json; charset=utf-8',
contentType: 'application/json; charset=utf-8', },
data: JSON.stringify(data),
dataType: 'json',
}); });
}, },
@ -140,40 +137,37 @@ const Api = {
.replace(':id', encodeURIComponent(id)) .replace(':id', encodeURIComponent(id))
.replace(':branch', branch); .replace(':branch', branch);
return this.wrapAjaxCall({ return axios.get(url);
url,
type: 'GET',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
});
}, },
// Return text for a specific license // Return text for a specific license
licenseText(key, data, callback) { licenseText(key, data, callback) {
const url = Api.buildUrl(Api.licensePath) const url = Api.buildUrl(Api.licensePath)
.replace(':key', key); .replace(':key', key);
return $.ajax({ return axios.get(url, {
url, params: data,
data,
}) })
.done(license => callback(license)); .then(res => callback(res.data));
}, },
gitignoreText(key, callback) { gitignoreText(key, callback) {
const url = Api.buildUrl(Api.gitignorePath) const url = Api.buildUrl(Api.gitignorePath)
.replace(':key', key); .replace(':key', key);
return $.get(url, gitignore => callback(gitignore)); return axios.get(url)
.then(({ data }) => callback(data));
}, },
gitlabCiYml(key, callback) { gitlabCiYml(key, callback) {
const url = Api.buildUrl(Api.gitlabCiYmlPath) const url = Api.buildUrl(Api.gitlabCiYmlPath)
.replace(':key', key); .replace(':key', key);
return $.get(url, file => callback(file)); return axios.get(url)
.then(({ data }) => callback(data));
}, },
dockerfileYml(key, callback) { dockerfileYml(key, callback) {
const url = Api.buildUrl(Api.dockerfilePath).replace(':key', key); const url = Api.buildUrl(Api.dockerfilePath).replace(':key', key);
$.get(url, callback); return axios.get(url)
.then(({ data }) => callback(data));
}, },
issueTemplate(namespacePath, projectPath, key, type, callback) { issueTemplate(namespacePath, projectPath, key, type, callback) {
@ -182,23 +176,18 @@ const Api = {
.replace(':type', type) .replace(':type', type)
.replace(':project_path', projectPath) .replace(':project_path', projectPath)
.replace(':namespace_path', namespacePath); .replace(':namespace_path', namespacePath);
$.ajax({ return axios.get(url)
url, .then(({ data }) => callback(null, data))
dataType: 'json', .catch(callback);
})
.done(file => callback(null, file))
.fail(callback);
}, },
users(query, options) { users(query, options) {
const url = Api.buildUrl(this.usersPath); const url = Api.buildUrl(this.usersPath);
return Api.wrapAjaxCall({ return axios.get(url, {
url, params: Object.assign({
data: Object.assign({
search: query, search: query,
per_page: 20, per_page: 20,
}, options), }, options),
dataType: 'json',
}); });
}, },
@ -209,21 +198,6 @@ const Api = {
} }
return urlRoot + url.replace(':version', gon.api_version); return urlRoot + url.replace(':version', gon.api_version);
}, },
wrapAjaxCall(options) {
return new Promise((resolve, reject) => {
// jQuery 2 is not Promises/A+ compatible (missing catch)
$.ajax(options) // eslint-disable-line promise/catch-or-return
.then(data => resolve(data),
(jqXHR, textStatus, errorThrown) => {
const error = new Error(`${options.url}: ${errorThrown}`);
error.textStatus = textStatus;
if (jqXHR && jqXHR.responseJSON) error.responseJSON = jqXHR.responseJSON;
reject(error);
},
);
});
},
}; };
export default Api; export default Api;

View file

@ -1,5 +1,6 @@
import Flash from '../../flash'; import Flash from '../../flash';
import { handleLocationHash } from '../../lib/utils/common_utils'; import { handleLocationHash } from '../../lib/utils/common_utils';
import axios from '../../lib/utils/axios_utils';
export default class BlobViewer { export default class BlobViewer {
constructor() { constructor() {
@ -127,25 +128,18 @@ export default class BlobViewer {
const viewer = viewerParam; const viewer = viewerParam;
const url = viewer.getAttribute('data-url'); const url = viewer.getAttribute('data-url');
return new Promise((resolve, reject) => { if (!url || viewer.getAttribute('data-loaded') || viewer.getAttribute('data-loading')) {
if (!url || viewer.getAttribute('data-loaded') || viewer.getAttribute('data-loading')) { return Promise.resolve(viewer);
resolve(viewer); }
return;
}
viewer.setAttribute('data-loading', 'true'); viewer.setAttribute('data-loading', 'true');
$.ajax({ return axios.get(url)
url, .then(({ data }) => {
dataType: 'JSON',
})
.fail(reject)
.done((data) => {
viewer.innerHTML = data.html; viewer.innerHTML = data.html;
viewer.setAttribute('data-loaded', 'true'); viewer.setAttribute('data-loaded', 'true');
resolve(viewer); return viewer;
}); });
});
} }
} }

View file

@ -5,6 +5,7 @@
import { pluralize } from './lib/utils/text_utility'; import { pluralize } from './lib/utils/text_utility';
import { localTimeAgo } from './lib/utils/datetime_utility'; import { localTimeAgo } from './lib/utils/datetime_utility';
import Pager from './pager'; import Pager from './pager';
import axios from './lib/utils/axios_utils';
export default (function () { export default (function () {
const CommitsList = {}; const CommitsList = {};
@ -43,29 +44,30 @@ export default (function () {
CommitsList.filterResults = function () { CommitsList.filterResults = function () {
const form = $('.commits-search-form'); const form = $('.commits-search-form');
const search = CommitsList.searchField.val(); const search = CommitsList.searchField.val();
if (search === CommitsList.lastSearch) return; if (search === CommitsList.lastSearch) return Promise.resolve();
const commitsUrl = form.attr('action') + '?' + form.serialize(); const commitsUrl = form.attr('action') + '?' + form.serialize();
CommitsList.content.fadeTo('fast', 0.5); CommitsList.content.fadeTo('fast', 0.5);
return $.ajax({ const params = form.serializeArray().reduce((acc, obj) => Object.assign(acc, {
type: 'GET', [obj.name]: obj.value,
url: form.attr('action'), }), {});
data: form.serialize(),
complete: function () { return axios.get(form.attr('action'), {
return CommitsList.content.fadeTo('fast', 1.0); params,
}, })
success: function (data) { .then(({ data }) => {
CommitsList.lastSearch = search; CommitsList.lastSearch = search;
CommitsList.content.html(data.html); CommitsList.content.html(data.html);
return history.replaceState({ CommitsList.content.fadeTo('fast', 1.0);
page: commitsUrl,
// Change url so if user reload a page - search results are saved // Change url so if user reload a page - search results are saved
history.replaceState({
page: commitsUrl,
}, document.title, commitsUrl); }, document.title, commitsUrl);
}, })
error: function () { .catch(() => {
CommitsList.content.fadeTo('fast', 1.0);
CommitsList.lastSearch = null; CommitsList.lastSearch = null;
}, });
dataType: 'json',
});
}; };
// Prepare loaded data. // Prepare loaded data.

View file

@ -71,7 +71,7 @@ export const setResizingStatus = ({ commit }, resizing) => {
export const checkCommitStatus = ({ state }) => export const checkCommitStatus = ({ state }) =>
service service
.getBranchData(state.currentProjectId, state.currentBranchId) .getBranchData(state.currentProjectId, state.currentBranchId)
.then((data) => { .then(({ data }) => {
const { id } = data.commit; const { id } = data.commit;
const selectedBranch = const selectedBranch =
state.projects[state.currentProjectId].branches[state.currentBranchId]; state.projects[state.currentProjectId].branches[state.currentBranchId];
@ -90,7 +90,7 @@ export const commitChanges = (
) => ) =>
service service
.commit(state.currentProjectId, payload) .commit(state.currentProjectId, payload)
.then((data) => { .then(({ data }) => {
const { branch } = payload; const { branch } = payload;
if (!data.short_id) { if (!data.short_id) {
flash(data.message, 'alert', document, null, false, true); flash(data.message, 'alert', document, null, false, true);
@ -147,8 +147,8 @@ export const commitChanges = (
}) })
.catch((err) => { .catch((err) => {
let errMsg = 'Error committing changes. Please try again.'; let errMsg = 'Error committing changes. Please try again.';
if (err.responseJSON && err.responseJSON.message) { if (err.response.data && err.response.data.message) {
errMsg += ` (${stripHtml(err.responseJSON.message)})`; errMsg += ` (${stripHtml(err.response.data.message)})`;
} }
flash(errMsg, 'alert', document, null, false, true); flash(errMsg, 'alert', document, null, false, true);
window.dispatchEvent(new Event('resize')); window.dispatchEvent(new Event('resize'));

View file

@ -10,7 +10,7 @@ export const getBranchData = (
!state.projects[`${projectId}`].branches[branchId]) !state.projects[`${projectId}`].branches[branchId])
|| force) { || force) {
service.getBranchData(`${projectId}`, branchId) service.getBranchData(`${projectId}`, branchId)
.then((data) => { .then(({ data }) => {
const { id } = data.commit; const { id } = data.commit;
commit(types.SET_BRANCH, { projectPath: `${projectId}`, branchName: branchId, branch: data }); commit(types.SET_BRANCH, { projectPath: `${projectId}`, branchName: branchId, branch: data });
commit(types.SET_BRANCH_WORKING_REFERENCE, { projectId, branchId, reference: id }); commit(types.SET_BRANCH_WORKING_REFERENCE, { projectId, branchId, reference: id });

View file

@ -8,16 +8,16 @@ class UsersCache extends Cache {
} }
return Api.users('', { username }) return Api.users('', { username })
.then((users) => { .then(({ data }) => {
if (!users.length) { if (!data.length) {
throw new Error(`User "${username}" could not be found!`); throw new Error(`User "${username}" could not be found!`);
} }
if (users.length > 1) { if (data.length > 1) {
throw new Error(`Expected username "${username}" to be unique!`); throw new Error(`Expected username "${username}" to be unique!`);
} }
const user = users[0]; const user = data[0];
this.internalStorage[username] = user; this.internalStorage[username] = user;
return user; return user;
}); });

View file

@ -122,7 +122,7 @@ feature 'Project > Members > Share with Group', :js do
select2 group.id, from: '#link_group_id' select2 group.id, from: '#link_group_id'
fill_in 'expires_at_groups', with: (Time.now + 4.5.days).strftime('%Y-%m-%d') fill_in 'expires_at_groups', with: (Time.now + 4.5.days).strftime('%Y-%m-%d')
page.find('body').click click_on 'share-with-group-tab'
find('.btn-create').click find('.btn-create').click
end end

View file

@ -1,3 +1,5 @@
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import Api from '~/api'; import Api from '~/api';
describe('Api', () => { describe('Api', () => {
@ -7,20 +9,17 @@ describe('Api', () => {
api_version: dummyApiVersion, api_version: dummyApiVersion,
relative_url_root: dummyUrlRoot, relative_url_root: dummyUrlRoot,
}; };
const dummyResponse = 'hello from outer space!';
const sendDummyResponse = () => {
const deferred = $.Deferred();
deferred.resolve(dummyResponse);
return deferred.promise();
};
let originalGon; let originalGon;
let mock;
beforeEach(() => { beforeEach(() => {
mock = new MockAdapter(axios);
originalGon = window.gon; originalGon = window.gon;
window.gon = Object.assign({}, dummyGon); window.gon = Object.assign({}, dummyGon);
}); });
afterEach(() => { afterEach(() => {
mock.restore();
window.gon = originalGon; window.gon = originalGon;
}); });
@ -38,15 +37,13 @@ describe('Api', () => {
describe('group', () => { describe('group', () => {
it('fetches a group', (done) => { it('fetches a group', (done) => {
const groupId = '123456'; const groupId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}.json`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}`;
spyOn(jQuery, 'ajax').and.callFake((request) => { mock.onGet(expectedUrl).reply(200, {
expect(request.url).toEqual(expectedUrl); name: 'test',
expect(request.dataType).toEqual('json');
return sendDummyResponse();
}); });
Api.group(groupId, (response) => { Api.group(groupId, (response) => {
expect(response).toBe(dummyResponse); expect(response.name).toBe('test');
done(); done();
}); });
}); });
@ -57,19 +54,13 @@ describe('Api', () => {
const query = 'dummy query'; const query = 'dummy query';
const options = { unused: 'option' }; const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups.json`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups.json`;
const expectedData = Object.assign({ mock.onGet(expectedUrl).reply(200, [{
search: query, name: 'test',
per_page: 20, }]);
}, options);
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.dataType).toEqual('json');
expect(request.data).toEqual(expectedData);
return sendDummyResponse();
});
Api.groups(query, options, (response) => { Api.groups(query, options, (response) => {
expect(response).toBe(dummyResponse); expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done(); done();
}); });
}); });
@ -79,19 +70,13 @@ describe('Api', () => {
it('fetches namespaces', (done) => { it('fetches namespaces', (done) => {
const query = 'dummy query'; const query = 'dummy query';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/namespaces.json`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/namespaces.json`;
const expectedData = { mock.onGet(expectedUrl).reply(200, [{
search: query, name: 'test',
per_page: 20, }]);
};
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.dataType).toEqual('json');
expect(request.data).toEqual(expectedData);
return sendDummyResponse();
});
Api.namespaces(query, (response) => { Api.namespaces(query, (response) => {
expect(response).toBe(dummyResponse); expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done(); done();
}); });
}); });
@ -103,21 +88,13 @@ describe('Api', () => {
const options = { unused: 'option' }; const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json`;
window.gon.current_user_id = 1; window.gon.current_user_id = 1;
const expectedData = Object.assign({ mock.onGet(expectedUrl).reply(200, [{
search: query, name: 'test',
per_page: 20, }]);
membership: true,
simple: true,
}, options);
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.dataType).toEqual('json');
expect(request.data).toEqual(expectedData);
return sendDummyResponse();
});
Api.projects(query, options, (response) => { Api.projects(query, options, (response) => {
expect(response).toBe(dummyResponse); expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done(); done();
}); });
}); });
@ -126,20 +103,13 @@ describe('Api', () => {
const query = 'dummy query'; const query = 'dummy query';
const options = { unused: 'option' }; const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json`;
const expectedData = Object.assign({ mock.onGet(expectedUrl).reply(200, [{
search: query, name: 'test',
per_page: 20, }]);
simple: true,
}, options);
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.dataType).toEqual('json');
expect(request.data).toEqual(expectedData);
return sendDummyResponse();
});
Api.projects(query, options, (response) => { Api.projects(query, options, (response) => {
expect(response).toBe(dummyResponse); expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done(); done();
}); });
}); });
@ -154,16 +124,16 @@ describe('Api', () => {
const expectedData = { const expectedData = {
label: labelData, label: labelData,
}; };
spyOn(jQuery, 'ajax').and.callFake((request) => { mock.onPost(expectedUrl).reply((config) => {
expect(request.url).toEqual(expectedUrl); expect(config.data).toBe(JSON.stringify(expectedData));
expect(request.dataType).toEqual('json');
expect(request.type).toEqual('POST'); return [200, {
expect(request.data).toEqual(expectedData); name: 'test',
return sendDummyResponse(); }];
}); });
Api.newLabel(namespace, project, labelData, (response) => { Api.newLabel(namespace, project, labelData, (response) => {
expect(response).toBe(dummyResponse); expect(response.name).toBe('test');
done(); done();
}); });
}); });
@ -174,19 +144,13 @@ describe('Api', () => {
const groupId = '123456'; const groupId = '123456';
const query = 'dummy query'; const query = 'dummy query';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/projects.json`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/projects.json`;
const expectedData = { mock.onGet(expectedUrl).reply(200, [{
search: query, name: 'test',
per_page: 20, }]);
};
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.dataType).toEqual('json');
expect(request.data).toEqual(expectedData);
return sendDummyResponse();
});
Api.groupProjects(groupId, query, (response) => { Api.groupProjects(groupId, query, (response) => {
expect(response).toBe(dummyResponse); expect(response.length).toBe(1);
expect(response[0].name).toBe('test');
done(); done();
}); });
}); });
@ -197,14 +161,10 @@ describe('Api', () => {
const licenseKey = "driver's license"; const licenseKey = "driver's license";
const data = { unused: 'option' }; const data = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/licenses/${licenseKey}`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/licenses/${licenseKey}`;
spyOn(jQuery, 'ajax').and.callFake((request) => { mock.onGet(expectedUrl).reply(200, 'test');
expect(request.url).toEqual(expectedUrl);
expect(request.data).toEqual(data);
return sendDummyResponse();
});
Api.licenseText(licenseKey, data, (response) => { Api.licenseText(licenseKey, data, (response) => {
expect(response).toBe(dummyResponse); expect(response).toBe('test');
done(); done();
}); });
}); });
@ -214,13 +174,10 @@ describe('Api', () => {
it('fetches a gitignore text', (done) => { it('fetches a gitignore text', (done) => {
const gitignoreKey = 'ignore git'; const gitignoreKey = 'ignore git';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/gitignores/${gitignoreKey}`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/gitignores/${gitignoreKey}`;
spyOn(jQuery, 'get').and.callFake((url, callback) => { mock.onGet(expectedUrl).reply(200, 'test');
expect(url).toEqual(expectedUrl);
callback(dummyResponse);
});
Api.gitignoreText(gitignoreKey, (response) => { Api.gitignoreText(gitignoreKey, (response) => {
expect(response).toBe(dummyResponse); expect(response).toBe('test');
done(); done();
}); });
}); });
@ -230,13 +187,10 @@ describe('Api', () => {
it('fetches a .gitlab-ci.yml', (done) => { it('fetches a .gitlab-ci.yml', (done) => {
const gitlabCiYmlKey = 'Y CI ML'; const gitlabCiYmlKey = 'Y CI ML';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/gitlab_ci_ymls/${gitlabCiYmlKey}`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/gitlab_ci_ymls/${gitlabCiYmlKey}`;
spyOn(jQuery, 'get').and.callFake((url, callback) => { mock.onGet(expectedUrl).reply(200, 'test');
expect(url).toEqual(expectedUrl);
callback(dummyResponse);
});
Api.gitlabCiYml(gitlabCiYmlKey, (response) => { Api.gitlabCiYml(gitlabCiYmlKey, (response) => {
expect(response).toBe(dummyResponse); expect(response).toBe('test');
done(); done();
}); });
}); });
@ -246,13 +200,10 @@ describe('Api', () => {
it('fetches a Dockerfile', (done) => { it('fetches a Dockerfile', (done) => {
const dockerfileYmlKey = 'a giant whale'; const dockerfileYmlKey = 'a giant whale';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/dockerfiles/${dockerfileYmlKey}`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/dockerfiles/${dockerfileYmlKey}`;
spyOn(jQuery, 'get').and.callFake((url, callback) => { mock.onGet(expectedUrl).reply(200, 'test');
expect(url).toEqual(expectedUrl);
callback(dummyResponse);
});
Api.dockerfileYml(dockerfileYmlKey, (response) => { Api.dockerfileYml(dockerfileYmlKey, (response) => {
expect(response).toBe(dummyResponse); expect(response).toBe('test');
done(); done();
}); });
}); });
@ -265,14 +216,10 @@ describe('Api', () => {
const templateKey = ' template #%?.key '; const templateKey = ' template #%?.key ';
const templateType = 'template type'; const templateType = 'template type';
const expectedUrl = `${dummyUrlRoot}/${namespace}/${project}/templates/${templateType}/${encodeURIComponent(templateKey)}`; const expectedUrl = `${dummyUrlRoot}/${namespace}/${project}/templates/${templateType}/${encodeURIComponent(templateKey)}`;
spyOn(jQuery, 'ajax').and.callFake((request) => { mock.onGet(expectedUrl).reply(200, 'test');
expect(request.url).toEqual(expectedUrl);
return sendDummyResponse();
});
Api.issueTemplate(namespace, project, templateKey, templateType, (error, response) => { Api.issueTemplate(namespace, project, templateKey, templateType, (error, response) => {
expect(error).toBe(null); expect(response).toBe('test');
expect(response).toBe(dummyResponse);
done(); done();
}); });
}); });
@ -283,20 +230,14 @@ describe('Api', () => {
const query = 'dummy query'; const query = 'dummy query';
const options = { unused: 'option' }; const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users.json`; const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users.json`;
const expectedData = Object.assign({ mock.onGet(expectedUrl).reply(200, [{
search: query, name: 'test',
per_page: 20, }]);
}, options);
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.dataType).toEqual('json');
expect(request.data).toEqual(expectedData);
return sendDummyResponse();
});
Api.users(query, options) Api.users(query, options)
.then((response) => { .then(({ data }) => {
expect(response).toBe(dummyResponse); expect(data.length).toBe(1);
expect(data[0].name).toBe('test');
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);

View file

@ -1,28 +1,35 @@
/* eslint-disable no-new */ /* eslint-disable no-new */
import MockAdapter from 'axios-mock-adapter';
import BlobViewer from '~/blob/viewer/index'; import BlobViewer from '~/blob/viewer/index';
import axios from '~/lib/utils/axios_utils';
describe('Blob viewer', () => { describe('Blob viewer', () => {
let blob; let blob;
let mock;
preloadFixtures('snippets/show.html.raw'); preloadFixtures('snippets/show.html.raw');
beforeEach(() => { beforeEach(() => {
mock = new MockAdapter(axios);
loadFixtures('snippets/show.html.raw'); loadFixtures('snippets/show.html.raw');
$('#modal-upload-blob').remove(); $('#modal-upload-blob').remove();
blob = new BlobViewer(); blob = new BlobViewer();
spyOn($, 'ajax').and.callFake(() => { mock.onGet('http://test.host/snippets/1.json?viewer=rich').reply(200, {
const d = $.Deferred(); html: '<div>testing</div>',
d.resolve({
html: '<div>testing</div>',
});
return d.promise();
}); });
mock.onGet('http://test.host/snippets/1.json?viewer=simple').reply(200, {
html: '<div>testing</div>',
});
spyOn(axios, 'get').and.callThrough();
}); });
afterEach(() => { afterEach(() => {
mock.restore();
location.hash = ''; location.hash = '';
}); });
@ -30,7 +37,6 @@ describe('Blob viewer', () => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click(); document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => { setTimeout(() => {
expect($.ajax).toHaveBeenCalled();
expect( expect(
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]') document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
.classList.contains('hidden'), .classList.contains('hidden'),
@ -46,7 +52,6 @@ describe('Blob viewer', () => {
new BlobViewer(); new BlobViewer();
setTimeout(() => { setTimeout(() => {
expect($.ajax).toHaveBeenCalled();
expect( expect(
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]') document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
.classList.contains('hidden'), .classList.contains('hidden'),
@ -64,12 +69,8 @@ describe('Blob viewer', () => {
}); });
asyncClick() asyncClick()
.then(() => asyncClick())
.then(() => { .then(() => {
expect($.ajax).toHaveBeenCalled();
return asyncClick();
})
.then(() => {
expect($.ajax.calls.count()).toBe(1);
expect( expect(
document.querySelector('.blob-viewer[data-type="simple"]').getAttribute('data-loaded'), document.querySelector('.blob-viewer[data-type="simple"]').getAttribute('data-loaded'),
).toBe('true'); ).toBe('true');
@ -122,7 +123,6 @@ describe('Blob viewer', () => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click(); document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => { setTimeout(() => {
expect($.ajax).toHaveBeenCalled();
expect( expect(
copyButton.classList.contains('disabled'), copyButton.classList.contains('disabled'),
).toBeFalsy(); ).toBeFalsy();
@ -135,8 +135,6 @@ describe('Blob viewer', () => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click(); document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
setTimeout(() => { setTimeout(() => {
expect($.ajax).toHaveBeenCalled();
expect( expect(
copyButton.getAttribute('data-original-title'), copyButton.getAttribute('data-original-title'),
).toBe('Copy source to clipboard'); ).toBe('Copy source to clipboard');
@ -171,14 +169,14 @@ describe('Blob viewer', () => {
it('sends AJAX request when switching to simple view', () => { it('sends AJAX request when switching to simple view', () => {
blob.switchToViewer('simple'); blob.switchToViewer('simple');
expect($.ajax).toHaveBeenCalled(); expect(axios.get).toHaveBeenCalled();
}); });
it('does not send AJAX request when switching to rich view', () => { it('does not send AJAX request when switching to rich view', () => {
blob.switchToViewer('simple'); blob.switchToViewer('simple');
blob.switchToViewer('rich'); blob.switchToViewer('rich');
expect($.ajax.calls.count()).toBe(1); expect(axios.get.calls.count()).toBe(1);
}); });
}); });
}); });

View file

@ -1,4 +1,6 @@
import 'vendor/jquery.endless-scroll'; import 'vendor/jquery.endless-scroll';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import CommitsList from '~/commits'; import CommitsList from '~/commits';
describe('Commits List', () => { describe('Commits List', () => {
@ -43,30 +45,47 @@ describe('Commits List', () => {
describe('on entering input', () => { describe('on entering input', () => {
let ajaxSpy; let ajaxSpy;
let mock;
beforeEach(() => { beforeEach(() => {
CommitsList.init(25); CommitsList.init(25);
CommitsList.searchField.val(''); CommitsList.searchField.val('');
spyOn(history, 'replaceState').and.stub(); spyOn(history, 'replaceState').and.stub();
ajaxSpy = spyOn(jQuery, 'ajax').and.callFake((req) => { mock = new MockAdapter(axios);
req.success({
data: '<li>Result</li>', mock.onGet('/h5bp/html5-boilerplate/commits/master').reply(200, {
}); html: '<li>Result</li>',
}); });
ajaxSpy = spyOn(axios, 'get').and.callThrough();
}); });
it('should save the last search string', () => { afterEach(() => {
mock.restore();
});
it('should save the last search string', (done) => {
CommitsList.searchField.val('GitLab'); CommitsList.searchField.val('GitLab');
CommitsList.filterResults(); CommitsList.filterResults()
expect(ajaxSpy).toHaveBeenCalled(); .then(() => {
expect(CommitsList.lastSearch).toEqual('GitLab'); expect(ajaxSpy).toHaveBeenCalled();
expect(CommitsList.lastSearch).toEqual('GitLab');
done();
})
.catch(done.fail);
}); });
it('should not make ajax call if the input does not change', () => { it('should not make ajax call if the input does not change', (done) => {
CommitsList.filterResults(); CommitsList.filterResults()
expect(ajaxSpy).not.toHaveBeenCalled(); .then(() => {
expect(CommitsList.lastSearch).toEqual(''); expect(ajaxSpy).not.toHaveBeenCalled();
expect(CommitsList.lastSearch).toEqual('');
done();
})
.catch(done.fail);
}); });
}); });
}); });

View file

@ -92,7 +92,9 @@ describe('UsersCache', () => {
apiSpy = (query, options) => { apiSpy = (query, options) => {
expect(query).toBe(''); expect(query).toBe('');
expect(options).toEqual({ username: dummyUsername }); expect(options).toEqual({ username: dummyUsername });
return Promise.resolve([dummyUser]); return Promise.resolve({
data: [dummyUser],
});
}; };
UsersCache.retrieve(dummyUsername) UsersCache.retrieve(dummyUsername)

View file

@ -18,8 +18,10 @@ describe('new file modal component', () => {
})); }));
spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({
commit: { data: {
id: '123branch', commit: {
id: '123branch',
},
}, },
})); }));

View file

@ -17,8 +17,10 @@ describe('new dropdown upload', () => {
})); }));
spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({
commit: { data: {
id: '123branch', commit: {
id: '123branch',
},
}, },
})); }));

View file

@ -87,8 +87,10 @@ describe('RepoCommitSection', () => {
changedFiles = JSON.parse(JSON.stringify(vm.$store.getters.changedFiles)); changedFiles = JSON.parse(JSON.stringify(vm.$store.getters.changedFiles));
spyOn(service, 'commit').and.returnValue(Promise.resolve({ spyOn(service, 'commit').and.returnValue(Promise.resolve({
short_id: '1', data: {
stats: {}, short_id: '1',
stats: {},
},
})); }));
}); });

View file

@ -178,7 +178,9 @@ describe('Multi-file store actions', () => {
it('calls service', (done) => { it('calls service', (done) => {
spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({
commit: { id: '123' }, data: {
commit: { id: '123' },
},
})); }));
store.dispatch('checkCommitStatus') store.dispatch('checkCommitStatus')
@ -192,7 +194,9 @@ describe('Multi-file store actions', () => {
it('returns true if current ref does not equal returned ID', (done) => { it('returns true if current ref does not equal returned ID', (done) => {
spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({
commit: { id: '123' }, data: {
commit: { id: '123' },
},
})); }));
store.dispatch('checkCommitStatus') store.dispatch('checkCommitStatus')
@ -206,7 +210,9 @@ describe('Multi-file store actions', () => {
it('returns false if current ref equals returned ID', (done) => { it('returns false if current ref equals returned ID', (done) => {
spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({ spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({
commit: { id: '1' }, data: {
commit: { id: '1' },
},
})); }));
store.dispatch('checkCommitStatus') store.dispatch('checkCommitStatus')
@ -250,13 +256,15 @@ describe('Multi-file store actions', () => {
describe('success', () => { describe('success', () => {
beforeEach(() => { beforeEach(() => {
spyOn(service, 'commit').and.returnValue(Promise.resolve({ spyOn(service, 'commit').and.returnValue(Promise.resolve({
id: '123456', data: {
short_id: '123', id: '123456',
message: 'test message', short_id: '123',
committed_date: 'date', message: 'test message',
stats: { committed_date: 'date',
additions: '1', stats: {
deletions: '2', additions: '1',
deletions: '2',
},
}, },
})); }));
}); });
@ -324,7 +332,9 @@ describe('Multi-file store actions', () => {
describe('failed', () => { describe('failed', () => {
beforeEach(() => { beforeEach(() => {
spyOn(service, 'commit').and.returnValue(Promise.resolve({ spyOn(service, 'commit').and.returnValue(Promise.resolve({
message: 'failed message', data: {
message: 'failed message',
},
})); }));
}); });