diff --git a/package.json b/package.json index 0f69ec5de..abf6a5a08 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Matrix Client-Server SDK for Javascript", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "jasmine-node spec --verbose --captureExceptions", "build-js": "./browser-build.sh", "watch-js": "./browser-build.sh -w" }, @@ -23,6 +23,7 @@ "request": "^2.53.0" }, "devDependencies": { - "watchify": "^3.2.1" + "watchify": "^3.2.1", + "jasmine-node": "^1.14.5" } } diff --git a/spec/integ/matrix-client.spec.js b/spec/integ/matrix-client.spec.js new file mode 100644 index 000000000..90f0db3c5 --- /dev/null +++ b/spec/integ/matrix-client.spec.js @@ -0,0 +1,54 @@ +"use strict"; +var sdk = require("../.."); +var HttpBackend = require("../mock-request"); + +describe("MatrixClient", function() { + var baseUrl = "http://localhost.or.something"; + var client, httpBackend; + var requestPool = []; + + beforeEach(function() { + httpBackend = new HttpBackend(); + sdk.request(httpBackend.requestFn); + client = sdk.createClient(baseUrl); + }); + + afterEach(function() { + httpBackend.verifyNoOutstandingExpectation(); + }); + + describe("startClient", function() { + var initialSync = { + end: "s_5_3", + presence: [], + rooms: [] + }; + var eventData = { + start: "s_5_3", + end: "e_6_7", + chunk: [] + }; + + it("should start with /initialSync then move onto /events.", function() { + httpBackend.when("GET", "/initialSync").respond(200, initialSync); + httpBackend.when("GET", "/events").respond(200, eventData); + + client.startClient(function(err, data, isLive) {}); + + httpBackend.flush(); + }); + + it("should pass the 'end' token from /initialSync to the from= param "+ + " of /events", function() { + httpBackend.when("GET", "/initialSync").respond(200, initialSync); + httpBackend.when("GET", "/events").check(function(req) { + expect(req.queryParams.from).toEqual(initialSync.end); + }).respond(200, eventData); + + client.startClient(function(err, data, isLive) {}); + + httpBackend.flush(); + }); + }); + +}); \ No newline at end of file diff --git a/spec/mock-request.js b/spec/mock-request.js new file mode 100644 index 000000000..1757d3551 --- /dev/null +++ b/spec/mock-request.js @@ -0,0 +1,100 @@ +"use strict"; + +function HttpBackend() { + this.requests = []; + this.expectedRequests = []; + var self = this; + this.requestFn = function(opts, callback) { + var realReq = new Request(opts.method, opts.uri, opts.body, opts.qs); + realReq.callback = callback; + self.requests.push(realReq); + } +}; +HttpBackend.prototype = { + flush: function() { + // if there's more real requests and more expected requests, flush 'em. + while(this.requests.length > 0 && this.expectedRequests.length > 0) { + var req = this.requests.shift(); + + var matchingReq = null; + for (var i = 0; i < this.expectedRequests.length; i++) { + var expectedReq = this.expectedRequests[i]; + if (expectedReq.method === req.method && + req.path.indexOf(expectedReq.path) !== -1) { + if (!expectedReq.data || (JSON.stringify(expectedReq.data) === + JSON.stringify(req.data))) { + matchingReq = expectedReq; + this.expectedRequests.splice(i, 1); + break; + } + } + } + + if (matchingReq) { + matchingReq.checks.forEach(function(check) { + check(req); + }); + var testResponse = matchingReq.response; + req.callback( + testResponse.err, testResponse.response, testResponse.body + ); + } + } + }, + verifyNoOutstandingRequests: function() { + var firstOutstandingReq = this.requests[0] || {}; + expect(this.requests.length).toEqual(0, + "Expected no more HTTP requests but received request to "+ + firstOutstandingReq.path + ); + }, + verifyNoOutstandingExpectation: function() { + var firstOutstandingExpectation = this.expectedRequests[0] || {}; + expect(this.expectedRequests.length).toEqual(0, + "Expected to see HTTP request for "+firstOutstandingExpectation.path + ); + }, + when: function(method, path, data) { + var pendingReq = new Request(method, path, data); + this.expectedRequests.push(pendingReq); + return pendingReq; + } +}; + +function Request(method, path, data, queryParams) { + this.method = method; + this.path = path; + this.data = data; + this.queryParams = queryParams; + this.callback = null; + this.response = null; + this.checks = []; +}; +Request.prototype = { + check: function(fn) { + this.checks.push(fn); + return this; + }, + respond: function(code, data) { + this.response = { + response: { + statusCode: code, + headers: {} + }, + body: data, + err: null + }; + }, + fail: function(code, err) { + this.response = { + response: { + statusCode: code, + headers: {} + }, + body: null, + err: err + }; + } +}; + +module.exports = HttpBackend;