Commit 9d2d1042 authored by Clement Ho's avatar Clement Ho

Merge branch 'winh-frontend-api-users' into 'master'

Add users endpoint to frontend API class

See merge request !11374
parents 776d4ba5 035b7cc0
/* eslint-disable func-names, space-before-function-paren, quotes, object-shorthand, camelcase, no-var, comma-dangle, prefer-arrow-callback, quote-props, no-param-reassign, max-len */ import $ from 'jquery';
var Api = { const Api = {
groupsPath: "/api/:version/groups.json", groupsPath: '/api/:version/groups.json',
groupPath: "/api/:version/groups/:id.json", groupPath: '/api/:version/groups/:id.json',
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?simple=true", projectsPath: '/api/:version/projects.json?simple=true',
labelsPath: "/:namespace_path/:project_path/labels", labelsPath: '/:namespace_path/:project_path/labels',
licensePath: "/api/:version/templates/licenses/:key", licensePath: '/api/:version/templates/licenses/:key',
gitignorePath: "/api/:version/templates/gitignores/:key", gitignorePath: '/api/:version/templates/gitignores/:key',
gitlabCiYmlPath: "/api/:version/templates/gitlab_ci_ymls/:key", gitlabCiYmlPath: '/api/:version/templates/gitlab_ci_ymls/:key',
dockerfilePath: "/api/:version/templates/dockerfiles/:key", dockerfilePath: '/api/:version/templates/dockerfiles/:key',
issuableTemplatePath: "/:namespace_path/:project_path/templates/:type/:key", issuableTemplatePath: '/:namespace_path/:project_path/templates/:type/:key',
group: function(group_id, callback) { usersPath: '/api/:version/users.json',
var url = Api.buildUrl(Api.groupPath)
.replace(':id', group_id); group(groupId, callback) {
const url = Api.buildUrl(Api.groupPath)
.replace(':id', groupId);
return $.ajax({ return $.ajax({
url: url, url,
dataType: "json" dataType: 'json',
}).done(function(group) { })
return callback(group); .done(group => callback(group));
});
}, },
// Return groups list. Filtered by query // Return groups list. Filtered by query
groups: function(query, options, callback) { groups(query, options, callback) {
var url = Api.buildUrl(Api.groupsPath); const url = Api.buildUrl(Api.groupsPath);
return $.ajax({ return $.ajax({
url: url, url,
data: $.extend({ data: Object.assign({
search: query, search: query,
per_page: 20 per_page: 20,
}, options), }, options),
dataType: "json" dataType: 'json',
}).done(function(groups) { })
return callback(groups); .done(groups => callback(groups));
});
}, },
// Return namespaces list. Filtered by query // Return namespaces list. Filtered by query
namespaces: function(query, callback) { namespaces(query, callback) {
var url = Api.buildUrl(Api.namespacesPath); const url = Api.buildUrl(Api.namespacesPath);
return $.ajax({ return $.ajax({
url: url, url,
data: { data: {
search: query, search: query,
per_page: 20 per_page: 20,
}, },
dataType: "json" dataType: 'json',
}).done(function(namespaces) { }).done(namespaces => callback(namespaces));
return callback(namespaces);
});
}, },
// Return projects list. Filtered by query // Return projects list. Filtered by query
projects: function(query, options, callback) { projects(query, options, callback) {
var url = Api.buildUrl(Api.projectsPath); const url = Api.buildUrl(Api.projectsPath);
return $.ajax({ return $.ajax({
url: url, url,
data: $.extend({ data: Object.assign({
search: query, search: query,
per_page: 20, per_page: 20,
membership: true membership: true,
}, options), }, options),
dataType: "json" dataType: 'json',
}).done(function(projects) { })
return callback(projects); .done(projects => callback(projects));
});
}, },
newLabel: function(namespace_path, project_path, data, callback) {
var url = Api.buildUrl(Api.labelsPath) newLabel(namespacePath, projectPath, data, callback) {
.replace(':namespace_path', namespace_path) const url = Api.buildUrl(Api.labelsPath)
.replace(':project_path', project_path); .replace(':namespace_path', namespacePath)
.replace(':project_path', projectPath);
return $.ajax({ return $.ajax({
url: url, url,
type: "POST", type: 'POST',
data: { 'label': data }, data: { label: data },
dataType: "json" dataType: 'json',
}).done(function(label) { })
return callback(label); .done(label => callback(label))
}).error(function(message) { .error(message => callback(message.responseJSON));
return callback(message.responseJSON);
});
}, },
// Return group projects list. Filtered by query // Return group projects list. Filtered by query
groupProjects: function(group_id, query, callback) { groupProjects(groupId, query, callback) {
var url = Api.buildUrl(Api.groupProjectsPath) const url = Api.buildUrl(Api.groupProjectsPath)
.replace(':id', group_id); .replace(':id', groupId);
return $.ajax({ return $.ajax({
url: url, url,
data: { data: {
search: query, search: query,
per_page: 20 per_page: 20,
}, },
dataType: "json" dataType: 'json',
}).done(function(projects) { })
return callback(projects); .done(projects => callback(projects));
});
}, },
// Return text for a specific license // Return text for a specific license
licenseText: function(key, data, callback) { licenseText(key, data, callback) {
var url = Api.buildUrl(Api.licensePath) const url = Api.buildUrl(Api.licensePath)
.replace(':key', key); .replace(':key', key);
return $.ajax({ return $.ajax({
url: url, url,
data: data data,
}).done(function(license) { })
return callback(license); .done(license => callback(license));
});
}, },
gitignoreText: function(key, callback) {
var url = Api.buildUrl(Api.gitignorePath) gitignoreText(key, callback) {
const url = Api.buildUrl(Api.gitignorePath)
.replace(':key', key); .replace(':key', key);
return $.get(url, function(gitignore) { return $.get(url, gitignore => callback(gitignore));
return callback(gitignore);
});
}, },
gitlabCiYml: function(key, callback) {
var url = Api.buildUrl(Api.gitlabCiYmlPath) gitlabCiYml(key, callback) {
const url = Api.buildUrl(Api.gitlabCiYmlPath)
.replace(':key', key); .replace(':key', key);
return $.get(url, function(file) { return $.get(url, file => callback(file));
return callback(file);
});
}, },
dockerfileYml: function(key, callback) {
var url = Api.buildUrl(Api.dockerfilePath).replace(':key', key); dockerfileYml(key, callback) {
const url = Api.buildUrl(Api.dockerfilePath).replace(':key', key);
$.get(url, callback); $.get(url, callback);
}, },
issueTemplate: function(namespacePath, projectPath, key, type, callback) {
var url = Api.buildUrl(Api.issuableTemplatePath) issueTemplate(namespacePath, projectPath, key, type, callback) {
const url = Api.buildUrl(Api.issuableTemplatePath)
.replace(':key', key) .replace(':key', key)
.replace(':type', type) .replace(':type', type)
.replace(':project_path', projectPath) .replace(':project_path', projectPath)
.replace(':namespace_path', namespacePath); .replace(':namespace_path', namespacePath);
$.ajax({ $.ajax({
url: url, url,
dataType: 'json' dataType: 'json',
}).done(function(file) { })
callback(null, file); .done(file => callback(null, file))
}).error(callback); .error(callback);
}, },
buildUrl: function(url) {
users(query, options) {
const url = Api.buildUrl(this.usersPath);
return Api.wrapAjaxCall({
url,
data: Object.assign({
search: query,
per_page: 20,
}, options),
dataType: 'json',
});
},
buildUrl(url) {
let urlRoot = '';
if (gon.relative_url_root != null) { if (gon.relative_url_root != null) {
url = gon.relative_url_root + url; urlRoot = gon.relative_url_root;
} }
return 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;
reject(error);
},
);
});
},
}; };
window.Api = Api; export default Api;
/* global Api */
export default class FileTemplateSelector { export default class FileTemplateSelector {
constructor(mediator) { constructor(mediator) {
this.mediator = mediator; this.mediator = mediator;
...@@ -65,4 +63,3 @@ export default class FileTemplateSelector { ...@@ -65,4 +63,3 @@ export default class FileTemplateSelector {
this.reportSelection(opts); this.reportSelection(opts);
} }
} }
/* global Api */ import Api from '../../api';
import FileTemplateSelector from '../file_template_selector'; import FileTemplateSelector from '../file_template_selector';
......
/* global Api */ import Api from '../../api';
import FileTemplateSelector from '../file_template_selector'; import FileTemplateSelector from '../file_template_selector';
......
/* global Api */ import Api from '../../api';
import FileTemplateSelector from '../file_template_selector'; import FileTemplateSelector from '../file_template_selector';
......
/* global Api */ import Api from '../../api';
import FileTemplateSelector from '../file_template_selector'; import FileTemplateSelector from '../file_template_selector';
......
/* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, comma-dangle, prefer-template, quotes, no-param-reassign, wrap-iife, max-len */ /* eslint-disable func-names, space-before-function-paren, prefer-arrow-callback, comma-dangle, prefer-template, quotes, no-param-reassign, wrap-iife, max-len */
/* global Api */ import Api from './api';
class CreateLabelDropdown { class CreateLabelDropdown {
constructor ($el, namespacePath, projectPath) { constructor ($el, namespacePath, projectPath) {
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
prefer-arrow-callback, comma-dangle, consistent-return, yoda, prefer-arrow-callback, comma-dangle, consistent-return, yoda,
prefer-rest-params, prefer-spread, no-unused-vars, prefer-template, prefer-rest-params, prefer-spread, no-unused-vars, prefer-template,
promise/catch-or-return */ promise/catch-or-return */
/* global Api */ import Api from './api';
var slice = [].slice; var slice = [].slice;
......
/* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, one-var, vars-on-top, one-var-declaration-per-line, comma-dangle, object-shorthand, no-else-return, prefer-template, quotes, prefer-arrow-callback, no-param-reassign, no-cond-assign, max-len */ /* eslint-disable func-names, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, one-var, vars-on-top, one-var-declaration-per-line, comma-dangle, object-shorthand, no-else-return, prefer-template, quotes, prefer-arrow-callback, no-param-reassign, no-cond-assign, max-len */
/* global Api */ import Api from './api';
(function() { (function() {
window.NamespaceSelect = (function() { window.NamespaceSelect = (function() {
......
/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, no-var, comma-dangle, object-shorthand, one-var, one-var-declaration-per-line, no-else-return, quotes, max-len */ /* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, no-var, comma-dangle, object-shorthand, one-var, one-var-declaration-per-line, no-else-return, quotes, max-len */
/* global Api */ import Api from './api';
(function() { (function() {
this.ProjectSelect = (function() { this.ProjectSelect = (function() {
......
/* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, one-var, one-var-declaration-per-line, object-shorthand, prefer-arrow-callback, comma-dangle, prefer-template, quotes, no-else-return, max-len */ /* eslint-disable func-names, space-before-function-paren, wrap-iife, no-var, one-var, one-var-declaration-per-line, object-shorthand, prefer-arrow-callback, comma-dangle, prefer-template, quotes, no-else-return, max-len */
/* global Flash */ /* global Flash */
/* global Api */ import Api from './api';
(function() { (function() {
this.Search = (function() { this.Search = (function() {
......
/* eslint-disable comma-dangle, max-len, no-useless-return, no-param-reassign, max-len */ /* eslint-disable comma-dangle, max-len, no-useless-return, no-param-reassign, max-len */
/* global Api */ import Api from '../api';
import TemplateSelector from '../blob/template_selector'; import TemplateSelector from '../blob/template_selector';
......
import Api from '~/api';
describe('Api', () => {
const dummyApiVersion = 'v3000';
const dummyUrlRoot = 'http://host.invalid';
const dummyGon = {
api_version: dummyApiVersion,
relative_url_root: dummyUrlRoot,
};
const dummyResponse = 'hello from outer space!';
const sendDummyResponse = () => {
const deferred = $.Deferred();
deferred.resolve(dummyResponse);
return deferred.promise();
};
let originalGon;
beforeEach(() => {
originalGon = window.gon;
window.gon = dummyGon;
});
afterEach(() => {
window.gon = originalGon;
});
describe('buildUrl', () => {
it('adds URL root and fills in API version', () => {
const input = '/api/:version/foo/bar';
const expectedOutput = `${dummyUrlRoot}/api/${dummyApiVersion}/foo/bar`;
const builtUrl = Api.buildUrl(input);
expect(builtUrl).toEqual(expectedOutput);
});
});
describe('group', () => {
it('fetches a group', (done) => {
const groupId = '123456';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}.json`;
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.dataType).toEqual('json');
return sendDummyResponse();
});
Api.group(groupId, (response) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('groups', () => {
it('fetches groups', (done) => {
const query = 'dummy query';
const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups.json`;
const expectedData = Object.assign({
search: query,
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) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('namespaces', () => {
it('fetches namespaces', (done) => {
const query = 'dummy query';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/namespaces.json`;
const expectedData = {
search: query,
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) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('projects', () => {
it('fetches projects', (done) => {
const query = 'dummy query';
const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects.json?simple=true`;
const expectedData = Object.assign({
search: query,
per_page: 20,
membership: 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) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('newLabel', () => {
it('creates a new label', (done) => {
const namespace = 'some namespace';
const project = 'some project';
const labelData = { some: 'data' };
const expectedUrl = `${dummyUrlRoot}/${namespace}/${project}/labels`;
const expectedData = {
label: labelData,
};
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.dataType).toEqual('json');
expect(request.type).toEqual('POST');
expect(request.data).toEqual(expectedData);
return sendDummyResponse();
});
Api.newLabel(namespace, project, labelData, (response) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('groupProjects', () => {
it('fetches group projects', (done) => {
const groupId = '123456';
const query = 'dummy query';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${groupId}/projects.json`;
const expectedData = {
search: query,
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) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('licenseText', () => {
it('fetches a license text', (done) => {
const licenseKey = "driver's license";
const data = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/licenses/${licenseKey}`;
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
expect(request.data).toEqual(data);
return sendDummyResponse();
});
Api.licenseText(licenseKey, data, (response) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('gitignoreText', () => {
it('fetches a gitignore text', (done) => {
const gitignoreKey = 'ignore git';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/gitignores/${gitignoreKey}`;
spyOn(jQuery, 'get').and.callFake((url, callback) => {
expect(url).toEqual(expectedUrl);
callback(dummyResponse);
});
Api.gitignoreText(gitignoreKey, (response) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('gitlabCiYml', () => {
it('fetches a .gitlab-ci.yml', (done) => {
const gitlabCiYmlKey = 'Y CI ML';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/gitlab_ci_ymls/${gitlabCiYmlKey}`;
spyOn(jQuery, 'get').and.callFake((url, callback) => {
expect(url).toEqual(expectedUrl);
callback(dummyResponse);
});
Api.gitlabCiYml(gitlabCiYmlKey, (response) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('dockerfileYml', () => {
it('fetches a Dockerfile', (done) => {
const dockerfileYmlKey = 'a giant whale';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/templates/dockerfiles/${dockerfileYmlKey}`;
spyOn(jQuery, 'get').and.callFake((url, callback) => {
expect(url).toEqual(expectedUrl);
callback(dummyResponse);
});
Api.dockerfileYml(dockerfileYmlKey, (response) => {
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('issueTemplate', () => {
it('fetches an issue template', (done) => {
const namespace = 'some namespace';
const project = 'some project';
const templateKey = 'template key';
const templateType = 'template type';
const expectedUrl = `${dummyUrlRoot}/${namespace}/${project}/templates/${templateType}/${templateKey}`;
spyOn(jQuery, 'ajax').and.callFake((request) => {
expect(request.url).toEqual(expectedUrl);
return sendDummyResponse();
});
Api.issueTemplate(namespace, project, templateKey, templateType, (error, response) => {
expect(error).toBe(null);
expect(response).toBe(dummyResponse);
done();
});
});
});
describe('users', () => {
it('fetches users', (done) => {
const query = 'dummy query';
const options = { unused: 'option' };
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/users.json`;
const expectedData = Object.assign({
search: query,
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)
.then((response) => {
expect(response).toBe(dummyResponse);
})
.then(done)
.catch(done.fail);
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment