Comply with noImplicitAny (#9940)

* Stash noImplicitAny work

* Stash

* Fix imports

* Iterate

* Fix tests

* Delint

* Fix tests
This commit is contained in:
Michael Telatynski 2023-02-13 11:39:16 +00:00 committed by GitHub
parent ac7f69216e
commit 61a63e47f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
359 changed files with 1621 additions and 1353 deletions

View file

@ -266,7 +266,7 @@ describe("Notifier", () => {
});
});
describe("_displayPopupNotification", () => {
describe("displayPopupNotification", () => {
const testCases: { event: IContent | undefined; count: number }[] = [
{ event: { is_silenced: true }, count: 0 },
{ event: { is_silenced: false }, count: 1 },
@ -274,13 +274,13 @@ describe("Notifier", () => {
];
it.each(testCases)("does not dispatch when notifications are silenced", ({ event, count }) => {
mockClient.setAccountData(accountDataEventKey, event!);
Notifier._displayPopupNotification(testEvent, testRoom);
Notifier.displayPopupNotification(testEvent, testRoom);
expect(MockPlatform.displayNotification).toHaveBeenCalledTimes(count);
});
it("should display a notification for a voice message", () => {
const audioEvent = mkAudioEvent();
Notifier._displayPopupNotification(audioEvent, testRoom);
Notifier.displayPopupNotification(audioEvent, testRoom);
expect(MockPlatform.displayNotification).toHaveBeenCalledWith(
"@user:example.com (!room1:server)",
"@user:example.com: test audio message",
@ -292,7 +292,7 @@ describe("Notifier", () => {
it("should display the expected notification for a broadcast chunk with sequence = 1", () => {
const audioEvent = mkAudioEvent({ sequence: 1 });
Notifier._displayPopupNotification(audioEvent, testRoom);
Notifier.displayPopupNotification(audioEvent, testRoom);
expect(MockPlatform.displayNotification).toHaveBeenCalledWith(
"@user:example.com (!room1:server)",
"@user:example.com started a voice broadcast",
@ -304,7 +304,7 @@ describe("Notifier", () => {
it("should display the expected notification for a broadcast chunk with sequence = 1", () => {
const audioEvent = mkAudioEvent({ sequence: 2 });
Notifier._displayPopupNotification(audioEvent, testRoom);
Notifier.displayPopupNotification(audioEvent, testRoom);
expect(MockPlatform.displayNotification).not.toHaveBeenCalled();
});
});
@ -330,7 +330,7 @@ describe("Notifier", () => {
Notifier.getSoundForRoom = jest.fn();
mockClient.setAccountData(accountDataEventKey, event!);
Notifier._playAudioNotification(testEvent, testRoom);
Notifier.playAudioNotification(testEvent, testRoom);
expect(Notifier.getSoundForRoom).toHaveBeenCalledTimes(count);
});
});
@ -445,7 +445,7 @@ describe("Notifier", () => {
});
});
describe("_evaluateEvent", () => {
describe("evaluateEvent", () => {
beforeEach(() => {
jest.spyOn(SdkContextClass.instance.roomViewStore, "getRoomId").mockReturnValue(testRoom.roomId);
@ -453,7 +453,7 @@ describe("Notifier", () => {
jest.spyOn(Modal, "hasDialogs").mockReturnValue(false);
jest.spyOn(Notifier, "_displayPopupNotification").mockReset();
jest.spyOn(Notifier, "displayPopupNotification").mockReset();
jest.spyOn(Notifier, "isEnabled").mockReturnValue(true);
mockClient.getPushActionsForEvent.mockReturnValue({
@ -465,9 +465,9 @@ describe("Notifier", () => {
});
it("should show a pop-up", () => {
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
Notifier._evaluateEvent(testEvent);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(0);
Notifier.evaluateEvent(testEvent);
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(0);
const eventFromOtherRoom = mkEvent({
event: true,
@ -477,8 +477,8 @@ describe("Notifier", () => {
content: {},
});
Notifier._evaluateEvent(eventFromOtherRoom);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
Notifier.evaluateEvent(eventFromOtherRoom);
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(1);
});
it("should a pop-up for thread event", async () => {
@ -489,13 +489,13 @@ describe("Notifier", () => {
participantUserIds: ["@bob:example.org"],
});
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(0);
Notifier._evaluateEvent(rootEvent);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(0);
Notifier.evaluateEvent(rootEvent);
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(0);
Notifier._evaluateEvent(events[1]);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
Notifier.evaluateEvent(events[1]);
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(1);
dis.dispatch<ThreadPayload>({
action: Action.ViewThread,
@ -504,13 +504,13 @@ describe("Notifier", () => {
await waitFor(() => expect(SdkContextClass.instance.roomViewStore.getThreadId()).toBe(rootEvent.getId()));
Notifier._evaluateEvent(events[1]);
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
Notifier.evaluateEvent(events[1]);
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(1);
});
it("should show a pop-up for an audio message", () => {
Notifier._evaluateEvent(mkAudioEvent());
expect(Notifier._displayPopupNotification).toHaveBeenCalledTimes(1);
Notifier.evaluateEvent(mkAudioEvent());
expect(Notifier.displayPopupNotification).toHaveBeenCalledTimes(1);
});
it("should not show a notification for broadcast info events in any case", () => {
@ -527,8 +527,8 @@ describe("Notifier", () => {
"ABC123",
);
Notifier._evaluateEvent(broadcastStartedEvent);
expect(Notifier._displayPopupNotification).not.toHaveBeenCalled();
Notifier.evaluateEvent(broadcastStartedEvent);
expect(Notifier.displayPopupNotification).not.toHaveBeenCalled();
});
});

View file

@ -42,7 +42,7 @@ export interface ITestEvent extends IPosthogEvent {
describe("PosthogAnalytics", () => {
let fakePosthog: PostHog;
const shaHashes = {
const shaHashes: Record<string, string> = {
"42": "73475cb40a568e8da8a045ced110137e159f890ac4da883b6b17dc651b3a8049",
"some": "a6b46dd0d1ae5e86cbc8f37e75ceeb6760230c1ca4ffbcb0c97b96dd7d9c464b",
"pii": "bd75b3e080945674c0351f75e0db33d1e90986fa07b318ea7edf776f5eef38d4",
@ -54,7 +54,7 @@ describe("PosthogAnalytics", () => {
window.crypto = {
subtle: {
digest: async (_, encodedMessage) => {
digest: async (_: AlgorithmIdentifier, encodedMessage: BufferSource) => {
const message = new TextDecoder().decode(encodedMessage);
const hexHash = shaHashes[message];
const bytes = [];

View file

@ -16,6 +16,7 @@ limitations under the License.
import { mocked } from "jest-mock";
import fetchMock from "fetch-mock-jest";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import ScalarAuthClient from "../src/ScalarAuthClient";
import { stubClient } from "./test-utils";
@ -32,7 +33,7 @@ describe("ScalarAuthClient", function () {
expires_in: 999,
};
let client;
let client: MatrixClient;
beforeEach(function () {
jest.clearAllMocks();
client = stubClient();

View file

@ -17,7 +17,7 @@ limitations under the License.
import { EventType, MatrixClient, MatrixEvent, Room, RoomMember } from "matrix-js-sdk/src/matrix";
import TestRenderer from "react-test-renderer";
import { ReactElement } from "react";
import { mocked } from "jest-mock";
import { Mocked, mocked } from "jest-mock";
import { textForEvent } from "../src/TextForEvent";
import SettingsStore from "../src/settings/SettingsStore";
@ -49,8 +49,14 @@ function mockPinnedEvent(pinnedMessageIds?: string[], prevPinnedMessageIds?: str
// Helper function that renders a component to a plain text string.
// Once snapshots are introduced in tests, this function will no longer be necessary,
// and should be replaced with snapshots.
function renderComponent(component): string {
const serializeObject = (object): string => {
function renderComponent(component: TestRenderer.ReactTestRenderer): string {
const serializeObject = (
object:
| TestRenderer.ReactTestRendererJSON
| TestRenderer.ReactTestRendererJSON[]
| TestRenderer.ReactTestRendererNode
| TestRenderer.ReactTestRendererNode[],
): string => {
if (typeof object === "string") {
return object === " " ? "" : object;
}
@ -59,7 +65,7 @@ function renderComponent(component): string {
return object[0];
}
if (object["type"] !== undefined && typeof object["children"] !== undefined) {
if (!Array.isArray(object) && object["type"] !== undefined && typeof object["children"] !== undefined) {
return serializeObject(object.children);
}
@ -168,26 +174,26 @@ describe("TextForEvent", () => {
});
describe("textForPowerEvent()", () => {
let mockClient;
let mockClient: Mocked<MatrixClient>;
const mockRoom = {
getMember: jest.fn(),
};
} as unknown as Mocked<Room>;
const userA = {
id: "@a",
userId: "@a",
name: "Alice",
rawDisplayName: "Alice",
};
} as RoomMember;
const userB = {
id: "@b",
userId: "@b",
name: "Bob (@b)",
rawDisplayName: "Bob",
};
} as RoomMember;
const userC = {
id: "@c",
userId: "@c",
name: "Bob (@c)",
rawDisplayName: "Bob",
};
} as RoomMember;
interface PowerEventProps {
usersDefault?: number;
prevDefault?: number;
@ -197,7 +203,7 @@ describe("TextForEvent", () => {
const mockPowerEvent = ({ usersDefault, prevDefault, users, prevUsers }: PowerEventProps): MatrixEvent => {
const mxEvent = new MatrixEvent({
type: EventType.RoomPowerLevels,
sender: userA.id,
sender: userA.userId,
state_key: "",
content: {
users_default: usersDefault,
@ -218,7 +224,7 @@ describe("TextForEvent", () => {
mockClient.getRoom.mockClear().mockReturnValue(mockRoom);
mockRoom.getMember
.mockClear()
.mockImplementation((userId) => [userA, userB, userC].find((u) => u.id === userId));
.mockImplementation((userId) => [userA, userB, userC].find((u) => u.userId === userId));
(SettingsStore.getValue as jest.Mock).mockReturnValue(true);
});
@ -231,10 +237,10 @@ describe("TextForEvent", () => {
it("returns falsy when no users have changed power level", () => {
const event = mockPowerEvent({
users: {
[userA.id]: 100,
[userA.userId]: 100,
},
prevUsers: {
[userA.id]: 100,
[userA.userId]: 100,
},
});
expect(textForEvent(event)).toBeFalsy();
@ -245,10 +251,10 @@ describe("TextForEvent", () => {
usersDefault: 100,
prevDefault: 50,
users: {
[userA.id]: 100,
[userA.userId]: 100,
},
prevUsers: {
[userA.id]: 50,
[userA.userId]: 50,
},
});
expect(textForEvent(event)).toBeFalsy();
@ -257,10 +263,10 @@ describe("TextForEvent", () => {
it("returns correct message for a single user with changed power level", () => {
const event = mockPowerEvent({
users: {
[userB.id]: 100,
[userB.userId]: 100,
},
prevUsers: {
[userB.id]: 50,
[userB.userId]: 50,
},
});
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Admin.";
@ -272,10 +278,10 @@ describe("TextForEvent", () => {
usersDefault: 20,
prevDefault: 101,
users: {
[userB.id]: 20,
[userB.userId]: 20,
},
prevUsers: {
[userB.id]: 50,
[userB.userId]: 50,
},
});
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Default.";
@ -285,10 +291,10 @@ describe("TextForEvent", () => {
it("returns correct message for a single user with power level changed to a custom level", () => {
const event = mockPowerEvent({
users: {
[userB.id]: -1,
[userB.userId]: -1,
},
prevUsers: {
[userB.id]: 50,
[userB.userId]: 50,
},
});
const expectedText = "Alice changed the power level of Bob (@b) from Moderator to Custom (-1).";
@ -298,12 +304,12 @@ describe("TextForEvent", () => {
it("returns correct message for a multiple power level changes", () => {
const event = mockPowerEvent({
users: {
[userB.id]: 100,
[userC.id]: 50,
[userB.userId]: 100,
[userC.userId]: 50,
},
prevUsers: {
[userB.id]: 50,
[userC.id]: 101,
[userB.userId]: 50,
[userC.userId]: 101,
},
});
const expectedText =
@ -315,7 +321,7 @@ describe("TextForEvent", () => {
describe("textForCanonicalAliasEvent()", () => {
const userA = {
id: "@a",
userId: "@a",
name: "Alice",
};
@ -328,7 +334,7 @@ describe("TextForEvent", () => {
const mockEvent = ({ alias, prevAlias, altAliases, prevAltAliases }: AliasEventProps): MatrixEvent =>
new MatrixEvent({
type: EventType.RoomCanonicalAlias,
sender: userA.id,
sender: userA.userId,
state_key: "",
content: {
alias,
@ -418,7 +424,7 @@ describe("TextForEvent", () => {
});
describe("textForPollStartEvent()", () => {
let pollEvent;
let pollEvent: MatrixEvent;
beforeEach(() => {
pollEvent = new MatrixEvent({
@ -449,7 +455,7 @@ describe("TextForEvent", () => {
});
describe("textForMessageEvent()", () => {
let messageEvent;
let messageEvent: MatrixEvent;
beforeEach(() => {
messageEvent = new MatrixEvent({

View file

@ -20,25 +20,25 @@ import EventEmitter from "events";
import UserActivity from "../src/UserActivity";
class FakeDomEventEmitter extends EventEmitter {
addEventListener(what, l) {
addEventListener(what: string, l: (...args: any[]) => void) {
this.on(what, l);
}
removeEventListener(what, l) {
removeEventListener(what: string, l: (...args: any[]) => void) {
this.removeListener(what, l);
}
}
describe("UserActivity", function () {
let fakeWindow;
let fakeDocument;
let userActivity;
let clock;
let fakeWindow: FakeDomEventEmitter;
let fakeDocument: FakeDomEventEmitter & { hasFocus?(): boolean };
let userActivity: UserActivity;
let clock: FakeTimers.InstalledClock;
beforeEach(function () {
fakeWindow = new FakeDomEventEmitter();
fakeDocument = new FakeDomEventEmitter();
userActivity = new UserActivity(fakeWindow, fakeDocument);
userActivity = new UserActivity(fakeWindow as unknown as Window, fakeDocument as unknown as Document);
userActivity.start();
clock = FakeTimers.install();
});
@ -65,7 +65,7 @@ describe("UserActivity", function () {
it("should not consider user active after activity if no window focus", function () {
fakeDocument.hasFocus = jest.fn().mockReturnValue(false);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
expect(userActivity.userActiveNow()).toBe(false);
expect(userActivity.userActiveRecently()).toBe(false);
});
@ -73,7 +73,7 @@ describe("UserActivity", function () {
it("should consider user active shortly after activity", function () {
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
expect(userActivity.userActiveNow()).toBe(true);
expect(userActivity.userActiveRecently()).toBe(true);
clock.tick(200);
@ -84,7 +84,7 @@ describe("UserActivity", function () {
it("should consider user not active after 10s of no activity", function () {
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
clock.tick(10000);
expect(userActivity.userActiveNow()).toBe(false);
});
@ -92,7 +92,7 @@ describe("UserActivity", function () {
it("should consider user passive after 10s of no activity", function () {
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
clock.tick(10000);
expect(userActivity.userActiveRecently()).toBe(true);
});
@ -100,7 +100,7 @@ describe("UserActivity", function () {
it("should not consider user passive after 10s if window un-focused", function () {
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
clock.tick(10000);
fakeDocument.hasFocus = jest.fn().mockReturnValue(false);
@ -112,7 +112,7 @@ describe("UserActivity", function () {
it("should not consider user passive after 3 mins", function () {
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
clock.tick(3 * 60 * 1000);
expect(userActivity.userActiveRecently()).toBe(false);
@ -121,11 +121,11 @@ describe("UserActivity", function () {
it("should extend timer on activity", function () {
fakeDocument.hasFocus = jest.fn().mockReturnValue(true);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
clock.tick(1 * 60 * 1000);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
clock.tick(1 * 60 * 1000);
userActivity.onUserActivity({});
userActivity.onUserActivity({ type: "event" } as Event);
clock.tick(1 * 60 * 1000);
expect(userActivity.userActiveRecently()).toBe(true);

View file

@ -20,7 +20,7 @@ import { mockPlatformPeg, unmockPlatformPeg } from "../test-utils";
const PATH_TO_KEYBOARD_SHORTCUTS = "../../src/accessibility/KeyboardShortcuts";
const PATH_TO_KEYBOARD_SHORTCUT_UTILS = "../../src/accessibility/KeyboardShortcutUtils";
const mockKeyboardShortcuts = (override) => {
const mockKeyboardShortcuts = (override: Record<string, any>) => {
jest.doMock(PATH_TO_KEYBOARD_SHORTCUTS, () => {
const original = jest.requireActual(PATH_TO_KEYBOARD_SHORTCUTS);
return {

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import * as React from "react";
import React, { HTMLAttributes } from "react";
import { render } from "@testing-library/react";
import {
@ -26,8 +26,8 @@ import {
useRovingTabIndex,
} from "../../src/accessibility/RovingTabIndex";
const Button = (props) => {
const [onFocus, isActive, ref] = useRovingTabIndex();
const Button = (props: HTMLAttributes<HTMLButtonElement>) => {
const [onFocus, isActive, ref] = useRovingTabIndex<HTMLButtonElement>();
return <button {...props} onFocus={onFocus} tabIndex={isActive ? 0 : -1} ref={ref} />;
};

View file

@ -18,7 +18,7 @@ limitations under the License.
import React from "react";
import ReactDOM from "react-dom";
import { EventEmitter } from "events";
import { Room, RoomMember } from "matrix-js-sdk/src/matrix";
import { MatrixEvent, Room, RoomMember } from "matrix-js-sdk/src/matrix";
import FakeTimers from "@sinonjs/fake-timers";
import { render } from "@testing-library/react";
import { Thread } from "matrix-js-sdk/src/models/thread";
@ -46,7 +46,7 @@ jest.mock("../../../src/utils/beacon", () => ({
const roomId = "!roomId:server_name";
describe("MessagePanel", function () {
let clock = null;
let clock: FakeTimers.InstalledClock | null = null;
const realSetTimeout = window.setTimeout;
const events = mkEvents();
const userId = "@me:here";
@ -79,7 +79,7 @@ describe("MessagePanel", function () {
callEventGroupers: new Map(),
room,
className: "cls",
events: [],
events: [] as MatrixEvent[],
};
const defaultRoomContext = {
@ -322,8 +322,8 @@ describe("MessagePanel", function () {
];
}
function isReadMarkerVisible(rmContainer) {
return rmContainer && rmContainer.children.length > 0;
function isReadMarkerVisible(rmContainer?: Element) {
return rmContainer?.children.length > 0;
}
it("should show the events", function () {

View file

@ -83,7 +83,7 @@ describe("ThreadView", () => {
return renderResult;
}
async function sendMessage(container, text): Promise<void> {
async function sendMessage(container: HTMLElement, text: string): Promise<void> {
const composer = getByTestId(container, "basicmessagecomposer");
await userEvent.click(composer);
await userEvent.keyboard(text);
@ -91,7 +91,7 @@ describe("ThreadView", () => {
await userEvent.click(sendMessageBtn);
}
function expectedMessageBody(rootEvent, message) {
function expectedMessageBody(rootEvent: MatrixEvent, message: string) {
return {
"body": message,
"m.relates_to": {

View file

@ -16,7 +16,7 @@ limitations under the License.
import React from "react";
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { mount, ReactWrapper } from "enzyme";
import { mocked } from "jest-mock";
import { logger } from "matrix-js-sdk/src/logger";
import { act } from "react-dom/test-utils";
@ -71,7 +71,7 @@ describe("<RecordingPlayback />", () => {
mocked(createAudioContext).mockReturnValue(mockAudioContext as unknown as AudioContext);
});
const getPlayButton = (component) => findByTestId(component, "play-pause-button").at(0);
const getPlayButton = (component: ReactWrapper) => findByTestId(component, "play-pause-button").at(0);
it("renders recording playback", () => {
const playback = new Playback(new ArrayBuffer(8));

View file

@ -19,7 +19,7 @@ import { mocked } from "jest-mock";
import { MatrixClient, PendingEventOrdering } from "matrix-js-sdk/src/client";
import { Room } from "matrix-js-sdk/src/models/room";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import React from "react";
import React, { ComponentProps } from "react";
import MemberAvatar from "../../../../src/components/views/avatars/MemberAvatar";
import RoomContext from "../../../../src/contexts/RoomContext";
@ -35,7 +35,7 @@ describe("MemberAvatar", () => {
let room: Room;
let member: RoomMember;
function getComponent(props) {
function getComponent(props: Partial<ComponentProps<typeof MemberAvatar>>) {
return (
<RoomContext.Provider value={getRoomContext(room, {})}>
<MemberAvatar member={null} width={35} height={35} {...props} />

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ComponentProps } from "react";
import { fireEvent, render } from "@testing-library/react";
import { act } from "react-dom/test-utils";
@ -29,7 +29,7 @@ import {
} from "../../../test-utils";
describe("<DialogSidebar />", () => {
const defaultProps = {
const defaultProps: ComponentProps<typeof DialogSidebar> = {
beacons: [],
requestClose: jest.fn(),
onBeaconClick: jest.fn(),

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ComponentProps } from "react";
import { IPassphraseInfo } from "matrix-js-sdk/src/crypto/api";
import { act, fireEvent, render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
@ -29,7 +29,7 @@ const securityKey = "EsTc WKmb ivvk jLS7 Y1NH 5CcQ mP1E JJwj B3Fd pFWm t4Dp dbyu
describe("AccessSecretStorageDialog", () => {
let mockClient: Mocked<MatrixClient>;
const defaultProps = {
const defaultProps: ComponentProps<typeof AccessSecretStorageDialog> = {
onFinished: jest.fn(),
checkPrivateKey: jest.fn(),
keyInfo: undefined,

View file

@ -16,7 +16,7 @@ limitations under the License.
import React from "react";
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { mount, ReactWrapper } from "enzyme";
import { mocked } from "jest-mock";
import { act } from "react-dom/test-utils";
import { Room } from "matrix-js-sdk/src/matrix";
@ -60,42 +60,43 @@ describe("<ExportDialog />", () => {
const getComponent = (props = {}) => mount(<ExportDialog {...defaultProps} {...props} />);
const getSizeInput = (component) => component.find('input[id="size-limit"]');
const getExportTypeInput = (component) => component.find('select[id="export-type"]');
const getAttachmentsCheckbox = (component) => component.find('input[id="include-attachments"]');
const getMessageCountInput = (component) => component.find('input[id="message-count"]');
const getExportFormatInput = (component, format) => component.find(`input[id="exportFormat-${format}"]`);
const getPrimaryButton = (component) => component.find('[data-testid="dialog-primary-button"]');
const getSecondaryButton = (component) => component.find('[data-testid="dialog-cancel-button"]');
const getSizeInput = (component: ReactWrapper) => component.find('input[id="size-limit"]');
const getExportTypeInput = (component: ReactWrapper) => component.find('select[id="export-type"]');
const getAttachmentsCheckbox = (component: ReactWrapper) => component.find('input[id="include-attachments"]');
const getMessageCountInput = (component: ReactWrapper) => component.find('input[id="message-count"]');
const getExportFormatInput = (component: ReactWrapper, format: ExportFormat) =>
component.find(`input[id="exportFormat-${format}"]`);
const getPrimaryButton = (component: ReactWrapper) => component.find('[data-testid="dialog-primary-button"]');
const getSecondaryButton = (component: ReactWrapper) => component.find('[data-testid="dialog-cancel-button"]');
const submitForm = async (component) =>
const submitForm = async (component: ReactWrapper) =>
act(async () => {
getPrimaryButton(component).simulate("click");
component.setProps({});
});
const selectExportFormat = async (component, format: ExportFormat) =>
const selectExportFormat = async (component: ReactWrapper, format: ExportFormat) =>
act(async () => {
getExportFormatInput(component, format).simulate("change");
component.setProps({});
});
const selectExportType = async (component, type: ExportType) =>
const selectExportType = async (component: ReactWrapper, type: ExportType) =>
act(async () => {
getExportTypeInput(component).simulate("change", { target: { value: type } });
component.setProps({});
});
const setMessageCount = async (component, count: number) =>
const setMessageCount = async (component: ReactWrapper, count: number) =>
act(async () => {
getMessageCountInput(component).simulate("change", { target: { value: count } });
component.setProps({});
});
const setSizeLimit = async (component, limit: number) =>
const setSizeLimit = async (component: ReactWrapper, limit: number) =>
act(async () => {
getSizeInput(component).simulate("change", { target: { value: limit } });
component.setProps({});
});
const setIncludeAttachments = async (component, checked) =>
const setIncludeAttachments = async (component: ReactWrapper, checked: boolean) =>
act(async () => {
getAttachmentsCheckbox(component).simulate("change", { target: { checked } });
component.setProps({});

View file

@ -125,8 +125,8 @@ describe("ForwardDialog", () => {
const { container } = mountForwardDialog();
// Make sendEvent require manual resolution so we can see the sending state
let finishSend;
let cancelSend;
let finishSend: (arg?: any) => void;
let cancelSend: () => void;
mockClient.sendEvent.mockImplementation(
<T extends {}>() =>
new Promise<T>((resolve, reject) => {
@ -135,8 +135,8 @@ describe("ForwardDialog", () => {
}),
);
let firstButton;
let secondButton;
let firstButton: Element;
let secondButton: Element;
const update = () => {
[firstButton, secondButton] = container.querySelectorAll(".mx_ForwardList_sendButton");
};
@ -253,7 +253,7 @@ describe("ForwardDialog", () => {
[M_ASSET.name]: { type: LocationAssetType.Pin },
[M_LOCATION.name]: {
uri: geoUri,
description: undefined,
description: undefined as string,
},
};
expect(mockClient.sendEvent).toHaveBeenCalledWith(
@ -280,7 +280,7 @@ describe("ForwardDialog", () => {
[M_ASSET.name]: { type: LocationAssetType.Pin },
[M_LOCATION.name]: {
uri: geoUri,
description: undefined,
description: undefined as string,
},
};
expect(mockClient.sendEvent).toHaveBeenCalledWith(
@ -301,7 +301,7 @@ describe("ForwardDialog", () => {
[M_ASSET.name]: { type: LocationAssetType.Pin },
[M_LOCATION.name]: {
uri: geoUri,
description: undefined,
description: undefined as string,
},
geo_uri: geoUri,
[M_TIMESTAMP.name]: timestamp,

View file

@ -73,8 +73,9 @@ describe("<UserSettingsDialog />", () => {
mockSdkConfig.get.mockReturnValue({ brand: "Test" });
});
const getActiveTabLabel = (container) => container.querySelector(".mx_TabbedView_tabLabel_active").textContent;
const getActiveTabHeading = (container) => container.querySelector(".mx_SettingsTab_heading").textContent;
const getActiveTabLabel = (container: Element) =>
container.querySelector(".mx_TabbedView_tabLabel_active").textContent;
const getActiveTabHeading = (container: Element) => container.querySelector(".mx_SettingsTab_heading").textContent;
it("should render general settings tab when no initialTabId", () => {
const { container } = render(getComponent());

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ComponentProps } from "react";
// eslint-disable-next-line deprecate/import
import { mount, ReactWrapper } from "enzyme";
import { MatrixEvent, RoomMember } from "matrix-js-sdk/src/matrix";
@ -60,7 +60,7 @@ describe("EventListSummary", function () {
*/
interface MembershipEventParams {
senderId?: string;
userId: string;
userId?: string;
membership: string;
prevMembership?: string;
}
@ -100,11 +100,11 @@ describe("EventListSummary", function () {
// Generate the same sequence of `events` for `n` users, where each user ID
// is created by replacing the first "$" in userIdTemplate with `i` for
// `i = 0 .. n`.
const generateEventsForUsers = (userIdTemplate, n, events) => {
const generateEventsForUsers = (userIdTemplate: string, n: number, events: MembershipEventParams[]) => {
let eventsForUsers: MatrixEvent[] = [];
let userId = "";
for (let i = 0; i < n; i++) {
userId = userIdTemplate.replace("$", i);
userId = userIdTemplate.replace("$", String(i));
events.forEach((e) => {
e.userId = userId;
});
@ -117,7 +117,7 @@ describe("EventListSummary", function () {
...mockClientMethodsUser(),
});
const defaultProps = {
const defaultProps: ComponentProps<typeof EventListSummary> = {
layout: Layout.Bubble,
events: [],
children: [],

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import React from "react";
import { fireEvent, render } from "@testing-library/react";
import { fireEvent, render, RenderResult } from "@testing-library/react";
import StyledRadioGroup from "../../../../src/components/views/elements/StyledRadioGroup";
@ -44,8 +44,10 @@ describe("<StyledRadioGroup />", () => {
};
const getComponent = (props = {}) => render(<StyledRadioGroup {...defaultProps} {...props} />);
const getInputByValue = (component, value) => component.container.querySelector(`input[value="${value}"]`);
const getCheckedInput = (component) => component.container.querySelector("input[checked]");
const getInputByValue = (component: RenderResult, value: string) =>
component.container.querySelector<HTMLInputElement>(`input[value="${value}"]`);
const getCheckedInput = (component: RenderResult) =>
component.container.querySelector<HTMLInputElement>("input[checked]");
it("renders radios correctly when no value is provided", () => {
const component = getComponent();

View file

@ -61,7 +61,7 @@ describe("<TooltipTarget />", () => {
});
const alignmentKeys = Object.keys(Alignment).filter((o: any) => isNaN(o));
it.each(alignmentKeys)("displays %s aligned tooltip on mouseover", async (alignment) => {
it.each(alignmentKeys)("displays %s aligned tooltip on mouseover", async (alignment: any) => {
const wrapper = getComponent({ alignment: Alignment[alignment] });
act(() => {
Simulate.mouseOver(wrapper);

View file

@ -16,7 +16,7 @@ limitations under the License.
import React from "react";
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { mount, ReactWrapper } from "enzyme";
import { act } from "react-dom/test-utils";
import LiveDurationDropdown, {
@ -33,9 +33,9 @@ describe("<LiveDurationDropdown />", () => {
};
const getComponent = (props = {}) => mount(<LiveDurationDropdown {...defaultProps} {...props} />);
const getOption = (wrapper, timeout) => findById(wrapper, `live-duration__${timeout}`).at(0);
const getSelectedOption = (wrapper) => findById(wrapper, "live-duration_value");
const openDropdown = (wrapper) =>
const getOption = (wrapper: ReactWrapper, timeout: number) => findById(wrapper, `live-duration__${timeout}`).at(0);
const getSelectedOption = (wrapper: ReactWrapper) => findById(wrapper, "live-duration_value");
const openDropdown = (wrapper: ReactWrapper) =>
act(() => {
wrapper.find('[role="button"]').at(0).simulate("click");
wrapper.setProps({});

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from "react";
import * as maplibregl from "maplibre-gl";
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { mount, ReactWrapper } from "enzyme";
import { act } from "react-dom/test-utils";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { MatrixClient } from "matrix-js-sdk/src/client";
@ -239,11 +239,12 @@ describe("LocationPicker", () => {
const shareType = LocationShareType.Live;
testUserLocationShareTypes(shareType);
const getOption = (wrapper, timeout) => findById(wrapper, `live-duration__${timeout}`).at(0);
const getDropdown = (wrapper) => findByTestId(wrapper, "live-duration-dropdown");
const getSelectedOption = (wrapper) => findById(wrapper, "live-duration_value");
const getOption = (wrapper: ReactWrapper, timeout: number) =>
findById(wrapper, `live-duration__${timeout}`).at(0);
const getDropdown = (wrapper: ReactWrapper) => findByTestId(wrapper, "live-duration-dropdown");
const getSelectedOption = (wrapper: ReactWrapper) => findById(wrapper, "live-duration_value");
const openDropdown = (wrapper) =>
const openDropdown = (wrapper: ReactWrapper) =>
act(() => {
const dropdown = getDropdown(wrapper);
dropdown.find('[role="button"]').at(0).simulate("click");

View file

@ -52,6 +52,6 @@ describe("<LocationViewDialog />", () => {
// @ts-ignore cheat assignment to property
selfShareEvent.sender = member;
const component = getComponent({ mxEvent: selfShareEvent });
expect(component.find("SmartMarker").props()["roomMember"]).toEqual(member);
expect(component.find("SmartMarker").prop("roomMember")).toEqual(member);
});
});

View file

@ -40,7 +40,7 @@ describe("DateSeparator", () => {
};
const RealDate = global.Date;
class MockDate extends Date {
constructor(date) {
constructor(date: string | number | Date) {
super(date || now);
}
}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ComponentProps } from "react";
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { act } from "react-dom/test-utils";
@ -63,7 +63,7 @@ describe("<MBeaconBody />", () => {
const defaultEvent = makeBeaconInfoEvent(aliceId, roomId, { isLive: true }, "$alice-room1-1");
const defaultProps = {
const defaultProps: ComponentProps<typeof MBeaconBody> = {
mxEvent: defaultEvent,
highlights: [],
highlightLink: "",
@ -343,7 +343,7 @@ describe("<MBeaconBody />", () => {
const redactionEvent = new MatrixEvent({ type: EventType.RoomRedaction, content: { reason: "test reason" } });
const setupRoomWithBeacon = (beaconInfoEvent, locationEvents: MatrixEvent[] = []) => {
const setupRoomWithBeacon = (beaconInfoEvent: MatrixEvent, locationEvents: MatrixEvent[] = []) => {
const room = makeRoomWithStateEvents([beaconInfoEvent], { roomId, mockClient });
const beaconInstance = room.currentState.beacons.get(getBeaconInfoIdentifier(beaconInfoEvent));
beaconInstance.addLocations(locationEvents);

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ComponentProps } from "react";
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { LocationAssetType } from "matrix-js-sdk/src/@types/location";
@ -46,7 +46,7 @@ describe("MLocationBody", () => {
isGuest: jest.fn().mockReturnValue(false),
});
const defaultEvent = makeLocationEvent("geo:51.5076,-0.1276", LocationAssetType.Pin);
const defaultProps = {
const defaultProps: ComponentProps<typeof MLocationBody> = {
mxEvent: defaultEvent,
highlights: [],
highlightLink: "",
@ -79,7 +79,7 @@ describe("MLocationBody", () => {
});
describe("with error", () => {
let sdkConfigSpy;
let sdkConfigSpy: jest.SpyInstance<any>;
beforeEach(() => {
// eat expected errors to keep console clean
@ -171,7 +171,7 @@ describe("MLocationBody", () => {
const component = getComponent({ mxEvent: selfShareEvent });
// render self locations with user avatars
expect(component.find("SmartMarker").at(0).props()["roomMember"]).toEqual(member);
expect(component.find("SmartMarker").at(0).prop("roomMember")).toEqual(member);
});
});
});

View file

@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import React, { ComponentProps } from "react";
import { IContent, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { render, RenderResult } from "@testing-library/react";
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
@ -43,7 +43,7 @@ describe("MVideoBody", () => {
});
function makeMVideoBody(w: number, h: number): RenderResult {
const content = {
const content: IContent = {
info: {
"w": w,
"h": h,
@ -66,7 +66,7 @@ function makeMVideoBody(w: number, h: number): RenderResult {
content,
});
const defaultProps = {
const defaultProps: ComponentProps<typeof MVideoBody> = {
mxEvent: event,
highlights: [],
highlightLink: "",

View file

@ -76,7 +76,7 @@ describe("<MessageActionBar />", () => {
});
const localStorageMock = (() => {
let store = {};
let store: Record<string, any> = {};
return {
getItem: jest.fn().mockImplementation((key) => store[key] ?? null),
setItem: jest.fn().mockImplementation((key, value) => {

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import React from "react";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { MockedObject } from "jest-mock";
import { render } from "@testing-library/react";
@ -38,9 +38,9 @@ describe("<TextualBody />", () => {
beforeEach(() => {
defaultMatrixClient = getMockClientWithEventEmitter({
getRoom: () => defaultRoom,
getAccountData: () => undefined,
getAccountData: (): MatrixEvent | undefined => undefined,
isGuest: () => false,
mxcUrlToHttp: (s) => s,
mxcUrlToHttp: (s: string) => s,
});
});
@ -56,7 +56,7 @@ describe("<TextualBody />", () => {
});
const defaultProps = {
mxEvent: defaultEvent,
highlights: [],
highlights: [] as string[],
highlightLink: "",
onMessageAllowed: jest.fn(),
onHeightChanged: jest.fn(),
@ -158,17 +158,17 @@ describe("<TextualBody />", () => {
});
describe("renders formatted m.text correctly", () => {
let matrixClient;
let matrixClient: MatrixClient;
beforeEach(() => {
matrixClient = getMockClientWithEventEmitter({
getRoom: () => mkStubRoom("room_id", "room name", undefined),
getAccountData: () => undefined,
getAccountData: (): MatrixEvent | undefined => undefined,
getUserId: () => "@me:my_server",
getHomeserverUrl: () => "https://my_server/",
on: () => undefined,
removeListener: () => undefined,
on: (): void => undefined,
removeListener: (): void => undefined,
isGuest: () => false,
mxcUrlToHttp: (s) => s,
mxcUrlToHttp: (s: string) => s,
});
DMRoomMap.makeShared();
});
@ -375,10 +375,10 @@ describe("<TextualBody />", () => {
const matrixClient = getMockClientWithEventEmitter({
getRoom: () => mkStubRoom("room_id", "room name", undefined),
getAccountData: () => undefined,
getUrlPreview: (url) => new Promise(() => {}),
getAccountData: (): MatrixClient | undefined => undefined,
getUrlPreview: (url: string) => new Promise(() => {}),
isGuest: () => false,
mxcUrlToHttp: (s) => s,
mxcUrlToHttp: (s: string) => s,
});
DMRoomMap.makeShared();

View file

@ -83,7 +83,7 @@ describe("<PinnedMessagesCard />", () => {
};
const mountPins = async (room: Room): Promise<ReactWrapper<ComponentProps<typeof PinnedMessagesCard>>> => {
let pins;
let pins: ReactWrapper<ComponentProps<typeof PinnedMessagesCard>>;
await act(async () => {
pins = mount(
<PinnedMessagesCard
@ -239,9 +239,9 @@ describe("<PinnedMessagesCard />", () => {
const answers = (poll.unstableExtensibleEvent as PollStartEvent).answers;
const responses = [
["@alice:example.org", 0],
["@bob:example.org", 0],
["@eve:example.org", 1],
["@alice:example.org", 0] as [string, number],
["@bob:example.org", 0] as [string, number],
["@eve:example.org", 1] as [string, number],
].map(([user, option], i) =>
mkEvent({
...PollResponseEvent.from([answers[option as number].id], poll.getId()!).serialize(),

View file

@ -15,13 +15,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { Component } from "react";
import ReactTestUtils from "react-dom/test-utils";
import ReactDOM from "react-dom";
import { Room } from "matrix-js-sdk/src/models/room";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { User } from "matrix-js-sdk/src/models/user";
import { compare } from "matrix-js-sdk/src/utils";
import { MatrixClient, RoomState } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import * as TestUtils from "../../../test-utils";
@ -43,15 +44,15 @@ describe("MemberList", () => {
return room;
}
let parentDiv = null;
let client = null;
let root = null;
let memberListRoom;
let memberList = null;
let parentDiv: HTMLDivElement = null;
let client: MatrixClient = null;
let root: Component = null;
let memberListRoom: Room;
let memberList: MemberList = null;
let adminUsers = [];
let moderatorUsers = [];
let defaultUsers = [];
let adminUsers: RoomMember[] = [];
let moderatorUsers: RoomMember[] = [];
let defaultUsers: RoomMember[] = [];
beforeEach(function () {
TestUtils.stubClient();
@ -109,13 +110,14 @@ describe("MemberList", () => {
memberListRoom.currentState = {
members: {},
getMember: jest.fn(),
getStateEvents: (eventType, stateKey) => (stateKey === undefined ? [] : null), // ignore 3pid invites
};
getStateEvents: ((eventType, stateKey) =>
stateKey === undefined ? [] : null) as RoomState["getStateEvents"], // ignore 3pid invites
} as unknown as RoomState;
for (const member of [...adminUsers, ...moderatorUsers, ...defaultUsers]) {
memberListRoom.currentState.members[member.userId] = member;
}
const gatherWrappedRef = (r) => {
const gatherWrappedRef = (r: MemberList) => {
memberList = r;
};
const context = new TestSdkContext();
@ -131,7 +133,7 @@ describe("MemberList", () => {
/>
</SDKContext.Provider>,
parentDiv,
);
) as unknown as Component;
});
afterEach((done) => {
@ -144,7 +146,7 @@ describe("MemberList", () => {
done();
});
function expectOrderedByPresenceAndPowerLevel(memberTiles, isPresenceEnabled) {
function expectOrderedByPresenceAndPowerLevel(memberTiles: MemberTile[], isPresenceEnabled: boolean) {
let prevMember = null;
for (const tile of memberTiles) {
const memberA = prevMember;
@ -164,8 +166,8 @@ describe("MemberList", () => {
let groupChange = false;
if (isPresenceEnabled) {
const convertPresence = (p) => (p === "unavailable" ? "online" : p);
const presenceIndex = (p) => {
const convertPresence = (p: string) => (p === "unavailable" ? "online" : p);
const presenceIndex = (p: string) => {
const order = ["active", "online", "offline"];
const idx = order.indexOf(convertPresence(p));
return idx === -1 ? order.length : idx; // unknown states at the end
@ -212,7 +214,7 @@ describe("MemberList", () => {
}
}
function itDoesOrderMembersCorrectly(enablePresence) {
function itDoesOrderMembersCorrectly(enablePresence: boolean) {
describe("does order members correctly", () => {
// Note: even if presence is disabled, we still expect that the presence
// tests will pass. All expectOrderedByPresenceAndPowerLevel does is ensure
@ -251,7 +253,7 @@ describe("MemberList", () => {
// We already have admin, moderator, and default users so leave them alone
// Bypass all the event listeners and skip to the good part
memberList._showPresence = enablePresence;
memberList.showPresence = enablePresence;
memberList.updateListNow();
const tiles = ReactTestUtils.scryRenderedComponentsWithType(root, MemberTile);

View file

@ -248,13 +248,12 @@ function createRoom(info: IRoomCreationInfo) {
}
function mountHeader(room: Room, propsOverride = {}, roomContext?: Partial<IRoomState>): ReactWrapper {
const props = {
const props: RoomHeaderProps = {
room,
inRoom: true,
onSearchClick: () => {},
onInviteClick: null,
onForgetClick: () => {},
onCallPlaced: (_type) => {},
onAppsClick: () => {},
e2eStatus: E2EStatus.Normal,
appsShown: true,
@ -320,7 +319,7 @@ function mkJoinEvent(roomId: string, userId: string) {
}
function mkDirectEvent(roomId: string, userId: string, otherUsers: string[]): MatrixEvent {
const content = {};
const content: Record<string, string[]> = {};
for (const otherUserId of otherUsers) {
content[otherUserId] = [roomId];
}

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ComponentProps } from "react";
import { render, fireEvent, RenderResult, waitFor } from "@testing-library/react";
import { Room, RoomMember, MatrixError, IContent } from "matrix-js-sdk/src/matrix";
@ -71,7 +71,7 @@ describe("<RoomPreviewBar />", () => {
const inviterUserId = "@inviter:test.com";
const otherUserId = "@othertester:test.com";
const getComponent = (props = {}) => {
const getComponent = (props: ComponentProps<typeof RoomPreviewBar> = {}) => {
const defaultProps = {
room: createRoom(roomId, userId),
};
@ -222,13 +222,13 @@ describe("<RoomPreviewBar />", () => {
});
describe("without an invited email", () => {
describe("for a non-dm room", () => {
const mockGetMember = (id) => {
const mockGetMember = (id: string) => {
if (id === userId) return userMember;
return inviterMember;
};
const onJoinClick = jest.fn();
const onRejectClick = jest.fn();
let room;
let room: Room;
beforeEach(() => {
room = createRoom(roomId, userId);
@ -282,13 +282,13 @@ describe("<RoomPreviewBar />", () => {
});
describe("for a dm room", () => {
const mockGetMember = (id) => {
const mockGetMember = (id: string) => {
if (id === userId) return userMemberWithDmInvite;
return inviterMember;
};
const onJoinClick = jest.fn();
const onRejectClick = jest.fn();
let room;
let room: Room;
beforeEach(() => {
room = createRoom(roomId, userId);
@ -324,7 +324,7 @@ describe("<RoomPreviewBar />", () => {
{ medium: "not-email", address: "address 2" },
];
const testJoinButton = (props) => async () => {
const testJoinButton = (props: ComponentProps<typeof RoomPreviewBar>) => async () => {
const onJoinClick = jest.fn();
const onRejectClick = jest.fn();
const component = getComponent({ ...props, onJoinClick, onRejectClick });

View file

@ -24,8 +24,8 @@ import * as mockKeyboard from "../../../../../../src/Keyboard";
describe("PlainTextComposer", () => {
const customRender = (
onChange = (_content: string) => void 0,
onSend = () => void 0,
onChange = (_content: string): void => void 0,
onSend = (): void => void 0,
disabled = false,
initialContent?: string,
) => {

View file

@ -21,7 +21,7 @@ import { Key } from "../../../../src/Keyboard";
import { mockPlatformPeg, unmockPlatformPeg } from "../../../test-utils/platform";
import { KeyboardKey, KeyboardShortcut } from "../../../../src/components/views/settings/KeyboardShortcut";
const renderKeyboardShortcut = (Component, props?) => {
const renderKeyboardShortcut = (Component: React.FunctionComponentFactory<any>, props: Record<string, any>) => {
return render(<Component {...props} />).container;
};

View file

@ -22,6 +22,7 @@ import {
MatrixEvent,
Room,
NotificationCountType,
PushRuleActionName,
} from "matrix-js-sdk/src/matrix";
import { IThreepid, ThreepidMedium } from "matrix-js-sdk/src/@types/threepids";
import { act } from "react-dom/test-utils";
@ -38,15 +39,14 @@ jest.mock("matrix-js-sdk/src/logger");
// Avoid indirectly importing any eagerly created stores that would require extra setup
jest.mock("../../../../src/Notifier");
const masterRule = {
actions: ["dont_notify"],
const masterRule: IPushRule = {
actions: [PushRuleActionName.DontNotify],
conditions: [],
default: true,
enabled: false,
rule_id: RuleId.Master,
};
// eslint-disable-next-line max-len
const oneToOneRule = {
const oneToOneRule: IPushRule = {
conditions: [
{ kind: "room_member_count", is: "2" },
{ kind: "event_match", key: "type", pattern: "m.room.message" },
@ -56,8 +56,7 @@ const oneToOneRule = {
default: true,
enabled: true,
} as IPushRule;
// eslint-disable-next-line max-len
const encryptedOneToOneRule = {
const encryptedOneToOneRule: IPushRule = {
conditions: [
{ kind: "room_member_count", is: "2" },
{ kind: "event_match", key: "type", pattern: "m.room.encrypted" },
@ -67,15 +66,13 @@ const encryptedOneToOneRule = {
default: true,
enabled: true,
} as IPushRule;
// eslint-disable-next-line max-len
const encryptedGroupRule = {
const encryptedGroupRule: IPushRule = {
conditions: [{ kind: "event_match", key: "type", pattern: "m.room.encrypted" }],
actions: ["dont_notify"],
rule_id: ".m.rule.encrypted",
default: true,
enabled: true,
} as IPushRule;
// eslint-disable-next-line max-len
const pushRules: IPushRules = {
global: {
underride: [
@ -367,7 +364,7 @@ describe("<Notifications />", () => {
it("toggles and sets settings correctly", async () => {
await getComponentAndWait();
let audioNotifsToggle;
let audioNotifsToggle: HTMLDivElement;
const update = () => {
audioNotifsToggle = screen

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ComponentProps } from "react";
import { fireEvent, render } from "@testing-library/react";
import { PUSHER_ENABLED } from "matrix-js-sdk/src/@types/event";
@ -28,11 +28,10 @@ describe("<DeviceDetails />", () => {
isVerified: false,
deviceType: DeviceType.Unknown,
};
const defaultProps = {
const defaultProps: ComponentProps<typeof DeviceDetails> = {
device: baseDevice,
pusher: null,
isSigningOut: false,
isLoading: false,
onSignOutDevice: jest.fn(),
saveDeviceName: jest.fn(),
setPushNotifications: jest.fn(),

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from "react";
import React, { ComponentProps } from "react";
import { act, fireEvent, render } from "@testing-library/react";
import { FilteredDeviceList } from "../../../../../src/components/views/settings/devices/FilteredDeviceList";
@ -59,13 +59,12 @@ describe("<FilteredDeviceList />", () => {
last_seen_ts: Date.now() - MS_DAY * 100,
deviceType: DeviceType.Unknown,
};
const defaultProps = {
const defaultProps: ComponentProps<typeof FilteredDeviceList> = {
onFilterChange: jest.fn(),
onDeviceExpandToggle: jest.fn(),
onSignOutDevices: jest.fn(),
saveDeviceName: jest.fn(),
setPushNotifications: jest.fn(),
setPusherEnabled: jest.fn(),
setSelectedDeviceIds: jest.fn(),
localNotificationSettings: new Map(),
expandedDeviceIds: [],

View file

@ -28,7 +28,7 @@ jest.mock("matrix-js-sdk/src/rendezvous/channels");
const mockedFlow = jest.fn();
jest.mock("../../../../../src/components/views/auth/LoginWithQRFlow", () => (props) => {
jest.mock("../../../../../src/components/views/auth/LoginWithQRFlow", () => (props: Record<string, any>) => {
mockedFlow(props);
return <div />;
});

View file

@ -14,6 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { UIAFlow } from "matrix-js-sdk/src/matrix";
import { deleteDevicesWithInteractiveAuth } from "../../../../../src/components/views/settings/devices/deleteDevices";
import Modal from "../../../../../src/Modal";
import { getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
@ -28,7 +30,7 @@ describe("deleteDevices()", () => {
const modalSpy = jest.spyOn(Modal, "createDialog");
const interactiveAuthError = { httpStatus: 401, data: { flows: [] } };
const interactiveAuthError = { httpStatus: 401, data: { flows: [] as UIAFlow[] } };
beforeEach(() => {
jest.clearAllMocks();

View file

@ -46,7 +46,7 @@ describe("RolesRoomSettingsTab", () => {
});
describe("Element Call", () => {
const mockPowerLevels = (events): void => {
const mockPowerLevels = (events: Record<string, number>): void => {
jest.spyOn(room.currentState, "getStateEvents").mockReturnValue({
getContent: () => ({
events,

View file

@ -24,7 +24,7 @@ import { mockPlatformPeg } from "../../../../../test-utils/platform";
const PATH_TO_KEYBOARD_SHORTCUTS = "../../../../../../src/accessibility/KeyboardShortcuts";
const PATH_TO_KEYBOARD_SHORTCUT_UTILS = "../../../../../../src/accessibility/KeyboardShortcutUtils";
const mockKeyboardShortcuts = (override) => {
const mockKeyboardShortcuts = (override: Record<string, any>) => {
jest.doMock(PATH_TO_KEYBOARD_SHORTCUTS, () => {
const original = jest.requireActual(PATH_TO_KEYBOARD_SHORTCUTS);
return {
@ -34,7 +34,7 @@ const mockKeyboardShortcuts = (override) => {
});
};
const mockKeyboardShortcutUtils = (override) => {
const mockKeyboardShortcutUtils = (override: Record<string, any>) => {
jest.doMock(PATH_TO_KEYBOARD_SHORTCUT_UTILS, () => {
const original = jest.requireActual(PATH_TO_KEYBOARD_SHORTCUT_UTILS);
return {
@ -68,7 +68,7 @@ describe("KeyboardUserSettingsTab", () => {
},
});
mockKeyboardShortcutUtils({
getKeyboardShortcutValue: (name) => {
getKeyboardShortcutValue: (name: string) => {
switch (name) {
case "keybind1":
return {
@ -88,7 +88,7 @@ describe("KeyboardUserSettingsTab", () => {
}
}
},
getKeyboardShortcutDisplayName: (name) => {
getKeyboardShortcutDisplayName: (name: string) => {
switch (name) {
case "keybind1":
return "Cancel replying to a message";

View file

@ -927,7 +927,7 @@ describe("<SessionManagerTab />", () => {
// get a handle for resolving the delete call
// because promise flushing after the confirm modal is resolving this too
// and we want to test the loading state here
let resolveDeleteRequest;
let resolveDeleteRequest: (v?: IAuthData) => void;
mockClient.deleteMultipleDevices.mockImplementation(() => {
const promise = new Promise<IAuthData>((resolve) => {
resolveDeleteRequest = resolve;

View file

@ -21,7 +21,7 @@ import { MatrixClient } from "matrix-js-sdk/src/matrix";
import UnwrappedSpacePanel from "../../../../src/components/views/spaces/SpacePanel";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import { SpaceKey } from "../../../../src/stores/spaces";
import { MetaSpace, SpaceKey } from "../../../../src/stores/spaces";
import { shouldShowComponent } from "../../../../src/customisations/helpers/UIComponents";
import { UIComponent } from "../../../../src/settings/UIFeature";
import { wrapInSdkContext } from "../../../test-utils";
@ -31,9 +31,9 @@ jest.mock("../../../../src/stores/spaces/SpaceStore", () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const EventEmitter = require("events");
class MockSpaceStore extends EventEmitter {
invitedSpaces = [];
enabledMetaSpaces = [];
spacePanelSpaces = [];
invitedSpaces: SpaceKey[] = [];
enabledMetaSpaces: MetaSpace[] = [];
spacePanelSpaces: string[] = [];
activeSpace: SpaceKey = "!space1";
}
return {

View file

@ -93,15 +93,15 @@ describe("<SpaceSettingsVisibilityTab />", () => {
};
const getByTestId = (container: Element, id: string) => container.querySelector(`[data-test-id=${id}]`);
const toggleGuestAccessSection = async (component) => {
const toggleGuestAccessSection = async (component: Element) => {
const toggleButton = getByTestId(component, "toggle-guest-access-btn");
await act(async () => {
Simulate.click(toggleButton);
});
};
const getGuestAccessToggle = (component) => component.querySelector('[aria-label="Enable guest access"');
const getHistoryVisibilityToggle = (component) => component.querySelector('[aria-label="Preview Space"');
const getErrorMessage = (component) => getByTestId(component, "space-settings-error")?.textContent;
const getGuestAccessToggle = (component: Element) => component.querySelector('[aria-label="Enable guest access"');
const getHistoryVisibilityToggle = (component: Element) => component.querySelector('[aria-label="Preview Space"');
const getErrorMessage = (component: Element) => getByTestId(component, "space-settings-error")?.textContent;
beforeEach(() => {
(mockMatrixClient.sendStateEvent as jest.Mock).mockClear().mockResolvedValue({});

View file

@ -16,6 +16,7 @@ limitations under the License.
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import { parseEvent } from "../../src/editor/deserialize";
import { Part } from "../../src/editor/parts";
import { createPartCreator } from "./mock";
const FOUR_SPACES = " ".repeat(4);
@ -50,12 +51,12 @@ function textMessageReply(body: string, msgtype = "m.text") {
} as unknown as MatrixEvent;
}
function mergeAdjacentParts(parts) {
let prevPart;
function mergeAdjacentParts(parts: Part[]) {
let prevPart: Part | undefined;
for (let i = 0; i < parts.length; ++i) {
let part = parts[i];
const isEmpty = !part.text.length;
const isMerged = !isEmpty && prevPart && prevPart.merge(part);
const isMerged = !isEmpty && prevPart && prevPart.merge?.(part);
if (isEmpty || isMerged) {
// remove empty or merged part
part = prevPart;
@ -67,7 +68,7 @@ function mergeAdjacentParts(parts) {
}
}
function normalize(parts) {
function normalize(parts: Part[]) {
// merge adjacent parts as this will happen
// in the model anyway, and whether 1 or multiple
// plain parts are returned is an implementation detail

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { Room, MatrixClient } from "matrix-js-sdk/src/matrix";
import { Room, MatrixClient, RoomMember } from "matrix-js-sdk/src/matrix";
import AutocompleteWrapperModel, { UpdateCallback } from "../../src/editor/autocomplete";
import { Caret } from "../../src/editor/caret";
@ -63,7 +63,7 @@ class MockAutoComplete {
// MockClient & MockRoom are only used for avatars in room and user pills,
// which is not tested
class MockRoom {
getMember() {
getMember(): RoomMember | null {
return null;
}
}

View file

@ -16,9 +16,10 @@ limitations under the License.
import EditorModel from "../../src/editor/model";
import { createPartCreator } from "./mock";
import { Caret } from "../../src/editor/caret";
function createRenderer() {
const render = (c) => {
const render = (c: Caret) => {
render.caret = c;
render.count += 1;
};

View file

@ -22,7 +22,7 @@ describe("useDebouncedCallback", () => {
beforeAll(() => jest.useFakeTimers());
afterAll(() => jest.useRealTimers());
function render(enabled: boolean, callback: (...params: any) => void, params: any) {
function render(enabled: boolean, callback: (...params: any[]) => void, params: any[]) {
return renderHook(({ enabled, callback, params }) => useDebouncedCallback(enabled, callback, params), {
initialProps: {
enabled,
@ -34,7 +34,7 @@ describe("useDebouncedCallback", () => {
it("should be able to handle empty parameters", async () => {
// When
const params = [];
const params: any[] = [];
const callback = jest.fn();
render(true, callback, params);
jest.advanceTimersByTime(1);

View file

@ -22,12 +22,12 @@ import { act } from "react-dom/test-utils";
import { useLatestResult } from "../../src/hooks/useLatestResult";
function LatestResultsComponent({ query, doRequest }) {
function LatestResultsComponent({ query, doRequest }: { query: number; doRequest(query: number): Promise<number> }) {
const [value, setValueInternal] = useState<number>(0);
const [updateQuery, updateResult] = useLatestResult(setValueInternal);
useEffect(() => {
updateQuery(query);
doRequest(query).then((it) => {
doRequest(query).then((it: number) => {
updateResult(query, it);
});
}, [doRequest, query, updateQuery, updateResult]);
@ -37,7 +37,7 @@ function LatestResultsComponent({ query, doRequest }) {
describe("useLatestResult", () => {
it("should return results", async () => {
const doRequest = async (query) => {
const doRequest = async (query: number) => {
await sleep(180);
return query;
};
@ -63,7 +63,7 @@ describe("useLatestResult", () => {
});
it("should prevent out-of-order results", async () => {
const doRequest = async (query) => {
const doRequest = async (query: number) => {
await sleep(query);
return query;
};

View file

@ -16,6 +16,7 @@ limitations under the License.
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { sleep } from "matrix-js-sdk/src/utils";
import React from "react";
import { act } from "react-dom/test-utils";
@ -24,7 +25,7 @@ import { useProfileInfo } from "../../src/hooks/useProfileInfo";
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
import { stubClient } from "../test-utils/test-utils";
function ProfileInfoComponent({ onClick }) {
function ProfileInfoComponent({ onClick }: { onClick(hook: ReturnType<typeof useProfileInfo>): void }) {
const profileInfo = useProfileInfo();
const { ready, loading, profile } = profileInfo;
@ -38,7 +39,7 @@ function ProfileInfoComponent({ onClick }) {
}
describe("useProfileInfo", () => {
let cli;
let cli: MatrixClient;
beforeEach(() => {
stubClient();
@ -58,7 +59,6 @@ describe("useProfileInfo", () => {
<ProfileInfoComponent
onClick={(hook) => {
hook.search({
limit: 1,
query,
});
}}
@ -79,7 +79,6 @@ describe("useProfileInfo", () => {
<ProfileInfoComponent
onClick={(hook) => {
hook.search({
limit: 1,
query: "",
});
}}
@ -103,7 +102,6 @@ describe("useProfileInfo", () => {
<ProfileInfoComponent
onClick={(hook) => {
hook.search({
limit: 1,
query,
});
}}
@ -130,7 +128,6 @@ describe("useProfileInfo", () => {
<ProfileInfoComponent
onClick={(hook) => {
hook.search({
limit: 1,
query,
});
}}
@ -153,7 +150,6 @@ describe("useProfileInfo", () => {
<ProfileInfoComponent
onClick={(hook) => {
hook.search({
limit: 1,
query,
});
}}

View file

@ -16,6 +16,7 @@ limitations under the License.
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { sleep } from "matrix-js-sdk/src/utils";
import React from "react";
import { act } from "react-dom/test-utils";
@ -24,7 +25,7 @@ import { usePublicRoomDirectory } from "../../src/hooks/usePublicRoomDirectory";
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
import { stubClient } from "../test-utils/test-utils";
function PublicRoomComponent({ onClick }) {
function PublicRoomComponent({ onClick }: { onClick(hook: ReturnType<typeof usePublicRoomDirectory>): void }) {
const roomDirectory = usePublicRoomDirectory();
const { ready, loading, publicRooms } = roomDirectory;
@ -38,7 +39,7 @@ function PublicRoomComponent({ onClick }) {
}
describe("usePublicRoomDirectory", () => {
let cli;
let cli: MatrixClient;
beforeEach(() => {
stubClient();

View file

@ -16,6 +16,7 @@ limitations under the License.
// eslint-disable-next-line deprecate/import
import { mount } from "enzyme";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { sleep } from "matrix-js-sdk/src/utils";
import React from "react";
import { act } from "react-dom/test-utils";
@ -24,7 +25,7 @@ import { useUserDirectory } from "../../src/hooks/useUserDirectory";
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
import { stubClient } from "../test-utils";
function UserDirectoryComponent({ onClick }) {
function UserDirectoryComponent({ onClick }: { onClick(hook: ReturnType<typeof useUserDirectory>): void }) {
const userDirectory = useUserDirectory();
const { ready, loading, users } = userDirectory;
@ -37,7 +38,7 @@ function UserDirectoryComponent({ onClick }) {
}
describe("useUserDirectory", () => {
let cli;
let cli: MatrixClient;
beforeEach(() => {
stubClient();
@ -53,6 +54,7 @@ describe("useUserDirectory", () => {
display_name: query,
},
],
limited: false,
});
});

View file

@ -49,7 +49,7 @@ describe("languageHandler", function () {
{ policyLink: () => "foo" },
"Accept foo to continue:",
],
["handles text in tags", textInTagSub, {}, { a: (sub) => `x${sub}x` }, "xUpgradex to your own domain"],
["handles text in tags", textInTagSub, {}, { a: (sub: string) => `x${sub}x` }, "xUpgradex to your own domain"],
[
"handles variable substitution with React function component",
variableSub,
@ -82,7 +82,7 @@ describe("languageHandler", function () {
],
];
let oldNodeEnv;
let oldNodeEnv: string;
beforeAll(() => {
oldNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "test";
@ -138,7 +138,7 @@ describe("languageHandler", function () {
// counterpart doesnt expose any way to restore default config
// missingEntryGenerator is mocked in the root setup file
// reset to default here
const counterpartDefaultMissingEntryGen = function (key) {
const counterpartDefaultMissingEntryGen = function (key: string) {
return "missing translation: " + key;
};
setMissingEntryGenerator(counterpartDefaultMissingEntryGen);

View file

@ -16,7 +16,7 @@ limitations under the License.
import { linkify, Type } from "../src/linkify-matrix";
describe("linkify-matrix", () => {
const linkTypesByInitialCharacter = {
const linkTypesByInitialCharacter: Record<string, string> = {
"#": "roomalias",
"@": "userid",
};

View file

@ -28,7 +28,7 @@ const TEST_DATA = [
];
describe("SettingsStore", () => {
let platformSettings: object;
let platformSettings: Record<string, any>;
beforeAll(() => {
jest.clearAllMocks();

View file

@ -72,17 +72,15 @@ describe("IncompatibleController", () => {
describe("getValueOverride()", () => {
it("returns forced value when setting is incompatible", () => {
settingsGetValueSpy.mockReturnValue(true);
const forcedValue = { key: null };
const controller = new IncompatibleController("feature_spotlight", forcedValue);
const controller = new IncompatibleController("feature_spotlight", { key: null });
expect(
controller.getValueOverride(SettingLevel.ACCOUNT, "$room:server", true, SettingLevel.ACCOUNT),
).toEqual(forcedValue);
).toEqual({ key: null });
});
it("returns null when setting is not incompatible", () => {
settingsGetValueSpy.mockReturnValue(false);
const forcedValue = { key: null };
const controller = new IncompatibleController("feature_spotlight", forcedValue);
const controller = new IncompatibleController("feature_spotlight", { key: null });
expect(
controller.getValueOverride(SettingLevel.ACCOUNT, "$room:server", true, SettingLevel.ACCOUNT),
).toEqual(null);

View file

@ -30,8 +30,10 @@ const lv = {
// de_DE.json
// lv.json - mock version with few translations, used to test fallback translation
function weblateToCounterpart(inTrs: object): object {
const outTrs = {};
type Translations = Record<string, Record<string, string> | string>;
function weblateToCounterpart(inTrs: Record<string, string>): Translations {
const outTrs: Translations = {};
for (const key of Object.keys(inTrs)) {
const keyParts = key.split("|", 2);

View file

@ -16,7 +16,7 @@ limitations under the License.
import fetchMock from "fetch-mock-jest";
import { TextDecoder, TextEncoder } from "util";
import fetch from "node-fetch";
import { Response } from "node-fetch";
// jest 27 removes setImmediate from jsdom
// polyfill until setImmediate use in client can be removed
@ -88,7 +88,8 @@ fetchMock.get("/image-file-stub", "image file stub");
// @ts-ignore
window.fetch = fetchMock.sandbox();
window.Response = fetch.Response;
// @ts-ignore
window.Response = Response;
// set up mediaDevices mock
Object.defineProperty(navigator, "mediaDevices", {

View file

@ -26,6 +26,7 @@ import {
import { makeBeaconContent, makeBeaconInfoContent } from "matrix-js-sdk/src/content-helpers";
import { M_BEACON } from "matrix-js-sdk/src/@types/beacon";
import { logger } from "matrix-js-sdk/src/logger";
import { Mocked } from "jest-mock";
import { OwnBeaconStore, OwnBeaconStoreEvent } from "../../src/stores/OwnBeaconStore";
import {
@ -48,7 +49,7 @@ jest.mock("lodash", () => ({
jest.useFakeTimers();
describe("OwnBeaconStore", () => {
let geolocation;
let geolocation: Mocked<Geolocation>;
// 14.03.2022 16:15
const now = 1647270879403;
const HOUR_MS = 3600000;
@ -82,7 +83,7 @@ describe("OwnBeaconStore", () => {
// make fresh rooms every time
// as we update room state
const makeRoomsWithStateEvents = (stateEvents = []): [Room, Room] => {
const makeRoomsWithStateEvents = (stateEvents: MatrixEvent[] = []): [Room, Room] => {
const room1 = new Room(room1Id, mockClient, aliceId);
const room2 = new Room(room2Id, mockClient, aliceId);
@ -100,7 +101,7 @@ describe("OwnBeaconStore", () => {
return store;
};
const expireBeaconAndEmit = (store, beaconInfoEvent: MatrixEvent): void => {
const expireBeaconAndEmit = (store: OwnBeaconStore, beaconInfoEvent: MatrixEvent): void => {
const beacon = store.getBeaconById(getBeaconInfoIdentifier(beaconInfoEvent));
// time travel until beacon is expired
advanceDateAndTime(beacon.beaconInfo.timeout + 100);
@ -112,7 +113,11 @@ describe("OwnBeaconStore", () => {
mockClient.emit(BeaconEvent.LivenessChange, false, beacon);
};
const updateBeaconLivenessAndEmit = (store, beaconInfoEvent: MatrixEvent, isLive: boolean): void => {
const updateBeaconLivenessAndEmit = (
store: OwnBeaconStore,
beaconInfoEvent: MatrixEvent,
isLive: boolean,
): void => {
const beacon = store.getBeaconById(getBeaconInfoIdentifier(beaconInfoEvent));
// matches original state of event content
// except for live property

View file

@ -20,7 +20,7 @@ import { EventType } from "matrix-js-sdk/src/@types/event";
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
import { defer } from "matrix-js-sdk/src/utils";
import { ClientEvent, RoomEvent, MatrixEvent } from "matrix-js-sdk/src/matrix";
import { ClientEvent, RoomEvent, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import SpaceStore from "../../src/stores/spaces/SpaceStore";
import {
@ -68,7 +68,7 @@ const space2 = "!space2:server";
const space3 = "!space3:server";
const space4 = "!space4:server";
const getUserIdForRoomId = jest.fn((roomId) => {
const getUserIdForRoomId = jest.fn((roomId: string) => {
return {
[dm1]: dm1Partner.userId,
[dm2]: dm2Partner.userId,
@ -97,10 +97,10 @@ describe("SpaceStore", () => {
const spyDispatcher = jest.spyOn(defaultDispatcher, "dispatch");
let rooms = [];
let rooms: Room[] = [];
const mkRoom = (roomId: string) => testUtils.mkRoom(client, roomId, rooms);
const mkSpace = (spaceId: string, children: string[] = []) => testUtils.mkSpace(client, spaceId, rooms, children);
const viewRoom = (roomId) => defaultDispatcher.dispatch({ action: Action.ViewRoom, room_id: roomId }, true);
const viewRoom = (roomId: string) => defaultDispatcher.dispatch({ action: Action.ViewRoom, room_id: roomId }, true);
const run = async () => {
mocked(client).getRoom.mockImplementation((roomId) => rooms.find((room) => room.roomId === roomId));
@ -785,7 +785,7 @@ describe("SpaceStore", () => {
mkSpace(space1, [fav1, room1, space4]);
});
const addChildRoom = (spaceId, childId) => {
const addChildRoom = (spaceId: string, childId: string) => {
const childEvent = mkEvent({
event: true,
type: EventType.SpaceChild,
@ -803,7 +803,7 @@ describe("SpaceStore", () => {
client.emit(RoomStateEvent.Events, childEvent, spaceRoom.currentState, undefined);
};
const addMember = (spaceId, user: RoomMember) => {
const addMember = (spaceId: string, user: RoomMember) => {
const memberEvent = mkEvent({
event: true,
type: EventType.RoomMember,
@ -998,8 +998,8 @@ describe("SpaceStore", () => {
});
describe("context switching tests", () => {
let dispatcherRef;
let currentRoom = null;
let dispatcherRef: string;
let currentRoom: Room | null = null;
beforeEach(async () => {
[room1, room2, orphan1].forEach(mkRoom);

View file

@ -31,7 +31,7 @@ describe("VoiceRecordingStore", () => {
const room1Recording = { destroy: jest.fn() } as unknown as VoiceMessageRecording;
const room2Recording = { destroy: jest.fn() } as unknown as VoiceMessageRecording;
const state = {
const state: Record<string, VoiceMessageRecording | undefined> = {
[room1Id]: room1Recording,
[room2Id]: room2Recording,
[room3Id]: undefined,

View file

@ -13,7 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { mocked } from "jest-mock";
import { Room } from "matrix-js-sdk/src/models/room";
import { SpaceWatcher } from "../../../src/stores/room-list/SpaceWatcher";
import type { RoomListStoreClass } from "../../../src/stores/room-list/RoomListStore";
@ -30,8 +32,8 @@ import DMRoomMap from "../../../src/utils/DMRoomMap";
let filter: SpaceFilterCondition = null;
const mockRoomListStore = {
addFilter: (f) => (filter = f),
removeFilter: () => (filter = null),
addFilter: (f: SpaceFilterCondition) => (filter = f),
removeFilter: (): void => (filter = null),
} as unknown as RoomListStoreClass;
const getUserIdForRoomId = jest.fn();
@ -47,7 +49,7 @@ describe("SpaceWatcher", () => {
const store = SpaceStore.instance;
const client = mocked(MatrixClientPeg.get());
let rooms = [];
let rooms: Room[] = [];
const mkSpaceForRooms = (spaceId: string, children: string[] = []) => mkSpace(client, spaceId, rooms, children);
const setShowAllRooms = async (value: boolean) => {

View file

@ -15,17 +15,20 @@ limitations under the License.
*/
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { stubClient, mkRoom, mkMessage } from "../../../test-utils";
import { mkMessage, mkRoom, stubClient } from "../../../test-utils";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import "../../../../src/stores/room-list/RoomListStore";
import { RecentAlgorithm } from "../../../../src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm";
import { EffectiveMembership } from "../../../../src/utils/membership";
import { makeThreadEvent, mkThread } from "../../../test-utils/threads";
import { DefaultTagID } from "../../../../src/stores/room-list/models";
describe("RecentAlgorithm", () => {
let algorithm;
let cli;
let algorithm: RecentAlgorithm;
let cli: MatrixClient;
beforeEach(() => {
stubClient();
cli = MatrixClientPeg.get();
@ -102,7 +105,7 @@ describe("RecentAlgorithm", () => {
room1.addLiveEvents([evt]);
room2.addLiveEvents([evt2]);
expect(algorithm.sortRooms([room2, room1])).toEqual([room1, room2]);
expect(algorithm.sortRooms([room2, room1], DefaultTagID.Untagged)).toEqual([room1, room2]);
});
it("orders rooms without messages first", () => {
@ -122,7 +125,7 @@ describe("RecentAlgorithm", () => {
room1.addLiveEvents([evt]);
expect(algorithm.sortRooms([room2, room1])).toEqual([room2, room1]);
expect(algorithm.sortRooms([room2, room1], DefaultTagID.Untagged)).toEqual([room2, room1]);
const { events } = mkThread({
room: room1,
@ -162,7 +165,7 @@ describe("RecentAlgorithm", () => {
});
room2.addLiveEvents(events2);
expect(algorithm.sortRooms([room1, room2])).toEqual([room2, room1]);
expect(algorithm.sortRooms([room1, room2], DefaultTagID.Untagged)).toEqual([room2, room1]);
const threadReply = makeThreadEvent({
user: "@bob:matrix.org",
@ -176,7 +179,7 @@ describe("RecentAlgorithm", () => {
});
room1.addLiveEvents([threadReply]);
expect(algorithm.sortRooms([room1, room2])).toEqual([room1, room2]);
expect(algorithm.sortRooms([room1, room2], DefaultTagID.Untagged)).toEqual([room1, room2]);
});
});
});

View file

@ -20,7 +20,7 @@ import { Room } from "matrix-js-sdk/src/matrix";
import SettingsStore from "../../../../src/settings/SettingsStore";
import { FILTER_CHANGED } from "../../../../src/stores/room-list/filters/IFilterCondition";
import { SpaceFilterCondition } from "../../../../src/stores/room-list/filters/SpaceFilterCondition";
import { MetaSpace } from "../../../../src/stores/spaces";
import { MetaSpace, SpaceKey } from "../../../../src/stores/spaces";
import SpaceStore from "../../../../src/stores/spaces/SpaceStore";
jest.mock("../../../../src/settings/SettingsStore");
@ -50,8 +50,8 @@ describe("SpaceFilterCondition", () => {
const user2Id = "@u2:server";
const user3Id = "@u3:server";
const makeMockGetValue =
(settings = {}) =>
(settingName, space) =>
(settings: Record<string, any> = {}) =>
(settingName: string, space: SpaceKey) =>
settings[settingName]?.[space] || false;
beforeEach(() => {
@ -61,7 +61,7 @@ describe("SpaceFilterCondition", () => {
SpaceStoreInstanceMock.isRoomInSpace.mockReturnValue(true);
});
const initFilter = (space): SpaceFilterCondition => {
const initFilter = (space: SpaceKey): SpaceFilterCondition => {
const filter = new SpaceFilterCondition();
filter.updateSpace(space);
jest.runOnlyPendingTimers();

View file

@ -38,7 +38,7 @@ describe("WidgetPermissionStore", () => {
type: "m.custom",
url: "https://invalid.address.here",
});
let settings = {}; // key value store
let settings: Record<string, any> = {}; // key value store
beforeEach(() => {
settings = {}; // clear settings

View file

@ -165,7 +165,7 @@ export const mockGeolocation = (): MockedObject<Geolocation> => {
* See for error codes: https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPositionError
*/
export const watchPositionMockImplementation = (delays: number[], errorCodes: number[] = []) => {
return (callback: PositionCallback, error: PositionErrorCallback) => {
return (callback: PositionCallback, error: PositionErrorCallback): number => {
const position = makeGeolocationPosition({});
let totalDelay = 0;
@ -180,6 +180,8 @@ export const watchPositionMockImplementation = (delays: number[], errorCodes: nu
}, totalDelay);
return timeout;
});
return totalDelay;
};
};

View file

@ -24,12 +24,12 @@ export const addTextToComposer = (container: HTMLElement, text: string) =>
act(() => {
// couldn't get input event on contenteditable to work
// paste works without illegal private method access
const pasteEvent = {
const pasteEvent: Partial<ClipboardEvent> = {
clipboardData: {
types: [],
files: [],
getData: (type) => (type === "text/plain" ? text : undefined),
},
getData: (type: string) => (type === "text/plain" ? text : undefined),
} as unknown as DataTransfer,
};
fireEvent.paste(container.querySelector('[role="textbox"]'), pasteEvent);
});
@ -38,12 +38,12 @@ export const addTextToComposerEnzyme = (wrapper: ReactWrapper, text: string) =>
act(() => {
// couldn't get input event on contenteditable to work
// paste works without illegal private method access
const pasteEvent = {
const pasteEvent: Partial<ClipboardEvent> = {
clipboardData: {
types: [],
files: [],
getData: (type) => (type === "text/plain" ? text : undefined),
},
getData: (type: string) => (type === "text/plain" ? text : undefined),
} as unknown as DataTransfer,
};
wrapper.find('[role="textbox"]').simulate("paste", pasteEvent);
wrapper.update();

View file

@ -47,7 +47,7 @@ export function untilDispatch(
const callback = waitForAction as (payload: ActionPayload) => boolean;
return new Promise((resolve, reject) => {
let fulfilled = false;
let timeoutId;
let timeoutId: number;
// set a timeout handler if needed
if (timeout > 0) {
timeoutId = window.setTimeout(() => {
@ -95,7 +95,7 @@ export function untilEmission(
const callerLine = new Error().stack.toString().split("\n")[2];
return new Promise((resolve, reject) => {
let fulfilled = false;
let timeoutId;
let timeoutId: number;
// set a timeout handler if needed
if (timeout > 0) {
timeoutId = window.setTimeout(() => {

View file

@ -26,7 +26,7 @@ type WrapperProps<T> = { wrappedRef?: RefCallback<ComponentType<T>> } & T;
export function wrapInMatrixClientContext<T>(WrappedComponent: ComponentType<T>): ComponentType<WrapperProps<T>> {
class Wrapper extends React.Component<WrapperProps<T>> {
_matrixClient: MatrixClient;
constructor(props) {
constructor(props: WrapperProps<T>) {
super(props);
this._matrixClient = peg.get();

View file

@ -18,33 +18,29 @@ import { setTheme } from "../src/theme";
describe("theme", () => {
describe("setTheme", () => {
let lightTheme;
let darkTheme;
let lightTheme: HTMLStyleElement;
let darkTheme: HTMLStyleElement;
let spyQuerySelectorAll: jest.MockInstance<NodeListOf<Element>, [selectors: string]>;
beforeEach(() => {
const styles = [
{
attributes: {
"data-mx-theme": {
value: "light",
},
dataset: {
mxTheme: "light",
},
disabled: true,
href: "urlLight",
onload: () => void 0,
},
onload: (): void => void 0,
} as unknown as HTMLStyleElement,
{
attributes: {
"data-mx-theme": {
value: "dark",
},
dataset: {
mxTheme: "dark",
},
disabled: true,
href: "urlDark",
onload: () => void 0,
},
onload: (): void => void 0,
} as unknown as HTMLStyleElement,
];
lightTheme = styles[0];
darkTheme = styles[1];
@ -62,7 +58,7 @@ describe("theme", () => {
// When
await new Promise((resolve) => {
setTheme("light").then(resolve);
lightTheme.onload();
lightTheme.onload(void 0);
});
// Then

View file

@ -42,7 +42,7 @@ describe("formatSeconds", () => {
});
describe("formatRelativeTime", () => {
let dateSpy;
let dateSpy: jest.SpyInstance<number, []>;
beforeAll(() => {
dateSpy = jest
.spyOn(global.Date, "now")

View file

@ -18,6 +18,8 @@ import { TextEncoder } from "util";
import nodeCrypto from "crypto";
import { Crypto } from "@peculiar/webcrypto";
import type * as MegolmExportEncryptionExport from "../../src/utils/MegolmExportEncryption";
const webCrypto = new Crypto();
function getRandomValues<T extends ArrayBufferView>(buf: T): T {
@ -70,7 +72,7 @@ function stringToArray(s: string): ArrayBufferLike {
}
describe("MegolmExportEncryption", function () {
let MegolmExportEncryption;
let MegolmExportEncryption: typeof MegolmExportEncryptionExport;
beforeEach(() => {
window.crypto = {
@ -131,7 +133,7 @@ cissyYBxjsfsAn
// TODO find a subtlecrypto shim which doesn't break this test
it.skip("should decrypt a range of inputs", function () {
function next(i) {
function next(i: number): unknown {
if (i >= TEST_VECTORS.length) {
return;
}

View file

@ -29,7 +29,7 @@ const MXID1 = "@user1:server";
const MXID2 = "@user2:server";
const MXID3 = "@user3:server";
const MXID_PROFILE_STATES = {
const MXID_PROFILE_STATES: Record<string, Promise<any>> = {
[MXID1]: Promise.resolve({}),
[MXID2]: Promise.reject({ errcode: "M_FORBIDDEN" }),
[MXID3]: Promise.reject({ errcode: "M_NOT_FOUND" }),

View file

@ -22,14 +22,14 @@ import DMRoomMap from "../../src/utils/DMRoomMap";
function mkClient(selfTrust = false) {
return {
getUserId: () => "@self:localhost",
checkUserTrust: (userId) => ({
checkUserTrust: (userId: string) => ({
isCrossSigningVerified: () => userId[1] == "T",
wasCrossSigningVerified: () => userId[1] == "T" || userId[1] == "W",
}),
checkDeviceTrust: (userId, deviceId) => ({
checkDeviceTrust: (userId: string, deviceId: string) => ({
isVerified: () => (userId === "@self:localhost" ? selfTrust : userId[2] == "T"),
}),
getStoredDevicesForUser: (userId) => ["DEVICE"],
getStoredDevicesForUser: (userId: string) => ["DEVICE"],
} as unknown as MatrixClient;
}
@ -61,7 +61,7 @@ describe("mkClient self-test", function () {
describe("shieldStatusForMembership self-trust behaviour", function () {
beforeAll(() => {
const mockInstance = {
getUserIdForRoomId: (roomId) => (roomId === "DM" ? "@any:h" : null),
getUserIdForRoomId: (roomId: string) => (roomId === "DM" ? "@any:h" : null),
} as unknown as DMRoomMap;
jest.spyOn(DMRoomMap, "shared").mockReturnValue(mockInstance);
});
@ -164,7 +164,7 @@ describe("shieldStatusForMembership self-trust behaviour", function () {
describe("shieldStatusForMembership other-trust behaviour", function () {
beforeAll(() => {
const mockInstance = {
getUserIdForRoomId: (roomId) => (roomId === "DM" ? "@any:h" : null),
getUserIdForRoomId: (roomId: string) => (roomId === "DM" ? "@any:h" : null),
} as unknown as DMRoomMap;
jest.spyOn(DMRoomMap, "shared").mockReturnValue(mockInstance);
});

View file

@ -15,8 +15,10 @@ limitations under the License.
*/
import { logger } from "matrix-js-sdk/src/logger";
import { Mocked } from "jest-mock";
import {
GenericPosition,
GeolocationError,
getGeoUri,
mapGeolocationError,
@ -27,7 +29,7 @@ import { getCurrentPosition } from "../../../src/utils/beacon/geolocation";
import { makeGeolocationPosition, mockGeolocation, getMockGeolocationPositionError } from "../../test-utils";
describe("geolocation utilities", () => {
let geolocation;
let geolocation: Mocked<Geolocation>;
const defaultPosition = makeGeolocationPosition({});
// 14.03.2022 16:15
@ -45,7 +47,7 @@ describe("geolocation utilities", () => {
describe("getGeoUri", () => {
it("Renders a URI with only lat and lon", () => {
const pos = {
const pos: GenericPosition = {
latitude: 43.2,
longitude: 12.4,
altitude: undefined,
@ -57,7 +59,7 @@ describe("geolocation utilities", () => {
});
it("Nulls in location are not shown in URI", () => {
const pos = {
const pos: GenericPosition = {
latitude: 43.2,
longitude: 12.4,
altitude: null,
@ -69,7 +71,7 @@ describe("geolocation utilities", () => {
});
it("Renders a URI with 3 coords", () => {
const pos = {
const pos: GenericPosition = {
latitude: 43.2,
longitude: 12.4,
altitude: 332.54,
@ -80,7 +82,7 @@ describe("geolocation utilities", () => {
});
it("Renders a URI with accuracy", () => {
const pos = {
const pos: GenericPosition = {
latitude: 43.2,
longitude: 12.4,
altitude: undefined,
@ -193,9 +195,10 @@ describe("geolocation utilities", () => {
it("maps geolocation position error and calls error handler", () => {
// suppress expected errors from test log
jest.spyOn(logger, "error").mockImplementation(() => {});
geolocation.watchPosition.mockImplementation((_callback, error) =>
error(getMockGeolocationPositionError(1, "message")),
);
geolocation.watchPosition.mockImplementation((_callback, error) => {
error(getMockGeolocationPositionError(1, "message"));
return -1;
});
const positionHandler = jest.fn();
const errorHandler = jest.fn();
watchPosition(positionHandler, errorHandler);

View file

@ -291,7 +291,7 @@ describe("export", function () {
it("tests the file extension splitter", function () {
const exporter = new PlainTextExporter(mockRoom, ExportType.Beginning, mockExportOptions, null);
const fileNameWithExtensions = {
const fileNameWithExtensions: Record<string, [string, string]> = {
"": ["", ""],
"name": ["name", ""],
"name.txt": ["name", ".txt"],

View file

@ -67,7 +67,7 @@ describe("local-room", () => {
});
describe("for a local room", () => {
let prom;
let prom: Promise<unknown>;
beforeEach(() => {
jest.spyOn(defaultDispatcher, "dispatch");

View file

@ -41,8 +41,8 @@ describe("isSelfLocation", () => {
[M_TEXT.name]: "",
[M_TIMESTAMP.name]: 0,
// Note: no m.asset!
};
expect(isSelfLocation(content as ILocationContent)).toBe(true);
} as unknown as ILocationContent;
expect(isSelfLocation(content)).toBe(true);
});
it("Returns true for a missing m.asset type", () => {
@ -56,8 +56,8 @@ describe("isSelfLocation", () => {
[M_ASSET.name]: {
// Note: no type!
},
};
expect(isSelfLocation(content as ILocationContent)).toBe(true);
} as unknown as ILocationContent;
expect(isSelfLocation(content)).toBe(true);
});
it("Returns false for an unknown asset type", () => {

View file

@ -15,6 +15,7 @@ limitations under the License.
*/
import { EventEmitter } from "events";
import { MatrixClient, RoomStateEvent } from "matrix-js-sdk/src/matrix";
import { waitForMember } from "../../src/utils/membership";
@ -22,14 +23,14 @@ import { waitForMember } from "../../src/utils/membership";
const timeout = 30;
describe("waitForMember", () => {
let client;
let client: EventEmitter;
beforeEach(() => {
client = new EventEmitter();
});
it("resolves with false if the timeout is reached", (done) => {
waitForMember(client, "", "", { timeout: 0 }).then((r) => {
waitForMember(<MatrixClient>client, "", "", { timeout: 0 }).then((r) => {
expect(r).toBe(false);
done();
});
@ -38,7 +39,7 @@ describe("waitForMember", () => {
it("resolves with false if the timeout is reached, even if other RoomState.newMember events fire", (done) => {
const roomId = "!roomId:domain";
const userId = "@clientId:domain";
waitForMember(client, roomId, userId, { timeout }).then((r) => {
waitForMember(<MatrixClient>client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(false);
done();
});
@ -48,9 +49,9 @@ describe("waitForMember", () => {
it("resolves with true if RoomState.newMember fires", (done) => {
const roomId = "!roomId:domain";
const userId = "@clientId:domain";
waitForMember(client, roomId, userId, { timeout }).then((r) => {
waitForMember(<MatrixClient>client, roomId, userId, { timeout }).then((r) => {
expect(r).toBe(true);
expect(client.listeners("RoomState.newMember").length).toBe(0);
expect((<MatrixClient>client).listeners(RoomStateEvent.NewMember).length).toBe(0);
done();
});
client.emit("RoomState.newMember", undefined, undefined, { roomId, userId });

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { mocked } from "jest-mock";
import { Mocked, mocked } from "jest-mock";
import { MatrixClient } from "matrix-js-sdk/src/client";
import { NotificationCountType, Room } from "matrix-js-sdk/src/models/room";
import { ReceiptType } from "matrix-js-sdk/src/@types/read_receipts";
@ -36,9 +36,9 @@ import { MatrixClientPeg } from "../../src/MatrixClientPeg";
jest.mock("../../src/settings/SettingsStore");
describe("notifications", () => {
let accountDataStore = {};
let mockClient;
let accountDataEventKey;
let accountDataStore: Record<string, MatrixEvent> = {};
let mockClient: Mocked<MatrixClient>;
let accountDataEventKey: string;
beforeEach(() => {
jest.clearAllMocks();

View file

@ -43,7 +43,7 @@ describe("Permalinks", function () {
serverACLContent?: { deny?: string[]; allow?: string[] },
): Room {
members.forEach((m) => (m.membership = "join"));
const powerLevelsUsers = members.reduce((pl, member) => {
const powerLevelsUsers = members.reduce<Record<string, number>>((pl, member) => {
if (Number.isFinite(member.powerLevel)) {
pl[member.userId] = member.powerLevel;
}

View file

@ -15,7 +15,7 @@ limitations under the License.
*/
import { Optional } from "matrix-events-sdk";
import { EventType, MatrixEvent, MsgType, RelationType, Room, RoomMember } from "matrix-js-sdk/src/matrix";
import { EventType, IContent, MatrixEvent, MsgType, RelationType, Room, RoomMember } from "matrix-js-sdk/src/matrix";
import { SdkContextClass } from "../../../src/contexts/SDKContext";
import {
@ -41,7 +41,7 @@ export const mkVoiceBroadcastInfoStateEvent = (
startedInfoEvent?: MatrixEvent,
lastChunkSequence?: number,
): MatrixEvent => {
const relationContent = {};
const relationContent: IContent = {};
if (startedInfoEvent) {
relationContent["m.relates_to"] = {