Skip to content

Commit 5398db2

Browse files
authored
Add ESLint Jest (matrix-org#10261)
1 parent db7748b commit 5398db2

File tree

55 files changed

+336
-351
lines changed

Some content is hidden

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

55 files changed

+336
-351
lines changed

.eslintrc.js

+26
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

+1-1
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

+22-21
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(() => {

package.json

+1
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",

test/ContentMessages-test.ts

+1-1
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

+9-25
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

+1-1
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();

test/PosthogAnalytics-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const getFakePosthog = (): PostHog =>
3535
register: jest.fn(),
3636
} as unknown as PostHog);
3737

38-
export interface ITestEvent extends IPosthogEvent {
38+
interface ITestEvent extends IPosthogEvent {
3939
eventName: "JestTestEvents";
4040
foo?: string;
4141
}

test/RoomNotifs-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ describe("RoomNotifs test", () => {
218218
expect(getUnreadNotificationCount(room, NotificationCountType.Highlight, THREAD_ID)).toBe(0);
219219
});
220220

221-
it("counts notifications type", () => {
221+
it("counts thread notifications type", () => {
222222
room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Total, 2);
223223
room.setThreadUnreadNotificationCount(THREAD_ID, NotificationCountType.Highlight, 1);
224224

test/ScalarAuthClient-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ describe("ScalarAuthClient", function () {
5858

5959
await sac.connect();
6060

61-
expect(sac.exchangeForScalarToken).toBeCalledWith(tokenObject);
61+
expect(sac.exchangeForScalarToken).toHaveBeenCalledWith(tokenObject);
6262
expect(sac.hasCredentials).toBeTruthy();
6363
// @ts-ignore private property
6464
expect(sac.scalarToken).toEqual("wokentoken");

test/SlidingSyncManager-test.ts

+20-20
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe("SlidingSyncManager", () => {
4646
mocked(slidingSync.getRoomSubscriptions).mockReturnValue(subs);
4747
mocked(slidingSync.modifyRoomSubscriptions).mockResolvedValue("yep");
4848
await manager.setRoomVisible(roomId, true);
49-
expect(slidingSync.modifyRoomSubscriptions).toBeCalledWith(new Set<string>([roomId]));
49+
expect(slidingSync.modifyRoomSubscriptions).toHaveBeenCalledWith(new Set<string>([roomId]));
5050
});
5151
it("adds a custom subscription for a lazy-loadable room", async () => {
5252
const roomId = "!lazy:id";
@@ -72,9 +72,9 @@ describe("SlidingSyncManager", () => {
7272
mocked(slidingSync.getRoomSubscriptions).mockReturnValue(subs);
7373
mocked(slidingSync.modifyRoomSubscriptions).mockResolvedValue("yep");
7474
await manager.setRoomVisible(roomId, true);
75-
expect(slidingSync.modifyRoomSubscriptions).toBeCalledWith(new Set<string>([roomId]));
75+
expect(slidingSync.modifyRoomSubscriptions).toHaveBeenCalledWith(new Set<string>([roomId]));
7676
// we aren't prescriptive about what the sub name is.
77-
expect(slidingSync.useCustomSubscription).toBeCalledWith(roomId, expect.anything());
77+
expect(slidingSync.useCustomSubscription).toHaveBeenCalledWith(roomId, expect.anything());
7878
});
7979
});
8080

@@ -86,7 +86,7 @@ describe("SlidingSyncManager", () => {
8686
await manager.ensureListRegistered(listKey, {
8787
sort: ["by_recency"],
8888
});
89-
expect(slidingSync.setList).toBeCalledWith(
89+
expect(slidingSync.setList).toHaveBeenCalledWith(
9090
listKey,
9191
expect.objectContaining({
9292
sort: ["by_recency"],
@@ -103,7 +103,7 @@ describe("SlidingSyncManager", () => {
103103
await manager.ensureListRegistered(listKey, {
104104
sort: ["by_recency"],
105105
});
106-
expect(slidingSync.setList).toBeCalledWith(
106+
expect(slidingSync.setList).toHaveBeenCalledWith(
107107
listKey,
108108
expect.objectContaining({
109109
sort: ["by_recency"],
@@ -121,8 +121,8 @@ describe("SlidingSyncManager", () => {
121121
await manager.ensureListRegistered(listKey, {
122122
ranges: [[0, 52]],
123123
});
124-
expect(slidingSync.setList).not.toBeCalled();
125-
expect(slidingSync.setListRanges).toBeCalledWith(listKey, [[0, 52]]);
124+
expect(slidingSync.setList).not.toHaveBeenCalled();
125+
expect(slidingSync.setListRanges).toHaveBeenCalledWith(listKey, [[0, 52]]);
126126
});
127127

128128
it("no-ops for idential changes", async () => {
@@ -136,8 +136,8 @@ describe("SlidingSyncManager", () => {
136136
ranges: [[0, 42]],
137137
sort: ["by_recency"],
138138
});
139-
expect(slidingSync.setList).not.toBeCalled();
140-
expect(slidingSync.setListRanges).not.toBeCalled();
139+
expect(slidingSync.setList).not.toHaveBeenCalled();
140+
expect(slidingSync.setListRanges).not.toHaveBeenCalled();
141141
});
142142
});
143143

@@ -163,20 +163,20 @@ describe("SlidingSyncManager", () => {
163163
[50, 59],
164164
[60, 69],
165165
];
166-
expect(slidingSync.getListData).toBeCalledTimes(wantWindows.length);
167-
expect(slidingSync.setList).toBeCalledTimes(1);
168-
expect(slidingSync.setListRanges).toBeCalledTimes(wantWindows.length - 1);
166+
expect(slidingSync.getListData).toHaveBeenCalledTimes(wantWindows.length);
167+
expect(slidingSync.setList).toHaveBeenCalledTimes(1);
168+
expect(slidingSync.setListRanges).toHaveBeenCalledTimes(wantWindows.length - 1);
169169
wantWindows.forEach((range, i) => {
170170
if (i === 0) {
171-
expect(slidingSync.setList).toBeCalledWith(
171+
expect(slidingSync.setList).toHaveBeenCalledWith(
172172
SlidingSyncManager.ListSearch,
173173
expect.objectContaining({
174174
ranges: [[0, batchSize - 1], range],
175175
}),
176176
);
177177
return;
178178
}
179-
expect(slidingSync.setListRanges).toBeCalledWith(SlidingSyncManager.ListSearch, [
179+
expect(slidingSync.setListRanges).toHaveBeenCalledWith(SlidingSyncManager.ListSearch, [
180180
[0, batchSize - 1],
181181
range,
182182
]);
@@ -193,9 +193,9 @@ describe("SlidingSyncManager", () => {
193193
};
194194
});
195195
await manager.startSpidering(batchSize, gapMs);
196-
expect(slidingSync.getListData).toBeCalledTimes(1);
197-
expect(slidingSync.setList).toBeCalledTimes(1);
198-
expect(slidingSync.setList).toBeCalledWith(
196+
expect(slidingSync.getListData).toHaveBeenCalledTimes(1);
197+
expect(slidingSync.setList).toHaveBeenCalledTimes(1);
198+
expect(slidingSync.setList).toHaveBeenCalledWith(
199199
SlidingSyncManager.ListSearch,
200200
expect.objectContaining({
201201
ranges: [
@@ -216,9 +216,9 @@ describe("SlidingSyncManager", () => {
216216
};
217217
});
218218
await manager.startSpidering(batchSize, gapMs);
219-
expect(slidingSync.getListData).toBeCalledTimes(1);
220-
expect(slidingSync.setList).toBeCalledTimes(1);
221-
expect(slidingSync.setList).toBeCalledWith(
219+
expect(slidingSync.getListData).toHaveBeenCalledTimes(1);
220+
expect(slidingSync.setList).toHaveBeenCalledTimes(1);
221+
expect(slidingSync.setList).toHaveBeenCalledWith(
222222
SlidingSyncManager.ListSearch,
223223
expect.objectContaining({
224224
ranges: [

0 commit comments

Comments
 (0)