1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-06 12:02:40 +03:00

Merge remote-tracking branch 'origin/develop' into dbkr/gcmerge_26oct22

This commit is contained in:
David Baker
2022-10-26 11:56:41 +01:00
78 changed files with 879 additions and 730 deletions

View File

@@ -222,9 +222,9 @@ describe.each([
["IndexedDBCryptoStore",
() => new IndexedDBCryptoStore(global.indexedDB, "tests")],
["LocalStorageCryptoStore",
() => new IndexedDBCryptoStore(undefined, "tests")],
() => new IndexedDBCryptoStore(undefined!, "tests")],
["MemoryCryptoStore", () => {
const store = new IndexedDBCryptoStore(undefined, "tests");
const store = new IndexedDBCryptoStore(undefined!, "tests");
// @ts-ignore set private properties
store._backend = new MemoryCryptoStore();
// @ts-ignore
@@ -255,6 +255,6 @@ describe.each([
expect(nokey).toBeNull();
const key = await getCrossSigningKeyCache!("self_signing", "");
expect(new Uint8Array(key)).toEqual(testKey);
expect(new Uint8Array(key!)).toEqual(testKey);
});
});

View File

@@ -536,6 +536,7 @@ describe("MegolmDecryption", function() {
"@bob:example.com", BOB_DEVICES,
);
aliceClient.crypto!.deviceList.downloadKeys = async function(userIds) {
// @ts-ignore short-circuiting private method
return this.getDevicesFromStore(userIds);
};

View File

@@ -437,6 +437,7 @@ describe("Secrets", function() {
return [keyId, secretStorageKeys[keyId]];
}
}
return null;
},
},
},
@@ -571,6 +572,7 @@ describe("Secrets", function() {
return [keyId, secretStorageKeys[keyId]];
}
}
return null;
},
},
},

View File

@@ -131,7 +131,11 @@ function makeRemoteEcho(event) {
}));
}
async function distributeEvent(ownRequest, theirRequest, event) {
async function distributeEvent(
ownRequest: VerificationRequest,
theirRequest: VerificationRequest,
event: MatrixEvent,
): Promise<void> {
await ownRequest.channel.handleEvent(
makeRemoteEcho(event),
ownRequest,

View File

@@ -45,7 +45,7 @@ describe('EventTimelineSet', () => {
it('should return the related events', () => {
eventTimelineSet.relations.aggregateChildEvent(messageEvent);
const relations = eventTimelineSet.relations.getChildEventsForEvent(
messageEvent.getId(),
messageEvent.getId()!,
"m.in_reply_to",
EventType.RoomMessage,
);
@@ -193,7 +193,7 @@ describe('EventTimelineSet', () => {
it('should not return the related events', () => {
eventTimelineSet.relations.aggregateChildEvent(messageEvent);
const relations = eventTimelineSet.relations.getChildEventsForEvent(
messageEvent.getId(),
messageEvent.getId()!,
"m.in_reply_to",
EventType.RoomMessage,
);
@@ -236,7 +236,7 @@ describe('EventTimelineSet', () => {
"m.relates_to": {
"event_id": root.getId(),
"m.in_reply_to": {
"event_id": root.getId(),
"event_id": root.getId()!,
},
"rel_type": "m.thread",
},
@@ -278,14 +278,14 @@ describe('EventTimelineSet', () => {
});
it("should return true if the timeline set is for a thread and the event is its thread root", () => {
const thread = new Thread(messageEvent.getId(), messageEvent, { room, client });
const thread = new Thread(messageEvent.getId()!, messageEvent, { room, client });
const eventTimelineSet = new EventTimelineSet(room, {}, client, thread);
messageEvent.setThread(thread);
expect(eventTimelineSet.canContain(messageEvent)).toBeTruthy();
});
it("should return true if the timeline set is for a thread and the event is a response to it", () => {
const thread = new Thread(messageEvent.getId(), messageEvent, { room, client });
const thread = new Thread(messageEvent.getId()!, messageEvent, { room, client });
const eventTimelineSet = new EventTimelineSet(room, {}, client, thread);
messageEvent.setThread(thread);
const event = mkThreadResponse(messageEvent);
@@ -310,7 +310,7 @@ describe('EventTimelineSet', () => {
content: { body: "test" },
event_id: "!test1:server",
});
eventTimelineSet.handleRemoteEcho(roomMessageEvent, "~!local-event-id:server", roomMessageEvent.getId());
eventTimelineSet.handleRemoteEcho(roomMessageEvent, "~!local-event-id:server", roomMessageEvent.getId()!);
expect(eventTimelineSet.getLiveTimeline().getEvents()).toContain(roomMessageEvent);
const roomFilteredEvent = new MatrixEvent({
@@ -318,7 +318,7 @@ describe('EventTimelineSet', () => {
content: { body: "test" },
event_id: "!test2:server",
});
eventTimelineSet.handleRemoteEcho(roomFilteredEvent, "~!local-event-id:server", roomFilteredEvent.getId());
eventTimelineSet.handleRemoteEcho(roomFilteredEvent, "~!local-event-id:server", roomFilteredEvent.getId()!);
expect(eventTimelineSet.getLiveTimeline().getEvents()).not.toContain(roomFilteredEvent);
});
});

View File

@@ -341,11 +341,11 @@ describe("EventTimeline", function() {
timeline.addEvent(events[1], { toStartOfTimeline: false });
expect(timeline.getEvents().length).toEqual(2);
let ev = timeline.removeEvent(events[0].getId());
let ev = timeline.removeEvent(events[0].getId()!);
expect(ev).toBe(events[0]);
expect(timeline.getEvents().length).toEqual(1);
ev = timeline.removeEvent(events[1].getId());
ev = timeline.removeEvent(events[1].getId()!);
expect(ev).toBe(events[1]);
expect(timeline.getEvents().length).toEqual(0);
});
@@ -357,11 +357,11 @@ describe("EventTimeline", function() {
expect(timeline.getEvents().length).toEqual(3);
expect(timeline.getBaseIndex()).toEqual(1);
timeline.removeEvent(events[2].getId());
timeline.removeEvent(events[2].getId()!);
expect(timeline.getEvents().length).toEqual(2);
expect(timeline.getBaseIndex()).toEqual(1);
timeline.removeEvent(events[1].getId());
timeline.removeEvent(events[1].getId()!);
expect(timeline.getEvents().length).toEqual(1);
expect(timeline.getBaseIndex()).toEqual(0);
});
@@ -372,7 +372,7 @@ describe("EventTimeline", function() {
it("should not make baseIndex assplode when removing the last event",
function() {
timeline.addEvent(events[0], { toStartOfTimeline: true });
timeline.removeEvent(events[0].getId());
timeline.removeEvent(events[0].getId()!);
const initialIndex = timeline.getBaseIndex();
timeline.addEvent(events[1], { toStartOfTimeline: false });
timeline.addEvent(events[2], { toStartOfTimeline: false });

View File

@@ -1,65 +0,0 @@
/*
Copyright 2017 New Vector Ltd
Copyright 2019, 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixEvent } from "../../src/models/event";
describe("MatrixEvent", () => {
describe(".attemptDecryption", () => {
let encryptedEvent;
const eventId = 'test_encrypted_event';
beforeEach(() => {
encryptedEvent = new MatrixEvent({
event_id: eventId,
type: 'm.room.encrypted',
content: {
ciphertext: 'secrets',
},
});
});
it('should retry decryption if a retry is queued', async () => {
const eventAttemptDecryptionSpy = jest.spyOn(encryptedEvent, 'attemptDecryption');
const crypto = {
decryptEvent: jest.fn()
.mockImplementationOnce(() => {
// schedule a second decryption attempt while
// the first one is still running.
encryptedEvent.attemptDecryption(crypto);
const error = new Error("nope");
error.name = 'DecryptionError';
return Promise.reject(error);
})
.mockImplementationOnce(() => {
return Promise.resolve({
clearEvent: {
type: 'm.room.message',
},
});
}),
};
await encryptedEvent.attemptDecryption(crypto);
expect(eventAttemptDecryptionSpy).toHaveBeenCalledTimes(2);
expect(crypto.decryptEvent).toHaveBeenCalledTimes(2);
expect(encryptedEvent.getType()).toEqual('m.room.message');
});
});
});

View File

@@ -312,7 +312,7 @@ describe("MSC3089Branch", () => {
} as MatrixEvent);
const events = [await branch.getFileEvent(), await branch2.getFileEvent(), {
replacingEventId: (): string => null,
replacingEventId: (): string | undefined => undefined,
getId: () => "$unknown",
}];
staticRoom.getLiveTimeline = () => ({ getEvents: () => events }) as EventTimeline;

View File

@@ -135,7 +135,7 @@ describe("MSC3089TreeSpace", () => {
// noinspection ExceptionCaughtLocallyJS
throw new Error("Failed to fail");
} catch (e) {
expect(e.errcode).toEqual("M_FORBIDDEN");
expect((<MatrixError>e).errcode).toEqual("M_FORBIDDEN");
}
expect(fn).toHaveBeenCalledTimes(1);
@@ -513,7 +513,7 @@ describe("MSC3089TreeSpace", () => {
function expectOrder(childRoomId: string, order: number) {
const child = childTrees.find(c => c.roomId === childRoomId);
expect(child).toBeDefined();
expect(child.getOrder()).toEqual(order);
expect(child!.getOrder()).toEqual(order);
}
function makeMockChildRoom(roomId: string): Room {
@@ -608,7 +608,7 @@ describe("MSC3089TreeSpace", () => {
// noinspection ExceptionCaughtLocallyJS
throw new Error("Failed to fail");
} catch (e) {
expect(e.message).toEqual("Cannot set order of top level spaces currently");
expect((<Error>e).message).toEqual("Cannot set order of top level spaces currently");
}
});
@@ -706,7 +706,7 @@ describe("MSC3089TreeSpace", () => {
const treeA = childTrees.find(c => c.roomId === a);
expect(treeA).toBeDefined();
await treeA.setOrder(1);
await treeA!.setOrder(1);
expect(clientSendStateFn).toHaveBeenCalledTimes(3);
expect(clientSendStateFn).toHaveBeenCalledWith(tree.roomId, EventType.SpaceChild, expect.objectContaining({
@@ -743,7 +743,7 @@ describe("MSC3089TreeSpace", () => {
const treeA = childTrees.find(c => c.roomId === a);
expect(treeA).toBeDefined();
await treeA.setOrder(1);
await treeA!.setOrder(1);
expect(clientSendStateFn).toHaveBeenCalledTimes(1);
expect(clientSendStateFn).toHaveBeenCalledWith(tree.roomId, EventType.SpaceChild, expect.objectContaining({
@@ -771,7 +771,7 @@ describe("MSC3089TreeSpace", () => {
const treeA = childTrees.find(c => c.roomId === a);
expect(treeA).toBeDefined();
await treeA.setOrder(2);
await treeA!.setOrder(2);
expect(clientSendStateFn).toHaveBeenCalledTimes(1);
expect(clientSendStateFn).toHaveBeenCalledWith(tree.roomId, EventType.SpaceChild, expect.objectContaining({
@@ -800,7 +800,7 @@ describe("MSC3089TreeSpace", () => {
const treeB = childTrees.find(c => c.roomId === b);
expect(treeB).toBeDefined();
await treeB.setOrder(2);
await treeB!.setOrder(2);
expect(clientSendStateFn).toHaveBeenCalledTimes(1);
expect(clientSendStateFn).toHaveBeenCalledWith(tree.roomId, EventType.SpaceChild, expect.objectContaining({
@@ -829,7 +829,7 @@ describe("MSC3089TreeSpace", () => {
const treeC = childTrees.find(ch => ch.roomId === c);
expect(treeC).toBeDefined();
await treeC.setOrder(1);
await treeC!.setOrder(1);
expect(clientSendStateFn).toHaveBeenCalledTimes(1);
expect(clientSendStateFn).toHaveBeenCalledWith(tree.roomId, EventType.SpaceChild, expect.objectContaining({
@@ -858,7 +858,7 @@ describe("MSC3089TreeSpace", () => {
const treeB = childTrees.find(ch => ch.roomId === b);
expect(treeB).toBeDefined();
await treeB.setOrder(2);
await treeB!.setOrder(2);
expect(clientSendStateFn).toHaveBeenCalledTimes(2);
expect(clientSendStateFn).toHaveBeenCalledWith(tree.roomId, EventType.SpaceChild, expect.objectContaining({
@@ -903,7 +903,7 @@ describe("MSC3089TreeSpace", () => {
url: mxc,
file: fileInfo,
metadata: true, // additional content from test
[UNSTABLE_MSC3089_LEAF.unstable]: {}, // test to ensure we're definitely using unstable
[UNSTABLE_MSC3089_LEAF.unstable!]: {}, // test to ensure we're definitely using unstable
});
return Promise.resolve({ event_id: fileEventId }); // eslint-disable-line camelcase
@@ -965,7 +965,7 @@ describe("MSC3089TreeSpace", () => {
expect(contents).toMatchObject({
...content,
"m.new_content": content,
[UNSTABLE_MSC3089_LEAF.unstable]: {}, // test to ensure we're definitely using unstable
[UNSTABLE_MSC3089_LEAF.unstable!]: {}, // test to ensure we're definitely using unstable
});
return Promise.resolve({ event_id: fileEventId }); // eslint-disable-line camelcase
@@ -1010,7 +1010,7 @@ describe("MSC3089TreeSpace", () => {
const file = tree.getFile(fileEventId);
expect(file).toBeDefined();
expect(file.indexEvent).toBe(fileEvent);
expect(file!.indexEvent).toBe(fileEvent);
});
it('should return falsy for unknown files', () => {

View File

@@ -263,7 +263,7 @@ describe('Beacon', () => {
roomId,
);
// less than the original event
oldUpdateEvent.event.origin_server_ts = liveBeaconEvent.event.origin_server_ts - 1000;
oldUpdateEvent.event.origin_server_ts = liveBeaconEvent.event.origin_server_ts! - 1000;
beacon.update(oldUpdateEvent);
// didnt update

View File

@@ -115,8 +115,53 @@ describe('MatrixEvent', () => {
});
const prom = emitPromise(ev, MatrixEventEvent.VisibilityChange);
ev.applyVisibilityEvent({ visible: false, eventId: ev.getId(), reason: null });
ev.applyVisibilityEvent({ visible: false, eventId: ev.getId()!, reason: null });
await prom;
});
});
describe(".attemptDecryption", () => {
let encryptedEvent;
const eventId = 'test_encrypted_event';
beforeEach(() => {
encryptedEvent = new MatrixEvent({
event_id: eventId,
type: 'm.room.encrypted',
content: {
ciphertext: 'secrets',
},
});
});
it('should retry decryption if a retry is queued', async () => {
const eventAttemptDecryptionSpy = jest.spyOn(encryptedEvent, 'attemptDecryption');
const crypto = {
decryptEvent: jest.fn()
.mockImplementationOnce(() => {
// schedule a second decryption attempt while
// the first one is still running.
encryptedEvent.attemptDecryption(crypto);
const error = new Error("nope");
error.name = 'DecryptionError';
return Promise.reject(error);
})
.mockImplementationOnce(() => {
return Promise.resolve({
clearEvent: {
type: 'm.room.message',
},
});
}),
};
await encryptedEvent.attemptDecryption(crypto);
expect(eventAttemptDecryptionSpy).toHaveBeenCalledTimes(2);
expect(crypto.decryptEvent).toHaveBeenCalledTimes(2);
expect(encryptedEvent.getType()).toEqual('m.room.message');
});
});
});

View File

@@ -128,11 +128,11 @@ describe.each([
],
});
await flushAndRunTimersUntil(() => httpBackend.requests.length > 0);
expect(httpBackend.flushSync(null, 1)).toEqual(1);
expect(httpBackend.flushSync(undefined, 1)).toEqual(1);
await flushAndRunTimersUntil(() => httpBackend.requests.length > 0);
expect(httpBackend.flushSync(null, 1)).toEqual(1);
expect(httpBackend.flushSync(undefined, 1)).toEqual(1);
// flush, as per comment in first test
await flushPromises();
@@ -152,7 +152,7 @@ describe.each([
],
});
await flushAndRunTimersUntil(() => httpBackend.requests.length > 0);
expect(httpBackend.flushSync(null, 1)).toEqual(1);
expect(httpBackend.flushSync(undefined, 1)).toEqual(1);
// Asserting that another request is never made is obviously
// a bit tricky - we just flush the queue what should hopefully
@@ -188,7 +188,7 @@ describe.each([
],
});
await flushAndRunTimersUntil(() => httpBackend.requests.length > 0);
expect(httpBackend.flushSync(null, 1)).toEqual(1);
expect(httpBackend.flushSync(undefined, 1)).toEqual(1);
await flushPromises();
logger.info("Advancing clock to just before expected retry time...");
@@ -203,7 +203,7 @@ describe.each([
jest.advanceTimersByTime(2000);
await flushPromises();
expect(httpBackend.flushSync(null, 1)).toEqual(1);
expect(httpBackend.flushSync(undefined, 1)).toEqual(1);
});
it("retries on retryImmediately()", async function() {
@@ -211,7 +211,7 @@ describe.each([
versions: ["r0.0.1"],
});
await Promise.all([client.startClient(), httpBackend.flush(null, 1, 20)]);
await Promise.all([client.startClient(), httpBackend.flush(undefined, 1, 20)]);
httpBackend.when(
"PUT", "/sendToDevice/org.example.foo/",
@@ -227,13 +227,13 @@ describe.each([
FAKE_MSG,
],
});
expect(await httpBackend.flush(null, 1, 1)).toEqual(1);
expect(await httpBackend.flush(undefined, 1, 1)).toEqual(1);
await flushPromises();
client.retryImmediately();
// longer timeout here to try & avoid flakiness
expect(await httpBackend.flush(null, 1, 3000)).toEqual(1);
expect(await httpBackend.flush(undefined, 1, 3000)).toEqual(1);
});
it("retries on when client is started", async function() {
@@ -257,13 +257,13 @@ describe.each([
FAKE_MSG,
],
});
expect(await httpBackend.flush(null, 1, 1)).toEqual(1);
expect(await httpBackend.flush(undefined, 1, 1)).toEqual(1);
await flushPromises();
client.stopClient();
await Promise.all([client.startClient(), httpBackend.flush("/_matrix/client/versions", 1, 20)]);
expect(await httpBackend.flush(null, 1, 20)).toEqual(1);
expect(await httpBackend.flush(undefined, 1, 20)).toEqual(1);
});
it("retries when a message is retried", async function() {
@@ -271,7 +271,7 @@ describe.each([
versions: ["r0.0.1"],
});
await Promise.all([client.startClient(), httpBackend.flush(null, 1, 20)]);
await Promise.all([client.startClient(), httpBackend.flush(undefined, 1, 20)]);
httpBackend.when(
"PUT", "/sendToDevice/org.example.foo/",
@@ -288,7 +288,7 @@ describe.each([
],
});
expect(await httpBackend.flush(null, 1, 1)).toEqual(1);
expect(await httpBackend.flush(undefined, 1, 1)).toEqual(1);
await flushPromises();
const dummyEvent = new MatrixEvent({
@@ -299,7 +299,7 @@ describe.each([
} as unknown as Room;
client.resendEvent(dummyEvent, mockRoom);
expect(await httpBackend.flush(null, 1, 20)).toEqual(1);
expect(await httpBackend.flush(undefined, 1, 20)).toEqual(1);
});
it("splits many messages into multiple HTTP requests", async function() {

View File

@@ -97,7 +97,7 @@ describe("Read receipt", () => {
"POST", encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", {
$roomId: ROOM_ID,
$receiptType: ReceiptType.Read,
$eventId: threadEvent.getId(),
$eventId: threadEvent.getId()!,
}),
).check((request) => {
expect(request.data.thread_id).toEqual(THREAD_ID);
@@ -115,7 +115,7 @@ describe("Read receipt", () => {
"POST", encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", {
$roomId: ROOM_ID,
$receiptType: ReceiptType.Read,
$eventId: roomEvent.getId(),
$eventId: roomEvent.getId()!,
}),
).check((request) => {
expect(request.data.thread_id).toEqual(MAIN_ROOM_TIMELINE);
@@ -133,7 +133,7 @@ describe("Read receipt", () => {
"POST", encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", {
$roomId: ROOM_ID,
$receiptType: ReceiptType.Read,
$eventId: threadEvent.getId(),
$eventId: threadEvent.getId()!,
}),
).check((request) => {
expect(request.data.thread_id).toBeUndefined();
@@ -151,7 +151,7 @@ describe("Read receipt", () => {
"POST", encodeUri("/rooms/$roomId/receipt/$receiptType/$eventId", {
$roomId: ROOM_ID,
$receiptType: ReceiptType.Read,
$eventId: threadEvent.getId(),
$eventId: threadEvent.getId()!,
}),
).check((request) => {
expect(request.data).toEqual({});

View File

@@ -1,3 +1,19 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import * as callbacks from "../../src/realtime-callbacks";
let wallTime = 1234567890;
@@ -37,7 +53,7 @@ describe("realtime-callbacks", function() {
it("should set 'this' to the global object", function() {
let passed = false;
const callback = function() {
const callback = function(this: typeof global) {
expect(this).toBe(global); // eslint-disable-line @typescript-eslint/no-invalid-this
expect(this.console).toBeTruthy(); // eslint-disable-line @typescript-eslint/no-invalid-this
passed = true;

View File

@@ -22,7 +22,7 @@ import { TestClient } from "../TestClient";
describe("Relations", function() {
it("should deduplicate annotations", function() {
const room = new Room("room123", null, null);
const room = new Room("room123", null!, null!);
const relations = new Relations("m.annotation", "m.reaction", room);
// Create an instance of an annotation
@@ -99,7 +99,7 @@ describe("Relations", function() {
// Add the target event first, then the relation event
{
const room = new Room("room123", null, null);
const room = new Room("room123", null!, null!);
const relationsCreated = new Promise(resolve => {
targetEvent.once(MatrixEventEvent.RelationsCreated, resolve);
});
@@ -113,7 +113,7 @@ describe("Relations", function() {
// Add the relation event first, then the target event
{
const room = new Room("room123", null, null);
const room = new Room("room123", null!, null!);
const relationsCreated = new Promise(resolve => {
targetEvent.once(MatrixEventEvent.RelationsCreated, resolve);
});
@@ -127,7 +127,7 @@ describe("Relations", function() {
});
it("should re-use Relations between all timeline sets in a room", async () => {
const room = new Room("room123", null, null);
const room = new Room("room123", null!, null!);
const timelineSet1 = new EventTimelineSet(room);
const timelineSet2 = new EventTimelineSet(room);
expect(room.relations).toBe(timelineSet1.relations);
@@ -136,7 +136,7 @@ describe("Relations", function() {
it("should ignore m.replace for state events", async () => {
const userId = "@bob:example.com";
const room = new Room("room123", null, userId);
const room = new Room("room123", null!, userId);
const relations = new Relations("m.replace", "m.room.topic", room);
// Create an instance of a state event with rel_type m.replace

View File

@@ -172,7 +172,7 @@ describe("RoomState", function() {
state.on(RoomStateEvent.Members, function(ev, st, mem) {
expect(ev).toEqual(memberEvents[emitCount]);
expect(st).toEqual(state);
expect(mem).toEqual(state.getMember(ev.getSender()));
expect(mem).toEqual(state.getMember(ev.getSender()!));
emitCount += 1;
});
state.setStateEvents(memberEvents);

View File

@@ -24,7 +24,7 @@ import {
DuplicateStrategy,
EventStatus,
EventTimelineSet,
EventType,
EventType, IStateEventWithRoomId,
JoinRule,
MatrixEvent,
MatrixEventEvent,
@@ -66,7 +66,7 @@ describe("Room", function() {
"body": "Reply :: " + Math.random(),
"m.relates_to": {
"m.in_reply_to": {
"event_id": target.getId(),
"event_id": target.getId()!,
},
},
},
@@ -84,7 +84,7 @@ describe("Room", function() {
},
"m.relates_to": {
rel_type: RelationType.Replace,
event_id: target.getId(),
event_id: target.getId()!,
},
},
}, room.client);
@@ -97,9 +97,9 @@ describe("Room", function() {
content: {
"body": "Thread response :: " + Math.random(),
"m.relates_to": {
"event_id": root.getId(),
"event_id": root.getId()!,
"m.in_reply_to": {
"event_id": root.getId(),
"event_id": root.getId()!,
},
"rel_type": "m.thread",
},
@@ -114,7 +114,7 @@ describe("Room", function() {
content: {
"m.relates_to": {
"rel_type": RelationType.Annotation,
"event_id": target.getId(),
"event_id": target.getId()!,
"key": Math.random().toString(),
},
},
@@ -125,7 +125,7 @@ describe("Room", function() {
type: EventType.RoomRedaction,
user: userA,
room: roomId,
redacts: target.getId(),
redacts: target.getId()!,
content: {},
}, room.client);
@@ -722,13 +722,13 @@ describe("Room", function() {
it("should handle events in the same timeline", function() {
room.addLiveEvents(events);
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[0].getId(),
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[0].getId()!,
events[1].getId()))
.toBeLessThan(0);
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[2].getId(),
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[2].getId()!,
events[1].getId()))
.toBeGreaterThan(0);
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[1].getId(),
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[1].getId()!,
events[1].getId()))
.toEqual(0);
});
@@ -741,10 +741,10 @@ describe("Room", function() {
room.addEventsToTimeline([events[0]], false, oldTimeline);
room.addLiveEvents([events[1]]);
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[0].getId(),
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[0].getId()!,
events[1].getId()))
.toBeLessThan(0);
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[1].getId(),
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[1].getId()!,
events[0].getId()))
.toBeGreaterThan(0);
});
@@ -755,10 +755,10 @@ describe("Room", function() {
room.addEventsToTimeline([events[0]], false, oldTimeline);
room.addLiveEvents([events[1]]);
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[0].getId(),
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[0].getId()!,
events[1].getId()))
.toBe(null);
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[1].getId(),
expect(room.getUnfilteredTimelineSet().compareEventOrdering(events[1].getId()!,
events[0].getId()))
.toBe(null);
});
@@ -767,13 +767,13 @@ describe("Room", function() {
room.addLiveEvents(events);
expect(room.getUnfilteredTimelineSet()
.compareEventOrdering(events[0].getId(), "xxx"))
.compareEventOrdering(events[0].getId()!, "xxx"))
.toBe(null);
expect(room.getUnfilteredTimelineSet()
.compareEventOrdering("xxx", events[0].getId()))
.toBe(null);
expect(room.getUnfilteredTimelineSet()
.compareEventOrdering(events[0].getId(), events[0].getId()))
.compareEventOrdering(events[0].getId()!, events[0].getId()))
.toBe(0);
});
});
@@ -1228,7 +1228,7 @@ describe("Room", function() {
it("should store the receipt so it can be obtained via getReceiptsForEvent", function() {
const ts = 13787898424;
room.addReceipt(mkReceipt(roomId, [
mkRecord(eventToAck.getId(), "m.read", userB, ts),
mkRecord(eventToAck.getId()!, "m.read", userB, ts),
]));
expect(room.getReceiptsForEvent(eventToAck)).toEqual([{
type: "m.read",
@@ -1247,7 +1247,7 @@ describe("Room", function() {
const ts = 13787898424;
const receiptEvent = mkReceipt(roomId, [
mkRecord(eventToAck.getId(), "m.read", userB, ts),
mkRecord(eventToAck.getId()!, "m.read", userB, ts),
]);
room.addReceipt(receiptEvent);
@@ -1261,11 +1261,11 @@ describe("Room", function() {
});
const ts = 13787898424;
room.addReceipt(mkReceipt(roomId, [
mkRecord(eventToAck.getId(), "m.read", userB, ts),
mkRecord(eventToAck.getId()!, "m.read", userB, ts),
]));
const ts2 = 13787899999;
room.addReceipt(mkReceipt(roomId, [
mkRecord(nextEventToAck.getId(), "m.read", userB, ts2),
mkRecord(nextEventToAck.getId()!, "m.read", userB, ts2),
]));
expect(room.getReceiptsForEvent(eventToAck)).toEqual([]);
expect(room.getReceiptsForEvent(nextEventToAck)).toEqual([{
@@ -1280,9 +1280,9 @@ describe("Room", function() {
it("should persist multiple receipts for a single event ID", function() {
const ts = 13787898424;
room.addReceipt(mkReceipt(roomId, [
mkRecord(eventToAck.getId(), "m.read", userB, ts),
mkRecord(eventToAck.getId(), "m.read", userC, ts),
mkRecord(eventToAck.getId(), "m.read", userD, ts),
mkRecord(eventToAck.getId()!, "m.read", userB, ts),
mkRecord(eventToAck.getId()!, "m.read", userC, ts),
mkRecord(eventToAck.getId()!, "m.read", userD, ts),
]));
expect(room.getUsersReadUpTo(eventToAck)).toEqual(
[userB, userC, userD],
@@ -1300,9 +1300,9 @@ describe("Room", function() {
});
const ts = 13787898424;
room.addReceipt(mkReceipt(roomId, [
mkRecord(eventToAck.getId(), "m.read", userB, ts),
mkRecord(eventTwo.getId(), "m.read", userC, ts),
mkRecord(eventThree.getId(), "m.read", userD, ts),
mkRecord(eventToAck.getId()!, "m.read", userB, ts),
mkRecord(eventTwo.getId()!, "m.read", userC, ts),
mkRecord(eventThree.getId()!, "m.read", userD, ts),
]));
expect(room.getUsersReadUpTo(eventToAck)).toEqual([userB]);
expect(room.getUsersReadUpTo(eventTwo)).toEqual([userC]);
@@ -1311,9 +1311,9 @@ describe("Room", function() {
it("should persist multiple receipts for a single user ID", function() {
room.addReceipt(mkReceipt(roomId, [
mkRecord(eventToAck.getId(), "m.delivered", userB, 13787898424),
mkRecord(eventToAck.getId(), "m.read", userB, 22222222),
mkRecord(eventToAck.getId(), "m.seen", userB, 33333333),
mkRecord(eventToAck.getId()!, "m.delivered", userB, 13787898424),
mkRecord(eventToAck.getId()!, "m.read", userB, 22222222),
mkRecord(eventToAck.getId()!, "m.seen", userB, 33333333),
]));
expect(room.getReceiptsForEvent(eventToAck)).toEqual([
{
@@ -1361,19 +1361,19 @@ describe("Room", function() {
// check it initialises correctly
room.addReceipt(mkReceipt(roomId, [
mkRecord(events[0].getId(), "m.read", userB, ts),
mkRecord(events[0].getId()!, "m.read", userB, ts),
]));
expect(room.getEventReadUpTo(userB)).toEqual(events[0].getId());
// 2>0, so it should move forward
room.addReceipt(mkReceipt(roomId, [
mkRecord(events[2].getId(), "m.read", userB, ts),
mkRecord(events[2].getId()!, "m.read", userB, ts),
]));
expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId());
// 1<2, so it should stay put
room.addReceipt(mkReceipt(roomId, [
mkRecord(events[1].getId(), "m.read", userB, ts),
mkRecord(events[1].getId()!, "m.read", userB, ts),
]));
expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId());
});
@@ -1399,13 +1399,13 @@ describe("Room", function() {
// check it initialises correctly
room.addReceipt(mkReceipt(roomId, [
mkRecord(events[0].getId(), "m.read", userB, ts),
mkRecord(events[0].getId()!, "m.read", userB, ts),
]));
expect(room.getEventReadUpTo(userB)).toEqual(events[0].getId());
// 2>0, so it should move forward
room.addReceipt(mkReceipt(roomId, [
mkRecord(events[2].getId(), "m.read", userB, ts),
mkRecord(events[2].getId()!, "m.read", userB, ts),
]), true);
expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId());
expect(room.getReceiptsForEvent(events[2])).toEqual([
@@ -1414,7 +1414,7 @@ describe("Room", function() {
// 1<2, so it should stay put
room.addReceipt(mkReceipt(roomId, [
mkRecord(events[1].getId(), "m.read", userB, ts),
mkRecord(events[1].getId()!, "m.read", userB, ts),
]));
expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId());
expect(room.getEventReadUpTo(userB, true)).toEqual(events[1].getId());
@@ -1428,7 +1428,7 @@ describe("Room", function() {
it("should return user IDs read up to the given event", function() {
const ts = 13787898424;
room.addReceipt(mkReceipt(roomId, [
mkRecord(eventToAck.getId(), "m.read", userB, ts),
mkRecord(eventToAck.getId()!, "m.read", userB, ts),
]));
expect(room.getUsersReadUpTo(eventToAck)).toEqual([userB]);
});
@@ -1438,9 +1438,9 @@ describe("Room", function() {
it("should acknowledge if an event has been read", function() {
const ts = 13787898424;
room.addReceipt(mkReceipt(roomId, [
mkRecord(eventToAck.getId(), "m.read", userB, ts),
mkRecord(eventToAck.getId()!, "m.read", userB, ts),
]));
expect(room.hasUserReadEvent(userB, eventToAck.getId())).toEqual(true);
expect(room.hasUserReadEvent(userB, eventToAck.getId()!)).toEqual(true);
});
it("return false for an unknown event", function() {
expect(room.hasUserReadEvent(userB, "unknown_event")).toEqual(false);
@@ -1556,7 +1556,7 @@ describe("Room", function() {
user: userA,
type: EventType.RoomRedaction,
content: {},
redacts: eventA.getId(),
redacts: eventA.getId()!,
event: true,
});
redactA.status = EventStatus.SENDING;
@@ -1609,7 +1609,7 @@ describe("Room", function() {
});
it("should remove cancelled events from the timeline", function() {
const room = new Room(roomId, null, userA);
const room = new Room(roomId, null!, userA);
const eventA = utils.mkMessage({
room: roomId, user: userA, event: true,
});
@@ -1643,7 +1643,7 @@ describe("Room", function() {
});
describe("loadMembersIfNeeded", function() {
function createClientMock(serverResponse, storageResponse = null) {
function createClientMock(serverResponse, storageResponse: MatrixEvent[] | Error | null = null) {
return {
getEventMapper: function() {
// events should already be MatrixEvents
@@ -1664,7 +1664,7 @@ describe("Room", function() {
}),
store: {
storageResponse,
storedMembers: null,
storedMembers: [] as IStateEventWithRoomId[] | null,
getOutOfBandMembers: function() {
if (this.storageResponse instanceof Error) {
return Promise.reject(this.storageResponse);
@@ -1693,11 +1693,11 @@ describe("Room", function() {
it("should load members from server on first call", async function() {
const client = createClientMock([memberEvent]);
const room = new Room(roomId, client as any, null, { lazyLoadMembers: true });
const room = new Room(roomId, client as any, null!, { lazyLoadMembers: true });
await room.loadMembersIfNeeded();
const memberA = room.getMember("@user_a:bar");
const memberA = room.getMember("@user_a:bar")!;
expect(memberA.name).toEqual("User A");
const storedMembers = client.store.storedMembers;
const storedMembers = client.store.storedMembers!;
expect(storedMembers.length).toEqual(1);
expect(storedMembers[0].event_id).toEqual(memberEvent.getId());
});
@@ -1711,17 +1711,17 @@ describe("Room", function() {
name: "Ms A",
});
const client = createClientMock([memberEvent2], [memberEvent]);
const room = new Room(roomId, client as any, null, { lazyLoadMembers: true });
const room = new Room(roomId, client as any, null!, { lazyLoadMembers: true });
await room.loadMembersIfNeeded();
const memberA = room.getMember("@user_a:bar");
const memberA = room.getMember("@user_a:bar")!;
expect(memberA.name).toEqual("User A");
});
it("should allow retry on error", async function() {
const client = createClientMock(new Error("server says no"));
const room = new Room(roomId, client as any, null, { lazyLoadMembers: true });
const room = new Room(roomId, client as any, null!, { lazyLoadMembers: true });
let hasThrown = false;
try {
await room.loadMembersIfNeeded();
@@ -1740,27 +1740,68 @@ describe("Room", function() {
describe("getMyMembership", function() {
it("should return synced membership if membership isn't available yet",
function() {
const room = new Room(roomId, null, userA);
const room = new Room(roomId, null!, userA);
room.updateMyMembership(JoinRule.Invite);
expect(room.getMyMembership()).toEqual(JoinRule.Invite);
});
it("should emit a Room.myMembership event on a change",
function() {
const room = new Room(roomId, null, userA);
const events = [];
room.on(RoomEvent.MyMembership, (_room, membership, oldMembership) => {
events.push({ membership, oldMembership });
});
room.updateMyMembership(JoinRule.Invite);
expect(room.getMyMembership()).toEqual(JoinRule.Invite);
expect(events[0]).toEqual({ membership: "invite", oldMembership: undefined });
events.splice(0); //clear
room.updateMyMembership(JoinRule.Invite);
expect(events.length).toEqual(0);
room.updateMyMembership("join");
expect(room.getMyMembership()).toEqual("join");
expect(events[0]).toEqual({ membership: "join", oldMembership: "invite" });
it("should emit a Room.myMembership event on a change", function() {
const room = new Room(roomId, null!, userA);
const events: {
membership: string;
oldMembership?: string;
}[] = [];
room.on(RoomEvent.MyMembership, (_room, membership, oldMembership) => {
events.push({ membership, oldMembership });
});
room.updateMyMembership(JoinRule.Invite);
expect(room.getMyMembership()).toEqual(JoinRule.Invite);
expect(events[0]).toEqual({ membership: "invite", oldMembership: undefined });
events.splice(0); //clear
room.updateMyMembership(JoinRule.Invite);
expect(events.length).toEqual(0);
room.updateMyMembership("join");
expect(room.getMyMembership()).toEqual("join");
expect(events[0]).toEqual({ membership: "join", oldMembership: "invite" });
});
});
describe("getDMInviter", () => {
it("should delegate to RoomMember::getDMInviter if available", () => {
const room = new Room(roomId, null!, userA);
room.currentState.markOutOfBandMembersStarted();
room.currentState.setOutOfBandMembers([
new MatrixEvent({
type: EventType.RoomMember,
state_key: userA,
sender: userB,
content: {
membership: "invite",
is_direct: true,
},
}),
]);
expect(room.getDMInviter()).toBe(userB);
});
it("should fall back to summary heroes and return the first one", () => {
const room = new Room(roomId, null!, userA);
room.updateMyMembership("invite");
room.setSummary({
"m.heroes": [userA, userC],
"m.joined_member_count": 1,
"m.invited_member_count": 1,
});
expect(room.getDMInviter()).toBe(userC);
});
it("should return undefined if we're not joined or invited to the room", () => {
const room = new Room(roomId, null!, userA);
expect(room.getDMInviter()).toBeUndefined();
room.updateMyMembership("leave");
expect(room.getDMInviter()).toBeUndefined();
});
});
describe("guessDMUserId", function() {
@@ -1789,6 +1830,36 @@ describe("Room", function() {
});
});
describe("getAvatarFallbackMember", () => {
it("should should return undefined if the room isn't a 1:1", () => {
const room = new Room(roomId, null!, userA);
room.currentState.setJoinedMemberCount(2);
room.currentState.setInvitedMemberCount(1);
expect(room.getAvatarFallbackMember()).toBeUndefined();
});
it("should use summary heroes member if 1:1", () => {
const room = new Room(roomId, null!, userA);
room.currentState.markOutOfBandMembersStarted();
room.currentState.setOutOfBandMembers([
new MatrixEvent({
type: EventType.RoomMember,
state_key: userD,
sender: userD,
content: {
membership: "join",
},
}),
]);
room.setSummary({
"m.heroes": [userA, userD],
"m.joined_member_count": 1,
"m.invited_member_count": 1,
});
expect(room.getAvatarFallbackMember()?.userId).toBe(userD);
});
});
describe("maySendMessage", function() {
it("should return false if synced membership not join", function() {
const room = new Room(roomId, { isRoomEncrypted: () => false } as any, userA);
@@ -2118,7 +2189,7 @@ describe("Room", function() {
},
});
expect(() => room.createThread(rootEvent.getId(), rootEvent, [])).not.toThrow();
expect(() => room.createThread(rootEvent.getId()!, rootEvent, [])).not.toThrow();
});
it("creating thread from edited event should not conflate old versions of the event", () => {
@@ -2339,7 +2410,7 @@ describe("Room", function() {
const threadReaction2 = mkReaction(threadRoot);
const threadReaction2Redaction = mkRedaction(threadReaction2);
const roots = new Set([threadRoot.getId()]);
const roots = new Set([threadRoot.getId()!]);
const events = [
randomMessage,
threadRoot,
@@ -2377,7 +2448,7 @@ describe("Room", function() {
const threadReaction2 = mkReaction(threadResponse1);
const threadReaction2Redaction = mkRedaction(threadReaction2);
const roots = new Set([threadRoot.getId()]);
const roots = new Set([threadRoot.getId()!]);
const events = [threadRoot, threadResponse1, threadReaction1, threadReaction2, threadReaction2Redaction];
expect(room.eventShouldLiveIn(threadReaction1, events, roots).shouldLiveInRoom).toBeFalsy();
@@ -2399,7 +2470,7 @@ describe("Room", function() {
const reaction2 = mkReaction(reply1);
const reaction2Redaction = mkRedaction(reply1);
const roots = new Set([threadRoot.getId()]);
const roots = new Set([threadRoot.getId()!]);
const events = [
threadRoot,
threadResponse1,
@@ -2425,7 +2496,7 @@ describe("Room", function() {
const reply1 = mkReply(threadRoot);
const reply2 = mkReply(reply1);
const roots = new Set([threadRoot.getId()]);
const roots = new Set([threadRoot.getId()!]);
const events = [
threadRoot,
threadResponse1,
@@ -2459,7 +2530,7 @@ describe("Room", function() {
expect(thread.rootEvent).toBe(threadRoot);
const rootRelations = thread.timelineSet.relations.getChildEventsForEvent(
threadRoot.getId(),
threadRoot.getId()!,
RelationType.Annotation,
EventType.Reaction,
)!.getSortedAnnotationsByKey();
@@ -2469,7 +2540,7 @@ describe("Room", function() {
expect(rootRelations![0][1].has(rootReaction)).toBeTruthy();
const responseRelations = thread.timelineSet.relations.getChildEventsForEvent(
threadResponse.getId(),
threadResponse.getId()!,
RelationType.Annotation,
EventType.Reaction,
)!.getSortedAnnotationsByKey();
@@ -2744,7 +2815,7 @@ describe("Room", function() {
expect(pendingEvents[1].isBeingDecrypted()).toBeFalsy();
expect(pendingEvents[1].isEncrypted()).toBeTruthy();
for (const ev of pendingEvents) {
expect(room.getPendingEvent(ev.getId())).toBe(ev);
expect(room.getPendingEvent(ev.getId()!)).toBe(ev);
}
});
});

View File

@@ -160,10 +160,10 @@ describe("MatrixScheduler", function() {
const eventD = utils.mkMessage({ user: "@b:bar", room: roomId, event: true });
const buckets = {};
buckets[eventA.getId()] = "queue_A";
buckets[eventD.getId()] = "queue_A";
buckets[eventB.getId()] = "queue_B";
buckets[eventC.getId()] = "queue_B";
buckets[eventA.getId()!] = "queue_A";
buckets[eventD.getId()!] = "queue_A";
buckets[eventB.getId()!] = "queue_B";
buckets[eventC.getId()!] = "queue_B";
retryFn = function() {
return 0;