Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 5b520e8

Browse files
duxovnit3chguy
andauthored
Start adding Cypress tests for crypto (#8577)
Co-authored-by: Michael Telatynski <[email protected]>
1 parent f742e3a commit 5b520e8

File tree

4 files changed

+158
-3
lines changed

4 files changed

+158
-3
lines changed

cypress/global.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ limitations under the License.
1616

1717
import "matrix-js-sdk/src/@types/global";
1818
import type { MatrixClient, ClientEvent } from "matrix-js-sdk/src/client";
19+
import type { MatrixScheduler, MemoryCryptoStore, MemoryStore, RoomStateEvent } from "matrix-js-sdk/src/matrix";
1920
import type { RoomMemberEvent } from "matrix-js-sdk/src/models/room-member";
21+
import type { WebStorageSessionStore } from "matrix-js-sdk/src/store/session/webstorage";
2022
import type { MatrixDispatcher } from "../src/dispatcher/dispatcher";
2123
import type PerformanceMonitor from "../src/performance";
2224

@@ -35,6 +37,11 @@ declare global {
3537
MatrixClient: typeof MatrixClient;
3638
ClientEvent: typeof ClientEvent;
3739
RoomMemberEvent: typeof RoomMemberEvent;
40+
RoomStateEvent: typeof RoomStateEvent;
41+
MatrixScheduler: typeof MatrixScheduler;
42+
MemoryStore: typeof MemoryStore;
43+
MemoryCryptoStore: typeof MemoryCryptoStore;
44+
WebStorageSessionStore: typeof WebStorageSessionStore;
3845
};
3946
}
4047
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
/// <reference types="cypress" />
18+
19+
import type { MatrixClient } from "matrix-js-sdk/src/matrix";
20+
import { SynapseInstance } from "../../plugins/synapsedocker";
21+
22+
function waitForEncryption(cli: MatrixClient, roomId: string, win: Cypress.AUTWindow, resolve: () => void) {
23+
cli.crypto.cryptoStore.getEndToEndRooms(null, (result) => {
24+
if (result[roomId]) {
25+
resolve();
26+
} else {
27+
cli.once(win.matrixcs.RoomStateEvent.Update, () => waitForEncryption(cli, roomId, win, resolve));
28+
}
29+
});
30+
}
31+
32+
describe("Cryptography", () => {
33+
beforeEach(() => {
34+
cy.startSynapse("default").as('synapse').then(
35+
synapse => cy.initTestUser(synapse, "Alice"),
36+
);
37+
});
38+
39+
afterEach(() => {
40+
cy.get<SynapseInstance>('@synapse').then(synapse => cy.stopSynapse(synapse));
41+
});
42+
43+
it("should receive and decrypt encrypted messages", () => {
44+
cy.get<SynapseInstance>('@synapse').then(synapse => cy.getBot(synapse, "Beatrice").as('bot'));
45+
46+
cy.createRoom({
47+
initial_state: [
48+
{
49+
type: "m.room.encryption",
50+
state_key: '',
51+
content: {
52+
algorithm: "m.megolm.v1.aes-sha2",
53+
},
54+
},
55+
],
56+
}).as('roomId');
57+
58+
cy.all([
59+
cy.get<MatrixClient>('@bot'),
60+
cy.get<string>('@roomId'),
61+
cy.window(),
62+
]).then(([bot, roomId, win]) => {
63+
cy.inviteUser(roomId, bot.getUserId());
64+
cy.visit("/#/room/" + roomId);
65+
cy.wrap(
66+
new Promise<void>(resolve =>
67+
waitForEncryption(bot, roomId, win, resolve),
68+
).then(() => bot.sendMessage(roomId, {
69+
body: "Top secret message",
70+
msgtype: "m.text",
71+
})),
72+
);
73+
});
74+
75+
cy.get(".mx_RoomView_body .mx_cryptoEvent").should("contain", "Encryption enabled");
76+
77+
cy.get(".mx_EventTile_body")
78+
.contains("Top secret message")
79+
.closest(".mx_EventTile_line")
80+
.should("not.have.descendants", ".mx_EventTile_e2eIcon_warning");
81+
});
82+
});

cypress/support/bot.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import request from "browser-request";
2020

2121
import type { MatrixClient } from "matrix-js-sdk/src/client";
2222
import { SynapseInstance } from "../plugins/synapsedocker";
23+
import { MockStorage } from "./storage";
2324
import Chainable = Cypress.Chainable;
2425

2526
declare global {
@@ -47,6 +48,10 @@ Cypress.Commands.add("getBot", (synapse: SynapseInstance, displayName?: string):
4748
deviceId: credentials.deviceId,
4849
accessToken: credentials.accessToken,
4950
request,
51+
store: new win.matrixcs.MemoryStore(),
52+
scheduler: new win.matrixcs.MatrixScheduler(),
53+
cryptoStore: new win.matrixcs.MemoryCryptoStore(),
54+
sessionStore: new win.matrixcs.WebStorageSessionStore(new MockStorage()),
5055
});
5156

5257
cli.on(win.matrixcs.RoomMemberEvent.Membership, (event, member) => {
@@ -55,9 +60,12 @@ Cypress.Commands.add("getBot", (synapse: SynapseInstance, displayName?: string):
5560
}
5661
});
5762

58-
cli.startClient();
59-
60-
return cli;
63+
return cy.wrap(
64+
cli.initCrypto()
65+
.then(() => cli.setGlobalErrorOnUnknownDevices(false))
66+
.then(() => cli.startClient())
67+
.then(() => cli),
68+
);
6169
});
6270
});
6371
});

cypress/support/storage.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
export class MockStorage implements Storage {
18+
private data: Record<string, string> = {};
19+
private keys: string[] = [];
20+
public length = 0;
21+
22+
constructor() {}
23+
24+
public setItem(k: string, v: string) {
25+
this.data[k] = v;
26+
this.recalc();
27+
}
28+
29+
public getItem(k: string): string | null {
30+
return this.data[k] || null;
31+
}
32+
33+
public removeItem(k: string) {
34+
delete this.data[k];
35+
this.recalc();
36+
}
37+
38+
public clear() {
39+
this.data = {};
40+
this.recalc();
41+
}
42+
43+
public key(index: number): string {
44+
return this.keys[index];
45+
}
46+
47+
private recalc() {
48+
const keys = [];
49+
for (const k in this.data) {
50+
if (!this.data.hasOwnProperty(k)) {
51+
continue;
52+
}
53+
keys.push(k);
54+
}
55+
this.keys = keys;
56+
this.length = keys.length;
57+
}
58+
}

0 commit comments

Comments
 (0)