Skip to content

Commit

Permalink
Apply more strict typescript around the codebase (#2778)
Browse files Browse the repository at this point in the history
* Apply more strict typescript around the codebase

* Fix tests

* Revert strict mode commit

* Iterate strict

* Iterate

* Iterate strict

* Iterate

* Fix tests

* Iterate

* Iterate strict

* Add tests

* Iterate

* Iterate

* Fix tests

* Fix tests

* Strict types be strict

* Fix types

* detectOpenHandles

* Strict

* Fix client not stopping

* Add sync peeking tests

* Make test happier

* More strict

* Iterate

* Stabilise

* Moar strictness

* Improve coverage

* Fix types

* Fix types

* Improve types further

* Fix types

* Improve typing of NamespacedValue

* Fix types
  • Loading branch information
t3chguy authored Oct 21, 2022
1 parent fdbbd9b commit 867a0ca
Show file tree
Hide file tree
Showing 94 changed files with 1,969 additions and 1,724 deletions.
26 changes: 13 additions & 13 deletions spec/TestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ import { IKeysUploadResponse, IUploadKeysRequest } from '../src/client';
export class TestClient {
public readonly httpBackend: MockHttpBackend;
public readonly client: MatrixClient;
public deviceKeys: IDeviceKeys;
public oneTimeKeys: Record<string, IOneTimeKey>;
public deviceKeys?: IDeviceKeys | null;
public oneTimeKeys?: Record<string, IOneTimeKey>;

constructor(
public readonly userId?: string,
Expand Down Expand Up @@ -123,7 +123,7 @@ export class TestClient {

logger.log(this + ': received device keys');
// we expect this to happen before any one-time keys are uploaded.
expect(Object.keys(this.oneTimeKeys).length).toEqual(0);
expect(Object.keys(this.oneTimeKeys!).length).toEqual(0);

this.deviceKeys = content.device_keys;
return { one_time_key_counts: { signed_curve25519: 0 } };
Expand All @@ -138,17 +138,17 @@ export class TestClient {
* @returns {Promise} for the one-time keys
*/
public awaitOneTimeKeyUpload(): Promise<Record<string, IOneTimeKey>> {
if (Object.keys(this.oneTimeKeys).length != 0) {
if (Object.keys(this.oneTimeKeys!).length != 0) {
// already got one-time keys
return Promise.resolve(this.oneTimeKeys);
return Promise.resolve(this.oneTimeKeys!);
}

this.httpBackend.when("POST", "/keys/upload")
.respond<IKeysUploadResponse, IUploadKeysRequest>(200, (_path, content: IUploadKeysRequest) => {
expect(content.device_keys).toBe(undefined);
expect(content.one_time_keys).toBe(undefined);
return { one_time_key_counts: {
signed_curve25519: Object.keys(this.oneTimeKeys).length,
signed_curve25519: Object.keys(this.oneTimeKeys!).length,
} };
});

Expand All @@ -158,17 +158,17 @@ export class TestClient {
expect(content.one_time_keys).toBeTruthy();
expect(content.one_time_keys).not.toEqual({});
logger.log('%s: received %i one-time keys', this,
Object.keys(content.one_time_keys).length);
Object.keys(content.one_time_keys!).length);
this.oneTimeKeys = content.one_time_keys;
return { one_time_key_counts: {
signed_curve25519: Object.keys(this.oneTimeKeys).length,
signed_curve25519: Object.keys(this.oneTimeKeys!).length,
} };
});

// this can take ages
return this.httpBackend.flush('/keys/upload', 2, 1000).then((flushed) => {
expect(flushed).toEqual(2);
return this.oneTimeKeys;
return this.oneTimeKeys!;
});
}

Expand All @@ -183,7 +183,7 @@ export class TestClient {
this.httpBackend.when('POST', '/keys/query').respond<IDownloadKeyResult>(
200, (_path, content) => {
Object.keys(response.device_keys).forEach((userId) => {
expect(content.device_keys[userId]).toEqual([]);
expect(content.device_keys![userId]).toEqual([]);
});
return response;
});
Expand All @@ -206,7 +206,7 @@ export class TestClient {
*/
public getDeviceKey(): string {
const keyId = 'curve25519:' + this.deviceId;
return this.deviceKeys.keys[keyId];
return this.deviceKeys!.keys[keyId];
}

/**
Expand All @@ -216,7 +216,7 @@ export class TestClient {
*/
public getSigningKey(): string {
const keyId = 'ed25519:' + this.deviceId;
return this.deviceKeys.keys[keyId];
return this.deviceKeys!.keys[keyId];
}

/**
Expand All @@ -237,6 +237,6 @@ export class TestClient {
}

public getUserId(): string {
return this.userId;
return this.userId!;
}
}
12 changes: 6 additions & 6 deletions spec/integ/matrix-client-crypto.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async function bobUploadsDeviceKeys(): Promise<void> {
bobTestClient.client.uploadKeys(),
bobTestClient.httpBackend.flushAllExpected(),
]);
expect(Object.keys(bobTestClient.deviceKeys).length).not.toEqual(0);
expect(Object.keys(bobTestClient.deviceKeys!).length).not.toEqual(0);
}

/**
Expand Down Expand Up @@ -99,7 +99,7 @@ async function expectAliClaimKeys(): Promise<void> {
expect(claimType).toEqual("signed_curve25519");
let keyId = '';
for (keyId in keys) {
if (bobTestClient.oneTimeKeys.hasOwnProperty(keyId)) {
if (bobTestClient.oneTimeKeys!.hasOwnProperty(keyId)) {
if (keyId.indexOf(claimType + ":") === 0) {
break;
}
Expand Down Expand Up @@ -137,7 +137,7 @@ async function aliDownloadsKeys(): Promise<void> {
// @ts-ignore - protected
aliTestClient.client.cryptoStore.getEndToEndDeviceData(null, (data) => {
const devices = data!.devices[bobUserId]!;
expect(devices[bobDeviceId].keys).toEqual(bobTestClient.deviceKeys.keys);
expect(devices[bobDeviceId].keys).toEqual(bobTestClient.deviceKeys!.keys);
expect(devices[bobDeviceId].verified).
toBe(DeviceInfo.DeviceVerification.UNVERIFIED);
});
Expand Down Expand Up @@ -223,7 +223,7 @@ async function expectBobSendMessageRequest(): Promise<OlmPayload> {
const content = await expectSendMessageRequest(bobTestClient.httpBackend);
bobMessages.push(content);
const aliKeyId = "curve25519:" + aliDeviceId;
const aliDeviceCurve25519Key = aliTestClient.deviceKeys.keys[aliKeyId];
const aliDeviceCurve25519Key = aliTestClient.deviceKeys!.keys[aliKeyId];
expect(Object.keys(content.ciphertext)).toEqual([aliDeviceCurve25519Key]);
const ciphertext = content.ciphertext[aliDeviceCurve25519Key];
expect(ciphertext).toBeTruthy();
Expand Down Expand Up @@ -393,7 +393,7 @@ describe("MatrixClient crypto", () => {
it("Ali gets keys with an invalid signature", async () => {
await bobUploadsDeviceKeys();
// tamper bob's keys
const bobDeviceKeys = bobTestClient.deviceKeys;
const bobDeviceKeys = bobTestClient.deviceKeys!;
expect(bobDeviceKeys.keys["curve25519:" + bobDeviceId]).toBeTruthy();
bobDeviceKeys.keys["curve25519:" + bobDeviceId] += "abc";
await Promise.all([
Expand Down Expand Up @@ -479,7 +479,7 @@ describe("MatrixClient crypto", () => {
await bobTestClient.start();
const keys = await bobTestClient.awaitOneTimeKeyUpload();
expect(Object.keys(keys).length).toEqual(5);
expect(Object.keys(bobTestClient.deviceKeys).length).not.toEqual(0);
expect(Object.keys(bobTestClient.deviceKeys!).length).not.toEqual(0);
});

it("Ali sends a message", async () => {
Expand Down
2 changes: 1 addition & 1 deletion spec/integ/matrix-client-event-timeline.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1047,7 +1047,7 @@ describe("MatrixClient event timelines", function() {
response = {
chunk: [THREAD_ROOT],
state: [],
next_batch: RANDOM_TOKEN,
next_batch: RANDOM_TOKEN as string | null,
},
): ExpectedHttpRequest {
const request = httpBackend.when("GET", encodeUri("/_matrix/client/r0/rooms/$roomId/threads", {
Expand Down
42 changes: 21 additions & 21 deletions spec/integ/matrix-client-methods.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ describe("MatrixClient", function() {
const r = client!.cancelUpload(prom);
expect(r).toBe(true);
await expect(prom).rejects.toThrow("Aborted");
expect(client.getCurrentUploads()).toHaveLength(0);
expect(client!.getCurrentUploads()).toHaveLength(0);
});
});

Expand Down Expand Up @@ -178,7 +178,7 @@ describe("MatrixClient", function() {
expect(request.data.third_party_signed).toEqual(signature);
}).respond(200, { room_id: roomId });

const prom = client.joinRoom(roomId, {
const prom = client!.joinRoom(roomId, {
inviteSignUrl,
viaServers,
});
Expand Down Expand Up @@ -1164,18 +1164,18 @@ describe("MatrixClient", function() {

describe("logout", () => {
it("should abort pending requests when called with stopClient=true", async () => {
httpBackend.when("POST", "/logout").respond(200, {});
httpBackend!.when("POST", "/logout").respond(200, {});
const fn = jest.fn();
client.http.request(Method.Get, "/test").catch(fn);
client.logout(true);
await httpBackend.flush(undefined);
client!.http.request(Method.Get, "/test").catch(fn);
client!.logout(true);
await httpBackend!.flush(undefined);
expect(fn).toHaveBeenCalled();
});
});

describe("sendHtmlEmote", () => {
it("should send valid html emote", async () => {
httpBackend.when("PUT", "/send").check(req => {
httpBackend!.when("PUT", "/send").check(req => {
expect(req.data).toStrictEqual({
"msgtype": "m.emote",
"body": "Body",
Expand All @@ -1184,15 +1184,15 @@ describe("MatrixClient", function() {
"org.matrix.msc1767.message": expect.anything(),
});
}).respond(200, { event_id: "$foobar" });
const prom = client.sendHtmlEmote("!room:server", "Body", "<h1>Body</h1>");
await httpBackend.flush(undefined);
const prom = client!.sendHtmlEmote("!room:server", "Body", "<h1>Body</h1>");
await httpBackend!.flush(undefined);
await expect(prom).resolves.toStrictEqual({ event_id: "$foobar" });
});
});

describe("sendHtmlMessage", () => {
it("should send valid html message", async () => {
httpBackend.when("PUT", "/send").check(req => {
httpBackend!.when("PUT", "/send").check(req => {
expect(req.data).toStrictEqual({
"msgtype": "m.text",
"body": "Body",
Expand All @@ -1201,24 +1201,24 @@ describe("MatrixClient", function() {
"org.matrix.msc1767.message": expect.anything(),
});
}).respond(200, { event_id: "$foobar" });
const prom = client.sendHtmlMessage("!room:server", "Body", "<h1>Body</h1>");
await httpBackend.flush(undefined);
const prom = client!.sendHtmlMessage("!room:server", "Body", "<h1>Body</h1>");
await httpBackend!.flush(undefined);
await expect(prom).resolves.toStrictEqual({ event_id: "$foobar" });
});
});

describe("forget", () => {
it("should remove from store by default", async () => {
const room = new Room("!roomId:server", client, userId);
client.store.storeRoom(room);
expect(client.store.getRooms()).toContain(room);
const room = new Room("!roomId:server", client!, userId);
client!.store.storeRoom(room);
expect(client!.store.getRooms()).toContain(room);

httpBackend.when("POST", "/forget").respond(200, {});
httpBackend!.when("POST", "/forget").respond(200, {});
await Promise.all([
client.forget(room.roomId),
httpBackend.flushAllExpected(),
client!.forget(room.roomId),
httpBackend!.flushAllExpected(),
]);
expect(client.store.getRooms()).not.toContain(room);
expect(client!.store.getRooms()).not.toContain(room);
});
});

Expand Down Expand Up @@ -1306,8 +1306,8 @@ describe("MatrixClient", function() {
const resp = await prom;
expect(resp.access_token).toBe(token);
expect(resp.user_id).toBe(userId);
expect(client.getUserId()).toBe(userId);
expect(client.http.opts.accessToken).toBe(token);
expect(client!.getUserId()).toBe(userId);
expect(client!.http.opts.accessToken).toBe(token);
});
});

Expand Down
61 changes: 61 additions & 0 deletions spec/integ/matrix-client-syncing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,67 @@ describe("MatrixClient syncing", () => {
});
});

describe("peek", () => {
beforeEach(() => {
httpBackend!.expectedRequests = [];
});

it("should return a room based on the room initialSync API", async () => {
httpBackend!.when("GET", `/rooms/${encodeURIComponent(roomOne)}/initialSync`).respond(200, {
room_id: roomOne,
membership: "leave",
messages: {
start: "start",
end: "end",
chunk: [{
content: { body: "Message 1" },
type: "m.room.message",
event_id: "$eventId1",
sender: userA,
origin_server_ts: 12313525,
room_id: roomOne,
}, {
content: { body: "Message 2" },
type: "m.room.message",
event_id: "$eventId2",
sender: userB,
origin_server_ts: 12315625,
room_id: roomOne,
}],
},
state: [{
content: { name: "Room Name" },
type: "m.room.name",
event_id: "$eventId",
sender: userA,
origin_server_ts: 12314525,
state_key: "",
room_id: roomOne,
}],
presence: [{
content: {},
type: "m.presence",
sender: userA,
}],
});
httpBackend!.when("GET", "/events").respond(200, { chunk: [] });

const prom = client!.peekInRoom(roomOne);
await httpBackend!.flushAllExpected();
const room = await prom;

expect(room.roomId).toBe(roomOne);
expect(room.getMyMembership()).toBe("leave");
expect(room.name).toBe("Room Name");
expect(room.currentState.getStateEvents("m.room.name", "").getId()).toBe("$eventId");
expect(room.timeline[0].getContent().body).toBe("Message 1");
expect(room.timeline[1].getContent().body).toBe("Message 2");
client?.stopPeeking();
httpBackend!.when("GET", "/events").respond(200, { chunk: [] });
await httpBackend!.flushAllExpected();
});
});

/**
* waits for the MatrixClient to emit one or more 'sync' events.
*
Expand Down
16 changes: 8 additions & 8 deletions spec/integ/megolm-integ.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1160,11 +1160,11 @@ describe("megolm", () => {
"algorithm": 'm.megolm.v1.aes-sha2',
"room_id": ROOM_ID,
"sender_key": content.sender_key,
"sender_claimed_ed25519_key": groupSessionKey.sender_claimed_ed25519_key,
"sender_claimed_ed25519_key": groupSessionKey!.sender_claimed_ed25519_key,
"session_id": content.session_id,
"session_key": groupSessionKey.key,
"chain_index": groupSessionKey.chain_index,
"forwarding_curve25519_key_chain": groupSessionKey.forwarding_curve25519_key_chain,
"session_key": groupSessionKey!.key,
"chain_index": groupSessionKey!.chain_index,
"forwarding_curve25519_key_chain": groupSessionKey!.forwarding_curve25519_key_chain,
"org.matrix.msc3061.shared_history": true,
},
plaintype: 'm.forwarded_room_key',
Expand Down Expand Up @@ -1298,11 +1298,11 @@ describe("megolm", () => {
"algorithm": 'm.megolm.v1.aes-sha2',
"room_id": ROOM_ID,
"sender_key": content.sender_key,
"sender_claimed_ed25519_key": groupSessionKey.sender_claimed_ed25519_key,
"sender_claimed_ed25519_key": groupSessionKey!.sender_claimed_ed25519_key,
"session_id": content.session_id,
"session_key": groupSessionKey.key,
"chain_index": groupSessionKey.chain_index,
"forwarding_curve25519_key_chain": groupSessionKey.forwarding_curve25519_key_chain,
"session_key": groupSessionKey!.key,
"chain_index": groupSessionKey!.chain_index,
"forwarding_curve25519_key_chain": groupSessionKey!.forwarding_curve25519_key_chain,
"org.matrix.msc3061.shared_history": true,
},
plaintype: 'm.forwarded_room_key',
Expand Down
3 changes: 1 addition & 2 deletions spec/integ/sliding-sync-sdk.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ describe("SlidingSyncSdk", () => {
it("emits SyncState.Reconnecting when < FAILED_SYNC_ERROR_THRESHOLD & SyncState.Error when over", async () => {
mockSlidingSync!.emit(
SlidingSyncEvent.Lifecycle, SlidingSyncState.Complete,
{ pos: "h", lists: [], rooms: {}, extensions: {} }, null,
{ pos: "h", lists: [], rooms: {}, extensions: {} },
);
expect(sdk!.getSyncState()).toEqual(SyncState.Syncing);

Expand All @@ -490,7 +490,6 @@ describe("SlidingSyncSdk", () => {
SlidingSyncEvent.Lifecycle,
SlidingSyncState.Complete,
{ pos: "i", lists: [], rooms: {}, extensions: {} },
null,
);
expect(sdk!.getSyncState()).toEqual(SyncState.Syncing);
});
Expand Down
Loading

0 comments on commit 867a0ca

Please sign in to comment.