Skip to content

Commit

Permalink
Lazily compute the token
Browse files Browse the repository at this point in the history
  • Loading branch information
argon committed Sep 23, 2016
1 parent 3782e66 commit c1bb29e
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 23 deletions.
23 changes: 16 additions & 7 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,15 @@ module.exports = function (dependencies) {
return this.getStream().then( stream => {
stream.setEncoding("utf8");

let headers = extend({
stream.headers(extend({},
{
":scheme": "https",
":method": "POST",
":authority": this.config.address,
":path": "/3/device/" + device,
}, notification.headers);

if (this.config.token) {
headers["authorization"] = "bearer " + this.config.token();
}
stream.headers(headers);
},
this.getAuthorization(),
notification.headers));

let status, responseData = "";
stream.on("headers", headers => {
Expand Down Expand Up @@ -107,6 +105,17 @@ module.exports = function (dependencies) {
});
}

Client.prototype.getAuthorization = function getToken() {
if (!this.config.token) {
return {};
}

if (!this.currentToken) {
this.currentToken = this.config.token();
}
return { authorization: "bearer " + this.currentToken };
}

Client.prototype.shutdown = function shutdown() {
if (this.queue.length > 0) {
this.shutdownPending = true;
Expand Down
15 changes: 9 additions & 6 deletions lib/util/extend.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"use strict";

module.exports = function extend(target, source) {
for (var key in source) {
if (source[key] !== undefined) {
target[key] = source[key];
}
}
module.exports = function extend(target) {
for (let i=1; i<arguments.length; i++) {
let source = arguments[i];
for (var key in source) {
if (source[key] !== undefined) {
target[key] = source[key];
}
}
}
return target;
};
62 changes: 52 additions & 10 deletions test/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ describe("Client", function () {
fakes.endpointManager.getStream.onCall(0).returns(fakes.stream);
});

it("does not send an authorization header", function () {
it("does not set an authorization header", function () {
let notification = builtNotification();

return client.write(notification, "abcd1234").then(function () {
expect(fakes.stream.headers).to.not.be.calledWithMatch({ authorization: sinon.match.string });
expect(fakes.stream.headers.firstCall.args[0]).to.not.have.property("authorization");
})
});
})
Expand Down Expand Up @@ -178,17 +178,26 @@ describe("Client", function () {
context("error occurs", function () {
let promise;

beforeEach(function () {
const client = new Client( { address: "testapi" } );
context("general case", function () {
beforeEach(function () {
const client = new Client( { address: "testapi" } );

fakes.stream = new FakeStream("abcd1234", "400", { "reason" : "BadDeviceToken" });
fakes.endpointManager.getStream.onCall(0).returns(fakes.stream);
fakes.stream = new FakeStream("abcd1234", "400", { "reason" : "BadDeviceToken" });
fakes.endpointManager.getStream.onCall(0).returns(fakes.stream);

promise = client.write(builtNotification(), "abcd1234");
});
promise = client.write(builtNotification(), "abcd1234");
});

it("resolves with the device token, status code and response", function () {
return expect(promise).to.eventually.deep.equal({ status: "400", device: "abcd1234", response: { reason: "BadDeviceToken" }});
it("resolves with the device token, status code and response", function () {
return expect(promise).to.eventually.deep.equal({ status: "400", device: "abcd1234", response: { reason: "BadDeviceToken" }});
});
})

context("ExpiredProviderToken", function () {
beforeEach(function () {
let tokenGenerator = sinon.stub().returns("fake-token");
const client = new Client( { address: "testapi", token: tokenGenerator });
})
});
});

Expand Down Expand Up @@ -491,6 +500,39 @@ describe("Client", function () {
})
})
});

});

describe("token generator behaviour", function () {
beforeEach(function () {
fakes.streams = [
new FakeStream("abcd1234", "200"),
new FakeStream("adfe5969", "400", { reason: "MissingTopic" }),
new FakeStream("abcd1335", "410", { reason: "BadDeviceToken", timestamp: 123456789 }),
];
});

it("reuses the token", function () {
const tokenGenerator = sinon.stub();
const client = new Client( { address: "testapi", token: tokenGenerator } );

tokenGenerator.onCall(0).returns("fake-token");
tokenGenerator.onCall(1).returns("second-token");

fakes.endpointManager.getStream.onCall(0).returns(fakes.streams[0]);
fakes.endpointManager.getStream.onCall(1).returns(fakes.streams[1]);
fakes.endpointManager.getStream.onCall(2).returns(fakes.streams[2]);

return Promise.all([
client.write(builtNotification(), "abcd1234"),
client.write(builtNotification(), "adfe5969"),
client.write(builtNotification(), "abcd1335"),
]).then(function () {
expect(fakes.streams[0].headers).to.be.calledWithMatch({ authorization: "bearer fake-token" });
expect(fakes.streams[1].headers).to.be.calledWithMatch({ authorization: "bearer fake-token" });
expect(fakes.streams[2].headers).to.be.calledWithMatch({ authorization: "bearer fake-token" });
});
});
});
});

Expand Down

0 comments on commit c1bb29e

Please sign in to comment.