Skip to content

Commit c6e5123

Browse files
author
Jenkins User
committed
Merge commit '644f73f6cbc178c8027352bead29eeff38154cfc'
2 parents 7ac784e + 644f73f commit c6e5123

File tree

5 files changed

+171
-32
lines changed

5 files changed

+171
-32
lines changed

examples/deal-updates.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*!
2+
* This basic example shows how to fetch updates to
3+
* a deal
4+
*
5+
* It starts by fetching the first deal from the
6+
* account, it then fetches 10 updates of this deal.
7+
*
8+
* Usage:
9+
* node deal-updates.js APITOKEN
10+
**/
11+
12+
if (!process.argv[2]) {
13+
process.stderr.write('Please provide API token!' + "\n");
14+
process.exit();
15+
}
16+
17+
var Pipedrive = require(__dirname + '/../index');
18+
var pipedrive = new Pipedrive.Client(process.argv[2]);
19+
var _ = require('lodash');
20+
21+
pipedrive.Deals.getAll({ start: 0, limit: 1 }, function(dealsListErr, dealsList) {
22+
if (dealsListErr) console.log(dealsListErr);
23+
var deal = _.first(dealsList);
24+
25+
console.log('Deal '+ deal.title + ' (' + deal.value + ' ' + deal.currency + ')')
26+
27+
deal.getUpdates(function(err, updates) {
28+
if (err) console.log(err);
29+
_.each(updates, function(update) {
30+
console.log(update.object + ' from ' + update.timestamp.split(' ')[0] + ':');
31+
console.log(JSON.stringify(update.data) + '\n');
32+
});
33+
});
34+
});

lib/CollectionItem.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,20 @@
102102
methodSuffix = inflection.singularize(methodSuffix);
103103
}
104104

105-
var objectKey = kind + '/' + currentItem.id + '/' + relatedObject;
105+
// All sub-objects are fetched from URLs using their real names.
106+
var relatedObjectEndpoint = relatedObject;
107+
108+
// However, there are a couple of exceptions...
109+
var relatedObjectEndpointMapping = {
110+
'updates': 'flow'
111+
};
112+
113+
// ...which will be used instead of their real names.
114+
if (relatedObjectEndpointMapping.hasOwnProperty(relatedObject)) {
115+
relatedObjectEndpoint = relatedObjectEndpointMapping[relatedObject];
116+
}
117+
118+
var objectKey = kind + '/' + currentItem.id + '/' + relatedObjectEndpoint;
106119

107120
currentItem[methodType + methodSuffix] = function(params, callback) {
108121

@@ -112,8 +125,13 @@
112125
callback = function() {};
113126
}
114127

128+
// The assumption here is that the related object is managed under the main object in terms of API URLs.
129+
// e.g. GET and POST both use /v1/deals/:id/products as the API URL.
115130
var relatedObjectPath = relatedObject;
116131

132+
// However, self-managed related objects refers to a list of objects that are fetched as sub-objects
133+
// (e.g. /v1/mainObjects/:id/subObjectName) but then modified as main objects (/v1/subObjectName) when
134+
// it comes to API URL mapping.
117135
if (blueprint.selfManagedRelatedObjects.indexOf(relatedObject) !== -1) {
118136
relatedObjectPath = objectKey;
119137
}

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
},
3636
"devDependencies": {
3737
"chai": "^4.1.2",
38-
"mocha": "^3.2.0"
38+
"mocha": "^3.2.0",
39+
"proxyquire": "^2.0.1",
40+
"sinon": "^3.2.0"
3941
}
4042
}

test/integration/client.js

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var Pipedrive = require('./../..');
22
var assert = require('chai').assert;
3+
var _ = require('lodash');
34

45
var API_TOKEN = process.env.API_TOKEN;
56
if (!API_TOKEN) {
@@ -16,7 +17,35 @@ describe('client', function () {
1617
strictClient = new Pipedrive.Client(API_TOKEN, {strictMode: true});
1718
});
1819

19-
describe('.getAll()', function () {
20+
21+
describe('client.on()', function () {
22+
it('should allow event binding to connect and deal adding', function (done) {
23+
this.timeout(10000);
24+
25+
var deal = {title: 'Client-nodejs - .on() test', value: 10000, currency: 'EUR'};
26+
27+
strictClient.on('connect', function () {
28+
strictClient.Deals.add(deal, function (error, result) {
29+
deal.id = result.id;
30+
});
31+
});
32+
33+
strictClient.on('deal.added', function (event, data) {
34+
assert.equal(data.current.title, deal.title);
35+
assert.equal(data.current.value, deal.value);
36+
assert.equal(data.current.currency, deal.currency);
37+
38+
strictClient.removeAllListeners();
39+
40+
//cleanup
41+
strictClient.Deals.remove(deal.id, function () {
42+
done();
43+
});
44+
});
45+
});
46+
});
47+
48+
describe('collection.getAll()', function () {
2049
it('should list filters and deals', function (done) {
2150
client.Filters.getAll({type: 'deals'}, function (filtersListErr, filtersList) {
2251

@@ -37,7 +66,7 @@ describe('client', function () {
3766
});
3867
});
3968

40-
describe('.add() & .getItem()', function () {
69+
describe('collection.add() & collection.getItem()', function () {
4170
it('should create and get deal', function (done) {
4271

4372
var payloadDeal = {
@@ -66,34 +95,7 @@ describe('client', function () {
6695
});
6796
});
6897

69-
describe('.on()', function () {
70-
it('should allow event binding to connect and deal adding', function (done) {
71-
this.timeout(10000);
72-
73-
var deal = {title: 'Client-nodejs - .on() test', value: 10000, currency: 'EUR'};
74-
75-
strictClient.on('connect', function () {
76-
strictClient.Deals.add(deal, function (error, result) {
77-
deal.id = result.id;
78-
});
79-
});
80-
81-
strictClient.on('deal.added', function (event, data) {
82-
assert.equal(data.current.title, deal.title);
83-
assert.equal(data.current.value, deal.value);
84-
assert.equal(data.current.currency, deal.currency);
85-
86-
strictClient.removeAllListeners();
87-
88-
//cleanup
89-
strictClient.Deals.remove(deal.id, function () {
90-
done();
91-
});
92-
});
93-
});
94-
});
95-
96-
describe('.find()', function () {
98+
describe('сollection.find()', function () {
9799
it('should find first person by name', function (done) {
98100
client.Persons.getAll(function (err, listedPersons) {
99101
assert.isTrue(listedPersons.length > 0);
@@ -108,5 +110,21 @@ describe('client', function () {
108110
});
109111
});
110112
})
113+
});
114+
115+
describe('item.getUpdates()', function () {
116+
it('should get changes deal had', function (done) {
117+
client.Deals.getAll({start: 0, limit: 1}, function (dealsListErr, dealsList) {
118+
if (dealsListErr) console.log(dealsListErr);
119+
var deal = _.first(dealsList);
120+
121+
deal.getUpdates(function (err, updates) {
122+
assert.isTrue(updates.length > 0);
123+
assert.equal(updates[0].object, 'dealChange');
124+
125+
done();
126+
});
127+
});
128+
});
111129
})
112130
});

test/unit/CollectionItem.js

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
var assert = require('chai').assert,
2+
path = require('path'),
3+
proxyquire = require('proxyquire'),
4+
sinon = require('sinon');
5+
6+
describe('CollectionItem', function () {
7+
8+
var item;
9+
10+
var restHandlersPath = path.normalize(__dirname + '/../../lib/restHandlers');
11+
12+
var restHandlerMock = {
13+
editItem: sinon.spy(),
14+
listItems: sinon.spy()
15+
};
16+
17+
var initWithMocks = function () {
18+
var stubs = {};
19+
stubs[restHandlersPath] = function () {
20+
return restHandlerMock
21+
};
22+
23+
var CollectionItem = proxyquire('./../../lib/CollectionItem', stubs);
24+
25+
item = new CollectionItem('deals', {
26+
title: 'Deal title'
27+
}, 1);
28+
29+
return item;
30+
};
31+
32+
beforeEach(function () {
33+
item = initWithMocks(restHandlerMock);
34+
});
35+
36+
it('should return object', function () {
37+
console.log(item);
38+
assert.isObject(item);
39+
assert.isFunction(item.getUpdates);
40+
});
41+
42+
describe('subMethods', function () {
43+
it('should be generated for deal products', function () {
44+
assert.isFunction(item.addProduct);
45+
assert.isFunction(item.updateProduct);
46+
assert.isFunction(item.deleteProduct);
47+
});
48+
49+
it('.getUpdates() should call restHandler.editItem()', function () {
50+
item.getUpdates({
51+
id: 3
52+
});
53+
54+
sinon.assert.calledOnce(restHandlerMock.listItems);
55+
sinon.assert.calledWith(restHandlerMock.listItems, 'deals/1/flow', {id: 3});
56+
});
57+
58+
it('.updateProduct() should call restHandler.editItem()', function () {
59+
item.updateProduct({
60+
id: 2
61+
});
62+
63+
sinon.assert.calledOnce(restHandlerMock.editItem);
64+
sinon.assert.calledWith(restHandlerMock.editItem, 2, 'deals/1/products', {id: 2});
65+
});
66+
});
67+
});

0 commit comments

Comments
 (0)