mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-06-02 18:41:37 +03:00
Much of this transformation has been done automatically: * add expect import to each file * replace `not.to` with `toNot` * replace `to[Not]Be{Undefined,Null}` with equivalents * replace `jasmine.createSpy(...)` with `except.createSpy`, and `andCallFake` with `andCall` Also: * replace `jasmine.createSpyObj` with manual alternatives * replace `jasmine.Clock` with `lolex`
746 lines
27 KiB
JavaScript
746 lines
27 KiB
JavaScript
"use strict";
|
|
import 'source-map-support/register';
|
|
const q = require("q");
|
|
const sdk = require("../..");
|
|
const HttpBackend = require("../mock-request");
|
|
const utils = require("../test-utils");
|
|
const EventTimeline = sdk.EventTimeline;
|
|
|
|
const baseUrl = "http://localhost.or.something";
|
|
const userId = "@alice:localhost";
|
|
const userName = "Alice";
|
|
const accessToken = "aseukfgwef";
|
|
const roomId = "!foo:bar";
|
|
const otherUserId = "@bob:localhost";
|
|
|
|
const USER_MEMBERSHIP_EVENT = utils.mkMembership({
|
|
room: roomId, mship: "join", user: userId, name: userName,
|
|
});
|
|
|
|
const ROOM_NAME_EVENT = utils.mkEvent({
|
|
type: "m.room.name", room: roomId, user: otherUserId,
|
|
content: {
|
|
name: "Old room name",
|
|
},
|
|
});
|
|
|
|
const INITIAL_SYNC_DATA = {
|
|
next_batch: "s_5_3",
|
|
rooms: {
|
|
join: {
|
|
"!foo:bar": { // roomId
|
|
timeline: {
|
|
events: [
|
|
utils.mkMessage({
|
|
room: roomId, user: otherUserId, msg: "hello",
|
|
}),
|
|
],
|
|
prev_batch: "f_1_1",
|
|
},
|
|
state: {
|
|
events: [
|
|
ROOM_NAME_EVENT,
|
|
utils.mkMembership({
|
|
room: roomId, mship: "join",
|
|
user: otherUserId, name: "Bob",
|
|
}),
|
|
USER_MEMBERSHIP_EVENT,
|
|
utils.mkEvent({
|
|
type: "m.room.create", room: roomId, user: userId,
|
|
content: {
|
|
creator: userId,
|
|
},
|
|
}),
|
|
],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
const EVENTS = [
|
|
utils.mkMessage({
|
|
room: roomId, user: userId, msg: "we",
|
|
}),
|
|
utils.mkMessage({
|
|
room: roomId, user: userId, msg: "could",
|
|
}),
|
|
utils.mkMessage({
|
|
room: roomId, user: userId, msg: "be",
|
|
}),
|
|
utils.mkMessage({
|
|
room: roomId, user: userId, msg: "heroes",
|
|
}),
|
|
];
|
|
|
|
// start the client, and wait for it to initialise
|
|
function startClient(httpBackend, client) {
|
|
httpBackend.when("GET", "/pushrules").respond(200, {});
|
|
httpBackend.when("POST", "/filter").respond(200, { filter_id: "fid" });
|
|
httpBackend.when("GET", "/sync").respond(200, INITIAL_SYNC_DATA);
|
|
|
|
client.startClient();
|
|
|
|
// set up a promise which will resolve once the client is initialised
|
|
const deferred = q.defer();
|
|
client.on("sync", function(state) {
|
|
console.log("sync", state);
|
|
if (state != "SYNCING") {
|
|
return;
|
|
}
|
|
deferred.resolve();
|
|
});
|
|
|
|
httpBackend.flush();
|
|
return deferred.promise;
|
|
}
|
|
|
|
describe("getEventTimeline support", function() {
|
|
let httpBackend;
|
|
let client;
|
|
|
|
beforeEach(function() {
|
|
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
|
httpBackend = new HttpBackend();
|
|
sdk.request(httpBackend.requestFn);
|
|
});
|
|
|
|
afterEach(function() {
|
|
if (client) {
|
|
client.stopClient();
|
|
}
|
|
});
|
|
|
|
it("timeline support must be enabled to work", function(done) {
|
|
client = sdk.createClient({
|
|
baseUrl: baseUrl,
|
|
userId: userId,
|
|
accessToken: accessToken,
|
|
});
|
|
|
|
startClient(httpBackend, client,
|
|
).then(function() {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
expect(function() {
|
|
client.getEventTimeline(timelineSet, "event");
|
|
}).toThrow();
|
|
}).catch(utils.failTest).done(done);
|
|
});
|
|
|
|
it("timeline support works when enabled", function(done) {
|
|
client = sdk.createClient({
|
|
baseUrl: baseUrl,
|
|
userId: userId,
|
|
accessToken: accessToken,
|
|
timelineSupport: true,
|
|
});
|
|
|
|
startClient(httpBackend, client,
|
|
).then(function() {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
expect(function() {
|
|
client.getEventTimeline(timelineSet, "event");
|
|
}).toNotThrow();
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush().catch(utils.failTest);
|
|
});
|
|
|
|
|
|
it("scrollback should be able to scroll back to before a gappy /sync",
|
|
function(done) {
|
|
// need a client with timelineSupport disabled to make this work
|
|
client = sdk.createClient({
|
|
baseUrl: baseUrl,
|
|
userId: userId,
|
|
accessToken: accessToken,
|
|
});
|
|
let room;
|
|
|
|
startClient(httpBackend, client,
|
|
).then(function() {
|
|
room = client.getRoom(roomId);
|
|
|
|
httpBackend.when("GET", "/sync").respond(200, {
|
|
next_batch: "s_5_4",
|
|
rooms: {
|
|
join: {
|
|
"!foo:bar": {
|
|
timeline: {
|
|
events: [
|
|
EVENTS[0],
|
|
],
|
|
prev_batch: "f_1_1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
httpBackend.when("GET", "/sync").respond(200, {
|
|
next_batch: "s_5_5",
|
|
rooms: {
|
|
join: {
|
|
"!foo:bar": {
|
|
timeline: {
|
|
events: [
|
|
EVENTS[1],
|
|
],
|
|
limited: true,
|
|
prev_batch: "f_1_2",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
httpBackend.when("GET", "/messages").respond(200, {
|
|
chunk: [EVENTS[0]],
|
|
start: "pagin_start",
|
|
end: "pagin_end",
|
|
});
|
|
|
|
|
|
return httpBackend.flush("/sync", 2);
|
|
}).then(function() {
|
|
expect(room.timeline.length).toEqual(1);
|
|
expect(room.timeline[0].event).toEqual(EVENTS[1]);
|
|
|
|
httpBackend.flush("/messages", 1);
|
|
return client.scrollback(room);
|
|
}).then(function() {
|
|
expect(room.timeline.length).toEqual(2);
|
|
expect(room.timeline[0].event).toEqual(EVENTS[0]);
|
|
expect(room.timeline[1].event).toEqual(EVENTS[1]);
|
|
expect(room.oldState.paginationToken).toEqual("pagin_end");
|
|
}).catch(utils.failTest).done(done);
|
|
});
|
|
});
|
|
|
|
import expect from 'expect';
|
|
|
|
describe("MatrixClient event timelines", function() {
|
|
let client = null;
|
|
let httpBackend = null;
|
|
|
|
beforeEach(function(done) {
|
|
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
|
httpBackend = new HttpBackend();
|
|
sdk.request(httpBackend.requestFn);
|
|
|
|
client = sdk.createClient({
|
|
baseUrl: baseUrl,
|
|
userId: userId,
|
|
accessToken: accessToken,
|
|
timelineSupport: true,
|
|
});
|
|
|
|
startClient(httpBackend, client)
|
|
.catch(utils.failTest).done(done);
|
|
});
|
|
|
|
afterEach(function() {
|
|
httpBackend.verifyNoOutstandingExpectation();
|
|
client.stopClient();
|
|
});
|
|
|
|
describe("getEventTimeline", function() {
|
|
it("should create a new timeline for new events", function(done) {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1%3Abar")
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token",
|
|
events_before: [EVENTS[1], EVENTS[0]],
|
|
event: EVENTS[2],
|
|
events_after: [EVENTS[3]],
|
|
state: [
|
|
ROOM_NAME_EVENT,
|
|
USER_MEMBERSHIP_EVENT,
|
|
],
|
|
end: "end_token",
|
|
};
|
|
});
|
|
|
|
client.getEventTimeline(timelineSet, "event1:bar").then(function(tl) {
|
|
expect(tl.getEvents().length).toEqual(4);
|
|
for (let i = 0; i < 4; i++) {
|
|
expect(tl.getEvents()[i].event).toEqual(EVENTS[i]);
|
|
expect(tl.getEvents()[i].sender.name).toEqual(userName);
|
|
}
|
|
expect(tl.getPaginationToken(EventTimeline.BACKWARDS))
|
|
.toEqual("start_token");
|
|
expect(tl.getPaginationToken(EventTimeline.FORWARDS))
|
|
.toEqual("end_token");
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush().catch(utils.failTest);
|
|
});
|
|
|
|
it("should return existing timeline for known events", function(done) {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
httpBackend.when("GET", "/sync").respond(200, {
|
|
next_batch: "s_5_4",
|
|
rooms: {
|
|
join: {
|
|
"!foo:bar": {
|
|
timeline: {
|
|
events: [
|
|
EVENTS[0],
|
|
],
|
|
prev_batch: "f_1_2",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
httpBackend.flush("/sync").then(function() {
|
|
return client.getEventTimeline(timelineSet, EVENTS[0].event_id);
|
|
}).then(function(tl) {
|
|
expect(tl.getEvents().length).toEqual(2);
|
|
expect(tl.getEvents()[1].event).toEqual(EVENTS[0]);
|
|
expect(tl.getEvents()[1].sender.name).toEqual(userName);
|
|
expect(tl.getPaginationToken(EventTimeline.BACKWARDS)).toEqual("f_1_1");
|
|
// expect(tl.getPaginationToken(EventTimeline.FORWARDS)).toEqual("s_5_4");
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush().catch(utils.failTest);
|
|
});
|
|
|
|
it("should update timelines where they overlap a previous /sync", function() {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
httpBackend.when("GET", "/sync").respond(200, {
|
|
next_batch: "s_5_4",
|
|
rooms: {
|
|
join: {
|
|
"!foo:bar": {
|
|
timeline: {
|
|
events: [
|
|
EVENTS[3],
|
|
],
|
|
prev_batch: "f_1_2",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
|
encodeURIComponent(EVENTS[2].event_id))
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token",
|
|
events_before: [EVENTS[1]],
|
|
event: EVENTS[2],
|
|
events_after: [EVENTS[3]],
|
|
end: "end_token",
|
|
state: [],
|
|
};
|
|
});
|
|
|
|
const deferred = q.defer();
|
|
client.on("sync", function() {
|
|
client.getEventTimeline(timelineSet, EVENTS[2].event_id,
|
|
).then(function(tl) {
|
|
expect(tl.getEvents().length).toEqual(4);
|
|
expect(tl.getEvents()[0].event).toEqual(EVENTS[1]);
|
|
expect(tl.getEvents()[1].event).toEqual(EVENTS[2]);
|
|
expect(tl.getEvents()[3].event).toEqual(EVENTS[3]);
|
|
expect(tl.getPaginationToken(EventTimeline.BACKWARDS))
|
|
.toEqual("start_token");
|
|
// expect(tl.getPaginationToken(EventTimeline.FORWARDS))
|
|
// .toEqual("s_5_4");
|
|
}).done(() => deferred.resolve(),
|
|
(e) => deferred.reject(e));
|
|
});
|
|
|
|
return q.all([
|
|
httpBackend.flush(),
|
|
deferred.promise,
|
|
]);
|
|
});
|
|
|
|
it("should join timelines where they overlap a previous /context",
|
|
function(done) {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
|
|
// we fetch event 0, then 2, then 3, and finally 1. 1 is returned
|
|
// with context which joins them all up.
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
|
encodeURIComponent(EVENTS[0].event_id))
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token0",
|
|
events_before: [],
|
|
event: EVENTS[0],
|
|
events_after: [],
|
|
end: "end_token0",
|
|
state: [],
|
|
};
|
|
});
|
|
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
|
encodeURIComponent(EVENTS[2].event_id))
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token2",
|
|
events_before: [],
|
|
event: EVENTS[2],
|
|
events_after: [],
|
|
end: "end_token2",
|
|
state: [],
|
|
};
|
|
});
|
|
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
|
encodeURIComponent(EVENTS[3].event_id))
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token3",
|
|
events_before: [],
|
|
event: EVENTS[3],
|
|
events_after: [],
|
|
end: "end_token3",
|
|
state: [],
|
|
};
|
|
});
|
|
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
|
encodeURIComponent(EVENTS[1].event_id))
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token4",
|
|
events_before: [EVENTS[0]],
|
|
event: EVENTS[1],
|
|
events_after: [EVENTS[2], EVENTS[3]],
|
|
end: "end_token4",
|
|
state: [],
|
|
};
|
|
});
|
|
|
|
let tl0;
|
|
let tl3;
|
|
client.getEventTimeline(timelineSet, EVENTS[0].event_id,
|
|
).then(function(tl) {
|
|
expect(tl.getEvents().length).toEqual(1);
|
|
tl0 = tl;
|
|
return client.getEventTimeline(timelineSet, EVENTS[2].event_id);
|
|
}).then(function(tl) {
|
|
expect(tl.getEvents().length).toEqual(1);
|
|
return client.getEventTimeline(timelineSet, EVENTS[3].event_id);
|
|
}).then(function(tl) {
|
|
expect(tl.getEvents().length).toEqual(1);
|
|
tl3 = tl;
|
|
return client.getEventTimeline(timelineSet, EVENTS[1].event_id);
|
|
}).then(function(tl) {
|
|
// we expect it to get merged in with event 2
|
|
expect(tl.getEvents().length).toEqual(2);
|
|
expect(tl.getEvents()[0].event).toEqual(EVENTS[1]);
|
|
expect(tl.getEvents()[1].event).toEqual(EVENTS[2]);
|
|
expect(tl.getNeighbouringTimeline(EventTimeline.BACKWARDS))
|
|
.toBe(tl0);
|
|
expect(tl.getNeighbouringTimeline(EventTimeline.FORWARDS))
|
|
.toBe(tl3);
|
|
expect(tl0.getPaginationToken(EventTimeline.BACKWARDS))
|
|
.toEqual("start_token0");
|
|
expect(tl0.getPaginationToken(EventTimeline.FORWARDS))
|
|
.toBe(null);
|
|
expect(tl3.getPaginationToken(EventTimeline.BACKWARDS))
|
|
.toBe(null);
|
|
expect(tl3.getPaginationToken(EventTimeline.FORWARDS))
|
|
.toEqual("end_token3");
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush().catch(utils.failTest);
|
|
});
|
|
|
|
it("should fail gracefully if there is no event field", function(done) {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
// we fetch event 0, then 2, then 3, and finally 1. 1 is returned
|
|
// with context which joins them all up.
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/event1")
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token",
|
|
events_before: [],
|
|
events_after: [],
|
|
end: "end_token",
|
|
state: [],
|
|
};
|
|
});
|
|
|
|
client.getEventTimeline(timelineSet, "event1",
|
|
).then(function(tl) {
|
|
// could do with a fail()
|
|
expect(true).toBeFalsy();
|
|
}).catch(function(e) {
|
|
expect(String(e)).toMatch(/'event'/);
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush().catch(utils.failTest);
|
|
});
|
|
});
|
|
|
|
describe("paginateEventTimeline", function() {
|
|
it("should allow you to paginate backwards", function(done) {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
|
encodeURIComponent(EVENTS[0].event_id))
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token0",
|
|
events_before: [],
|
|
event: EVENTS[0],
|
|
events_after: [],
|
|
end: "end_token0",
|
|
state: [],
|
|
};
|
|
});
|
|
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/messages")
|
|
.check(function(req) {
|
|
const params = req.queryParams;
|
|
expect(params.dir).toEqual("b");
|
|
expect(params.from).toEqual("start_token0");
|
|
expect(params.limit).toEqual(30);
|
|
}).respond(200, function() {
|
|
return {
|
|
chunk: [EVENTS[1], EVENTS[2]],
|
|
end: "start_token1",
|
|
};
|
|
});
|
|
|
|
let tl;
|
|
client.getEventTimeline(timelineSet, EVENTS[0].event_id,
|
|
).then(function(tl0) {
|
|
tl = tl0;
|
|
return client.paginateEventTimeline(tl, {backwards: true});
|
|
}).then(function(success) {
|
|
expect(success).toBeTruthy();
|
|
expect(tl.getEvents().length).toEqual(3);
|
|
expect(tl.getEvents()[0].event).toEqual(EVENTS[2]);
|
|
expect(tl.getEvents()[1].event).toEqual(EVENTS[1]);
|
|
expect(tl.getEvents()[2].event).toEqual(EVENTS[0]);
|
|
expect(tl.getPaginationToken(EventTimeline.BACKWARDS))
|
|
.toEqual("start_token1");
|
|
expect(tl.getPaginationToken(EventTimeline.FORWARDS))
|
|
.toEqual("end_token0");
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush().catch(utils.failTest);
|
|
});
|
|
|
|
|
|
it("should allow you to paginate forwards", function(done) {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/context/" +
|
|
encodeURIComponent(EVENTS[0].event_id))
|
|
.respond(200, function() {
|
|
return {
|
|
start: "start_token0",
|
|
events_before: [],
|
|
event: EVENTS[0],
|
|
events_after: [],
|
|
end: "end_token0",
|
|
state: [],
|
|
};
|
|
});
|
|
|
|
httpBackend.when("GET", "/rooms/!foo%3Abar/messages")
|
|
.check(function(req) {
|
|
const params = req.queryParams;
|
|
expect(params.dir).toEqual("f");
|
|
expect(params.from).toEqual("end_token0");
|
|
expect(params.limit).toEqual(20);
|
|
}).respond(200, function() {
|
|
return {
|
|
chunk: [EVENTS[1], EVENTS[2]],
|
|
end: "end_token1",
|
|
};
|
|
});
|
|
|
|
let tl;
|
|
client.getEventTimeline(timelineSet, EVENTS[0].event_id,
|
|
).then(function(tl0) {
|
|
tl = tl0;
|
|
return client.paginateEventTimeline(
|
|
tl, {backwards: false, limit: 20});
|
|
}).then(function(success) {
|
|
expect(success).toBeTruthy();
|
|
expect(tl.getEvents().length).toEqual(3);
|
|
expect(tl.getEvents()[0].event).toEqual(EVENTS[0]);
|
|
expect(tl.getEvents()[1].event).toEqual(EVENTS[1]);
|
|
expect(tl.getEvents()[2].event).toEqual(EVENTS[2]);
|
|
expect(tl.getPaginationToken(EventTimeline.BACKWARDS))
|
|
.toEqual("start_token0");
|
|
expect(tl.getPaginationToken(EventTimeline.FORWARDS))
|
|
.toEqual("end_token1");
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush().catch(utils.failTest);
|
|
});
|
|
});
|
|
|
|
describe("event timeline for sent events", function() {
|
|
const TXN_ID = "txn1";
|
|
const event = utils.mkMessage({
|
|
room: roomId, user: userId, msg: "a body",
|
|
});
|
|
event.unsigned = {transaction_id: TXN_ID};
|
|
|
|
beforeEach(function() {
|
|
// set up handlers for both the message send, and the
|
|
// /sync
|
|
httpBackend.when("PUT", "/send/m.room.message/" + TXN_ID)
|
|
.respond(200, {
|
|
event_id: event.event_id,
|
|
});
|
|
httpBackend.when("GET", "/sync").respond(200, {
|
|
next_batch: "s_5_4",
|
|
rooms: {
|
|
join: {
|
|
"!foo:bar": {
|
|
timeline: {
|
|
events: [
|
|
event,
|
|
],
|
|
prev_batch: "f_1_1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
it("should work when /send returns before /sync", function(done) {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
|
|
client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) {
|
|
expect(res.event_id).toEqual(event.event_id);
|
|
return client.getEventTimeline(timelineSet, event.event_id);
|
|
}).then(function(tl) {
|
|
// 2 because the initial sync contained an event
|
|
expect(tl.getEvents().length).toEqual(2);
|
|
expect(tl.getEvents()[1].getContent().body).toEqual("a body");
|
|
|
|
// now let the sync complete, and check it again
|
|
return httpBackend.flush("/sync", 1);
|
|
}).then(function() {
|
|
return client.getEventTimeline(timelineSet, event.event_id);
|
|
}).then(function(tl) {
|
|
expect(tl.getEvents().length).toEqual(2);
|
|
expect(tl.getEvents()[1].event).toEqual(event);
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush("/send/m.room.message/" + TXN_ID, 1).catch(utils.failTest);
|
|
});
|
|
|
|
it("should work when /send returns after /sync", function(done) {
|
|
const room = client.getRoom(roomId);
|
|
const timelineSet = room.getTimelineSets()[0];
|
|
|
|
// initiate the send, and set up checks to be done when it completes
|
|
// - but note that it won't complete until after the /sync does, below.
|
|
client.sendTextMessage(roomId, "a body", TXN_ID).then(function(res) {
|
|
console.log("sendTextMessage completed");
|
|
expect(res.event_id).toEqual(event.event_id);
|
|
return client.getEventTimeline(timelineSet, event.event_id);
|
|
}).then(function(tl) {
|
|
console.log("getEventTimeline completed (2)");
|
|
expect(tl.getEvents().length).toEqual(2);
|
|
expect(tl.getEvents()[1].getContent().body).toEqual("a body");
|
|
}).catch(utils.failTest).done(done);
|
|
|
|
httpBackend.flush("/sync", 1).then(function() {
|
|
return client.getEventTimeline(timelineSet, event.event_id);
|
|
}).then(function(tl) {
|
|
console.log("getEventTimeline completed (1)");
|
|
expect(tl.getEvents().length).toEqual(2);
|
|
expect(tl.getEvents()[1].event).toEqual(event);
|
|
|
|
// now let the send complete.
|
|
return httpBackend.flush("/send/m.room.message/" + TXN_ID, 1);
|
|
}).catch(utils.failTest);
|
|
});
|
|
});
|
|
|
|
|
|
it("should handle gappy syncs after redactions", function(done) {
|
|
// https://github.com/vector-im/vector-web/issues/1389
|
|
|
|
// a state event, followed by a redaction thereof
|
|
const event = utils.mkMembership({
|
|
room: roomId, mship: "join", user: otherUserId,
|
|
});
|
|
const redaction = utils.mkEvent({
|
|
type: "m.room.redaction",
|
|
room_id: roomId,
|
|
sender: otherUserId,
|
|
content: {},
|
|
});
|
|
redaction.redacts = event.event_id;
|
|
|
|
const syncData = {
|
|
next_batch: "batch1",
|
|
rooms: {
|
|
join: {},
|
|
},
|
|
};
|
|
syncData.rooms.join[roomId] = {
|
|
timeline: {
|
|
events: [
|
|
event,
|
|
redaction,
|
|
],
|
|
limited: false,
|
|
},
|
|
};
|
|
httpBackend.when("GET", "/sync").respond(200, syncData);
|
|
|
|
httpBackend.flush().then(function() {
|
|
const room = client.getRoom(roomId);
|
|
const tl = room.getLiveTimeline();
|
|
expect(tl.getEvents().length).toEqual(3);
|
|
expect(tl.getEvents()[1].isRedacted()).toBe(true);
|
|
|
|
const sync2 = {
|
|
next_batch: "batch2",
|
|
rooms: {
|
|
join: {},
|
|
},
|
|
};
|
|
sync2.rooms.join[roomId] = {
|
|
timeline: {
|
|
events: [
|
|
utils.mkMessage({
|
|
room: roomId, user: otherUserId, msg: "world",
|
|
}),
|
|
],
|
|
limited: true,
|
|
prev_batch: "newerTok",
|
|
},
|
|
};
|
|
httpBackend.when("GET", "/sync").respond(200, sync2);
|
|
|
|
return httpBackend.flush();
|
|
}).then(function() {
|
|
const room = client.getRoom(roomId);
|
|
const tl = room.getLiveTimeline();
|
|
expect(tl.getEvents().length).toEqual(1);
|
|
}).catch(utils.failTest).done(done);
|
|
});
|
|
});
|