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

Commit 1c6d1bf

Browse files
authored
Merge branch 'develop' into module_auth_fix_dispatch
2 parents 71c1f66 + e5291c1 commit 1c6d1bf

File tree

60 files changed

+516
-538
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+516
-538
lines changed

.eslintrc.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,17 +165,43 @@ module.exports = {
165165
},
166166
{
167167
files: ["test/**/*.{ts,tsx}", "cypress/**/*.ts"],
168+
extends: ["plugin:matrix-org/jest"],
168169
rules: {
169170
// We don't need super strict typing in test utilities
170171
"@typescript-eslint/explicit-function-return-type": "off",
171172
"@typescript-eslint/explicit-member-accessibility": "off",
173+
174+
// Jest/Cypress specific
175+
176+
// Disabled tests are a reality for now but as soon as all of the xits are
177+
// eliminated, we should enforce this.
178+
"jest/no-disabled-tests": "off",
179+
// TODO: There are many tests with invalid expects that should be fixed,
180+
// https://github.com/vector-im/element-web/issues/24709
181+
"jest/valid-expect": "off",
182+
// TODO: There are many cases to refactor away,
183+
// https://github.com/vector-im/element-web/issues/24710
184+
"jest/no-conditional-expect": "off",
185+
// Also treat "oldBackendOnly" as a test function.
186+
// Used in some crypto tests.
187+
"jest/no-standalone-expect": [
188+
"error",
189+
{
190+
additionalTestBlockFunctions: ["beforeAll", "beforeEach", "oldBackendOnly"],
191+
},
192+
],
172193
},
173194
},
174195
{
175196
files: ["cypress/**/*.ts"],
176197
parserOptions: {
177198
project: ["./cypress/tsconfig.json"],
178199
},
200+
rules: {
201+
// Cypress "promises" work differently - disable some related rules
202+
"jest/valid-expect-in-promise": "off",
203+
"jest/no-done-callback": "off",
204+
},
179205
},
180206
],
181207
settings: {

cypress/e2e/sliding-sync/sliding-sync.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ describe("Sliding Sync", () => {
356356
});
357357

358358
// Regression test for https://github.com/vector-im/element-web/issues/21462
359-
it("should not cancel replies when permalinks are clicked ", () => {
359+
it("should not cancel replies when permalinks are clicked", () => {
360360
cy.get<string>("@roomId").then((roomId) => {
361361
// we require a first message as you cannot click the permalink text with the avatar in the way
362362
return cy

cypress/e2e/spotlight/spotlight.spec.ts

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Timeoutable = Cypress.Timeoutable;
2424
import Withinable = Cypress.Withinable;
2525
import Shadow = Cypress.Shadow;
2626

27-
export enum Filter {
27+
enum Filter {
2828
People = "people",
2929
PublicRooms = "public_rooms",
3030
}
@@ -297,27 +297,28 @@ describe("Spotlight", () => {
297297

298298
// TODO: We currently can’t test finding rooms on other homeservers/other protocols
299299
// We obviously don’t have federation or bridges in cypress tests
300-
/*
301-
const room3Name = "Matrix HQ";
302-
const room3Id = "#matrix:matrix.org";
303-
304-
it("should find unknown public rooms on other homeservers", () => {
305-
cy.openSpotlightDialog().within(() => {
306-
cy.spotlightFilter(Filter.PublicRooms);
307-
cy.spotlightSearch().clear().type(room3Name);
308-
cy.get("[aria-haspopup=true][role=button]").click();
309-
}).then(() => {
310-
cy.contains(".mx_GenericDropdownMenu_Option--header", "matrix.org")
311-
.next("[role=menuitemradio]")
312-
.click();
313-
cy.wait(3_600_000);
314-
}).then(() => cy.spotlightDialog().within(() => {
315-
cy.spotlightResults().should("have.length", 1);
316-
cy.spotlightResults().eq(0).should("contain", room3Name);
317-
cy.spotlightResults().eq(0).should("contain", room3Id);
318-
}));
300+
it.skip("should find unknown public rooms on other homeservers", () => {
301+
cy.openSpotlightDialog()
302+
.within(() => {
303+
cy.spotlightFilter(Filter.PublicRooms);
304+
cy.spotlightSearch().clear().type(room3Name);
305+
cy.get("[aria-haspopup=true][role=button]").click();
306+
})
307+
.then(() => {
308+
cy.contains(".mx_GenericDropdownMenu_Option--header", "matrix.org")
309+
.next("[role=menuitemradio]")
310+
.click();
311+
cy.wait(3_600_000);
312+
})
313+
.then(() =>
314+
cy.spotlightDialog().within(() => {
315+
cy.spotlightResults().should("have.length", 1);
316+
cy.spotlightResults().eq(0).should("contain", room3Name);
317+
cy.spotlightResults().eq(0).should("contain", room3Id);
318+
}),
319+
);
319320
});
320-
*/
321+
321322
it("should find known people", () => {
322323
cy.openSpotlightDialog()
323324
.within(() => {

cypress/e2e/timeline/timeline.spec.ts

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,11 @@ describe("Timeline", () => {
238238
});
239239
});
240240

241-
it("should click top left of view source event toggle", () => {
241+
it("should click view source event toggle", () => {
242+
// This test checks:
243+
// 1. clickability of top left of view source event toggle
244+
// 2. clickability of view source toggle on IRC layout
245+
242246
sendEvent(roomId);
243247
cy.visit("/#/room/" + roomId);
244248
cy.setSettingValue("showHiddenEventsInTimeline", null, SettingLevel.DEVICE, true);
@@ -254,16 +258,52 @@ describe("Timeline", () => {
254258
});
255259
cy.contains(".mx_RoomView_body .mx_EventTile[data-scroll-tokens]", "MessageEdit").should("exist");
256260

261+
// 1. clickability of top left of view source event toggle
262+
257263
// Click top left of the event toggle, which should not be covered by MessageActionBar's safe area
258-
cy.get(".mx_EventTile:not(:first-child) .mx_ViewSourceEvent")
264+
cy.get(".mx_EventTile_last[data-layout=group] .mx_ViewSourceEvent")
265+
.should("exist")
266+
.realHover()
267+
.within(() => {
268+
cy.get(".mx_ViewSourceEvent_toggle").click("topLeft", { force: false });
269+
});
270+
271+
// Make sure the expand toggle worked
272+
cy.get(".mx_EventTile .mx_ViewSourceEvent_expanded").should("be.visible");
273+
274+
// Click again to collapse the source
275+
cy.get(".mx_EventTile_last[data-layout=group] .mx_ViewSourceEvent")
276+
.should("exist")
277+
.realHover()
278+
.within(() => {
279+
cy.get(".mx_ViewSourceEvent_toggle").click("topLeft", { force: false });
280+
});
281+
cy.get(".mx_EventTile .mx_ViewSourceEvent_expanded").should("not.exist");
282+
283+
// 2. clickability of view source toggle on IRC layout
284+
285+
// Enable IRC layout
286+
cy.setSettingValue("layout", null, SettingLevel.DEVICE, Layout.IRC);
287+
288+
// Exclude timestamp from snapshot
289+
const percyCSS = ".mx_MessageTimestamp { visibility: hidden !important; }";
290+
291+
// Hover the view source toggle on IRC layout
292+
cy.get(".mx_GenericEventListSummary[data-layout=irc] .mx_EventTile .mx_ViewSourceEvent")
293+
.should("exist")
294+
.realHover()
295+
.percySnapshotElement("Hovered hidden event line on IRC layout", { percyCSS });
296+
297+
// Click view source event toggle
298+
cy.get(".mx_GenericEventListSummary[data-layout=irc] .mx_EventTile .mx_ViewSourceEvent")
259299
.should("exist")
260300
.realHover()
261301
.within(() => {
262302
cy.get(".mx_ViewSourceEvent_toggle").click("topLeft", { force: false });
263303
});
264304

265305
// Make sure the expand toggle worked
266-
cy.get(".mx_EventTile .mx_ViewSourceEvent_expanded .mx_ViewSourceEvent_toggle").should("be.visible");
306+
cy.get(".mx_EventTile[data-layout=irc] .mx_ViewSourceEvent_expanded").should("be.visible");
267307
});
268308

269309
it("should click 'collapse' link button on the first hovered info event line on bubble layout", () => {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@
194194
"eslint-config-prettier": "^8.5.0",
195195
"eslint-plugin-deprecate": "^0.7.0",
196196
"eslint-plugin-import": "^2.25.4",
197+
"eslint-plugin-jest": "^27.2.1",
197198
"eslint-plugin-jsx-a11y": "^6.5.1",
198199
"eslint-plugin-matrix-org": "1.0.0",
199200
"eslint-plugin-react": "^7.28.0",

res/css/views/rooms/_IRCLayout.pcss

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,17 @@ $irc-line-height: $font-18px;
130130
.mx_TextualEvent,
131131
.mx_ViewSourceEvent,
132132
.mx_MTextBody {
133-
display: inline-block;
134133
/* add a 1px padding top and bottom because our larger
135134
emoji font otherwise gets cropped by anti-zalgo */
136135
padding: var(--EventTile_irc_line-padding-block) 0;
137136
}
138137

138+
.mx_EventTile_e2eIcon,
139+
.mx_TextualEvent,
140+
.mx_MTextBody {
141+
display: inline-block;
142+
}
143+
139144
.mx_ReplyTile {
140145
.mx_MTextBody {
141146
display: -webkit-box; /* Enable -webkit-line-clamp */

src/components/views/rooms/MemberList.tsx

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ interface IState {
6868
}
6969

7070
export default class MemberList extends React.Component<IProps, IState> {
71-
// XXX: exported for tests
72-
public showPresence = true;
71+
private readonly showPresence: boolean;
7372
private mounted = false;
7473

7574
public static contextType = SDKContext;
@@ -260,32 +259,6 @@ export default class MemberList extends React.Component<IProps, IState> {
260259
});
261260
};
262261

263-
/**
264-
* SHOULD ONLY BE USED BY TESTS
265-
*/
266-
public memberString(member: RoomMember): string {
267-
if (!member) {
268-
return "(null)";
269-
} else {
270-
const u = member.user;
271-
return (
272-
"(" +
273-
member.name +
274-
", " +
275-
member.powerLevel +
276-
", " +
277-
(u ? u.lastActiveAgo : "<null>") +
278-
", " +
279-
(u ? u.getLastActiveTs() : "<null>") +
280-
", " +
281-
(u ? u.currentlyActive : "<null>") +
282-
", " +
283-
(u ? u.presence : "<null>") +
284-
")"
285-
);
286-
}
287-
}
288-
289262
public componentDidUpdate(prevProps: Readonly<IProps>, prevState: Readonly<IState>, snapshot?: any): void {
290263
if (prevProps.searchQuery !== this.props.searchQuery) {
291264
this.updateListNow(false);

test/ContentMessages-test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,6 @@ describe("uploadFile", () => {
327327
const prom = uploadFile(client, "!roomId:server", file);
328328
mocked(client.uploadContent).mock.calls[0][1]!.abortController!.abort();
329329
deferred.resolve({ content_uri: "mxc://foo/bar" });
330-
await expect(prom).rejects.toThrowError(UploadCanceledError);
330+
await expect(prom).rejects.toThrow(UploadCanceledError);
331331
});
332332
});

test/DecryptionFailureTracker-test.js

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function createFailedDecryptionEvent() {
3838
}
3939

4040
describe("DecryptionFailureTracker", function () {
41-
it("tracks a failed decryption for a visible event", function (done) {
41+
it("tracks a failed decryption for a visible event", function () {
4242
const failedDecryptionEvent = createFailedDecryptionEvent();
4343

4444
let count = 0;
@@ -59,11 +59,9 @@ describe("DecryptionFailureTracker", function () {
5959
tracker.trackFailures();
6060

6161
expect(count).not.toBe(0, "should track a failure for an event that failed decryption");
62-
63-
done();
6462
});
6563

66-
it("tracks a failed decryption with expected raw error for a visible event", function (done) {
64+
it("tracks a failed decryption with expected raw error for a visible event", function () {
6765
const failedDecryptionEvent = createFailedDecryptionEvent();
6866

6967
let count = 0;
@@ -89,11 +87,9 @@ describe("DecryptionFailureTracker", function () {
8987

9088
expect(count).not.toBe(0, "should track a failure for an event that failed decryption");
9189
expect(reportedRawCode).toBe("INBOUND_SESSION_MISMATCH_ROOM_ID", "Should add the rawCode to the event context");
92-
93-
done();
9490
});
9591

96-
it("tracks a failed decryption for an event that becomes visible later", function (done) {
92+
it("tracks a failed decryption for an event that becomes visible later", function () {
9793
const failedDecryptionEvent = createFailedDecryptionEvent();
9894

9995
let count = 0;
@@ -114,11 +110,9 @@ describe("DecryptionFailureTracker", function () {
114110
tracker.trackFailures();
115111

116112
expect(count).not.toBe(0, "should track a failure for an event that failed decryption");
117-
118-
done();
119113
});
120114

121-
it("does not track a failed decryption for an event that never becomes visible", function (done) {
115+
it("does not track a failed decryption for an event that never becomes visible", function () {
122116
const failedDecryptionEvent = createFailedDecryptionEvent();
123117

124118
let count = 0;
@@ -137,11 +131,9 @@ describe("DecryptionFailureTracker", function () {
137131
tracker.trackFailures();
138132

139133
expect(count).toBe(0, "should not track a failure for an event that never became visible");
140-
141-
done();
142134
});
143135

144-
it("does not track a failed decryption where the event is subsequently successfully decrypted", (done) => {
136+
it("does not track a failed decryption where the event is subsequently successfully decrypted", () => {
145137
const decryptedEvent = createFailedDecryptionEvent();
146138
const tracker = new DecryptionFailureTracker(
147139
(total) => {
@@ -164,13 +156,12 @@ describe("DecryptionFailureTracker", function () {
164156

165157
// Immediately track the newest failures
166158
tracker.trackFailures();
167-
done();
168159
});
169160

170161
it(
171162
"does not track a failed decryption where the event is subsequently successfully decrypted " +
172163
"and later becomes visible",
173-
(done) => {
164+
() => {
174165
const decryptedEvent = createFailedDecryptionEvent();
175166
const tracker = new DecryptionFailureTracker(
176167
(total) => {
@@ -193,11 +184,10 @@ describe("DecryptionFailureTracker", function () {
193184

194185
// Immediately track the newest failures
195186
tracker.trackFailures();
196-
done();
197187
},
198188
);
199189

200-
it("only tracks a single failure per event, despite multiple failed decryptions for multiple events", (done) => {
190+
it("only tracks a single failure per event, despite multiple failed decryptions for multiple events", () => {
201191
const decryptedEvent = createFailedDecryptionEvent();
202192
const decryptedEvent2 = createFailedDecryptionEvent();
203193

@@ -231,11 +221,9 @@ describe("DecryptionFailureTracker", function () {
231221
tracker.trackFailures();
232222

233223
expect(count).toBe(2, count + " failures tracked, should only track a single failure per event");
234-
235-
done();
236224
});
237225

238-
it("should not track a failure for an event that was tracked previously", (done) => {
226+
it("should not track a failure for an event that was tracked previously", () => {
239227
const decryptedEvent = createFailedDecryptionEvent();
240228

241229
let count = 0;
@@ -261,11 +249,9 @@ describe("DecryptionFailureTracker", function () {
261249
tracker.trackFailures();
262250

263251
expect(count).toBe(1, "should only track a single failure per event");
264-
265-
done();
266252
});
267253

268-
xit("should not track a failure for an event that was tracked in a previous session", (done) => {
254+
it.skip("should not track a failure for an event that was tracked in a previous session", () => {
269255
// This test uses localStorage, clear it beforehand
270256
localStorage.clear();
271257

@@ -304,8 +290,6 @@ describe("DecryptionFailureTracker", function () {
304290
secondTracker.trackFailures();
305291

306292
expect(count).toBe(1, count + " failures tracked, should only track a single failure per event");
307-
308-
done();
309293
});
310294

311295
it("should count different error codes separately for multiple failures with different error codes", () => {

test/Notifier-test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ describe("Notifier", () => {
302302
);
303303
});
304304

305-
it("should display the expected notification for a broadcast chunk with sequence = 1", () => {
305+
it("should display the expected notification for a broadcast chunk with sequence = 2", () => {
306306
const audioEvent = mkAudioEvent({ sequence: 2 });
307307
Notifier.displayPopupNotification(audioEvent, testRoom);
308308
expect(MockPlatform.displayNotification).not.toHaveBeenCalled();

0 commit comments

Comments
 (0)