Skip to content

Commit 71affe4

Browse files
author
Hamlet Hakobyan
committed
Added support for create, edit, login, logout and execute. Made some refactoring.
1 parent 8ff4042 commit 71affe4

19 files changed

+441
-39
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
# angular-stream-api
22
A Workfront Stream API for AngularJS
3+
4+
Supported API version: 5.0, unsupported, internal

src/service/Api.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ function Api(config) {
2020
var parsedUrl = new Url(config.url);
2121

2222
var path;
23+
config.version = config.version || 'internal';
2324
if (config.version === 'internal' || config.version === 'unsupported') {
2425
path = '/attask/api-' + config.version;
2526
}
@@ -30,7 +31,8 @@ function Api(config) {
3031
}
3132
}
3233

33-
this.baseUrl = parsedUrl.protocol + '//' + parsedUrl.host + path;
34+
this.options = {};
35+
this.options.url = parsedUrl.protocol + '//' + parsedUrl.host + path;
3436
}
3537

3638
Api.prototype.Constants = require('./ApiConstants');
@@ -40,5 +42,10 @@ require('./request')(Api);
4042
require('./get')(Api);
4143
require('./copy')(Api);
4244
require('./count')(Api);
45+
require('./create')(Api);
46+
require('./edit')(Api);
47+
require('./login')(Api);
48+
require('./logout')(Api);
49+
require('./execute')(Api);
4350

4451
module.exports = Api;

src/service/count.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ module.exports = function(Api) {
55
var path = objCode + '/count';
66
return this.request(path, null, query, null, this.Methods.GET)
77
.then(function(response) {
8-
return response.data.count;
9-
});
8+
if(response.data && response.data.count) {
9+
return response.data.count;
10+
}
11+
12+
return this.promise.reject({message: 'Error'});
13+
}.bind(this));
1014
};
1115
};

src/service/create.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
module.exports = function(Api) {
4+
Api.prototype.create = function(objCode, data, fields) {
5+
return this.request(objCode, data, null, fields, this.Methods.POST);
6+
};
7+
};

src/service/edit.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
3+
var angular = require('angular');
4+
5+
module.exports = function(Api) {
6+
Api.prototype.edit = function(objCode, objID, data, fields) {
7+
if(!data) {
8+
throw new Error('You should pass edit data as \'data\' argument');
9+
}
10+
if(angular.isObject(objID) && ('ID' in objID)) {
11+
angular.extend(data, objID);
12+
} else if(typeof objID === 'string') {
13+
data.ID = objID;
14+
} else {
15+
throw new Error('You should pass \'objID\' as a string or object with property \'ID\'');
16+
}
17+
return this.request(objCode, data, null, fields, this.Methods.PUT);
18+
};
19+
};

src/service/execute.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
module.exports = function(Api) {
4+
Api.prototype.execute = function (objCode, objID, action, actionArgs) {
5+
var endPoint = objCode;
6+
if (objID) {
7+
endPoint += '/' + objID + '/' + action;
8+
}
9+
else {
10+
actionArgs = actionArgs || {};
11+
actionArgs['action'] = action;
12+
}
13+
return this.request(endPoint, actionArgs, null, this.Methods.PUT);
14+
};
15+
};

src/service/login.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
3+
module.exports = function(Api) {
4+
Api.prototype.login = function(username, password) {
5+
var params = {
6+
username: username,
7+
password: password
8+
};
9+
10+
this.request('login', null, params, null, this.Methods.POST)
11+
.then(function(response) {
12+
if(response.data && response.data.data) {
13+
this.options.sessionID = response.data.data.sessionID;
14+
return response.data.data;
15+
}
16+
17+
return this.promise.reject();
18+
}.bind(this));
19+
};
20+
};

src/service/logout.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
module.exports = function(Api) {
4+
Api.prototype.logout = function() {
5+
return this.request('logout', null, null, null, this.Methods.GET)
6+
.then(function(response) {
7+
if(response.data && response.data.success) {
8+
delete this.options.sessionID;
9+
return this.promise.resolve();
10+
}
11+
12+
return this.promise.reject();
13+
}.bind(this));
14+
};
15+
};

src/service/request.js

+8-9
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ var angular = require('angular');
55
module.exports = function(Api) {
66
Api.prototype.request = function(path, data, params, fields, method) {
77
this.config = {};
8-
this.config.url = this.baseUrl;
9-
path = path.indexOf('/') === 0 ? path : '/' + path;
10-
this.config.url = this.config.url + path;
8+
this.config = angular.extend({}, this.options);
9+
10+
var fullPath = path.indexOf('/') === 0 ? path : '/' + path;
11+
this.config.url = this.config.url + fullPath;
1112

1213
fields = fields || [];
1314
if(typeof fields === 'string') {
@@ -16,17 +17,15 @@ module.exports = function(Api) {
1617

1718
this.config.method = method;
1819
if(method === this.Methods.POST || method === this.Methods.PUT) {
19-
if(!data) {
20+
if(!data && path !== 'login') {
2021
throw new Error('You must specify \'data\' in case you have used PUT or POST');
2122
}
2223

2324
this.config.data = data;
24-
this.config.headers = {};
25+
this.config.headers = this.config.headers || {};
2526
this.config.headers['Content-Type'] = 'application/json;charset=utf-8';
26-
} else {
27-
if(data) {
28-
throw new Error('You must specify method PUT or POST in case have passed \'data\'');
29-
}
27+
} else if(data && path !== 'login') {
28+
throw new Error('You must specify method PUT or POST in case have passed \'data\'');
3029
}
3130

3231
params = params || {};

src/spec/Api.spec.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,25 @@ describe('Api', function() {
5555

5656
it('should set it\'s config.url correctly when passed correct url and not passed version', function() {
5757
var api = streamApiService.getInstance({url: 'https://foo'});
58-
expect(api.baseUrl)
59-
.toBe('https://foo/attask/api');
58+
expect(api.options.url)
59+
.toBe('https://foo/attask/api-internal');
6060
});
6161

6262
it('should set it\'s config.url when passed valid url and version unsupported', function() {
6363
var api = streamApiService.getInstance({url: 'https://foo', version: 'unsupported'});
64-
expect(api.baseUrl)
64+
expect(api.options.url)
6565
.toBe('https://foo/attask/api-unsupported');
6666
});
6767

6868
it('should set it\'s config.url when passed valid url and version internal', function() {
6969
var api = streamApiService.getInstance({url: 'https://foo', version: 'internal'});
70-
expect(api.baseUrl)
70+
expect(api.options.url)
7171
.toBe('https://foo/attask/api-internal');
7272
});
7373

7474
it('should set it\'s config.url when passed valid url and version number', function() {
7575
var api = streamApiService.getInstance({url: 'https://foo', version: '5.0'});
76-
expect(api.baseUrl)
76+
expect(api.options.url)
7777
.toBe('https://foo/attask/api/v5.0');
7878
});
7979

src/spec/copy.spec.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
var angular = require('angular');
66

7-
describe('get', function() {
7+
describe('copy', function() {
88
beforeEach(function() {
99
var ngModule = angular.module('mockModule', []);
1010
require('./../ApiServiceProvider')(ngModule);
@@ -24,8 +24,8 @@ describe('get', function() {
2424
streamApi = streamApiService.getInstance({url: 'https://foo'});
2525
});
2626

27-
it('should make call to requested object', function() {
28-
var requestedUrl = 'https://foo/attask/api/task?copySourceID=12345678&fields=*';
27+
it('should make call to correct url with correct data and headers', function() {
28+
var requestedUrl = 'https://foo/attask/api-internal/task?copySourceID=12345678&fields=*';
2929
var headerData = function(headers) {
3030
return headers['Content-Type'] === 'application/json;charset=utf-8';
3131
};

src/spec/count.spec.js

+31-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-env jasmine */
2-
/* global dump */
32

43
'use strict';
54

@@ -26,27 +25,45 @@ describe('count', function() {
2625
});
2726

2827

29-
// it('should make call to correct url', function() {
30-
// var requestedUrl = 'https://foo/attask/api/task/count?name=some+task+name&name_Mod=cicontains';
31-
// $httpBackend.expectGET(requestedUrl)
32-
// .respond(200);
33-
// var query = {};
34-
// query['name'] = 'some task name';
35-
// query['name' + streamApi.Constants.MOD] = streamApi.Constants.Operators.CICONTAINS;
36-
// streamApi.count('task', query);
37-
38-
// $httpBackend.flush();
39-
// });
28+
it('should make call to correct url', function() {
29+
var requestedUrl = 'https://foo/attask/api-internal/task/count?name=some+task+name&name_Mod=cicontains';
30+
var data = {count: 1};
31+
$httpBackend.whenGET(requestedUrl)
32+
.respond(200);
33+
var query = {};
34+
query['name'] = 'some task name';
35+
query['name' + streamApi.Constants.MOD] = streamApi.Constants.Operators.CICONTAINS;
36+
streamApi.count('task', query);
4037

41-
it('should extract correct count from returend data', function(done) {
42-
var data = {count: 5};
38+
$httpBackend.flush();
39+
});
40+
41+
42+
it('should fail when response not correct', function(done) {
43+
var response = {aaa:3};
44+
var errorHander = jasmine.createSpy('errorHandler');
4345
$httpBackend.whenGET()
46+
.respond(200, response);
47+
streamApi.count('task', {})
48+
.catch(errorHander)
49+
.finally(function() {
50+
expect(errorHander).toHaveBeenCalled();
51+
done();
52+
});
53+
54+
$httpBackend.flush();
55+
});
56+
57+
it('should extract correct count from returend data', function(done) {
58+
var data = { count: 5 };
59+
$httpBackend.expectGET()
4460
.respond(200, data);
4561
streamApi.count('task', {})
4662
.then(function(count) {
4763
expect(count).toBe(data.count);
4864
done();
4965
});
66+
5067
$httpBackend.flush();
5168
});
5269
});

src/spec/create.spec.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* eslint-env jasmine */
2+
3+
'use strict';
4+
5+
var angular = require('angular');
6+
7+
describe('create', function() {
8+
beforeEach(function() {
9+
var ngModule = angular.module('mockModule', []);
10+
require('./../ApiServiceProvider')(ngModule);
11+
});
12+
13+
beforeEach(angular.mock.module('mockModule'));
14+
15+
var streamApiService,
16+
$httpBackend;
17+
beforeEach(angular.mock.inject(function(_streamApiService_, _$httpBackend_) {
18+
streamApiService = _streamApiService_;
19+
$httpBackend = _$httpBackend_;
20+
}));
21+
22+
var streamApi;
23+
beforeEach(function() {
24+
streamApi = streamApiService.getInstance({url: 'https://foo'});
25+
});
26+
27+
it('should make call to correct url', function() {
28+
var requestedUrl = 'https://foo/attask/api-internal/task';
29+
$httpBackend.expectPOST(requestedUrl)
30+
.respond(200);
31+
streamApi.create('task', {});
32+
33+
$httpBackend.flush();
34+
});
35+
36+
it('should have correct data in request', function() {
37+
var data = {
38+
name: 'some task name',
39+
projectID: '12345678'
40+
};
41+
42+
$httpBackend.expectPOST(/.*/, data)
43+
.respond(200);
44+
streamApi.create('task', data);
45+
46+
$httpBackend.flush();
47+
});
48+
49+
it('should set correct headers', function() {
50+
var headerData = function(headers) {
51+
return headers['Content-Type'] === 'application/json;charset=utf-8';
52+
};
53+
54+
$httpBackend.expectPOST(/.*/, /.*/, headerData)
55+
.respond(200);
56+
streamApi.create('task', {});
57+
58+
$httpBackend.flush();
59+
});
60+
});

0 commit comments

Comments
 (0)