From c4c68a0287ee87b470b53eba66cee917b1280808 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Thu, 25 Jun 2015 15:24:56 +0100 Subject: [PATCH] Add local echo tests. --- .../integ/matrix-client-room-timeline.spec.js | 173 ++++++++++++++++++ spec/mock-request.js | 31 +++- 2 files changed, 195 insertions(+), 9 deletions(-) create mode 100644 spec/integ/matrix-client-room-timeline.spec.js diff --git a/spec/integ/matrix-client-room-timeline.spec.js b/spec/integ/matrix-client-room-timeline.spec.js new file mode 100644 index 000000000..e2ed112e9 --- /dev/null +++ b/spec/integ/matrix-client-room-timeline.spec.js @@ -0,0 +1,173 @@ +"use strict"; +var sdk = require("../.."); +var EventStatus = sdk.EventStatus; +var HttpBackend = require("../mock-request"); +var utils = require("../test-utils"); + +describe("MatrixClient room timelines", function() { + var baseUrl = "http://localhost.or.something"; + var client, httpBackend; + var userId = "@alice:localhost"; + var accessToken = "aseukfgwef"; + var roomId = "!foo:bar"; + var otherUserId = "@bob:localhost"; + var eventData; + var initialSync = { + end: "s_5_3", + presence: [], + rooms: [{ + membership: "join", + room_id: roomId, + messages: { + start: "f_1_1", + end: "f_2_2", + chunk: [ + utils.mkMessage({ + room: roomId, user: otherUserId, msg: "hello" + }) + ] + }, + state: [ + utils.mkEvent({ + type: "m.room.name", room: roomId, user: otherUserId, + content: { + name: "Old room name" + } + }), + utils.mkMembership({ + room: roomId, mship: "join", user: otherUserId, name: "Bob" + }), + utils.mkMembership({ + room: roomId, mship: "join", user: userId, name: "Alice" + }), + utils.mkEvent({ + type: "m.room.create", room: roomId, user: userId, + content: { + creator: userId + } + }) + ] + }] + }; + + beforeEach(function() { + utils.beforeEach(this); + httpBackend = new HttpBackend(); + sdk.request(httpBackend.requestFn); + client = sdk.createClient({ + baseUrl: baseUrl, + userId: userId, + accessToken: accessToken + }); + eventData = { + chunk: [], + end: "end_", + start: "start_" + }; + httpBackend.when("GET", "/initialSync").respond(200, initialSync); + httpBackend.when("GET", "/events").respond(200, eventData); + }); + + afterEach(function() { + httpBackend.verifyNoOutstandingExpectation(); + }); + + describe("local echo events", function() { + var sendEvent = utils.mkMessage({ + room: roomId, user: otherUserId, msg: "hello" + }); + + it("should be added immediately after calling MatrixClient.sendEvent "+ + "with EventStatus.SENDING and the right event.sender", function(done) { + client.on("syncComplete", function() { + var room = client.getRoom(roomId); + expect(room.timeline.length).toEqual(1); + + var promise = client.sendTextMessage(roomId, "I am a fish", "txn1"); + // check it was added + expect(room.timeline.length).toEqual(2); + // check status + expect(room.timeline[1].status).toEqual(EventStatus.SENDING); + // check member + var member = room.timeline[1].sender; + expect(member.userId).toEqual(userId); + expect(member.name).toEqual("Alice"); + + httpBackend.flush("/events", 1).done(function() { + done(); + }) + }); + client.startClient(); + httpBackend.flush("/initialSync", 1); + }); + + it("should be updated correctly when the send request finishes "+ + "BEFORE the event comes down the event stream", function(done) { + var eventId = "$foo:bar"; + httpBackend.when("PUT", "/txn1").respond(200, { + event_id: eventId + }); + eventData.chunk = [ + utils.mkMessage({ + body: "I am a fish", user: userId, room: roomId + }) + ]; + eventData.chunk[0].event_id = eventId; + + client.on("syncComplete", function() { + var room = client.getRoom(roomId); + client.sendTextMessage(roomId, "I am a fish", "txn1").done( + function() { + expect(room.timeline[1].getId()).toEqual(eventId); + httpBackend.flush("/events", 1).done(function() { + expect(room.timeline[1].getId()).toEqual(eventId); + done(); + }); + }); + httpBackend.flush("/txn1", 1); + }); + client.startClient(); + httpBackend.flush("/initialSync", 1); + }); + + it("should be updated correctly when the send request finishes "+ + "AFTER the event comes down the event stream", function(done) { + var eventId = "$foo:bar"; + httpBackend.when("PUT", "/txn1").respond(200, { + event_id: eventId + }); + eventData.chunk = [ + utils.mkMessage({ + body: "I am a fish", user: userId, room: roomId + }) + ]; + eventData.chunk[0].event_id = eventId; + + client.on("syncComplete", function() { + var room = client.getRoom(roomId); + var promise = client.sendTextMessage(roomId, "I am a fish", "txn1"); + httpBackend.flush("/events", 1).done(function() { + // expect 3rd msg, it doesn't know this is the request is just did + expect(room.timeline.length).toEqual(3); + httpBackend.flush("/txn1", 1); + promise.done(function() { + expect(room.timeline.length).toEqual(2); + expect(room.timeline[1].getId()).toEqual(eventId); + done(); + }); + }); + + }); + client.startClient(); + httpBackend.flush("/initialSync", 1); + }); + }); + + describe("paginated events", function() { + + }); + + describe("new events", function() { + + }); +}); \ No newline at end of file diff --git a/spec/mock-request.js b/spec/mock-request.js index fb6998589..dbc66207a 100644 --- a/spec/mock-request.js +++ b/spec/mock-request.js @@ -19,25 +19,35 @@ function HttpBackend() { HttpBackend.prototype = { /** * Respond to all of the requests (flush the queue). + * @param {string} path The path to flush (optional) default: all. + * @param {integer} numToFlush The number of things to flush (optional), default: all. * @return {Promise} resolved when there is nothing left to flush. */ - flush: function() { + flush: function(path, numToFlush) { var defer = q.defer(); var self = this; - console.log("HTTP backend flushing..."); + var flushed = 0; + console.log("HTTP backend flushing... (path=%s numToFlush=%s)", path, numToFlush); var tryFlush = function() { // if there's more real requests and more expected requests, flush 'em. console.log( - " trying to flush queue => reqs=%s expected=%s", - self.requests.length, self.expectedRequests.length + " trying to flush queue => reqs=%s expected=%s [%s]", + self.requests.length, self.expectedRequests.length, path ); - if (self._takeFromQueue()) { + if (self._takeFromQueue(path)) { // try again on the next tick. - console.log(" flushed. Trying for more."); - setTimeout(tryFlush, 0); + console.log(" flushed. Trying for more. [%s]", path); + flushed += 1; + if (numToFlush && flushed === numToFlush) { + console.log(" [%s] Flushed assigned amount: %s", path, numToFlush); + defer.resolve(); + } + else { + setTimeout(tryFlush, 0); + } } else { - console.log(" no more flushes."); + console.log(" no more flushes. [%s]", path); defer.resolve(); } }; @@ -49,9 +59,10 @@ HttpBackend.prototype = { /** * Attempts to resolve requests/expected requests. + * @param {string} path The path to flush (optional) default: all. * @return {boolean} true if something was resolved. */ - _takeFromQueue: function() { + _takeFromQueue: function(path) { var req = null; var i, j; var matchingReq, expectedReq, testResponse = null; @@ -59,6 +70,7 @@ HttpBackend.prototype = { req = this.requests[i]; for (j = 0; j < this.expectedRequests.length; j++) { expectedReq = this.expectedRequests[j]; + if (path && path !== expectedReq.path) { continue; } if (expectedReq.method === req.method && req.path.indexOf(expectedReq.path) !== -1) { if (!expectedReq.data || (JSON.stringify(expectedReq.data) === @@ -84,6 +96,7 @@ HttpBackend.prototype = { req.callback( testResponse.err, testResponse.response, testResponse.body ); + matchingReq = null; } } if (testResponse) { // flushed something