You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-07-31 15:24:23 +03:00
test typescriptification - autodiscovery / crypto specs (#2550)
* spec/unit/autodiscovery.spec.js -> spec/unit/autodiscovery.spec.ts * fix ts in autodiscovery.spec * renamed: spec/unit/crypto.spec.js -> spec/unit/crypto.spec.ts * fix ts in crypto.spec * fix some strict errors
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2018 New Vector Ltd
|
Copyright 2018 New Vector Ltd
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
Copyright 2019, 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -17,19 +17,20 @@ limitations under the License.
|
|||||||
|
|
||||||
import MockHttpBackend from "matrix-mock-request";
|
import MockHttpBackend from "matrix-mock-request";
|
||||||
|
|
||||||
import * as sdk from "../../src";
|
import { request } from "../../src/matrix";
|
||||||
import { AutoDiscovery } from "../../src/autodiscovery";
|
import { AutoDiscovery } from "../../src/autodiscovery";
|
||||||
|
|
||||||
describe("AutoDiscovery", function() {
|
describe("AutoDiscovery", function() {
|
||||||
let httpBackend = null;
|
const getHttpBackend = (): MockHttpBackend => {
|
||||||
|
const httpBackend = new MockHttpBackend();
|
||||||
beforeEach(function() {
|
request(httpBackend.requestFn);
|
||||||
httpBackend = new MockHttpBackend();
|
return httpBackend;
|
||||||
sdk.request(httpBackend.requestFn);
|
};
|
||||||
});
|
|
||||||
|
|
||||||
it("should throw an error when no domain is specified", function() {
|
it("should throw an error when no domain is specified", function() {
|
||||||
|
getHttpBackend();
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
|
// @ts-ignore testing no args
|
||||||
AutoDiscovery.findClientConfig(/* no args */).then(() => {
|
AutoDiscovery.findClientConfig(/* no args */).then(() => {
|
||||||
throw new Error("Expected a failure, not success with no args");
|
throw new Error("Expected a failure, not success with no args");
|
||||||
}, () => {
|
}, () => {
|
||||||
@ -42,13 +43,13 @@ describe("AutoDiscovery", function() {
|
|||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
AutoDiscovery.findClientConfig(null).then(() => {
|
AutoDiscovery.findClientConfig(null as any).then(() => {
|
||||||
throw new Error("Expected a failure, not success with null");
|
throw new Error("Expected a failure, not success with null");
|
||||||
}, () => {
|
}, () => {
|
||||||
return true;
|
return true;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
AutoDiscovery.findClientConfig(true).then(() => {
|
AutoDiscovery.findClientConfig(true as any).then(() => {
|
||||||
throw new Error("Expected a failure, not success with a non-string");
|
throw new Error("Expected a failure, not success with a non-string");
|
||||||
}, () => {
|
}, () => {
|
||||||
return true;
|
return true;
|
||||||
@ -57,6 +58,7 @@ describe("AutoDiscovery", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return PROMPT when .well-known 404s", function() {
|
it("should return PROMPT when .well-known 404s", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(404, {});
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(404, {});
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
httpBackend.flushAllExpected(),
|
httpBackend.flushAllExpected(),
|
||||||
@ -80,6 +82,7 @@ describe("AutoDiscovery", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return FAIL_PROMPT when .well-known returns a 500 error", function() {
|
it("should return FAIL_PROMPT when .well-known returns a 500 error", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(500, {});
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(500, {});
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
httpBackend.flushAllExpected(),
|
httpBackend.flushAllExpected(),
|
||||||
@ -103,6 +106,7 @@ describe("AutoDiscovery", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return FAIL_PROMPT when .well-known returns a 400 error", function() {
|
it("should return FAIL_PROMPT when .well-known returns a 400 error", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(400, {});
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(400, {});
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
httpBackend.flushAllExpected(),
|
httpBackend.flushAllExpected(),
|
||||||
@ -126,6 +130,7 @@ describe("AutoDiscovery", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return FAIL_PROMPT when .well-known returns an empty body", function() {
|
it("should return FAIL_PROMPT when .well-known returns an empty body", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, "");
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, "");
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
httpBackend.flushAllExpected(),
|
httpBackend.flushAllExpected(),
|
||||||
@ -149,6 +154,7 @@ describe("AutoDiscovery", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return FAIL_PROMPT when .well-known returns not-JSON", function() {
|
it("should return FAIL_PROMPT when .well-known returns not-JSON", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, "abc");
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, "abc");
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
httpBackend.flushAllExpected(),
|
httpBackend.flushAllExpected(),
|
||||||
@ -173,6 +179,7 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return FAIL_PROMPT when .well-known does not have a base_url for " +
|
it("should return FAIL_PROMPT when .well-known does not have a base_url for " +
|
||||||
"m.homeserver (empty string)", function() {
|
"m.homeserver (empty string)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
||||||
"m.homeserver": {
|
"m.homeserver": {
|
||||||
base_url: "",
|
base_url: "",
|
||||||
@ -201,6 +208,7 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return FAIL_PROMPT when .well-known does not have a base_url for " +
|
it("should return FAIL_PROMPT when .well-known does not have a base_url for " +
|
||||||
"m.homeserver (no property)", function() {
|
"m.homeserver (no property)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
||||||
"m.homeserver": {},
|
"m.homeserver": {},
|
||||||
});
|
});
|
||||||
@ -227,6 +235,7 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return FAIL_ERROR when .well-known has an invalid base_url for " +
|
it("should return FAIL_ERROR when .well-known has an invalid base_url for " +
|
||||||
"m.homeserver (disallowed scheme)", function() {
|
"m.homeserver (disallowed scheme)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
||||||
"m.homeserver": {
|
"m.homeserver": {
|
||||||
base_url: "mxc://example.org",
|
base_url: "mxc://example.org",
|
||||||
@ -255,6 +264,7 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return FAIL_ERROR when .well-known has an invalid base_url for " +
|
it("should return FAIL_ERROR when .well-known has an invalid base_url for " +
|
||||||
"m.homeserver (verification failure: 404)", function() {
|
"m.homeserver (verification failure: 404)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").respond(404, {});
|
httpBackend.when("GET", "/_matrix/client/versions").respond(404, {});
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
||||||
"m.homeserver": {
|
"m.homeserver": {
|
||||||
@ -284,6 +294,7 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return FAIL_ERROR when .well-known has an invalid base_url for " +
|
it("should return FAIL_ERROR when .well-known has an invalid base_url for " +
|
||||||
"m.homeserver (verification failure: 500)", function() {
|
"m.homeserver (verification failure: 500)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").respond(500, {});
|
httpBackend.when("GET", "/_matrix/client/versions").respond(500, {});
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
||||||
"m.homeserver": {
|
"m.homeserver": {
|
||||||
@ -313,6 +324,7 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return FAIL_ERROR when .well-known has an invalid base_url for " +
|
it("should return FAIL_ERROR when .well-known has an invalid base_url for " +
|
||||||
"m.homeserver (verification failure: 200 but wrong content)", function() {
|
"m.homeserver (verification failure: 200 but wrong content)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").respond(200, {
|
httpBackend.when("GET", "/_matrix/client/versions").respond(200, {
|
||||||
not_matrix_versions: ["r0.0.1"],
|
not_matrix_versions: ["r0.0.1"],
|
||||||
});
|
});
|
||||||
@ -344,8 +356,9 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return SUCCESS when .well-known has a verifiably accurate base_url for " +
|
it("should return SUCCESS when .well-known has a verifiably accurate base_url for " +
|
||||||
"m.homeserver", function() {
|
"m.homeserver", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
||||||
expect(req.opts.uri).toEqual("https://example.org/_matrix/client/versions");
|
expect(req.path).toEqual("https://example.org/_matrix/client/versions");
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
versions: ["r0.0.1"],
|
versions: ["r0.0.1"],
|
||||||
});
|
});
|
||||||
@ -376,8 +389,9 @@ describe("AutoDiscovery", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return SUCCESS with the right homeserver URL", function() {
|
it("should return SUCCESS with the right homeserver URL", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://chat.example.org/_matrix/client/versions");
|
.toEqual("https://chat.example.org/_matrix/client/versions");
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
versions: ["r0.0.1"],
|
versions: ["r0.0.1"],
|
||||||
@ -411,8 +425,9 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return SUCCESS / FAIL_PROMPT when the identity server configuration " +
|
it("should return SUCCESS / FAIL_PROMPT when the identity server configuration " +
|
||||||
"is wrong (missing base_url)", function() {
|
"is wrong (missing base_url)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://chat.example.org/_matrix/client/versions");
|
.toEqual("https://chat.example.org/_matrix/client/versions");
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
versions: ["r0.0.1"],
|
versions: ["r0.0.1"],
|
||||||
@ -451,8 +466,9 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return SUCCESS / FAIL_PROMPT when the identity server configuration " +
|
it("should return SUCCESS / FAIL_PROMPT when the identity server configuration " +
|
||||||
"is wrong (empty base_url)", function() {
|
"is wrong (empty base_url)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://chat.example.org/_matrix/client/versions");
|
.toEqual("https://chat.example.org/_matrix/client/versions");
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
versions: ["r0.0.1"],
|
versions: ["r0.0.1"],
|
||||||
@ -491,8 +507,9 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return SUCCESS / FAIL_PROMPT when the identity server configuration " +
|
it("should return SUCCESS / FAIL_PROMPT when the identity server configuration " +
|
||||||
"is wrong (validation error: 404)", function() {
|
"is wrong (validation error: 404)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://chat.example.org/_matrix/client/versions");
|
.toEqual("https://chat.example.org/_matrix/client/versions");
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
versions: ["r0.0.1"],
|
versions: ["r0.0.1"],
|
||||||
@ -532,8 +549,9 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return SUCCESS / FAIL_PROMPT when the identity server configuration " +
|
it("should return SUCCESS / FAIL_PROMPT when the identity server configuration " +
|
||||||
"is wrong (validation error: 500)", function() {
|
"is wrong (validation error: 500)", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://chat.example.org/_matrix/client/versions");
|
.toEqual("https://chat.example.org/_matrix/client/versions");
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
versions: ["r0.0.1"],
|
versions: ["r0.0.1"],
|
||||||
@ -573,14 +591,15 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return SUCCESS when the identity server configuration is " +
|
it("should return SUCCESS when the identity server configuration is " +
|
||||||
"verifiably accurate", function() {
|
"verifiably accurate", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://chat.example.org/_matrix/client/versions");
|
.toEqual("https://chat.example.org/_matrix/client/versions");
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
versions: ["r0.0.1"],
|
versions: ["r0.0.1"],
|
||||||
});
|
});
|
||||||
httpBackend.when("GET", "/_matrix/identity/api/v1").check((req) => {
|
httpBackend.when("GET", "/_matrix/identity/api/v1").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://identity.example.org/_matrix/identity/api/v1");
|
.toEqual("https://identity.example.org/_matrix/identity/api/v1");
|
||||||
}).respond(200, {});
|
}).respond(200, {});
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
||||||
@ -615,14 +634,15 @@ describe("AutoDiscovery", function() {
|
|||||||
|
|
||||||
it("should return SUCCESS and preserve non-standard keys from the " +
|
it("should return SUCCESS and preserve non-standard keys from the " +
|
||||||
".well-known response", function() {
|
".well-known response", function() {
|
||||||
|
const httpBackend = getHttpBackend();
|
||||||
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
httpBackend.when("GET", "/_matrix/client/versions").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://chat.example.org/_matrix/client/versions");
|
.toEqual("https://chat.example.org/_matrix/client/versions");
|
||||||
}).respond(200, {
|
}).respond(200, {
|
||||||
versions: ["r0.0.1"],
|
versions: ["r0.0.1"],
|
||||||
});
|
});
|
||||||
httpBackend.when("GET", "/_matrix/identity/api/v1").check((req) => {
|
httpBackend.when("GET", "/_matrix/identity/api/v1").check((req) => {
|
||||||
expect(req.opts.uri)
|
expect(req.path)
|
||||||
.toEqual("https://identity.example.org/_matrix/identity/api/v1");
|
.toEqual("https://identity.example.org/_matrix/identity/api/v1");
|
||||||
}).respond(200, {});
|
}).respond(200, {});
|
||||||
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
httpBackend.when("GET", "/.well-known/matrix/client").respond(200, {
|
@ -27,7 +27,7 @@ describe("ContentRepo", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should return the empty string for null input", function() {
|
it("should return the empty string for null input", function() {
|
||||||
expect(getHttpUriForMxc(null, null)).toEqual("");
|
expect(getHttpUriForMxc(null as any, '')).toEqual("");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return a thumbnail URL if a width/height/resize is specified",
|
it("should return a thumbnail URL if a width/height/resize is specified",
|
||||||
|
@ -25,7 +25,7 @@ function awaitEvent(emitter, event) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function keyshareEventForEvent(client, event, index) {
|
async function keyshareEventForEvent(client, event, index): Promise<MatrixEvent> {
|
||||||
const roomId = event.getRoomId();
|
const roomId = event.getRoomId();
|
||||||
const eventContent = event.getWireContent();
|
const eventContent = event.getWireContent();
|
||||||
const key = await client.crypto.olmDevice.getInboundGroupSessionKey(
|
const key = await client.crypto.olmDevice.getInboundGroupSessionKey(
|
||||||
@ -50,6 +50,7 @@ async function keyshareEventForEvent(client, event, index) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
// make onRoomKeyEvent think this was an encrypted event
|
// make onRoomKeyEvent think this was an encrypted event
|
||||||
|
// @ts-ignore private property
|
||||||
ksEvent.senderCurve25519Key = "akey";
|
ksEvent.senderCurve25519Key = "akey";
|
||||||
return ksEvent;
|
return ksEvent;
|
||||||
}
|
}
|
||||||
@ -79,7 +80,7 @@ describe("Crypto", function() {
|
|||||||
getId: () => "$event_id",
|
getId: () => "$event_id",
|
||||||
getSenderKey: () => null,
|
getSenderKey: () => null,
|
||||||
getWireContent: () => {return {};},
|
getWireContent: () => {return {};},
|
||||||
};
|
} as unknown as MatrixEvent;
|
||||||
|
|
||||||
let encryptionInfo = client.getEventEncryptionInfo(event);
|
let encryptionInfo = client.getEventEncryptionInfo(event);
|
||||||
expect(encryptionInfo.encrypted).toBeFalsy();
|
expect(encryptionInfo.encrypted).toBeFalsy();
|
||||||
@ -154,12 +155,15 @@ describe("Crypto", function() {
|
|||||||
beforeEach(async function() {
|
beforeEach(async function() {
|
||||||
const mockStorage = new MockStorageApi();
|
const mockStorage = new MockStorageApi();
|
||||||
const clientStore = new MemoryStore({ localStorage: mockStorage });
|
const clientStore = new MemoryStore({ localStorage: mockStorage });
|
||||||
const cryptoStore = new MemoryCryptoStore(mockStorage);
|
const cryptoStore = new MemoryCryptoStore();
|
||||||
|
|
||||||
cryptoStore.storeEndToEndDeviceData({
|
cryptoStore.storeEndToEndDeviceData({
|
||||||
devices: {
|
devices: {
|
||||||
'@bob:home.server': {
|
'@bob:home.server': {
|
||||||
'BOBDEVICE': {
|
'BOBDEVICE': {
|
||||||
|
algorithms: [],
|
||||||
|
verified: 1,
|
||||||
|
known: false,
|
||||||
keys: {
|
keys: {
|
||||||
'curve25519:BOBDEVICE': 'this is a key',
|
'curve25519:BOBDEVICE': 'this is a key',
|
||||||
},
|
},
|
||||||
@ -167,7 +171,7 @@ describe("Crypto", function() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
trackingStatus: {},
|
trackingStatus: {},
|
||||||
});
|
}, {});
|
||||||
|
|
||||||
mockBaseApis = {
|
mockBaseApis = {
|
||||||
sendToDevice: jest.fn(),
|
sendToDevice: jest.fn(),
|
||||||
@ -185,6 +189,7 @@ describe("Crypto", function() {
|
|||||||
clientStore,
|
clientStore,
|
||||||
cryptoStore,
|
cryptoStore,
|
||||||
mockRoomList,
|
mockRoomList,
|
||||||
|
[],
|
||||||
);
|
);
|
||||||
crypto.registerEventHandlers(fakeEmitter);
|
crypto.registerEventHandlers(fakeEmitter);
|
||||||
await crypto.init();
|
await crypto.init();
|
||||||
@ -195,7 +200,7 @@ describe("Crypto", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("restarts wedged Olm sessions", async function() {
|
it("restarts wedged Olm sessions", async function() {
|
||||||
const prom = new Promise((resolve) => {
|
const prom = new Promise<void>((resolve) => {
|
||||||
mockBaseApis.claimOneTimeKeys = function() {
|
mockBaseApis.claimOneTimeKeys = function() {
|
||||||
resolve();
|
resolve();
|
||||||
return otkResponse;
|
return otkResponse;
|
||||||
@ -276,8 +281,12 @@ describe("Crypto", function() {
|
|||||||
// alice encrypts each event, and then bob tries to decrypt
|
// alice encrypts each event, and then bob tries to decrypt
|
||||||
// them without any keys, so that they'll be in pending
|
// them without any keys, so that they'll be in pending
|
||||||
await aliceClient.crypto.encryptEvent(event, aliceRoom);
|
await aliceClient.crypto.encryptEvent(event, aliceRoom);
|
||||||
|
// remove keys from the event
|
||||||
|
// @ts-ignore private properties
|
||||||
event.clearEvent = undefined;
|
event.clearEvent = undefined;
|
||||||
|
// @ts-ignore private properties
|
||||||
event.senderCurve25519Key = null;
|
event.senderCurve25519Key = null;
|
||||||
|
// @ts-ignore private properties
|
||||||
event.claimedEd25519Key = null;
|
event.claimedEd25519Key = null;
|
||||||
try {
|
try {
|
||||||
await bobClient.crypto.decryptEvent(event);
|
await bobClient.crypto.decryptEvent(event);
|
||||||
@ -291,7 +300,7 @@ describe("Crypto", function() {
|
|||||||
roomId, olmlib.MEGOLM_ALGORITHM,
|
roomId, olmlib.MEGOLM_ALGORITHM,
|
||||||
);
|
);
|
||||||
|
|
||||||
let eventPromise = Promise.all(events.map((ev) => {
|
const decryptEventsPromise = Promise.all(events.map((ev) => {
|
||||||
return awaitEvent(ev, "Event.decrypted");
|
return awaitEvent(ev, "Event.decrypted");
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -300,7 +309,7 @@ describe("Crypto", function() {
|
|||||||
// can
|
// can
|
||||||
let ksEvent = await keyshareEventForEvent(aliceClient, events[1], 1);
|
let ksEvent = await keyshareEventForEvent(aliceClient, events[1], 1);
|
||||||
await bobDecryptor.onRoomKeyEvent(ksEvent);
|
await bobDecryptor.onRoomKeyEvent(ksEvent);
|
||||||
await eventPromise;
|
await decryptEventsPromise;
|
||||||
expect(events[0].getContent().msgtype).toBe("m.bad.encrypted");
|
expect(events[0].getContent().msgtype).toBe("m.bad.encrypted");
|
||||||
expect(events[1].getContent().msgtype).not.toBe("m.bad.encrypted");
|
expect(events[1].getContent().msgtype).not.toBe("m.bad.encrypted");
|
||||||
|
|
||||||
@ -320,10 +329,10 @@ describe("Crypto", function() {
|
|||||||
|
|
||||||
// keyshare the session key starting at the first message, so
|
// keyshare the session key starting at the first message, so
|
||||||
// that it can now be decrypted
|
// that it can now be decrypted
|
||||||
eventPromise = awaitEvent(events[0], "Event.decrypted");
|
const decryptEventPromise = awaitEvent(events[0], "Event.decrypted");
|
||||||
ksEvent = await keyshareEventForEvent(aliceClient, events[0], 0);
|
ksEvent = await keyshareEventForEvent(aliceClient, events[0], 0);
|
||||||
await bobDecryptor.onRoomKeyEvent(ksEvent);
|
await bobDecryptor.onRoomKeyEvent(ksEvent);
|
||||||
await eventPromise;
|
await decryptEventPromise;
|
||||||
expect(events[0].getContent().msgtype).not.toBe("m.bad.encrypted");
|
expect(events[0].getContent().msgtype).not.toBe("m.bad.encrypted");
|
||||||
await sleep(1);
|
await sleep(1);
|
||||||
// the room key request should be gone since we've now decrypted everything
|
// the room key request should be gone since we've now decrypted everything
|
||||||
@ -354,8 +363,12 @@ describe("Crypto", function() {
|
|||||||
// alice encrypts each event, and then bob tries to decrypt
|
// alice encrypts each event, and then bob tries to decrypt
|
||||||
// them without any keys, so that they'll be in pending
|
// them without any keys, so that they'll be in pending
|
||||||
await aliceClient.crypto.encryptEvent(event, aliceRoom);
|
await aliceClient.crypto.encryptEvent(event, aliceRoom);
|
||||||
|
// remove keys from the event
|
||||||
|
// @ts-ignore private property
|
||||||
event.clearEvent = undefined;
|
event.clearEvent = undefined;
|
||||||
|
// @ts-ignore private property
|
||||||
event.senderCurve25519Key = null;
|
event.senderCurve25519Key = null;
|
||||||
|
// @ts-ignore private property
|
||||||
event.claimedEd25519Key = null;
|
event.claimedEd25519Key = null;
|
||||||
try {
|
try {
|
||||||
await bobClient.crypto.decryptEvent(event);
|
await bobClient.crypto.decryptEvent(event);
|
||||||
@ -451,7 +464,7 @@ describe("Crypto", function() {
|
|||||||
await client.initCrypto();
|
await client.initCrypto();
|
||||||
client.crypto.getSecretStorageKey = async () => null;
|
client.crypto.getSecretStorageKey = async () => null;
|
||||||
client.crypto.isCrossSigningReady = async () => false;
|
client.crypto.isCrossSigningReady = async () => false;
|
||||||
client.crypto.baseApis.uploadDeviceSigningKeys = () => null;
|
client.crypto.baseApis.uploadDeviceSigningKeys = jest.fn().mockResolvedValue(null);
|
||||||
client.crypto.baseApis.setAccountData = () => null;
|
client.crypto.baseApis.setAccountData = () => null;
|
||||||
client.crypto.baseApis.uploadKeySignatures = () => null;
|
client.crypto.baseApis.uploadKeySignatures = () => null;
|
||||||
client.crypto.baseApis.http.authedRequest = () => null;
|
client.crypto.baseApis.http.authedRequest = () => null;
|
@ -1,26 +1,36 @@
|
|||||||
|
import { mocked } from 'jest-mock';
|
||||||
|
|
||||||
import * as utils from "../test-utils/test-utils";
|
import * as utils from "../test-utils/test-utils";
|
||||||
import { EventTimeline } from "../../src/models/event-timeline";
|
import { EventTimeline } from "../../src/models/event-timeline";
|
||||||
import { RoomState } from "../../src/models/room-state";
|
import { RoomState } from "../../src/models/room-state";
|
||||||
|
import { MatrixClient } from "../../src/matrix";
|
||||||
|
import { Room } from "../../src/models/room";
|
||||||
|
import { RoomMember } from "../../src/models/room-member";
|
||||||
|
import { EventTimelineSet } from "../../src/models/event-timeline-set";
|
||||||
|
|
||||||
function mockRoomStates(timeline) {
|
jest.mock("../../src/models/room-state");
|
||||||
timeline.startState = utils.mock(RoomState, "startState");
|
|
||||||
timeline.endState = utils.mock(RoomState, "endState");
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("EventTimeline", function() {
|
describe("EventTimeline", function() {
|
||||||
const roomId = "!foo:bar";
|
const roomId = "!foo:bar";
|
||||||
const userA = "@alice:bar";
|
const userA = "@alice:bar";
|
||||||
const userB = "@bertha:bar";
|
const userB = "@bertha:bar";
|
||||||
let timeline;
|
let timeline: EventTimeline;
|
||||||
|
|
||||||
|
const mockClient = {} as unknown as MatrixClient;
|
||||||
|
|
||||||
|
const getTimeline = (): EventTimeline => {
|
||||||
|
const room = new Room(roomId, mockClient, userA);
|
||||||
|
const timelineSet = new EventTimelineSet(room);
|
||||||
|
jest.spyOn(timelineSet.room, 'getUnfilteredTimelineSet').mockReturnValue(timelineSet);
|
||||||
|
|
||||||
|
return new EventTimeline(timelineSet);
|
||||||
|
};
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
// XXX: this is a horrid hack; should use sinon or something instead to mock
|
// reset any RoomState mocks
|
||||||
const timelineSet = { room: { roomId: roomId } };
|
jest.resetAllMocks();
|
||||||
timelineSet.room.getUnfilteredTimelineSet = function() {
|
|
||||||
return timelineSet;
|
|
||||||
};
|
|
||||||
|
|
||||||
timeline = new EventTimeline(timelineSet);
|
timeline = getTimeline();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("construction", function() {
|
describe("construction", function() {
|
||||||
@ -31,10 +41,6 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("initialiseState", function() {
|
describe("initialiseState", function() {
|
||||||
beforeEach(function() {
|
|
||||||
mockRoomStates(timeline);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should copy state events to start and end state", function() {
|
it("should copy state events to start and end state", function() {
|
||||||
const events = [
|
const events = [
|
||||||
utils.mkMembership({
|
utils.mkMembership({
|
||||||
@ -48,11 +54,15 @@ describe("EventTimeline", function() {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
timeline.initialiseState(events);
|
timeline.initialiseState(events);
|
||||||
expect(timeline.startState.setStateEvents).toHaveBeenCalledWith(
|
// @ts-ignore private prop
|
||||||
|
const timelineStartState = timeline.startState;
|
||||||
|
expect(mocked(timelineStartState).setStateEvents).toHaveBeenCalledWith(
|
||||||
events,
|
events,
|
||||||
{ timelineWasEmpty: undefined },
|
{ timelineWasEmpty: undefined },
|
||||||
);
|
);
|
||||||
expect(timeline.endState.setStateEvents).toHaveBeenCalledWith(
|
// @ts-ignore private prop
|
||||||
|
const timelineEndState = timeline.endState;
|
||||||
|
expect(mocked(timelineEndState).setStateEvents).toHaveBeenCalledWith(
|
||||||
events,
|
events,
|
||||||
{ timelineWasEmpty: undefined },
|
{ timelineWasEmpty: undefined },
|
||||||
);
|
);
|
||||||
@ -103,8 +113,8 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("setNeighbouringTimeline should set neighbour", function() {
|
it("setNeighbouringTimeline should set neighbour", function() {
|
||||||
const prev = { a: "a" };
|
const prev = getTimeline();
|
||||||
const next = { b: "b" };
|
const next = getTimeline();
|
||||||
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
||||||
timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
timeline.setNeighbouringTimeline(next, EventTimeline.FORWARDS);
|
||||||
expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(prev);
|
expect(timeline.getNeighbouringTimeline(EventTimeline.BACKWARDS)).toBe(prev);
|
||||||
@ -112,8 +122,8 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("setNeighbouringTimeline should throw if called twice", function() {
|
it("setNeighbouringTimeline should throw if called twice", function() {
|
||||||
const prev = { a: "a" };
|
const prev = getTimeline();
|
||||||
const next = { b: "b" };
|
const next = getTimeline();
|
||||||
expect(function() {
|
expect(function() {
|
||||||
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
timeline.setNeighbouringTimeline(prev, EventTimeline.BACKWARDS);
|
||||||
}).not.toThrow();
|
}).not.toThrow();
|
||||||
@ -135,10 +145,6 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("addEvent", function() {
|
describe("addEvent", function() {
|
||||||
beforeEach(function() {
|
|
||||||
mockRoomStates(timeline);
|
|
||||||
});
|
|
||||||
|
|
||||||
const events = [
|
const events = [
|
||||||
utils.mkMessage({
|
utils.mkMessage({
|
||||||
room: roomId, user: userA, msg: "hungry hungry hungry",
|
room: roomId, user: userA, msg: "hungry hungry hungry",
|
||||||
@ -171,24 +177,22 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set event.sender for new and old events", function() {
|
it("should set event.sender for new and old events", function() {
|
||||||
const sentinel = {
|
const sentinel = new RoomMember(roomId, userA);
|
||||||
userId: userA,
|
sentinel.name = "Alice";
|
||||||
membership: "join",
|
sentinel.membership = "join";
|
||||||
name: "Alice",
|
|
||||||
};
|
const oldSentinel = new RoomMember(roomId, userA);
|
||||||
const oldSentinel = {
|
sentinel.name = "Old Alice";
|
||||||
userId: userA,
|
sentinel.membership = "join";
|
||||||
membership: "join",
|
|
||||||
name: "Old Alice",
|
mocked(timeline.getState(EventTimeline.FORWARDS)).getSentinelMember
|
||||||
};
|
|
||||||
timeline.getState(EventTimeline.FORWARDS).getSentinelMember
|
|
||||||
.mockImplementation(function(uid) {
|
.mockImplementation(function(uid) {
|
||||||
if (uid === userA) {
|
if (uid === userA) {
|
||||||
return sentinel;
|
return sentinel;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
timeline.getState(EventTimeline.BACKWARDS).getSentinelMember
|
mocked(timeline.getState(EventTimeline.BACKWARDS)).getSentinelMember
|
||||||
.mockImplementation(function(uid) {
|
.mockImplementation(function(uid) {
|
||||||
if (uid === userA) {
|
if (uid === userA) {
|
||||||
return oldSentinel;
|
return oldSentinel;
|
||||||
@ -212,43 +216,41 @@ describe("EventTimeline", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should set event.target for new and old m.room.member events",
|
it("should set event.target for new and old m.room.member events",
|
||||||
function() {
|
function() {
|
||||||
const sentinel = {
|
const sentinel = new RoomMember(roomId, userA);
|
||||||
userId: userA,
|
sentinel.name = "Alice";
|
||||||
membership: "join",
|
sentinel.membership = "join";
|
||||||
name: "Alice",
|
|
||||||
};
|
|
||||||
const oldSentinel = {
|
|
||||||
userId: userA,
|
|
||||||
membership: "join",
|
|
||||||
name: "Old Alice",
|
|
||||||
};
|
|
||||||
timeline.getState(EventTimeline.FORWARDS).getSentinelMember
|
|
||||||
.mockImplementation(function(uid) {
|
|
||||||
if (uid === userA) {
|
|
||||||
return sentinel;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
timeline.getState(EventTimeline.BACKWARDS).getSentinelMember
|
|
||||||
.mockImplementation(function(uid) {
|
|
||||||
if (uid === userA) {
|
|
||||||
return oldSentinel;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
const newEv = utils.mkMembership({
|
const oldSentinel = new RoomMember(roomId, userA);
|
||||||
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
sentinel.name = "Old Alice";
|
||||||
|
sentinel.membership = "join";
|
||||||
|
|
||||||
|
mocked(timeline.getState(EventTimeline.FORWARDS)).getSentinelMember
|
||||||
|
.mockImplementation(function(uid) {
|
||||||
|
if (uid === userA) {
|
||||||
|
return sentinel;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
mocked(timeline.getState(EventTimeline.BACKWARDS)).getSentinelMember
|
||||||
|
.mockImplementation(function(uid) {
|
||||||
|
if (uid === userA) {
|
||||||
|
return oldSentinel;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
const newEv = utils.mkMembership({
|
||||||
|
room: roomId, mship: "invite", user: userB, skey: userA, event: true,
|
||||||
|
});
|
||||||
|
const oldEv = utils.mkMembership({
|
||||||
|
room: roomId, mship: "ban", user: userB, skey: userA, event: true,
|
||||||
|
});
|
||||||
|
timeline.addEvent(newEv, { toStartOfTimeline: false });
|
||||||
|
expect(newEv.target).toEqual(sentinel);
|
||||||
|
timeline.addEvent(oldEv, { toStartOfTimeline: true });
|
||||||
|
expect(oldEv.target).toEqual(oldSentinel);
|
||||||
});
|
});
|
||||||
const oldEv = utils.mkMembership({
|
|
||||||
room: roomId, mship: "ban", user: userB, skey: userA, event: true,
|
|
||||||
});
|
|
||||||
timeline.addEvent(newEv, { toStartOfTimeline: false });
|
|
||||||
expect(newEv.target).toEqual(sentinel);
|
|
||||||
timeline.addEvent(oldEv, { toStartOfTimeline: true });
|
|
||||||
expect(oldEv.target).toEqual(oldSentinel);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should call setStateEvents on the right RoomState with the right " +
|
it("should call setStateEvents on the right RoomState with the right " +
|
||||||
"forwardLooking value for new events", function() {
|
"forwardLooking value for new events", function() {
|
||||||
@ -310,7 +312,11 @@ describe("EventTimeline", function() {
|
|||||||
|
|
||||||
it("Make sure legacy overload passing options directly as parameters still works", () => {
|
it("Make sure legacy overload passing options directly as parameters still works", () => {
|
||||||
expect(() => timeline.addEvent(events[0], { toStartOfTimeline: true })).not.toThrow();
|
expect(() => timeline.addEvent(events[0], { toStartOfTimeline: true })).not.toThrow();
|
||||||
expect(() => timeline.addEvent(events[0], { stateContext: new RoomState() })).not.toThrow();
|
// @ts-ignore stateContext is not a valid param
|
||||||
|
expect(() => timeline.addEvent(events[0], { stateContext: new RoomState(roomId) })).not.toThrow();
|
||||||
|
expect(() => timeline.addEvent(events[0],
|
||||||
|
{ toStartOfTimeline: false, roomState: new RoomState(roomId) },
|
||||||
|
)).not.toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -364,14 +370,14 @@ describe("EventTimeline", function() {
|
|||||||
// - removing the last event got baseIndex into such a state that
|
// - removing the last event got baseIndex into such a state that
|
||||||
// further addEvent(ev, false) calls made the index increase.
|
// further addEvent(ev, false) calls made the index increase.
|
||||||
it("should not make baseIndex assplode when removing the last event",
|
it("should not make baseIndex assplode when removing the last event",
|
||||||
function() {
|
function() {
|
||||||
timeline.addEvent(events[0], { toStartOfTimeline: true });
|
timeline.addEvent(events[0], { toStartOfTimeline: true });
|
||||||
timeline.removeEvent(events[0].getId());
|
timeline.removeEvent(events[0].getId());
|
||||||
const initialIndex = timeline.getBaseIndex();
|
const initialIndex = timeline.getBaseIndex();
|
||||||
timeline.addEvent(events[1], { toStartOfTimeline: false });
|
timeline.addEvent(events[1], { toStartOfTimeline: false });
|
||||||
timeline.addEvent(events[2], { toStartOfTimeline: false });
|
timeline.addEvent(events[2], { toStartOfTimeline: false });
|
||||||
expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
expect(timeline.getBaseIndex()).toEqual(initialIndex);
|
||||||
expect(timeline.getEvents().length).toEqual(2);
|
expect(timeline.getEvents().length).toEqual(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
Reference in New Issue
Block a user