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`
379 lines
14 KiB
JavaScript
379 lines
14 KiB
JavaScript
"use strict";
|
|
import 'source-map-support/register';
|
|
const sdk = require("../..");
|
|
const EventTimeline = sdk.EventTimeline;
|
|
const utils = require("../test-utils");
|
|
|
|
function mockRoomStates(timeline) {
|
|
timeline._startState = utils.mock(sdk.RoomState, "startState");
|
|
timeline._endState = utils.mock(sdk.RoomState, "endState");
|
|
}
|
|
|
|
import expect from 'expect';
|
|
|
|
describe("EventTimeline", function() {
|
|
const roomId = "!foo:bar";
|
|
const userA = "@alice:bar";
|
|
const userB = "@bertha:bar";
|
|
let timeline;
|
|
|
|
beforeEach(function() {
|
|
utils.beforeEach(this); // eslint-disable-line no-invalid-this
|
|
|
|
// XXX: this is a horrid hack; should use sinon or something instead to mock
|
|
const timelineSet = { room: { roomId: roomId }};
|
|
timelineSet.room.getUnfilteredTimelineSet = function() {
|
|
return timelineSet;
|
|
};
|
|
|
|
timeline = new EventTimeline(timelineSet);
|
|
});
|
|
|
|
describe("construction", function() {
|
|
it("getRoomId should get room id", function() {
|
|
const v = timeline.getRoomId();
|
|
expect(v).toEqual(roomId);
|
|
});
|
|
});
|
|
|
|
describe("initialiseState", function() {
|
|
beforeEach(function() {
|
|
mockRoomStates(timeline);
|
|
});
|
|
|
|
it("should copy state events to start and end state", function() {
|
|
const events = [
|
|
utils.mkMembership({
|
|
room: roomId, mship: "invite", user: userB, skey: userA,
|
|
event: true,
|
|
}),
|
|
utils.mkEvent({
|
|
type: "m.room.name", room: roomId, user: userB,
|
|
event: true,
|
|
content: { name: "New room" },
|
|
}),
|
|
];
|
|
timeline.initialiseState(events);
|
|
expect(timeline._startState.setStateEvents).toHaveBeenCalledWith(
|
|
events,
|
|
);
|
|
expect(timeline._endState.setStateEvents).toHaveBeenCalledWith(
|
|
events,
|
|
);
|
|
});
|
|
|
|
it("should raise an exception if called after events are added", function() {
|
|
const event =
|
|
utils.mkMessage({
|
|
room: roomId, user: userA, msg: "Adam stole the plushies",
|
|
event: true,
|
|
});
|
|
|
|
const state = [
|
|
utils.mkMembership({
|
|
room: roomId, mship: "invite", user: userB, skey: userA,
|
|
event: true,
|
|
}),
|
|
];
|
|
|
|
expect(function() {
|
|
timeline.initialiseState(state);
|
|
}).toNotThrow();
|
|
timeline.addEvent(event, false);
|
|
expect(function() {
|
|
timeline.initialiseState(state);
|
|
}).toThrow();
|
|
});
|
|
});
|
|
|
|
describe("paginationTokens", function() {
|
|
it("pagination tokens should start null", function() {
|
|
expect(timeline.getPaginationToken(EventTimeline.BACKWARDS)).toBe(null);
|
|
expect(timeline.getPaginationToken(EventTimeline.FORWARDS)).toBe(null);
|
|
});
|
|
|
|
it("setPaginationToken should set token", function() {
|
|
timeline.setPaginationToken("back", EventTimeline.BACKWARDS);
|
|
timeline.setPaginationToken("fwd", EventTimeline.FORWARDS);
|
|
expect(timeline.getPaginationToken(EventTimeline.BACKWARDS)).toEqual("back");
|
|
expect(timeline.getPaginationToken(EventTimeline.FORWARDS)).toEqual("fwd");
|
|
});
|
|
});
|
|
|
|
|
|
describe("neighbouringTimelines", function() {
|
|
it("neighbouring timelines should start null", function() {
|
|
expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(null);
|
|
expect(timeline.getNeighbouringTimeline(EventTimeline.FORWARDS)).toBe(null);
|
|
});
|
|
|
|
it("setNeighbouringTimeline should set neighbour", function() {
|
|
const prev = {a: "a"};
|
|
const next = {b: "b"};
|
|
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
|
timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
|
expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(prev);
|
|
expect(timeline.getNeighbouringTimeline(EventTimeline.FORWARDS)).toBe(next);
|
|
});
|
|
|
|
it("setNeighbouringTimeline should throw if called twice", function() {
|
|
const prev = {a: "a"};
|
|
const next = {b: "b"};
|
|
expect(function() {
|
|
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
|
}).toNotThrow();
|
|
expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS))
|
|
.toBe(prev);
|
|
expect(function() {
|
|
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
|
}).toThrow();
|
|
|
|
expect(function() {
|
|
timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
|
}).toNotThrow();
|
|
expect(timeline.getNeighbouringTimeline(EventTimeline.FORWARDS))
|
|
.toBe(next);
|
|
expect(function() {
|
|
timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
|
}).toThrow();
|
|
});
|
|
});
|
|
|
|
describe("addEvent", function() {
|
|
beforeEach(function() {
|
|
mockRoomStates(timeline);
|
|
});
|
|
|
|
const events = [
|
|
utils.mkMessage({
|
|
room: roomId, user: userA, msg: "hungry hungry hungry",
|
|
event: true,
|
|
}),
|
|
utils.mkMessage({
|
|
room: roomId, user: userB, msg: "nom nom nom",
|
|
event: true,
|
|
}),
|
|
];
|
|
|
|
it("should be able to add events to the end", function() {
|
|
timeline.addEvent(events[0], false);
|
|
const initialIndex = timeline.getBaseIndex();
|
|
timeline.addEvent(events[1], false);
|
|
expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
|
expect(timeline.getEvents().length).toEqual(2);
|
|
expect(timeline.getEvents()[0]).toEqual(events[0]);
|
|
expect(timeline.getEvents()[1]).toEqual(events[1]);
|
|
});
|
|
|
|
it("should be able to add events to the start", function() {
|
|
timeline.addEvent(events[0], true);
|
|
const initialIndex = timeline.getBaseIndex();
|
|
timeline.addEvent(events[1], true);
|
|
expect(timeline.getBaseIndex()).toEqual(initialIndex + 1);
|
|
expect(timeline.getEvents().length).toEqual(2);
|
|
expect(timeline.getEvents()[0]).toEqual(events[1]);
|
|
expect(timeline.getEvents()[1]).toEqual(events[0]);
|
|
});
|
|
|
|
it("should set event.sender for new and old events", function() {
|
|
const sentinel = {
|
|
userId: userA,
|
|
membership: "join",
|
|
name: "Alice",
|
|
};
|
|
const oldSentinel = {
|
|
userId: userA,
|
|
membership: "join",
|
|
name: "Old Alice",
|
|
};
|
|
timeline.getState(EventTimeline.FORWARDS).getSentinelMember
|
|
.andCall(function(uid) {
|
|
if (uid === userA) {
|
|
return sentinel;
|
|
}
|
|
return null;
|
|
});
|
|
timeline.getState(EventTimeline.BACKWARDS).getSentinelMember
|
|
.andCall(function(uid) {
|
|
if (uid === userA) {
|
|
return oldSentinel;
|
|
}
|
|
return null;
|
|
});
|
|
|
|
const newEv = utils.mkEvent({
|
|
type: "m.room.name", room: roomId, user: userA, event: true,
|
|
content: { name: "New Room Name" },
|
|
});
|
|
const oldEv = utils.mkEvent({
|
|
type: "m.room.name", room: roomId, user: userA, event: true,
|
|
content: { name: "Old Room Name" },
|
|
});
|
|
|
|
timeline.addEvent(newEv, false);
|
|
expect(newEv.sender).toEqual(sentinel);
|
|
timeline.addEvent(oldEv, true);
|
|
expect(oldEv.sender).toEqual(oldSentinel);
|
|
});
|
|
|
|
it("should set event.target for new and old m.room.member events",
|
|
function() {
|
|
const sentinel = {
|
|
userId: userA,
|
|
membership: "join",
|
|
name: "Alice",
|
|
};
|
|
const oldSentinel = {
|
|
userId: userA,
|
|
membership: "join",
|
|
name: "Old Alice",
|
|
};
|
|
timeline.getState(EventTimeline.FORWARDS).getSentinelMember
|
|
.andCall(function(uid) {
|
|
if (uid === userA) {
|
|
return sentinel;
|
|
}
|
|
return null;
|
|
});
|
|
timeline.getState(EventTimeline.BACKWARDS).getSentinelMember
|
|
.andCall(function(uid) {
|
|
if (uid === userA) {
|
|
return oldSentinel;
|
|
}
|
|
return null;
|
|
});
|
|
|
|
const newEv = utils.mkMembership({
|
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
|
});
|
|
const oldEv = utils.mkMembership({
|
|
room: roomId, mship: "ban", user: userB, skey: userA, event: true,
|
|
});
|
|
timeline.addEvent(newEv, false);
|
|
expect(newEv.target).toEqual(sentinel);
|
|
timeline.addEvent(oldEv, true);
|
|
expect(oldEv.target).toEqual(oldSentinel);
|
|
});
|
|
|
|
it("should call setStateEvents on the right RoomState with the right " +
|
|
"forwardLooking value for new events", function() {
|
|
const events = [
|
|
utils.mkMembership({
|
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
|
}),
|
|
utils.mkEvent({
|
|
type: "m.room.name", room: roomId, user: userB, event: true,
|
|
content: {
|
|
name: "New room",
|
|
},
|
|
}),
|
|
];
|
|
|
|
timeline.addEvent(events[0], false);
|
|
timeline.addEvent(events[1], false);
|
|
|
|
expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents).
|
|
toHaveBeenCalledWith([events[0]]);
|
|
expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents).
|
|
toHaveBeenCalledWith([events[1]]);
|
|
|
|
expect(events[0].forwardLooking).toBe(true);
|
|
expect(events[1].forwardLooking).toBe(true);
|
|
|
|
expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents).
|
|
toNotHaveBeenCalled();
|
|
});
|
|
|
|
|
|
it("should call setStateEvents on the right RoomState with the right " +
|
|
"forwardLooking value for old events", function() {
|
|
const events = [
|
|
utils.mkMembership({
|
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
|
}),
|
|
utils.mkEvent({
|
|
type: "m.room.name", room: roomId, user: userB, event: true,
|
|
content: {
|
|
name: "New room",
|
|
},
|
|
}),
|
|
];
|
|
|
|
timeline.addEvent(events[0], true);
|
|
timeline.addEvent(events[1], true);
|
|
|
|
expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents).
|
|
toHaveBeenCalledWith([events[0]]);
|
|
expect(timeline.getState(EventTimeline.BACKWARDS).setStateEvents).
|
|
toHaveBeenCalledWith([events[1]]);
|
|
|
|
expect(events[0].forwardLooking).toBe(false);
|
|
expect(events[1].forwardLooking).toBe(false);
|
|
|
|
expect(timeline.getState(EventTimeline.FORWARDS).setStateEvents).
|
|
toNotHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
describe("removeEvent", function() {
|
|
const events = [
|
|
utils.mkMessage({
|
|
room: roomId, user: userA, msg: "hungry hungry hungry",
|
|
event: true,
|
|
}),
|
|
utils.mkMessage({
|
|
room: roomId, user: userB, msg: "nom nom nom",
|
|
event: true,
|
|
}),
|
|
utils.mkMessage({
|
|
room: roomId, user: userB, msg: "piiie",
|
|
event: true,
|
|
}),
|
|
];
|
|
|
|
it("should remove events", function() {
|
|
timeline.addEvent(events[0], false);
|
|
timeline.addEvent(events[1], false);
|
|
expect(timeline.getEvents().length).toEqual(2);
|
|
|
|
let ev = timeline.removeEvent(events[0].getId());
|
|
expect(ev).toBe(events[0]);
|
|
expect(timeline.getEvents().length).toEqual(1);
|
|
|
|
ev = timeline.removeEvent(events[1].getId());
|
|
expect(ev).toBe(events[1]);
|
|
expect(timeline.getEvents().length).toEqual(0);
|
|
});
|
|
|
|
it("should update baseIndex", function() {
|
|
timeline.addEvent(events[0], false);
|
|
timeline.addEvent(events[1], true);
|
|
timeline.addEvent(events[2], false);
|
|
expect(timeline.getEvents().length).toEqual(3);
|
|
expect(timeline.getBaseIndex()).toEqual(1);
|
|
|
|
timeline.removeEvent(events[2].getId());
|
|
expect(timeline.getEvents().length).toEqual(2);
|
|
expect(timeline.getBaseIndex()).toEqual(1);
|
|
|
|
timeline.removeEvent(events[1].getId());
|
|
expect(timeline.getEvents().length).toEqual(1);
|
|
expect(timeline.getBaseIndex()).toEqual(0);
|
|
});
|
|
|
|
// this is basically https://github.com/vector-im/vector-web/issues/937
|
|
// - removing the last event got baseIndex into such a state that
|
|
// further addEvent(ev, false) calls made the index increase.
|
|
it("should not make baseIndex assplode when removing the last event",
|
|
function() {
|
|
timeline.addEvent(events[0], true);
|
|
timeline.removeEvent(events[0].getId());
|
|
const initialIndex = timeline.getBaseIndex();
|
|
timeline.addEvent(events[1], false);
|
|
timeline.addEvent(events[2], false);
|
|
expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
|
expect(timeline.getEvents().length).toEqual(2);
|
|
});
|
|
});
|
|
});
|