UNPKG

node-token-sockjs

Version:

A wrapper around express, sockjs-node, and redis that provides token based authentication, a websocket based rpc-like abstraction, and an optional publish subscribe interface.

155 lines (127 loc) 6.49 kB
var _ = require("lodash"), sinon = require("sinon"); module.exports = function(tokenServer, httpClient, TokenSocket, options){ describe("RPC tests", function(){ var socket, token; beforeEach(function(done){ socket = new TokenSocket(); var opts = _.extend({}, options); opts.method = "GET"; opts.path = tokenServer.tokenRoute + "?allow=1"; httpClient.request(opts, null, function(error, resp){ token = JSON.parse(resp.body).token; socket = new TokenSocket(); tokenServer.socketServer._connection(socket); socket._rpc("auth", { token: token }); // wait for redis to respond... I should probably mock that... defer(function(){ socket._frames.shift(); done(); }); }); }); afterEach(function(){ socket._emit("close"); }); it("Should allow authenticated sockets to make rpc to top level actions", function(){ var data = { foo: "bar" }; assert.lengthOf(socket._frames, 0, "Socket starts with no outgoing frames"); socket._rpc("echo", { req: data }); assert.isTrue(tokenServer.socketController.echo.calledOnce, "Echo was called once"); assert.lengthOf(socket._frames, 1, "Socket has one outgoing frame"); assert.isFalse(tokenServer.socketController.nested.echo.called, "Nested echo was not called"); var responseFrame = JSON.parse(socket._frames.shift()); assert.notOk(responseFrame.error, "Response does not have error"); assert.deepEqual(responseFrame.resp, data, "Data equals response for echo"); }); it("Should allow authenticated sockets to make rpc calls to nested actions", function(){ var data = { foo: "bar" }; assert.lengthOf(socket._frames, 0, "Socket starts with no outgoing frames"); socket._rpc("nested.echo", { req: data }); assert.isTrue(tokenServer.socketController.echo.calledOnce, "Outer echo was not called again"); assert.isTrue(tokenServer.socketController.nested.echo.calledOnce, "Nested echo was called once"); var responseFrame = JSON.parse(socket._frames.shift()); assert.notOk(responseFrame.error, "Response does not have error"); assert.deepEqual(responseFrame.resp, data, "Data equals response for echo"); }); it("Should return an error if the requested rpc function is not found", function(){ var data = { foo: "bar" }; assert.lengthOf(socket._frames, 0, "Socket starts with no outgoing frames"); socket._rpc("not.there", { req: data }); var responseFrame = socket._frames.shift(); assert.ok(responseFrame, "Response frame exists"); responseFrame = JSON.parse(responseFrame); assert.notOk(responseFrame.resp, "Response frame doesnt have response"); assert.equal(responseFrame.error, "Function not found", "Response has correct error message"); }); it("Should allow the server to make rpc calls to the client", function(){ var data = { foo: "bar" }, cmd = "baz"; assert.lengthOf(socket._frames, 0, "Socket starts with no outgoing frames"); var rpcCallback = sinon.spy(function(error, resp){ assert.notOk(error, "Error doesnt exist in rpc callback"); assert.deepEqual(resp, data, "RPC response equals input data"); }); assert.lengthOf(Object.keys(tokenServer._inTransit), 0, "Server inTransit is empty"); tokenServer.rpc(socket, cmd, data, rpcCallback); assert.lengthOf(Object.keys(tokenServer._inTransit), 1, "Server inTransit has one rpc ID"); var fid = Object.keys(tokenServer._inTransit)[0]; var socketFrame = socket._frames.shift(); assert.ok(socketFrame, "Socket frame exists"); socketFrame = JSON.parse(socketFrame); assert.isTrue(socketFrame.internal, "Internal flag exists on socket frame"); assert.equal(socketFrame.command, "rpc", "Internal rpc command flag is correct"); assert.isObject(socketFrame.data, "Socket frame has data object"); assert.equal(socketFrame.data.fid, fid, "Socket frame has correct rpc ID"); assert.equal(socketFrame.data.command, cmd, "Socket frame has correct internal rpc command"); assert.deepEqual(socketFrame.data.args, data, "Socket frame has correct rpc args"); var responseFrame = { rpc: "_rpc", fid: fid, resp: { data: data } }; assert.isFalse(rpcCallback.called, "RPC callback has not been called yet"); socket._emit("data", JSON.stringify(responseFrame)); assert.isTrue(rpcCallback.called, "RPC callback was called after response"); assert.lengthOf(Object.keys(tokenServer._inTransit), 0, "Server inTransit is empty"); assert.lengthOf(socket._frames, 0, "Socket ends with no outgoing frames"); }); it("Should work with express route functions", function(){ var data = { bar: "baz" }, route = "ping"; assert.lengthOf(socket._frames, 0, "Socket starts with no outgoing frames"); socket._rpc(route, { req: data }); var responseFrame = JSON.parse(socket._frames.shift()); assert.notOk(responseFrame.error, "Response does not have error"); assert.equal(responseFrame.resp.bar, data.bar, "Response has correct data"); assert.isObject(responseFrame.resp._headers, "Response has http headers"); assert.equal(responseFrame.resp._headers["content-type"], "application/json"); assert.isNumber(responseFrame.resp._code, "Response has http code"); }); it("Should work with nested express route functions", function(){ var data = { bar: "foo" }, route = "nested.ping"; assert.lengthOf(socket._frames, 0, "Socket starts with no outgoing frames"); socket._rpc(route, { req: data }); var responseFrame = JSON.parse(socket._frames.shift()); assert.notOk(responseFrame.error, "Response does not have error"); assert.equal(responseFrame.resp.bar, data.bar, "Response has correct data"); assert.isObject(responseFrame.resp._headers, "Response has http headers"); assert.equal(responseFrame.resp._headers["content-type"], "application/json"); assert.isNumber(responseFrame.resp._code, "Response has http code"); }); it("Should handle ping requests from clients", function(){ assert.isFunction(tokenServer.socketController._ping, "Server has ping function"); var expected = { message: "pong" }, route = "_ping", data = {}; assert.lengthOf(socket._frames, 0, "Socket starts with no outgoing frames"); socket._rpc(route, { req: data }); var responseFrame = JSON.parse(socket._frames.shift()); assert.notOk(responseFrame.error, "Response does not have error"); assert.deepEqual(responseFrame.resp, expected, "Ping response is correct"); }); }); };