heroku-client
Advanced tools
Comparing version
@@ -21,2 +21,3 @@ var https = require('https'), | ||
this.deferred = q.defer(); | ||
this.nextRange = 'id ]..; max=1000'; | ||
@@ -63,3 +64,4 @@ _.bindAll(this); | ||
'Accept': 'application/vnd.heroku+json; version=3', | ||
'Content-type': 'application/json' | ||
'Content-type': 'application/json', | ||
'Range': this.nextRange | ||
}, this.options.headers || {}); | ||
@@ -100,3 +102,3 @@ | ||
var key = this.options.path + '-' + this.options.cacheKeyPostfix; | ||
var key = this.options.path + '-' + this.nextRange + '-' + this.options.cacheKeyPostfix; | ||
@@ -119,4 +121,9 @@ cache.get(key, function (err, res) { | ||
if (res.statusCode === 304 && this.cachedResponse) { | ||
this.deferred.resolve(this.cachedResponse.body); | ||
this.callback(null, this.cachedResponse.body); | ||
if (this.cachedResponse.nextRange) { | ||
this.nextRequest(this.cachedResponse.nextRange, this.cachedResponse.body); | ||
} else { | ||
this.updateAggregate(this.cachedResponse.body); | ||
this.deferred.resolve(this.aggregate); | ||
this.callback(null, this.aggregate); | ||
} | ||
} else { | ||
@@ -252,4 +259,9 @@ buffer = ''; | ||
deferred.resolve(body); | ||
callback(null, body); | ||
if (res.headers['next-range']) { | ||
this.nextRequest(res.headers['next-range'], body); | ||
} else { | ||
this.updateAggregate(body); | ||
deferred.resolve(this.aggregate); | ||
callback(null, this.aggregate); | ||
} | ||
} | ||
@@ -259,2 +271,14 @@ | ||
/* | ||
* Since this request isn't the full response (206 or | ||
* 304 with a cached Next-Range), perform the next | ||
* request for more data. | ||
*/ | ||
Request.prototype.nextRequest = function nextRequest (nextRange, body) { | ||
this.updateAggregate(body); | ||
this.nextRange = nextRange; | ||
this.request(); | ||
} | ||
/* | ||
* If the cache client is alive, write the | ||
@@ -268,7 +292,8 @@ * provided response and body to the cache. | ||
key = path + '-' + cacheKeyPostfix; | ||
key = path + '-' + this.nextRange + '-' + cacheKeyPostfix; | ||
value = JSON.stringify({ | ||
body: body, | ||
etag: res.headers.etag | ||
etag: res.headers.etag, | ||
nextRange: res.headers['next-range'] | ||
}); | ||
@@ -281,2 +306,16 @@ | ||
/* | ||
* If given an object, sets aggregate to object, | ||
* otherwise concats array onto aggregate. | ||
*/ | ||
Request.prototype.updateAggregate = function updateAggregate (aggregate) { | ||
if (aggregate instanceof Array) { | ||
this.aggregate || (this.aggregate = []); | ||
this.aggregate = this.aggregate.concat(aggregate); | ||
} else { | ||
this.aggregate = aggregate; | ||
} | ||
} | ||
/* | ||
* Connect a cache client. | ||
@@ -283,0 +322,0 @@ */ |
{ | ||
"name": "heroku-client", | ||
"version": "0.5.2", | ||
"version": "0.6.0", | ||
"description": "A wrapper for the Heroku v3 API", | ||
@@ -22,3 +22,6 @@ "main": "./lib/heroku.js", | ||
"devDependencies": { | ||
"jasmine-node": "~1.11.0" | ||
"jasmine-node": "~1.11.0", | ||
"grunt": "~0.4.1", | ||
"grunt-contrib-watch": "~0.5.3", | ||
"grunt-shell": "~0.4.0" | ||
}, | ||
@@ -29,4 +32,5 @@ "dependencies": { | ||
"inflection": "~1.2.6", | ||
"lodash": "~1.3.1" | ||
"lodash": "~1.3.1", | ||
"grunt": "~0.4.1" | ||
} | ||
} |
@@ -11,2 +11,6 @@ # heroku-client [](https://travis-ci.org/heroku/node-heroku-client) | ||
## Documentation | ||
Docs are auto-generated and live in the [docs directory](https://github.com/heroku/node-heroku-client/tree/development/docs). | ||
## Usage | ||
@@ -110,3 +114,3 @@ | ||
Documentation for node-heroku is auto-generated from [the resources manifest](https://github.com/heroku/node-heroku-client/blob/development/lib/resources.js). | ||
Documentation for heroku-client is auto-generated from [the resources manifest](https://github.com/heroku/node-heroku-client/blob/development/lib/resources.js). | ||
Docs are generated like so: | ||
@@ -122,3 +126,3 @@ | ||
node-heroku uses [jasmine-node][jasmine-node] for tests: | ||
heroku-client uses [jasmine-node][jasmine-node] for tests: | ||
@@ -125,0 +129,0 @@ ```bash |
@@ -104,3 +104,4 @@ var https = require("https"), | ||
'Accept': 'application/vnd.heroku+json; version=3', | ||
'Content-type': 'application/json' | ||
'Content-type': 'application/json', | ||
'Range': 'id ]..; max=1000' | ||
} | ||
@@ -152,2 +153,26 @@ | ||
describe('handling Range headers', function() { | ||
it('sends a default Range header', function() { | ||
makeRequest('/apps', {}, function (err, body) { | ||
expect(https.request.mostRecentCall.args[0].headers['Range']).toEqual('id ]..; max=1000'); | ||
}); | ||
}); | ||
describe('when receiving a Next-Range header', function() { | ||
it('sends the Next-Range header on the next request', function(done) { | ||
makeRequest('/apps', {}, function (err, body) { | ||
expect(https.request.mostRecentCall.args[0].headers['Range']).toEqual('id abcdefg..; max=1000'); | ||
done(); | ||
}, { response: { headers: { 'next-range': 'id abcdefg..; max=1000' } } }); | ||
}); | ||
it('aggregates response bodies', function(done) { | ||
makeRequest('/apps', {}, function (err, body) { | ||
expect(body).toEqual([{ message: 'ok' }, { message: 'ok' }]); | ||
done(); | ||
}, { returnArray: true, response: { headers: { 'next-range': 'id abcdefg..; max=1000' } } }); | ||
}); | ||
}); | ||
}); | ||
describe('caching', function() { | ||
@@ -172,3 +197,3 @@ var cache = new MockCache(); | ||
makeRequest('/apps', { cacheKeyPostfix: '123' }, function(err, body) { | ||
expect(cache.get).toHaveBeenCalledWith('/apps-123', jasmine.any(Function)); | ||
expect(cache.get).toHaveBeenCalledWith('/apps-id ]..; max=1000-123', jasmine.any(Function)); | ||
done(); | ||
@@ -194,3 +219,3 @@ }); | ||
expect(cache.set).toHaveBeenCalledWith('/apps-123', expectedCache); | ||
expect(cache.set).toHaveBeenCalledWith('/apps-id ]..; max=1000-123', expectedCache); | ||
done(); | ||
@@ -207,2 +232,6 @@ }, { response: { headers: { etag: '123' } } }); | ||
spyOn(https, 'request').andCallFake(function (options, httpsCallback) { | ||
if (options.headers.Range !== 'id ]..; max=1000') { | ||
testOptions.response.headers['next-range'] = undefined; | ||
} | ||
var req = new MockRequest(), | ||
@@ -214,3 +243,8 @@ res = new MockResponse(testOptions.response || {}); | ||
setTimeout(function () { | ||
res.emit('data', '{ "message": "ok" }'); | ||
if (testOptions.returnArray) { | ||
res.emit('data', '[{ "message": "ok" }]'); | ||
} else { | ||
res.emit('data', '{ "message": "ok" }'); | ||
} | ||
if (!req.isAborted) res.emit('end'); | ||
@@ -217,0 +251,0 @@ }, testOptions.timeout || 0); |
Sorry, the diff of this file is not supported yet
151359
2.91%40
5.26%2579
3.45%134
3.08%5
25%4
300%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added