1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-07-31 15:24:23 +03:00

Enable noImplicitAny (#2895)

* Stash noImplicitAny work

* Enable noImplicitAny

* Update olm

* Fun

* Fix msgid stuff

* Fix tests

* Attempt to fix Browserify
This commit is contained in:
Michael Telatynski
2022-12-06 18:21:44 +00:00
committed by GitHub
parent 6f81371e61
commit 8d018f9c2d
83 changed files with 1615 additions and 1428 deletions

View File

@ -30,7 +30,7 @@ const ROOM_ID = "!room:id";
*
* @return {object} sync response
*/
function getSyncResponse(roomMembers) {
function getSyncResponse(roomMembers: string[]) {
const stateEvents = [
testUtils.mkEvent({
type: 'm.room.encryption',
@ -43,12 +43,10 @@ function getSyncResponse(roomMembers) {
Array.prototype.push.apply(
stateEvents,
roomMembers.map(
(m) => testUtils.mkMembership({
mship: 'join',
sender: m,
}),
),
roomMembers.map((m) => testUtils.mkMembership({
mship: 'join',
sender: m,
})),
);
const syncResponse = {
@ -73,8 +71,8 @@ describe("DeviceList management:", function() {
return;
}
let sessionStoreBackend;
let aliceTestClient;
let aliceTestClient: TestClient;
let sessionStoreBackend: Storage;
async function createTestClient() {
const testClient = new TestClient(
@ -97,7 +95,10 @@ describe("DeviceList management:", function() {
});
it("Alice shouldn't do a second /query for non-e2e-capable devices", function() {
aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } });
aliceTestClient.expectKeyQuery({
device_keys: { '@alice:localhost': {} },
failures: {},
});
return aliceTestClient.start().then(function() {
const syncResponse = getSyncResponse(['@bob:xyz']);
aliceTestClient.httpBackend.when('GET', '/sync').respond(200, syncResponse);
@ -138,7 +139,10 @@ describe("DeviceList management:", function() {
it.skip("We should not get confused by out-of-order device query responses", () => {
// https://github.com/vector-im/element-web/issues/3126
aliceTestClient.expectKeyQuery({ device_keys: { '@alice:localhost': {} } });
aliceTestClient.expectKeyQuery({
device_keys: { '@alice:localhost': {} },
failures: {},
});
return aliceTestClient.start().then(() => {
aliceTestClient.httpBackend.when('GET', '/sync').respond(
200, getSyncResponse(['@bob:xyz', '@chris:abc']));
@ -164,11 +168,12 @@ describe("DeviceList management:", function() {
aliceTestClient.httpBackend.flush('/keys/query', 1).then(
() => aliceTestClient.httpBackend.flush('/send/', 1),
),
aliceTestClient.client.crypto.deviceList.saveIfDirty(),
aliceTestClient.client.crypto!.deviceList.saveIfDirty(),
]);
}).then(() => {
aliceTestClient.client.cryptoStore.getEndToEndDeviceData(null, (data) => {
expect(data.syncToken).toEqual(1);
// @ts-ignore accessing a protected field
aliceTestClient.client.cryptoStore!.getEndToEndDeviceData(null, (data) => {
expect(data!.syncToken).toEqual(1);
});
// invalidate bob's and chris's device lists in separate syncs
@ -201,15 +206,16 @@ describe("DeviceList management:", function() {
return aliceTestClient.httpBackend.flush('/keys/query', 1);
}).then((flushed) => {
expect(flushed).toEqual(0);
return aliceTestClient.client.crypto.deviceList.saveIfDirty();
return aliceTestClient.client.crypto!.deviceList.saveIfDirty();
}).then(() => {
aliceTestClient.client.cryptoStore.getEndToEndDeviceData(null, (data) => {
const bobStat = data.trackingStatus['@bob:xyz'];
// @ts-ignore accessing a protected field
aliceTestClient.client.cryptoStore!.getEndToEndDeviceData(null, (data) => {
const bobStat = data!.trackingStatus['@bob:xyz'];
if (bobStat != 1 && bobStat != 2) {
throw new Error('Unexpected status for bob: wanted 1 or 2, got ' +
bobStat);
}
const chrisStat = data.trackingStatus['@chris:abc'];
const chrisStat = data!.trackingStatus['@chris:abc'];
if (chrisStat != 1 && chrisStat != 2) {
throw new Error(
'Unexpected status for chris: wanted 1 or 2, got ' + chrisStat,
@ -234,12 +240,13 @@ describe("DeviceList management:", function() {
// wait for the client to stop processing the response
return aliceTestClient.client.downloadKeys(['@bob:xyz']);
}).then(() => {
return aliceTestClient.client.crypto.deviceList.saveIfDirty();
return aliceTestClient.client.crypto!.deviceList.saveIfDirty();
}).then(() => {
aliceTestClient.client.cryptoStore.getEndToEndDeviceData(null, (data) => {
const bobStat = data.trackingStatus['@bob:xyz'];
// @ts-ignore accessing a protected field
aliceTestClient.client.cryptoStore!.getEndToEndDeviceData(null, (data) => {
const bobStat = data!.trackingStatus['@bob:xyz'];
expect(bobStat).toEqual(3);
const chrisStat = data.trackingStatus['@chris:abc'];
const chrisStat = data!.trackingStatus['@chris:abc'];
if (chrisStat != 1 && chrisStat != 2) {
throw new Error(
'Unexpected status for chris: wanted 1 or 2, got ' + bobStat,
@ -255,15 +262,16 @@ describe("DeviceList management:", function() {
// wait for the client to stop processing the response
return aliceTestClient.client.downloadKeys(['@chris:abc']);
}).then(() => {
return aliceTestClient.client.crypto.deviceList.saveIfDirty();
return aliceTestClient.client.crypto!.deviceList.saveIfDirty();
}).then(() => {
aliceTestClient.client.cryptoStore.getEndToEndDeviceData(null, (data) => {
const bobStat = data.trackingStatus['@bob:xyz'];
const chrisStat = data.trackingStatus['@bob:xyz'];
// @ts-ignore accessing a protected field
aliceTestClient.client.cryptoStore!.getEndToEndDeviceData(null, (data) => {
const bobStat = data!.trackingStatus['@bob:xyz'];
const chrisStat = data!.trackingStatus['@bob:xyz'];
expect(bobStat).toEqual(3);
expect(chrisStat).toEqual(3);
expect(data.syncToken).toEqual(3);
expect(data!.syncToken).toEqual(3);
});
});
});
@ -285,10 +293,11 @@ describe("DeviceList management:", function() {
},
);
await aliceTestClient.httpBackend.flush('/keys/query', 1);
await aliceTestClient.client.crypto.deviceList.saveIfDirty();
await aliceTestClient.client.crypto!.deviceList.saveIfDirty();
aliceTestClient.client.cryptoStore.getEndToEndDeviceData(null, (data) => {
const bobStat = data.trackingStatus['@bob:xyz'];
// @ts-ignore accessing a protected field
aliceTestClient.client.cryptoStore!.getEndToEndDeviceData(null, (data) => {
const bobStat = data!.trackingStatus['@bob:xyz'];
// Alice should be tracking bob's device list
expect(bobStat).toBeGreaterThan(
@ -322,10 +331,11 @@ describe("DeviceList management:", function() {
);
await aliceTestClient.flushSync();
await aliceTestClient.client.crypto.deviceList.saveIfDirty();
await aliceTestClient.client.crypto!.deviceList.saveIfDirty();
aliceTestClient.client.cryptoStore.getEndToEndDeviceData(null, (data) => {
const bobStat = data.trackingStatus['@bob:xyz'];
// @ts-ignore accessing a protected field
aliceTestClient.client.cryptoStore!.getEndToEndDeviceData(null, (data) => {
const bobStat = data!.trackingStatus['@bob:xyz'];
// Alice should have marked bob's device list as untracked
expect(bobStat).toEqual(
@ -359,15 +369,14 @@ describe("DeviceList management:", function() {
);
await aliceTestClient.flushSync();
await aliceTestClient.client.crypto.deviceList.saveIfDirty();
await aliceTestClient.client.crypto!.deviceList.saveIfDirty();
aliceTestClient.client.cryptoStore.getEndToEndDeviceData(null, (data) => {
const bobStat = data.trackingStatus['@bob:xyz'];
// @ts-ignore accessing a protected field
aliceTestClient.client.cryptoStore!.getEndToEndDeviceData(null, (data) => {
const bobStat = data!.trackingStatus['@bob:xyz'];
// Alice should have marked bob's device list as untracked
expect(bobStat).toEqual(
0,
);
expect(bobStat).toEqual(0);
});
});
@ -388,9 +397,7 @@ describe("DeviceList management:", function() {
const bobStat = data!.trackingStatus['@bob:xyz'];
// Alice should have marked bob's device list as untracked
expect(bobStat).toEqual(
0,
);
expect(bobStat).toEqual(0);
});
} finally {
anotherTestClient.stop();

View File

@ -28,12 +28,14 @@ limitations under the License.
// load olm before the sdk if possible
import '../olm-loader';
import type { Session } from "@matrix-org/olm";
import { logger } from '../../src/logger';
import * as testUtils from "../test-utils/test-utils";
import { TestClient } from "../TestClient";
import { CRYPTO_ENABLED, IUploadKeysRequest } from "../../src/client";
import { CRYPTO_ENABLED, IClaimKeysRequest, IQueryKeysRequest, IUploadKeysRequest } from "../../src/client";
import { ClientEvent, IContent, ISendEventResponse, MatrixClient, MatrixEvent } from "../../src/matrix";
import { DeviceInfo } from '../../src/crypto/deviceinfo';
import { IDeviceKeys, IOneTimeKey } from "../../src/crypto/dehydration";
let aliTestClient: TestClient;
const roomId = "!room:localhost";
@ -47,11 +49,7 @@ const bobAccessToken = "fewgfkuesa";
let aliMessages: IContent[];
let bobMessages: IContent[];
// IMessage isn't exported by src/crypto/algorithms/olm.ts
interface OlmPayload {
type: number;
body: string;
}
type OlmPayload = ReturnType<Session["encrypt"]>;
async function bobUploadsDeviceKeys(): Promise<void> {
bobTestClient.expectDeviceKeyUpload();
@ -71,12 +69,12 @@ function expectQueryKeys(querier: TestClient, uploader: TestClient): Promise<num
// can't query keys before bob has uploaded them
expect(uploader.deviceKeys).toBeTruthy();
const uploaderKeys = {};
uploaderKeys[uploader.deviceId!] = uploader.deviceKeys;
const uploaderKeys: Record<string, IDeviceKeys> = {};
uploaderKeys[uploader.deviceId!] = uploader.deviceKeys!;
querier.httpBackend.when("POST", "/keys/query")
.respond(200, function(_path, content: IUploadKeysRequest) {
.respond(200, function(_path, content: IQueryKeysRequest) {
expect(content.device_keys![uploader.userId!]).toEqual([]);
const result = {};
const result: Record<string, Record<string, IDeviceKeys>> = {};
result[uploader.userId!] = uploaderKeys;
return { device_keys: result };
});
@ -94,7 +92,7 @@ async function expectAliClaimKeys(): Promise<void> {
const keys = await bobTestClient.awaitOneTimeKeyUpload();
aliTestClient.httpBackend.when(
"POST", "/keys/claim",
).respond(200, function(_path, content: IUploadKeysRequest) {
).respond(200, function(_path, content: IClaimKeysRequest) {
const claimType = content.one_time_keys![bobUserId][bobDeviceId];
expect(claimType).toEqual("signed_curve25519");
let keyId = '';
@ -105,7 +103,7 @@ async function expectAliClaimKeys(): Promise<void> {
}
}
}
const result = {};
const result: Record<string, Record<string, Record<string, IOneTimeKey>>> = {};
result[bobUserId] = {};
result[bobUserId][bobDeviceId] = {};
result[bobUserId][bobDeviceId][keyId] = keys[keyId];
@ -276,22 +274,21 @@ async function recvMessage(
next_batch: "x",
rooms: {
join: {
[roomId]: {
timeline: {
events: [
testUtils.mkEvent({
type: "m.room.encrypted",
room: roomId,
content: message,
sender: sender,
}),
],
},
},
},
},
};
syncData.rooms.join[roomId] = {
timeline: {
events: [
testUtils.mkEvent({
type: "m.room.encrypted",
room: roomId,
content: message,
sender: sender,
}),
],
},
};
httpBackend.when("GET", "/sync").respond(200, syncData);
const eventPromise = new Promise<MatrixEvent>((resolve) => {
@ -335,24 +332,25 @@ function firstSync(testClient: TestClient): Promise<void> {
const syncData = {
next_batch: "x",
rooms: {
join: { },
},
};
syncData.rooms.join[roomId] = {
state: {
events: [
testUtils.mkMembership({
mship: "join",
user: aliUserId,
}),
testUtils.mkMembership({
mship: "join",
user: bobUserId,
}),
],
},
timeline: {
events: [],
join: {
[roomId]: {
state: {
events: [
testUtils.mkMembership({
mship: "join",
user: aliUserId,
}),
testUtils.mkMembership({
mship: "join",
user: bobUserId,
}),
],
},
timeline: {
events: [],
},
},
},
},
};
@ -424,7 +422,7 @@ describe("MatrixClient crypto", () => {
},
};
const bobKeys = {};
const bobKeys: Record<string, typeof bobDeviceKeys> = {};
bobKeys[bobDeviceId] = bobDeviceKeys;
aliTestClient.httpBackend.when(
"POST", "/keys/query",
@ -460,7 +458,7 @@ describe("MatrixClient crypto", () => {
},
};
const bobKeys = {};
const bobKeys: Record<string, typeof bobDeviceKeys> = {};
bobKeys[bobDeviceId] = bobDeviceKeys;
aliTestClient.httpBackend.when(
"POST", "/keys/query",
@ -515,22 +513,21 @@ describe("MatrixClient crypto", () => {
next_batch: "x",
rooms: {
join: {
[roomId]: {
timeline: {
events: [
testUtils.mkEvent({
type: "m.room.encrypted",
room: roomId,
content: message,
sender: "@bogus:sender",
}),
],
},
},
},
},
};
syncData.rooms.join[roomId] = {
timeline: {
events: [
testUtils.mkEvent({
type: "m.room.encrypted",
room: roomId,
content: message,
sender: "@bogus:sender",
}),
],
},
};
bobTestClient.httpBackend.when("GET", "/sync").respond(200, syncData);
const eventPromise = new Promise<MatrixEvent>((resolve) => {
@ -607,20 +604,21 @@ describe("MatrixClient crypto", () => {
const syncData = {
next_batch: '2',
rooms: {
join: {},
},
};
syncData.rooms.join[roomId] = {
state: {
events: [
testUtils.mkEvent({
type: 'm.room.encryption',
skey: '',
content: {
algorithm: 'm.olm.v1.curve25519-aes-sha2',
join: {
[roomId]: {
state: {
events: [
testUtils.mkEvent({
type: 'm.room.encryption',
skey: '',
content: {
algorithm: 'm.olm.v1.curve25519-aes-sha2',
},
}),
],
},
}),
],
},
},
},
};

View File

@ -536,20 +536,20 @@ describe("MatrixClient event timelines", function() {
};
});
let tl0;
let tl3;
let tl0: EventTimeline;
let tl3: EventTimeline;
return Promise.all([
client.getEventTimeline(timelineSet, EVENTS[0].event_id!,
).then(function(tl) {
expect(tl!.getEvents().length).toEqual(1);
tl0 = tl;
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;
tl3 = tl!;
return client.getEventTimeline(timelineSet, EVENTS[1].event_id!);
}).then(function(tl) {
// we expect it to get merged in with event 2
@ -953,11 +953,11 @@ describe("MatrixClient event timelines", function() {
};
});
let tl;
let tl: EventTimeline;
return Promise.all([
client.getEventTimeline(timelineSet, EVENTS[0].event_id!,
).then(function(tl0) {
tl = tl0;
tl = tl0!;
return client.paginateEventTimeline(tl, { backwards: true });
}).then(function(success) {
expect(success).toBeTruthy();
@ -1043,11 +1043,11 @@ describe("MatrixClient event timelines", function() {
};
});
let tl;
let tl: EventTimeline;
return Promise.all([
client.getEventTimeline(timelineSet, EVENTS[0].event_id!,
).then(function(tl0) {
tl = tl0;
tl = tl0!;
return client.paginateEventTimeline(
tl, { backwards: false, limit: 20 });
}).then(function(success) {
@ -1569,16 +1569,17 @@ describe("MatrixClient event timelines", function() {
const syncData = {
next_batch: "batch1",
rooms: {
join: {},
},
};
syncData.rooms.join[roomId] = {
timeline: {
events: [
event,
redaction,
],
limited: false,
join: {
[roomId]: {
timeline: {
events: [
event,
redaction,
],
limited: false,
},
},
},
},
};
httpBackend.when("GET", "/sync").respond(200, syncData);
@ -1595,18 +1596,19 @@ describe("MatrixClient event timelines", function() {
const sync2 = {
next_batch: "batch2",
rooms: {
join: {},
},
};
sync2.rooms.join[roomId] = {
timeline: {
events: [
utils.mkMessage({
user: otherUserId, msg: "world",
}),
],
limited: true,
prev_batch: "newerTok",
join: {
[roomId]: {
timeline: {
events: [
utils.mkMessage({
user: otherUserId, msg: "world",
}),
],
limited: true,
prev_batch: "newerTok",
},
},
},
},
};
httpBackend.when("GET", "/sync").respond(200, sync2);

View File

@ -618,13 +618,13 @@ describe("MatrixClient", function() {
});
describe("partitionThreadedEvents", function() {
let room;
let room: Room;
beforeEach(() => {
room = new Room("!STrMRsukXHtqQdSeHa:matrix.org", client!, userId);
});
it("returns empty arrays when given an empty arrays", function() {
const events = [];
const events: MatrixEvent[] = [];
const [timeline, threaded] = room.partitionThreadedEvents(events);
expect(timeline).toEqual([]);
expect(threaded).toEqual([]);
@ -1645,7 +1645,7 @@ const buildEventCreate = () => new MatrixEvent({
"user_id": "@andybalaam-test1:matrix.org",
});
function assertObjectContains(obj: object, expected: any): void {
function assertObjectContains(obj: Record<string, any>, expected: any): void {
for (const k in expected) {
if (expected.hasOwnProperty(k)) {
expect(obj[k]).toEqual(expected[k]);

View File

@ -1,7 +1,7 @@
import HttpBackend from "matrix-mock-request";
import * as utils from "../test-utils/test-utils";
import { MatrixClient } from "../../src/matrix";
import { ClientEvent, MatrixClient } from "../../src/matrix";
import { MatrixScheduler } from "../../src/scheduler";
import { MemoryStore } from "../../src/store/memory";
import { MatrixError } from "../../src/http-api";
@ -65,7 +65,7 @@ describe("MatrixClient opts", function() {
});
describe("without opts.store", function() {
let client;
let client: MatrixClient;
beforeEach(function() {
client = new MatrixClient({
fetchFn: httpBackend.fetchFn as typeof global.fetch,
@ -98,7 +98,7 @@ describe("MatrixClient opts", function() {
"m.room.message", "m.room.name", "m.room.member", "m.room.member",
"m.room.create",
];
client.on("event", function(event) {
client.on(ClientEvent.Event, function(event) {
expect(expectedEventTypes.indexOf(event.getType())).not.toEqual(
-1,
);
@ -125,7 +125,7 @@ describe("MatrixClient opts", function() {
});
describe("without opts.scheduler", function() {
let client;
let client: MatrixClient;
beforeEach(function() {
client = new MatrixClient({
fetchFn: httpBackend.fetchFn as typeof global.fetch,

View File

@ -18,7 +18,16 @@ import HttpBackend from "matrix-mock-request";
import * as utils from "../test-utils/test-utils";
import { EventStatus } from "../../src/models/event";
import { MatrixError, ClientEvent, IEvent, MatrixClient, RoomEvent } from "../../src";
import {
MatrixError,
ClientEvent,
IEvent,
MatrixClient,
RoomEvent,
ISyncResponse,
IMinimalEvent,
IRoomEvent, Room,
} from "../../src";
import { TestClient } from "../TestClient";
describe("MatrixClient room timelines", function() {
@ -39,7 +48,7 @@ describe("MatrixClient room timelines", function() {
name: "Old room name",
},
});
let NEXT_SYNC_DATA;
let NEXT_SYNC_DATA: Partial<ISyncResponse>;
const SYNC_DATA = {
next_batch: "s_5_3",
rooms: {
@ -88,7 +97,7 @@ describe("MatrixClient room timelines", function() {
},
},
leave: {},
},
} as unknown as ISyncResponse["rooms"],
};
events.forEach(function(e) {
if (e.room_id !== roomId) {
@ -96,11 +105,11 @@ describe("MatrixClient room timelines", function() {
}
if (e.state_key) {
// push the current
NEXT_SYNC_DATA.rooms.join[roomId].timeline.events.push(e);
NEXT_SYNC_DATA.rooms!.join[roomId].timeline.events.push(e as unknown as IRoomEvent);
} else if (["m.typing", "m.receipt"].indexOf(e.type!) !== -1) {
NEXT_SYNC_DATA.rooms.join[roomId].ephemeral.events.push(e);
NEXT_SYNC_DATA.rooms!.join[roomId].ephemeral.events.push(e as unknown as IMinimalEvent);
} else {
NEXT_SYNC_DATA.rooms.join[roomId].timeline.events.push(e);
NEXT_SYNC_DATA.rooms!.join[roomId].timeline.events.push(e as unknown as IRoomEvent);
}
});
}
@ -237,7 +246,7 @@ describe("MatrixClient room timelines", function() {
});
describe("paginated events", function() {
let sbEvents;
let sbEvents: Partial<IEvent>[];
const sbEndTok = "pagin_end";
beforeEach(function() {
@ -559,7 +568,7 @@ describe("MatrixClient room timelines", function() {
utils.mkMessage({ user: userId, room: roomId }),
];
setNextSyncData(eventData);
NEXT_SYNC_DATA.rooms.join[roomId].timeline.limited = true;
NEXT_SYNC_DATA.rooms!.join[roomId].timeline.limited = true;
return Promise.all([
httpBackend!.flush("/versions", 1),
@ -593,7 +602,7 @@ describe("MatrixClient room timelines", function() {
utils.mkMessage({ user: userId, room: roomId }),
];
setNextSyncData(eventData);
NEXT_SYNC_DATA.rooms.join[roomId].timeline.limited = true;
NEXT_SYNC_DATA.rooms!.join[roomId].timeline.limited = true;
return Promise.all([
httpBackend!.flush("/sync", 1),
@ -638,7 +647,7 @@ describe("MatrixClient room timelines", function() {
end: "end_token",
};
let room;
let room: Room;
beforeEach(async () => {
setNextSyncData(initialSyncEventData);

View File

@ -33,7 +33,7 @@ import {
IJoinedRoom,
IStateEvent,
IMinimalEvent,
NotificationCountType,
NotificationCountType, IEphemeral,
} from "../../src";
import { UNREAD_THREAD_NOTIFICATIONS } from '../../src/@types/sync';
import * as utils from "../test-utils/test-utils";
@ -524,105 +524,101 @@ describe("MatrixClient syncing", () => {
const syncData = {
rooms: {
join: {
[roomOne]: {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "hello",
}),
],
},
state: {
events: [
utils.mkEvent({
type: "m.room.name", room: roomOne, user: otherUserId,
content: {
name: "Old room name",
},
}),
utils.mkMembership({
room: roomOne, mship: "join", user: otherUserId,
}),
utils.mkMembership({
room: roomOne, mship: "join", user: selfUserId,
}),
utils.mkEvent({
type: "m.room.create", room: roomOne, user: selfUserId,
content: {
creator: selfUserId,
},
}),
],
},
},
[roomTwo]: {
timeline: {
events: [
utils.mkMessage({
room: roomTwo, user: otherUserId, msg: "hiii",
}),
],
},
state: {
events: [
utils.mkMembership({
room: roomTwo, mship: "join", user: otherUserId,
name: otherDisplayName,
}),
utils.mkMembership({
room: roomTwo, mship: "join", user: selfUserId,
}),
utils.mkEvent({
type: "m.room.create", room: roomTwo, user: selfUserId,
content: {
creator: selfUserId,
},
}),
],
},
},
},
},
};
syncData.rooms.join[roomOne] = {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "hello",
}),
],
},
state: {
events: [
utils.mkEvent({
type: "m.room.name", room: roomOne, user: otherUserId,
content: {
name: "Old room name",
},
}),
utils.mkMembership({
room: roomOne, mship: "join", user: otherUserId,
}),
utils.mkMembership({
room: roomOne, mship: "join", user: selfUserId,
}),
utils.mkEvent({
type: "m.room.create", room: roomOne, user: selfUserId,
content: {
creator: selfUserId,
},
}),
],
},
};
syncData.rooms.join[roomTwo] = {
timeline: {
events: [
utils.mkMessage({
room: roomTwo, user: otherUserId, msg: "hiii",
}),
],
},
state: {
events: [
utils.mkMembership({
room: roomTwo, mship: "join", user: otherUserId,
name: otherDisplayName,
}),
utils.mkMembership({
room: roomTwo, mship: "join", user: selfUserId,
}),
utils.mkEvent({
type: "m.room.create", room: roomTwo, user: selfUserId,
content: {
creator: selfUserId,
},
}),
],
},
};
const nextSyncData = {
rooms: {
join: {
[roomOne]: {
state: {
events: [
utils.mkEvent({
type: "m.room.name", room: roomOne, user: selfUserId,
content: { name: "A new room name" },
}),
],
},
},
[roomTwo]: {
timeline: {
events: [
utils.mkMessage({
room: roomTwo, user: otherUserId, msg: msgText,
}),
],
},
ephemeral: {
events: [
utils.mkEvent({
type: "m.typing", room: roomTwo,
content: { user_ids: [otherUserId] },
}),
],
},
},
},
},
};
nextSyncData.rooms.join[roomOne] = {
state: {
events: [
utils.mkEvent({
type: "m.room.name", room: roomOne, user: selfUserId,
content: { name: "A new room name" },
}),
],
},
};
nextSyncData.rooms.join[roomTwo] = {
timeline: {
events: [
utils.mkMessage({
room: roomTwo, user: otherUserId, msg: msgText,
}),
],
},
ephemeral: {
events: [
utils.mkEvent({
type: "m.typing", room: roomTwo,
content: { user_ids: [otherUserId] },
}),
],
},
};
it("should continually recalculate the right room name.", () => {
httpBackend!.when("GET", "/sync").respond(200, syncData);
httpBackend!.when("GET", "/sync").respond(200, nextSyncData);
@ -635,9 +631,7 @@ describe("MatrixClient syncing", () => {
]).then(() => {
const room = client!.getRoom(roomOne)!;
// should have clobbered the name to the one from /events
expect(room.name).toEqual(
nextSyncData.rooms.join[roomOne].state.events[0].content.name,
);
expect(room.name).toEqual(nextSyncData.rooms.join[roomOne].state.events[0].content?.name);
});
});
@ -742,46 +736,48 @@ describe("MatrixClient syncing", () => {
const normalFirstSync = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
normalFirstSync.rooms.join[roomOne] = {
timeline: {
events: [normalMessageEvent],
prev_batch: "pagTok",
},
state: {
events: [roomCreateEvent],
join: {
[roomOne]: {
timeline: {
events: [normalMessageEvent],
prev_batch: "pagTok",
},
state: {
events: [roomCreateEvent],
},
},
},
},
};
const nextSyncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
nextSyncData.rooms.join[roomOne] = {
timeline: {
events: [
// In subsequent syncs, a marker event in timeline
// range should normally trigger
// `timelineNeedsRefresh=true` but this marker isn't
// being sent by the room creator so it has no
// special meaning in existing room versions.
utils.mkEvent({
type: UNSTABLE_MSC2716_MARKER.name,
room: roomOne,
// The important part we're testing is here!
// `userC` is not the room creator.
user: userC,
skey: "",
content: {
"m.insertion_id": "$abc",
join: {
[roomOne]: {
timeline: {
events: [
// In subsequent syncs, a marker event in timeline
// range should normally trigger
// `timelineNeedsRefresh=true` but this marker isn't
// being sent by the room creator so it has no
// special meaning in existing room versions.
utils.mkEvent({
type: UNSTABLE_MSC2716_MARKER.name,
room: roomOne,
// The important part we're testing is here!
// `userC` is not the room creator.
user: userC,
skey: "",
content: {
"m.insertion_id": "$abc",
},
}),
],
prev_batch: "pagTok",
},
}),
],
prev_batch: "pagTok",
},
},
},
};
@ -831,16 +827,17 @@ describe("MatrixClient syncing", () => {
const normalFirstSync = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
normalFirstSync.rooms.join[roomOne] = {
timeline: {
events: [normalMessageEvent],
prev_batch: "pagTok",
},
state: {
events: [roomCreateEvent],
join: {
[roomOne]: {
timeline: {
events: [normalMessageEvent],
prev_batch: "pagTok",
},
state: {
events: [roomCreateEvent],
},
},
},
},
};
@ -849,16 +846,17 @@ describe("MatrixClient syncing", () => {
const syncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
syncData.rooms.join[roomOne] = {
timeline: {
events: [normalMessageEvent],
prev_batch: "pagTok",
},
state: {
events: [roomCreateEvent],
join: {
[roomOne]: {
timeline: {
events: [normalMessageEvent],
prev_batch: "pagTok",
},
state: {
events: [roomCreateEvent],
},
},
},
},
};
@ -879,16 +877,17 @@ describe("MatrixClient syncing", () => {
const syncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
syncData.rooms.join[roomOne] = {
timeline: {
events: [markerEventFromRoomCreator],
prev_batch: "pagTok",
},
state: {
events: [roomCreateEvent],
join: {
[roomOne]: {
timeline: {
events: [markerEventFromRoomCreator],
prev_batch: "pagTok",
},
state: {
events: [roomCreateEvent],
},
},
},
},
};
@ -909,19 +908,20 @@ describe("MatrixClient syncing", () => {
const syncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
syncData.rooms.join[roomOne] = {
timeline: {
events: [normalMessageEvent],
prev_batch: "pagTok",
},
state: {
events: [
roomCreateEvent,
markerEventFromRoomCreator,
],
join: {
[roomOne]: {
timeline: {
events: [normalMessageEvent],
prev_batch: "pagTok",
},
state: {
events: [
roomCreateEvent,
markerEventFromRoomCreator,
],
},
},
},
},
};
@ -942,17 +942,18 @@ describe("MatrixClient syncing", () => {
const nextSyncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
nextSyncData.rooms.join[roomOne] = {
timeline: {
events: [
// In subsequent syncs, a marker event in timeline
// range should trigger `timelineNeedsRefresh=true`
markerEventFromRoomCreator,
],
prev_batch: "pagTok",
join: {
[roomOne]: {
timeline: {
events: [
// In subsequent syncs, a marker event in timeline
// range should trigger `timelineNeedsRefresh=true`
markerEventFromRoomCreator,
],
prev_batch: "pagTok",
},
},
},
},
};
@ -993,24 +994,25 @@ describe("MatrixClient syncing", () => {
const nextSyncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
nextSyncData.rooms.join[roomOne] = {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "hello again",
}),
],
prev_batch: "pagTok",
},
state: {
events: [
// In subsequent syncs, a marker event in state
// should trigger `timelineNeedsRefresh=true`
markerEventFromRoomCreator,
],
join: {
[roomOne]: {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "hello again",
}),
],
prev_batch: "pagTok",
},
state: {
events: [
// In subsequent syncs, a marker event in state
// should trigger `timelineNeedsRefresh=true`
markerEventFromRoomCreator,
],
},
},
},
},
};
@ -1095,19 +1097,20 @@ describe("MatrixClient syncing", () => {
const limitedSyncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
limitedSyncData.rooms.join[roomOne] = {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "world",
}),
],
// The important part, make the sync `limited`
limited: true,
prev_batch: "newerTok",
join: {
[roomOne]: {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "world",
}),
],
// The important part, make the sync `limited`
limited: true,
prev_batch: "newerTok",
},
},
},
},
};
httpBackend!.when("GET", "/sync").respond(200, limitedSyncData);
@ -1167,7 +1170,7 @@ describe("MatrixClient syncing", () => {
const eventsInRoom = syncData.rooms.join[roomOne].timeline.events;
const contextUrl = `/rooms/${encodeURIComponent(roomOne)}/context/` +
`${encodeURIComponent(eventsInRoom[0].event_id)}`;
`${encodeURIComponent(eventsInRoom[0].event_id!)}`;
httpBackend!.when("GET", contextUrl)
.respond(200, () => {
return {
@ -1202,17 +1205,18 @@ describe("MatrixClient syncing", () => {
const syncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
syncData.rooms.join[roomOne] = {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "hello",
}),
],
prev_batch: "pagTok",
join: {
[roomOne]: {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "hello",
}),
],
prev_batch: "pagTok",
},
},
},
},
};
@ -1229,17 +1233,18 @@ describe("MatrixClient syncing", () => {
const syncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
syncData.rooms.join[roomTwo] = {
timeline: {
events: [
utils.mkMessage({
room: roomTwo, user: otherUserId, msg: "roomtwo",
}),
],
prev_batch: "roomtwotok",
join: {
[roomTwo]: {
timeline: {
events: [
utils.mkMessage({
room: roomTwo, user: otherUserId, msg: "roomtwo",
}),
],
prev_batch: "roomtwotok",
},
},
},
},
};
@ -1261,18 +1266,19 @@ describe("MatrixClient syncing", () => {
const syncData = {
next_batch: "batch_token",
rooms: {
join: {},
},
};
syncData.rooms.join[roomOne] = {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "world",
}),
],
limited: true,
prev_batch: "newerTok",
join: {
[roomOne]: {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "world",
}),
],
limited: true,
prev_batch: "newerTok",
},
},
},
},
};
httpBackend!.when("GET", "/sync").respond(200, syncData);
@ -1304,44 +1310,46 @@ describe("MatrixClient syncing", () => {
const syncData = {
rooms: {
join: {
[roomOne]: {
ephemeral: {
events: [],
} as IEphemeral,
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "hello",
}),
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "world",
}),
],
},
state: {
events: [
utils.mkEvent({
type: "m.room.name", room: roomOne, user: otherUserId,
content: {
name: "Old room name",
},
}),
utils.mkMembership({
room: roomOne, mship: "join", user: otherUserId,
}),
utils.mkMembership({
room: roomOne, mship: "join", user: selfUserId,
}),
utils.mkEvent({
type: "m.room.create", room: roomOne, user: selfUserId,
content: {
creator: selfUserId,
},
}),
],
} as Partial<IJoinedRoom>,
},
},
},
};
syncData.rooms.join[roomOne] = {
timeline: {
events: [
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "hello",
}),
utils.mkMessage({
room: roomOne, user: otherUserId, msg: "world",
}),
],
},
state: {
events: [
utils.mkEvent({
type: "m.room.name", room: roomOne, user: otherUserId,
content: {
name: "Old room name",
},
}),
utils.mkMembership({
room: roomOne, mship: "join", user: otherUserId,
}),
utils.mkMembership({
room: roomOne, mship: "join", user: selfUserId,
}),
utils.mkEvent({
type: "m.room.create", room: roomOne, user: selfUserId,
content: {
creator: selfUserId,
},
}),
],
},
};
beforeEach(() => {
syncData.rooms.join[roomOne].ephemeral = {
@ -1351,16 +1359,15 @@ describe("MatrixClient syncing", () => {
it("should sync receipts from /sync.", () => {
const ackEvent = syncData.rooms.join[roomOne].timeline.events[0];
const receipt = {};
receipt[ackEvent.event_id] = {
const receipt: Record<string, any> = {};
receipt[ackEvent.event_id!] = {
"m.read": {},
};
receipt[ackEvent.event_id]["m.read"][userC] = {
receipt[ackEvent.event_id!]["m.read"][userC] = {
ts: 176592842636,
};
syncData.rooms.join[roomOne].ephemeral.events = [{
content: receipt,
room_id: roomOne,
type: "m.receipt",
}];
httpBackend!.when("GET", "/sync").respond(200, syncData);
@ -1425,7 +1432,7 @@ describe("MatrixClient syncing", () => {
},
},
},
};
} as unknown as ISyncResponse;
it("should sync unread notifications.", () => {
syncData.rooms.join[roomOne][UNREAD_THREAD_NOTIFICATIONS.name] = {
[THREAD_ID]: {
@ -1509,18 +1516,18 @@ describe("MatrixClient syncing", () => {
const syncData = {
next_batch: "batch_token",
rooms: {
leave: {},
},
};
syncData.rooms.leave[roomTwo] = {
timeline: {
events: [
utils.mkMessage({
room: roomTwo, user: otherUserId, msg: "hello",
}),
],
prev_batch: "pagTok",
leave: {
[roomTwo]: {
timeline: {
events: [
utils.mkMessage({
room: roomTwo, user: otherUserId, msg: "hello",
}),
],
prev_batch: "pagTok",
},
},
},
},
};

View File

@ -126,12 +126,13 @@ describe("megolm key backups", function() {
const syncResponse = {
next_batch: 1,
rooms: {
join: {},
},
};
syncResponse.rooms.join[ROOM_ID] = {
timeline: {
events: [ENCRYPTED_EVENT],
join: {
[ROOM_ID]: {
timeline: {
events: [ENCRYPTED_EVENT],
},
},
},
},
};

View File

@ -119,13 +119,13 @@ describe("SlidingSyncSdk", () => {
};
// find an extension on a SlidingSyncSdk instance
const findExtension = (name: string): Extension => {
const findExtension = (name: string): Extension<any, any> => {
expect(mockSlidingSync!.registerExtension).toHaveBeenCalled();
const mockFn = mockSlidingSync!.registerExtension as jest.Mock;
// find the extension
for (let i = 0; i < mockFn.mock.calls.length; i++) {
const calledExtension = mockFn.mock.calls[i][0] as Extension;
if (calledExtension && calledExtension.name() === name) {
const calledExtension = mockFn.mock.calls[i][0] as Extension<any, any>;
if (calledExtension?.name() === name) {
return calledExtension;
}
}
@ -581,7 +581,7 @@ describe("SlidingSyncSdk", () => {
});
describe("ExtensionE2EE", () => {
let ext: Extension;
let ext: Extension<any, any>;
beforeAll(async () => {
await setupClient({
@ -647,7 +647,7 @@ describe("SlidingSyncSdk", () => {
});
describe("ExtensionAccountData", () => {
let ext: Extension;
let ext: Extension<any, any>;
beforeAll(async () => {
await setupClient();
@ -773,7 +773,7 @@ describe("SlidingSyncSdk", () => {
});
describe("ExtensionToDevice", () => {
let ext: Extension;
let ext: Extension<any, any>;
beforeAll(async () => {
await setupClient();
@ -871,7 +871,7 @@ describe("SlidingSyncSdk", () => {
});
describe("ExtensionTyping", () => {
let ext: Extension;
let ext: Extension<any, any>;
beforeAll(async () => {
await setupClient();
@ -970,7 +970,7 @@ describe("SlidingSyncSdk", () => {
});
describe("ExtensionReceipts", () => {
let ext: Extension;
let ext: Extension<any, any>;
const generateReceiptResponse = (
userId: string, roomId: string, eventId: string, recType: string, ts: number,

View File

@ -18,7 +18,15 @@ limitations under the License.
import EventEmitter from "events";
import MockHttpBackend from "matrix-mock-request";
import { SlidingSync, SlidingSyncState, ExtensionState, SlidingSyncEvent } from "../../src/sliding-sync";
import {
SlidingSync,
SlidingSyncState,
ExtensionState,
SlidingSyncEvent,
Extension,
SlidingSyncEventHandlerMap,
MSC3575RoomData,
} from "../../src/sliding-sync";
import { TestClient } from "../TestClient";
import { logger } from "../../src/logger";
import { MatrixClient } from "../../src";
@ -94,7 +102,7 @@ describe("SlidingSync", () => {
is_dm: true,
},
};
const ext = {
const ext: Extension<any, any> = {
name: () => "custom_extension",
onRequest: (initial) => { return { initial: initial }; },
onResponse: (res) => { return {}; },
@ -107,7 +115,7 @@ describe("SlidingSync", () => {
slidingSync.start();
// expect everything to be sent
let txnId;
let txnId: string | undefined;
httpBackend!.when("POST", syncUrl).check(function(req) {
const body = req.data;
logger.debug("got ", body);
@ -390,8 +398,8 @@ describe("SlidingSync", () => {
}],
rooms: rooms,
});
const listenerData = {};
const dataListener = (roomId, roomData) => {
const listenerData: Record<string, MSC3575RoomData> = {};
const dataListener: SlidingSyncEventHandlerMap[SlidingSyncEvent.RoomData] = (roomId, roomData) => {
expect(listenerData[roomId]).toBeFalsy();
listenerData[roomId] = roomData;
};
@ -912,7 +920,7 @@ describe("SlidingSync", () => {
slidingSync = new SlidingSync(proxyBaseUrl, [], roomSubInfo, client!, 1);
// modification before SlidingSync.start()
const subscribePromise = slidingSync.modifyRoomSubscriptions(new Set([roomId]));
let txnId;
let txnId: string | undefined;
httpBackend!.when("POST", syncUrl).check(function(req) {
const body = req.data;
logger.debug("got ", body);
@ -944,7 +952,7 @@ describe("SlidingSync", () => {
ranges: [[0, 20]],
};
const promise = slidingSync.setList(0, newList);
let txnId;
let txnId: string | undefined;
httpBackend!.when("POST", syncUrl).check(function(req) {
const body = req.data;
logger.debug("got ", body);
@ -966,7 +974,7 @@ describe("SlidingSync", () => {
});
it("should resolve setListRanges during a connection", async () => {
const promise = slidingSync.setListRanges(0, [[20, 40]]);
let txnId;
let txnId: string | undefined;
httpBackend!.when("POST", syncUrl).check(function(req) {
const body = req.data;
logger.debug("got ", body);
@ -992,7 +1000,7 @@ describe("SlidingSync", () => {
const promise = slidingSync.modifyRoomSubscriptionInfo({
timeline_limit: 99,
});
let txnId;
let txnId: string | undefined;
httpBackend!.when("POST", syncUrl).check(function(req) {
const body = req.data;
logger.debug("got ", body);
@ -1016,7 +1024,7 @@ describe("SlidingSync", () => {
it("should reject earlier pending promises if a later transaction is acknowledged", async () => {
// i.e if we have [A,B,C] and see txn_id=C then A,B should be rejected.
const gotTxnIds: any[] = [];
const pushTxn = function(req) {
const pushTxn = function(req: MockHttpBackend["requests"][0]) {
gotTxnIds.push(req.data.txn_id);
};
const failPromise = slidingSync.setListRanges(0, [[20, 40]]);
@ -1032,7 +1040,7 @@ describe("SlidingSync", () => {
expect(failPromise2).rejects.toEqual(gotTxnIds[1]);
const okPromise = slidingSync.setListRanges(0, [[0, 20]]);
let txnId;
let txnId: string | undefined;
httpBackend!.when("POST", syncUrl).check((req) => {
txnId = req.data.txn_id;
}).respond(200, () => {
@ -1050,7 +1058,7 @@ describe("SlidingSync", () => {
it("should not reject later pending promises if an earlier transaction is acknowledged", async () => {
// i.e if we have [A,B,C] and see txn_id=B then C should not be rejected but A should.
const gotTxnIds: any[] = [];
const pushTxn = function(req) {
const pushTxn = function(req: MockHttpBackend["requests"][0]) {
gotTxnIds.push(req.data?.txn_id);
};
const A = slidingSync.setListRanges(0, [[20, 40]]);
@ -1087,7 +1095,7 @@ describe("SlidingSync", () => {
promise.finally(() => {
pending = false;
});
let txnId;
let txnId: string | undefined;
httpBackend!.when("POST", syncUrl).check(function(req) {
const body = req.data;
logger.debug("got ", body);
@ -1275,21 +1283,21 @@ describe("SlidingSync", () => {
// Pre-extensions get called BEFORE processing the sync response
const preExtName = "foobar";
let onPreExtensionRequest;
let onPreExtensionResponse;
let onPreExtensionRequest: Extension<any, any>["onRequest"];
let onPreExtensionResponse: Extension<any, any>["onResponse"];
// Post-extensions get called AFTER processing the sync response
const postExtName = "foobar2";
let onPostExtensionRequest;
let onPostExtensionResponse;
let onPostExtensionRequest: Extension<any, any>["onRequest"];
let onPostExtensionResponse: Extension<any, any>["onResponse"];
const extPre = {
const extPre: Extension<any, any> = {
name: () => preExtName,
onRequest: (initial) => { return onPreExtensionRequest(initial); },
onResponse: (res) => { return onPreExtensionResponse(res); },
when: () => ExtensionState.PreProcess,
};
const extPost = {
const extPost: Extension<any, any> = {
name: () => postExtName,
onRequest: (initial) => { return onPostExtensionRequest(initial); },
onResponse: (res) => { return onPostExtensionResponse(res); },
@ -1421,7 +1429,7 @@ describe("SlidingSync", () => {
});
function timeout(delayMs: number, reason: string): { promise: Promise<never>, cancel: () => void } {
let timeoutId;
let timeoutId: NodeJS.Timeout;
return {
promise: new Promise((resolve, reject) => {
timeoutId = setTimeout(() => {
@ -1454,7 +1462,7 @@ function listenUntil<T>(
const trace = new Error().stack?.split(`\n`)[2];
const t = timeout(timeoutMs, "timed out waiting for event " + eventName + " " + trace);
return Promise.race([new Promise<T>((resolve, reject) => {
const wrapper = (...args) => {
const wrapper = (...args: any[]) => {
try {
const data = callback(...args);
if (data) {