1 | "use strict";
|
2 | import 'source-map-support/register';
|
3 | const sdk = require("../..");
|
4 | const EventTimeline = sdk.EventTimeline;
|
5 | const utils = require("../test-utils");
|
6 |
|
7 | function mockRoomStates(timeline) {
|
8 | timeline._startState = utils.mock(sdk.RoomState, "startState");
|
9 | timeline._endState = utils.mock(sdk.RoomState, "endState");
|
10 | }
|
11 |
|
12 | import expect from 'expect';
|
13 |
|
14 | describe("EventTimeline", function() {
|
15 | const roomId = "!foo:bar";
|
16 | const userA = "@alice:bar";
|
17 | const userB = "@bertha:bar";
|
18 | let timeline;
|
19 |
|
20 | beforeEach(function() {
|
21 | utils.beforeEach(this);
|
22 |
|
23 |
|
24 | const timelineSet = { room: { roomId: roomId }};
|
25 | timelineSet.room.getUnfilteredTimelineSet = function() {
|
26 | return timelineSet;
|
27 | };
|
28 |
|
29 | timeline = new EventTimeline(timelineSet);
|
30 | });
|
31 |
|
32 | describe("construction", function() {
|
33 | it("getRoomId should get room id", function() {
|
34 | const v = timeline.getRoomId();
|
35 | expect(v).toEqual(roomId);
|
36 | });
|
37 | });
|
38 |
|
39 | describe("initialiseState", function() {
|
40 | beforeEach(function() {
|
41 | mockRoomStates(timeline);
|
42 | });
|
43 |
|
44 | it("should copy state events to start and end state", function() {
|
45 | const events = [
|
46 | utils.mkMembership({
|
47 | room: roomId, mship: "invite", user: userB, skey: userA,
|
48 | event: true,
|
49 | }),
|
50 | utils.mkEvent({
|
51 | type: "m.room.name", room: roomId, user: userB,
|
52 | event: true,
|
53 | content: { name: "New room" },
|
54 | }),
|
55 | ];
|
56 | timeline.initialiseState(events);
|
57 | expect(timeline._startState.setStateEvents).toHaveBeenCalledWith(
|
58 | events,
|
59 | );
|
60 | expect(timeline._endState.setStateEvents).toHaveBeenCalledWith(
|
61 | events,
|
62 | );
|
63 | });
|
64 |
|
65 | it("should raise an exception if called after events are added", function() {
|
66 | const event =
|
67 | utils.mkMessage({
|
68 | room: roomId, user: userA, msg: "Adam stole the plushies",
|
69 | event: true,
|
70 | });
|
71 |
|
72 | const state = [
|
73 | utils.mkMembership({
|
74 | room: roomId, mship: "invite", user: userB, skey: userA,
|
75 | event: true,
|
76 | }),
|
77 | ];
|
78 |
|
79 | expect(function() {
|
80 | timeline.initialiseState(state);
|
81 | }).toNotThrow();
|
82 | timeline.addEvent(event, false);
|
83 | expect(function() {
|
84 | timeline.initialiseState(state);
|
85 | }).toThrow();
|
86 | });
|
87 | });
|
88 |
|
89 | describe("paginationTokens", function() {
|
90 | it("pagination tokens should start null", function() {
|
91 | expect(timeline.getPaginationToken(EventTimeline.BACKWARDS)).toBe(null);
|
92 | expect(timeline.getPaginationToken(EventTimeline.FORWARDS)).toBe(null);
|
93 | });
|
94 |
|
95 | it("setPaginationToken should set token", function() {
|
96 | timeline.setPaginationToken("back", EventTimeline.BACKWARDS);
|
97 | timeline.setPaginationToken("fwd", EventTimeline.FORWARDS);
|
98 | expect(timeline.getPaginationToken(EventTimeline.BACKWARDS)).toEqual("back");
|
99 | expect(timeline.getPaginationToken(EventTimeline.FORWARDS)).toEqual("fwd");
|
100 | });
|
101 | });
|
102 |
|
103 |
|
104 | describe("neighbouringTimelines", function() {
|
105 | it("neighbouring timelines should start null", function() {
|
106 | expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(null);
|
107 | expect(timeline.getNeighbouringTimeline(EventTimeline.FORWARDS)).toBe(null);
|
108 | });
|
109 |
|
110 | it("setNeighbouringTimeline should set neighbour", function() {
|
111 | const prev = {a: "a"};
|
112 | const next = {b: "b"};
|
113 | timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
114 | timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
115 | expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(prev);
|
116 | expect(timeline.getNeighbouringTimeline(EventTimeline.FORWARDS)).toBe(next);
|
117 | });
|
118 |
|
119 | it("setNeighbouringTimeline should throw if called twice", function() {
|
120 | const prev = {a: "a"};
|
121 | const next = {b: "b"};
|
122 | expect(function() {
|
123 | timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
124 | }).toNotThrow();
|
125 | expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS))
|
126 | .toBe(prev);
|
127 | expect(function() {
|
128 | timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
129 | }).toThrow();
|
130 |
|
131 | expect(function() {
|
132 | timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
133 | }).toNotThrow();
|
134 | expect(timeline.getNeighbouringTimeline(EventTimeline.FORWARDS))
|
135 | .toBe(next);
|
136 | expect(function() {
|
137 | timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
138 | }).toThrow();
|
139 | });
|
140 | });
|
141 |
|
142 | describe("addEvent", function() {
|
143 | beforeEach(function() {
|
144 | mockRoomStates(timeline);
|
145 | });
|
146 |
|
147 | const events = [
|
148 | utils.mkMessage({
|
149 | room: roomId, user: userA, msg: "hungry hungry hungry",
|
150 | event: true,
|
151 | }),
|
152 | utils.mkMessage({
|
153 | room: roomId, user: userB, msg: "nom nom nom",
|
154 | event: true,
|
155 | }),
|
156 | ];
|
157 |
|
158 | it("should be able to add events to the end", function() {
|
159 | timeline.addEvent(events[0], false);
|
160 | const initialIndex = timeline.getBaseIndex();
|
161 | timeline.addEvent(events[1], false);
|
162 | expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
163 | expect(timeline.getEvents().length).toEqual(2);
|
164 | expect(timeline.getEvents()[0]).toEqual(events[0]);
|
165 | expect(timeline.getEvents()[1]).toEqual(events[1]);
|
166 | });
|
167 |
|
168 | it("should be able to add events to the start", function() {
|
169 | timeline.addEvent(events[0], true);
|
170 | const initialIndex = timeline.getBaseIndex();
|
171 | timeline.addEvent(events[1], true);
|
172 | expect(timeline.getBaseIndex()).toEqual(initialIndex + 1);
|
173 | expect(timeline.getEvents().length).toEqual(2);
|
174 | expect(timeline.getEvents()[0]).toEqual(events[1]);
|
175 | expect(timeline.getEvents()[1]).toEqual(events[0]);
|
176 | });
|
177 |
|
178 | it("should set event.sender for new and old events", function() {
|
179 | const sentinel = {
|
180 | userId: userA,
|
181 | membership: "join",
|
182 | name: "Alice",
|
183 | };
|
184 | const oldSentinel = {
|
185 | userId: userA,
|
186 | membership: "join",
|
187 | name: "Old Alice",
|
188 | };
|
189 | timeline.getState(EventTimeline.FORWARDS).getSentinelMember
|
190 | .andCall(function(uid) {
|
191 | if (uid === userA) {
|
192 | return sentinel;
|
193 | }
|
194 | return null;
|
195 | });
|
196 | timeline.getState(EventTimeline.BACKWARDS).getSentinelMember
|
197 | .andCall(function(uid) {
|
198 | if (uid === userA) {
|
199 | return oldSentinel;
|
200 | }
|
201 | return null;
|
202 | });
|
203 |
|
204 | const newEv = utils.mkEvent({
|
205 | type: "m.room.name", room: roomId, user: userA, event: true,
|
206 | content: { name: "New Room Name" },
|
207 | });
|
208 | const oldEv = utils.mkEvent({
|
209 | type: "m.room.name", room: roomId, user: userA, event: true,
|
210 | content: { name: "Old Room Name" },
|
211 | });
|
212 |
|
213 | timeline.addEvent(newEv, false);
|
214 | expect(newEv.sender).toEqual(sentinel);
|
215 | timeline.addEvent(oldEv, true);
|
216 | expect(oldEv.sender).toEqual(oldSentinel);
|
217 | });
|
218 |
|
219 | it("should set event.target for new and old m.room.member events",
|
220 | function() {
|
221 | const sentinel = {
|
222 | userId: userA,
|
223 | membership: "join",
|
224 | name: "Alice",
|
225 | };
|
226 | const oldSentinel = {
|
227 | userId: userA,
|
228 | membership: "join",
|
229 | name: "Old Alice",
|
230 | };
|
231 | timeline.getState(EventTimeline.FORWARDS).getSentinelMember
|
232 | .andCall(function(uid) {
|
233 | if (uid === userA) {
|
234 | return sentinel;
|
235 | }
|
236 | return null;
|
237 | });
|
238 | timeline.getState(EventTimeline.BACKWARDS).getSentinelMember
|
239 | .andCall(function(uid) {
|
240 | if (uid === userA) {
|
241 | return oldSentinel;
|
242 | }
|
243 | return null;
|
244 | });
|
245 |
|
246 | const newEv = utils.mkMembership({
|
247 | room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
248 | });
|
249 | const oldEv = utils.mkMembership({
|
250 | room: roomId, mship: "ban", user: userB, skey: userA, event: true,
|
251 | });
|
252 | timeline.addEvent(newEv, false);
|
253 | expect(newEv.target).toEqual(sentinel);
|
254 | timeline.addEvent(oldEv, true);
|
255 | expect(oldEv.target).toEqual(oldSentinel);
|
256 | });
|
257 |
|
258 | it("should call setStateEvents on the right RoomState with the right " +
|
259 | "forwardLooking value for new events", function() {
|
260 | const events = [
|
261 | utils.mkMembership({
|
262 | room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
263 | }),
|
264 | utils.mkEvent({
|
265 | type: "m.room.name", room: roomId, user: userB, event: true,
|
266 | content: {
|
267 | name: "New room",
|
268 | },
|
269 | }),
|
270 | ];
|
271 |
|
272 | timeline.addEvent(events[0], false);
|
273 | timeline.addEvent(events[1], false);
|
274 |
|
275 | expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents).
|
276 | toHaveBeenCalledWith([events[0]]);
|
277 | expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents).
|
278 | toHaveBeenCalledWith([events[1]]);
|
279 |
|
280 | expect(events[0].forwardLooking).toBe(true);
|
281 | expect(events[1].forwardLooking).toBe(true);
|
282 |
|
283 | expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents).
|
284 | toNotHaveBeenCalled();
|
285 | });
|
286 |
|
287 |
|
288 | it("should call setStateEvents on the right RoomState with the right " +
|
289 | "forwardLooking value for old events", function() {
|
290 | const events = [
|
291 | utils.mkMembership({
|
292 | room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
293 | }),
|
294 | utils.mkEvent({
|
295 | type: "m.room.name", room: roomId, user: userB, event: true,
|
296 | content: {
|
297 | name: "New room",
|
298 | },
|
299 | }),
|
300 | ];
|
301 |
|
302 | timeline.addEvent(events[0], true);
|
303 | timeline.addEvent(events[1], true);
|
304 |
|
305 | expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents).
|
306 | toHaveBeenCalledWith([events[0]]);
|
307 | expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents).
|
308 | toHaveBeenCalledWith([events[1]]);
|
309 |
|
310 | expect(events[0].forwardLooking).toBe(false);
|
311 | expect(events[1].forwardLooking).toBe(false);
|
312 |
|
313 | expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents).
|
314 | toNotHaveBeenCalled();
|
315 | });
|
316 | });
|
317 |
|
318 | describe("removeEvent", function() {
|
319 | const events = [
|
320 | utils.mkMessage({
|
321 | room: roomId, user: userA, msg: "hungry hungry hungry",
|
322 | event: true,
|
323 | }),
|
324 | utils.mkMessage({
|
325 | room: roomId, user: userB, msg: "nom nom nom",
|
326 | event: true,
|
327 | }),
|
328 | utils.mkMessage({
|
329 | room: roomId, user: userB, msg: "piiie",
|
330 | event: true,
|
331 | }),
|
332 | ];
|
333 |
|
334 | it("should remove events", function() {
|
335 | timeline.addEvent(events[0], false);
|
336 | timeline.addEvent(events[1], false);
|
337 | expect(timeline.getEvents().length).toEqual(2);
|
338 |
|
339 | let ev = timeline.removeEvent(events[0].getId());
|
340 | expect(ev).toBe(events[0]);
|
341 | expect(timeline.getEvents().length).toEqual(1);
|
342 |
|
343 | ev = timeline.removeEvent(events[1].getId());
|
344 | expect(ev).toBe(events[1]);
|
345 | expect(timeline.getEvents().length).toEqual(0);
|
346 | });
|
347 |
|
348 | it("should update baseIndex", function() {
|
349 | timeline.addEvent(events[0], false);
|
350 | timeline.addEvent(events[1], true);
|
351 | timeline.addEvent(events[2], false);
|
352 | expect(timeline.getEvents().length).toEqual(3);
|
353 | expect(timeline.getBaseIndex()).toEqual(1);
|
354 |
|
355 | timeline.removeEvent(events[2].getId());
|
356 | expect(timeline.getEvents().length).toEqual(2);
|
357 | expect(timeline.getBaseIndex()).toEqual(1);
|
358 |
|
359 | timeline.removeEvent(events[1].getId());
|
360 | expect(timeline.getEvents().length).toEqual(1);
|
361 | expect(timeline.getBaseIndex()).toEqual(0);
|
362 | });
|
363 |
|
364 |
|
365 |
|
366 |
|
367 | it("should not make baseIndex assplode when removing the last event",
|
368 | function() {
|
369 | timeline.addEvent(events[0], true);
|
370 | timeline.removeEvent(events[0].getId());
|
371 | const initialIndex = timeline.getBaseIndex();
|
372 | timeline.addEvent(events[1], false);
|
373 | timeline.addEvent(events[2], false);
|
374 | expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
375 | expect(timeline.getEvents().length).toEqual(2);
|
376 | });
|
377 | });
|
378 | });
|