Skip to content

Commit 240a3e6

Browse files
author
Burcu Dogan
committed
Merge pull request #148 from stephenplusplus/connection-tests
tests: connection refactor.
2 parents 797c6f6 + b91ad63 commit 240a3e6

File tree

2 files changed

+64
-63
lines changed

2 files changed

+64
-63
lines changed

lib/common/connection.js

+27-28
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121

2222
'use strict';
2323

24+
var events = require('events');
2425
var fs = require('fs');
2526
var GAPIToken = require('gapitoken');
27+
var nodeutil = require('util');
2628
var req = require('request');
2729

2830
/** @type {module:common/util} */
@@ -91,14 +93,15 @@ module.exports.Token = Token;
9193
* var conn = new Connection({ scopes: SCOPES });
9294
*/
9395
function Connection(opts) {
96+
events.EventEmitter.call(this);
97+
9498
this.opts = opts || {};
9599

96100
this.credentials = null;
97101
this.scopes = opts.scopes || [];
98102
this.token = null; // existing access token, if exists
99103

100104
this.isConnecting = false;
101-
this.waitQueue = [];
102105

103106
if (opts.credentials) {
104107
if (opts.credentials.client_email && opts.credentials.private_key) {
@@ -110,27 +113,29 @@ function Connection(opts) {
110113
}
111114
}
112115

116+
nodeutil.inherits(Connection, events.EventEmitter);
117+
113118
/**
114119
* Retrieve a token to authorize requests.
115120
*
116121
* @todo Connect should be context aware, it should not require an email and
117122
* key, if it's running on Google Compute Engine.
118123
*
119-
* @param {function} callback - The callback function.
120-
*
121124
* @example
122-
* conn.connect(function(err) {});
125+
* conn.connect();
123126
*/
124-
Connection.prototype.connect = function(callback) {
127+
Connection.prototype.connect = function() {
125128
var that = this;
126129
this.isConnecting = true;
127130
// retrieves an access token
128131
this.fetchToken(function(err, token) {
129-
if (!err) {
130-
that.token = token;
131-
}
132132
that.isConnecting = false;
133-
callback(err);
133+
if (err) {
134+
that.emit('connected', err);
135+
return;
136+
}
137+
that.token = token;
138+
that.emit('connected');
134139
});
135140
};
136141

@@ -246,30 +251,24 @@ Connection.prototype.createAuthorizedReq = function(reqOpts, callback) {
246251
reqOpts.headers['User-Agent'] = USER_AGENT;
247252
}
248253

249-
if (this.isConnected()) {
250-
return callback(null, this.authorizeReq(reqOpts));
254+
function onConnected(err) {
255+
if (err) {
256+
callback(err);
257+
return;
258+
}
259+
callback(null, that.authorizeReq(reqOpts));
251260
}
252-
if (this.isConnecting) {
253-
this.waitQueue = this.waitQueue || [];
254-
this.waitQueue.push({ req: reqOpts, cb: callback });
261+
262+
if (this.isConnected()) {
263+
onConnected();
255264
return;
256265
}
257-
this.connect(function(err) {
258-
that.waitQueue.push({ req: reqOpts, cb: callback });
259-
that.waitQueue.forEach(function(v) {
260-
if (!v.cb) {
261-
return;
262-
}
263266

264-
if (err) {
265-
v.cb(err);
266-
return;
267-
}
267+
this.once('connected', onConnected);
268268

269-
v.cb(null, that.authorizeReq(v.req));
270-
});
271-
that.waitQueue = [];
272-
});
269+
if (!this.isConnecting) {
270+
this.connect();
271+
}
273272
};
274273

275274
/**

test/common/connection.js

+37-35
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ describe('Connection', function() {
3232
conn = new connection.Connection({
3333
keyFilename: path.join(__dirname, '../testdata/privateKeyFile.json')
3434
});
35+
conn.requester = function(opts, callback) {
36+
callback(null);
37+
};
3538
});
3639

3740
it('should use a private key json file', function(done) {
@@ -62,70 +65,69 @@ describe('Connection', function() {
6265
});
6366
});
6467

65-
6668
describe('Token', function() {
6769
var tokenNeverExpires = new connection.Token('token', new Date(3000, 0, 0));
6870
var tokenExpired = new connection.Token('token', new Date(2011, 0, 0));
6971

7072
it('should fetch a new token if token expires', function(done) {
71-
var c = new connection.Connection({
72-
email: 'x@provider',
73-
privateKey: '/some/path',
74-
scopes: ['scope1', 'scope2']
75-
});
76-
c.token = tokenExpired;
77-
c.fetchToken = function() {
73+
conn.token = tokenExpired;
74+
conn.fetchToken = function() {
7875
done();
7976
};
80-
c.requester = function(opts, callback) {
81-
callback(null);
77+
conn.req({ uri: 'https://someuri' }, function() {});
78+
});
79+
80+
it('should pass error to callback', function(done) {
81+
var error = new Error('Something terrible happened.');
82+
conn.fetchToken = function(cb) {
83+
cb(error);
8284
};
83-
c.req({ uri: 'https://someuri' }, function() {});
85+
conn.req({}, function(err) {
86+
assert.equal(error, err);
87+
done();
88+
});
8489
});
8590

8691
it('should make other requests wait while connecting', function(done) {
8792
var numTokenFetches = 0;
88-
var c = new connection.Connection({
89-
email: 'x@provider',
90-
privateKey: '/some/path',
91-
scopes: ['scope1', 'scope2']
92-
});
93-
c.fetchToken = function(cb) {
93+
var requestedUris = [];
94+
conn.fetchToken = function(cb) {
9495
numTokenFetches++;
9596
setImmediate(function() {
9697
cb(null, tokenNeverExpires);
9798
});
9899
};
99-
c.requester = function(opts, callback) {
100+
conn.requester = function(opts, callback) {
101+
requestedUris.push(opts.uri);
100102
callback(null);
101103
};
102-
103104
async.parallel([
104-
function(done) { c.req({ uri: 'https://someuri' }, done); },
105-
function(done) { c.req({ uri: 'https://someuri' }, done); },
106-
function(done) { c.req({ uri: 'https://someuri' }, done); }
105+
function(next) {
106+
assert.strictEqual(conn.isConnecting, false);
107+
conn.req({ uri: '1' }, next);
108+
},
109+
function(next) {
110+
assert.strictEqual(conn.isConnecting, true);
111+
conn.req({ uri: '2' }, next);
112+
},
113+
function(next) {
114+
conn.req({ uri: '3' }, next);
115+
}
107116
], function(err) {
108-
assert.equal(err, null);
117+
assert.ifError(err);
109118
assert.equal(numTokenFetches, 1);
110-
assert.equal(c.token, tokenNeverExpires);
119+
assert.equal(conn.token, tokenNeverExpires);
120+
assert.deepEqual(requestedUris, ['1', '2', '3']);
111121
done();
112122
});
113123
});
114124

115125
it('should fetch a new token if token is invalid', function(done) {
116-
var c = new connection.Connection({
117-
email: 'x@provider',
118-
privateKey: '/some/path',
119-
scopes: ['scope1', 'scope2']
120-
});
121-
c.token = new connection.Token();
122-
c.fetchToken = function() {
126+
conn.token = new connection.Token();
127+
conn.fetchToken = function() {
123128
done();
124129
};
125-
c.requester = function(opts, callback) {
126-
callback(null);
127-
};
128-
c.req({ uri: 'https://someuri' }, function() {});
130+
conn.req({ uri: 'https://someuri' }, function() {});
129131
});
130132
});
131133
});

0 commit comments

Comments
 (0)