1
0
mirror of https://github.com/matrix-org/matrix-react-sdk.git synced 2025-07-30 02:21:17 +03:00

Apply prettier formatting

This commit is contained in:
Michael Weimann
2022-12-12 12:24:14 +01:00
parent 1cac306093
commit 526645c791
1576 changed files with 65385 additions and 62478 deletions

View File

@ -16,12 +16,7 @@ limitations under the License.
import { MockedObject } from "jest-mock";
import { makeBeaconInfoContent, makeBeaconContent } from "matrix-js-sdk/src/content-helpers";
import {
MatrixClient,
MatrixEvent,
Beacon,
getBeaconInfoIdentifier,
} from "matrix-js-sdk/src/matrix";
import { MatrixClient, MatrixEvent, Beacon, getBeaconInfoIdentifier } from "matrix-js-sdk/src/matrix";
import { M_BEACON, M_BEACON_INFO } from "matrix-js-sdk/src/@types/beacon";
import { LocationAssetType } from "matrix-js-sdk/src/@types/location";
@ -50,13 +45,7 @@ export const makeBeaconInfoEvent = (
contentProps: Partial<InfoContentProps> = {},
eventId?: string,
): MatrixEvent => {
const {
timeout,
isLive,
description,
assetType,
timestamp,
} = {
const { timeout, isLive, description, assetType, timestamp } = {
...DEFAULT_INFO_CONTENT_PROPS,
...contentProps,
};
@ -84,9 +73,9 @@ type ContentProps = {
description?: string;
};
const DEFAULT_CONTENT_PROPS: ContentProps = {
geoUri: 'geo:-36.24484561954707,175.46884959563613;u=10',
geoUri: "geo:-36.24484561954707,175.46884959563613;u=10",
timestamp: 123,
beaconInfoId: '$123',
beaconInfoId: "$123",
};
/**
@ -116,10 +105,13 @@ export const makeBeaconEvent = (
* Create a mock geolocation position
* defaults all required properties
*/
export const makeGeolocationPosition = (
{ timestamp, coords }:
{ timestamp?: number, coords?: Partial<GeolocationCoordinates> },
): GeolocationPosition => ({
export const makeGeolocationPosition = ({
timestamp,
coords,
}: {
timestamp?: number;
coords?: Partial<GeolocationCoordinates>;
}): GeolocationPosition => ({
timestamp: timestamp ?? 1647256791840,
coords: {
accuracy: 1,
@ -141,8 +133,8 @@ export const makeGeolocationPosition = (
export const mockGeolocation = (): MockedObject<Geolocation> => {
const mockGeolocation = {
clearWatch: jest.fn(),
getCurrentPosition: jest.fn().mockImplementation(callback => callback(makeGeolocationPosition({}))),
watchPosition: jest.fn().mockImplementation(callback => callback(makeGeolocationPosition({}))),
getCurrentPosition: jest.fn().mockImplementation((callback) => callback(makeGeolocationPosition({}))),
watchPosition: jest.fn().mockImplementation((callback) => callback(makeGeolocationPosition({}))),
} as unknown as MockedObject<Geolocation>;
// jest jsdom does not provide geolocation
@ -181,7 +173,7 @@ export const watchPositionMockImplementation = (delays: number[], errorCodes: nu
totalDelay += delayMs;
const timeout = window.setTimeout(() => {
if (errorCodes[index]) {
error(getMockGeolocationPositionError(errorCodes[index], 'error message'));
error(getMockGeolocationPositionError(errorCodes[index], "error message"));
} else {
callback({ ...position, timestamp: position.timestamp + totalDelay });
}
@ -203,11 +195,11 @@ export const makeRoomWithBeacons = (
locationEvents?: MatrixEvent[],
): Beacon[] => {
const room = makeRoomWithStateEvents(beaconInfoEvents, { roomId, mockClient });
const beacons = beaconInfoEvents.map(event => room.currentState.beacons.get(getBeaconInfoIdentifier(event)));
const beacons = beaconInfoEvents.map((event) => room.currentState.beacons.get(getBeaconInfoIdentifier(event)));
if (locationEvents) {
beacons.forEach(beacon => {
beacons.forEach((beacon) => {
// this filtering happens in roomState, which is bypassed here
const validLocationEvents = locationEvents?.filter(event => event.getSender() === beacon.beaconInfoOwner);
const validLocationEvents = locationEvents?.filter((event) => event.getSender() === beacon.beaconInfoOwner);
beacon.addLocations(validLocationEvents);
});
}

View File

@ -45,21 +45,21 @@ export class MockedCall extends Call {
public static get(room: Room): MockedCall | null {
const [event] = room.currentState.getStateEvents(this.EVENT_TYPE);
return (event === undefined || "m.terminated" in event.getContent())
? null
: new MockedCall(room, event);
return event === undefined || "m.terminated" in event.getContent() ? null : new MockedCall(room, event);
}
public static create(room: Room, id: string) {
room.addLiveEvents([mkEvent({
event: true,
type: this.EVENT_TYPE,
room: room.roomId,
user: "@alice:example.org",
content: { "m.type": "m.video", "m.intent": "m.prompt" },
skey: id,
ts: Date.now(),
})]);
room.addLiveEvents([
mkEvent({
event: true,
type: this.EVENT_TYPE,
room: room.roomId,
user: "@alice:example.org",
content: { "m.type": "m.video", "m.intent": "m.prompt" },
skey: id,
ts: Date.now(),
}),
]);
// @ts-ignore deliberately calling a private method
// Let CallStore know that a call might now exist
CallStore.instance.updateRoom(room);
@ -86,15 +86,17 @@ export class MockedCall extends Call {
public destroy() {
// Terminate the call for good measure
this.room.addLiveEvents([mkEvent({
event: true,
type: MockedCall.EVENT_TYPE,
room: this.room.roomId,
user: "@alice:example.org",
content: { ...this.event.getContent(), "m.terminated": "Call ended" },
skey: this.widget.id,
ts: Date.now(),
})]);
this.room.addLiveEvents([
mkEvent({
event: true,
type: MockedCall.EVENT_TYPE,
room: this.room.roomId,
user: "@alice:example.org",
content: { ...this.event.getContent(), "m.terminated": "Call ended" },
skey: this.widget.id,
ts: Date.now(),
}),
]);
super.destroy();
}
@ -104,7 +106,7 @@ export class MockedCall extends Call {
* Sets up the call store to use mocked calls.
*/
export const useMockedCalls = () => {
Call.get = room => MockedCall.get(room);
JitsiCall.create = async room => MockedCall.create(room, "1");
ElementCall.create = async room => MockedCall.create(room, "1");
Call.get = (room) => MockedCall.get(room);
JitsiCall.create = async (room) => MockedCall.create(room, "1");
ElementCall.create = async (room) => MockedCall.create(room, "1");
};

View File

@ -32,7 +32,7 @@ export class MockEventEmitter<T> extends EventEmitter {
* @param mockProperties An object with the mock property or function implementations. 'getters'
* are correctly cloned to this event emitter.
*/
constructor(mockProperties: Partial<Record<MethodLikeKeys<T>|PropertyLikeKeys<T>, unknown>> = {}) {
constructor(mockProperties: Partial<Record<MethodLikeKeys<T> | PropertyLikeKeys<T>, unknown>> = {}) {
super();
// We must use defineProperties and not assign as the former clones getters correctly,
// whereas the latter invokes the getter and sets the return value permanently on the
@ -70,17 +70,17 @@ export const getMockClientWithEventEmitter = (
): MockedObject<MatrixClient> => {
const mock = mocked(new MockClientWithEventEmitter(mockProperties) as unknown as MatrixClient);
jest.spyOn(MatrixClientPeg, 'get').mockReturnValue(mock);
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(mock);
// @ts-ignore simplified test stub
mock.canSupport = new Map();
Object.keys(Feature).forEach(feature => {
Object.keys(Feature).forEach((feature) => {
mock.canSupport.set(feature as Feature, ServerSupport.Stable);
});
return mock;
};
export const unmockClientPeg = () => jest.spyOn(MatrixClientPeg, 'get').mockRestore();
export const unmockClientPeg = () => jest.spyOn(MatrixClientPeg, "get").mockRestore();
/**
* Returns basic mocked client methods related to the current user
@ -90,11 +90,11 @@ export const unmockClientPeg = () => jest.spyOn(MatrixClientPeg, 'get').mockRest
});
* ```
*/
export const mockClientMethodsUser = (userId = '@alice:domain') => ({
export const mockClientMethodsUser = (userId = "@alice:domain") => ({
getUserId: jest.fn().mockReturnValue(userId),
getUser: jest.fn().mockReturnValue(new User(userId)),
isGuest: jest.fn().mockReturnValue(false),
mxcUrlToHttp: jest.fn().mockReturnValue('mock-mxcUrlToHttp'),
mxcUrlToHttp: jest.fn().mockReturnValue("mock-mxcUrlToHttp"),
credentials: { userId },
getThreePids: jest.fn().mockResolvedValue({ threepids: [] }),
getAccessToken: jest.fn(),
@ -130,15 +130,15 @@ export const mockClientMethodsServer = (): Partial<Record<MethodLikeKeys<MatrixC
});
export const mockClientMethodsDevice = (
deviceId = 'test-device-id',
deviceId = "test-device-id",
): Partial<Record<MethodLikeKeys<MatrixClient>, unknown>> => ({
getDeviceId: jest.fn().mockReturnValue(deviceId),
getDeviceEd25519Key: jest.fn(),
getDevices: jest.fn().mockResolvedValue({ devices: [] }),
});
export const mockClientMethodsCrypto = (): Partial<Record<
MethodLikeKeys<MatrixClient> & PropertyLikeKeys<MatrixClient>, unknown>
export const mockClientMethodsCrypto = (): Partial<
Record<MethodLikeKeys<MatrixClient> & PropertyLikeKeys<MatrixClient>, unknown>
> => ({
isCryptoEnabled: jest.fn(),
isSecretStorageReady: jest.fn(),
@ -156,4 +156,3 @@ export const mockClientMethodsCrypto = (): Partial<Record<
},
},
});

View File

@ -19,29 +19,31 @@ import { ReactWrapper } from "enzyme";
import { act } from "react-dom/test-utils";
import { fireEvent } from "@testing-library/react";
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 = {
clipboardData: {
types: [],
files: [],
getData: type => type === "text/plain" ? text : undefined,
},
};
fireEvent.paste(container.querySelector('[role="textbox"]'), pasteEvent);
});
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 = {
clipboardData: {
types: [],
files: [],
getData: (type) => (type === "text/plain" ? text : undefined),
},
};
fireEvent.paste(container.querySelector('[role="textbox"]'), pasteEvent);
});
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 = {
clipboardData: {
types: [],
files: [],
getData: type => type === "text/plain" ? text : undefined,
},
};
wrapper.find('[role="textbox"]').simulate('paste', pasteEvent);
wrapper.update();
});
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 = {
clipboardData: {
types: [],
files: [],
getData: (type) => (type === "text/plain" ? text : undefined),
},
};
wrapper.find('[role="textbox"]').simulate("paste", pasteEvent);
wrapper.update();
});

View File

@ -30,12 +30,12 @@ const originalFunctions: FilteredConsole = {
* @param ignoreList Messages to be filtered
* @returns function to restore the console
*/
export const filterConsole = (...ignoreList: string[]): () => void => {
export const filterConsole = (...ignoreList: string[]): (() => void) => {
for (const [key, originalFunction] of Object.entries(originalFunctions)) {
window.console[key as keyof FilteredConsole] = (...data: any[]) => {
const message = data?.[0]?.message || data?.[0];
if (typeof message === "string" && ignoreList.some(i => message.includes(i))) {
if (typeof message === "string" && ignoreList.some((i) => message.includes(i))) {
return;
}

View File

@ -14,16 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
export * from './beacon';
export * from './client';
export * from './location';
export * from './platform';
export * from './poll';
export * from './room';
export * from './test-utils';
export * from './call';
export * from './wrappers';
export * from './utilities';
export * from './date';
export * from './relations';
export * from './console';
export * from "./beacon";
export * from "./client";
export * from "./location";
export * from "./platform";
export * from "./poll";
export * from "./room";
export * from "./test-utils";
export * from "./call";
export * from "./wrappers";
export * from "./utilities";
export * from "./date";
export * from "./relations";
export * from "./console";

View File

@ -20,38 +20,35 @@ import { MatrixEvent, EventType } from "matrix-js-sdk/src/matrix";
let id = 1;
export const makeLegacyLocationEvent = (geoUri: string): MatrixEvent => {
return new MatrixEvent(
{
"event_id": `$${++id}`,
"type": EventType.RoomMessage,
"content": {
"body": "Something about where I am",
"msgtype": "m.location",
"geo_uri": geoUri,
},
return new MatrixEvent({
event_id: `$${++id}`,
type: EventType.RoomMessage,
content: {
body: "Something about where I am",
msgtype: "m.location",
geo_uri: geoUri,
},
);
});
};
export const makeLocationEvent = (geoUri: string, assetType?: LocationAssetType): MatrixEvent => {
return new MatrixEvent(
{
"event_id": `$${++id}`,
"type": M_LOCATION.name,
"content": makeLocationContent(
`Found at ${geoUri} at 2021-12-21T12:22+0000`,
geoUri,
252523,
"Human-readable label",
assetType,
),
},
);
return new MatrixEvent({
event_id: `$${++id}`,
type: M_LOCATION.name,
content: makeLocationContent(
`Found at ${geoUri} at 2021-12-21T12:22+0000`,
geoUri,
252523,
"Human-readable label",
assetType,
),
});
};
// https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPositionError
export const getMockGeolocationPositionError = (code: number, message: string): GeolocationPositionError => ({
code, message,
code,
message,
PERMISSION_DENIED: 1,
POSITION_UNAVAILABLE: 2,
TIMEOUT: 3,

View File

@ -37,10 +37,10 @@ export const mockPlatformPeg = (
platformMocks: Partial<Record<MethodLikeKeys<BasePlatform>, unknown>> = {},
): MockedObject<BasePlatform> => {
const mockPlatform = new MockPlatform(platformMocks);
jest.spyOn(PlatformPeg, 'get').mockReturnValue(mockPlatform);
jest.spyOn(PlatformPeg, "get").mockReturnValue(mockPlatform);
return mocked(mockPlatform);
};
export const unmockPlatformPeg = () => {
jest.spyOn(PlatformPeg, 'get').mockRestore();
jest.spyOn(PlatformPeg, "get").mockRestore();
};

View File

@ -17,34 +17,28 @@ limitations under the License.
import { MatrixEvent } from "matrix-js-sdk/src/matrix";
import { M_TEXT, M_POLL_START, POLL_ANSWER, M_POLL_KIND_DISCLOSED } from "matrix-events-sdk";
export const makePollStartEvent = (
question: string,
sender: string,
answers?: POLL_ANSWER[],
): MatrixEvent => {
export const makePollStartEvent = (question: string, sender: string, answers?: POLL_ANSWER[]): MatrixEvent => {
if (!answers) {
answers = [
{ "id": "socks", [M_TEXT.name]: "Socks" },
{ "id": "shoes", [M_TEXT.name]: "Shoes" },
{ id: "socks", [M_TEXT.name]: "Socks" },
{ id: "shoes", [M_TEXT.name]: "Shoes" },
];
}
return new MatrixEvent(
{
"event_id": "$mypoll",
"room_id": "#myroom:example.com",
"sender": sender,
"type": M_POLL_START.name,
"content": {
[M_POLL_START.name]: {
"question": {
[M_TEXT.name]: question,
},
"kind": M_POLL_KIND_DISCLOSED.name,
"answers": answers,
return new MatrixEvent({
event_id: "$mypoll",
room_id: "#myroom:example.com",
sender: sender,
type: M_POLL_START.name,
content: {
[M_POLL_START.name]: {
question: {
[M_TEXT.name]: question,
},
[M_TEXT.name]: `${question}: answers`,
kind: M_POLL_KIND_DISCLOSED.name,
answers: answers,
},
[M_TEXT.name]: `${question}: answers`,
},
);
});
};

View File

@ -20,9 +20,7 @@ import { RelationsContainer } from "matrix-js-sdk/src/models/relations-container
import { PublicInterface } from "../@types/common";
export const mkRelations = (): Relations => {
return {
} as PublicInterface<Relations> as Relations;
return {} as PublicInterface<Relations> as Relations;
};
export const mkRelationsContainer = (): RelationsContainer => {

View File

@ -15,29 +15,23 @@ limitations under the License.
*/
import { MockedObject } from "jest-mock";
import {
MatrixClient,
MatrixEvent,
EventType,
Room,
} from "matrix-js-sdk/src/matrix";
import { MatrixClient, MatrixEvent, EventType, Room } from "matrix-js-sdk/src/matrix";
import { IRoomState } from "../../src/components/structures/RoomView";
import { TimelineRenderingType } from "../../src/contexts/RoomContext";
import { Layout } from "../../src/settings/enums/Layout";
import { mkEvent } from "./test-utils";
export const makeMembershipEvent = (
roomId: string, userId: string, membership = 'join',
) => mkEvent({
event: true,
type: EventType.RoomMember,
room: roomId,
user: userId,
skey: userId,
content: { membership },
ts: Date.now(),
});
export const makeMembershipEvent = (roomId: string, userId: string, membership = "join") =>
mkEvent({
event: true,
type: EventType.RoomMember,
room: roomId,
user: userId,
skey: userId,
content: { membership },
ts: Date.now(),
});
/**
* Creates a room
@ -47,8 +41,9 @@ export const makeMembershipEvent = (
*/
export const makeRoomWithStateEvents = (
stateEvents: MatrixEvent[] = [],
{ roomId, mockClient }: { roomId: string, mockClient: MockedObject<MatrixClient>}): Room => {
const room1 = new Room(roomId, mockClient, '@user:server.org');
{ roomId, mockClient }: { roomId: string; mockClient: MockedObject<MatrixClient> },
): Room => {
const room1 = new Room(roomId, mockClient, "@user:server.org");
room1.currentState.setStateEvents(stateEvents);
mockClient.getRoom.mockReturnValue(room1);
return room1;

View File

@ -15,9 +15,9 @@ limitations under the License.
*/
import EventEmitter from "events";
import { mocked, MockedObject } from 'jest-mock';
import { mocked, MockedObject } from "jest-mock";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { JoinRule } from 'matrix-js-sdk/src/@types/partials';
import { JoinRule } from "matrix-js-sdk/src/@types/partials";
import {
Room,
User,
@ -33,14 +33,14 @@ import {
IPusher,
RoomType,
KNOWN_SAFE_ROOM_VERSION,
} from 'matrix-js-sdk/src/matrix';
} from "matrix-js-sdk/src/matrix";
import { normalize } from "matrix-js-sdk/src/utils";
import { ReEmitter } from "matrix-js-sdk/src/ReEmitter";
import { MediaHandler } from "matrix-js-sdk/src/webrtc/mediaHandler";
import { Feature, ServerSupport } from "matrix-js-sdk/src/feature";
import type { GroupCall } from "matrix-js-sdk/src/webrtc/groupCall";
import { MatrixClientPeg as peg } from '../../src/MatrixClientPeg';
import { MatrixClientPeg as peg } from "../../src/MatrixClientPeg";
import { makeType } from "../../src/utils/TypeUtils";
import { ValidatedServerConfig } from "../../src/utils/ValidatedServerConfig";
import { EnhancedMap } from "../../src/utils/maps";
@ -62,12 +62,14 @@ export function stubClient(): MatrixClient {
//
// 'sandbox.restore()' doesn't work correctly on inherited methods,
// so we do this for each method
jest.spyOn(peg, 'get');
jest.spyOn(peg, 'unset');
jest.spyOn(peg, 'replaceUsingCreds');
jest.spyOn(peg, "get");
jest.spyOn(peg, "unset");
jest.spyOn(peg, "replaceUsingCreds");
// MatrixClientPeg.get() is called a /lot/, so implement it with our own
// fast stub function rather than a sinon stub
peg.get = function() { return client; };
peg.get = function () {
return client;
};
MatrixClientBackedSettingsHandler.matrixClient = client;
return client;
}
@ -108,7 +110,7 @@ export function createTestClient(): MatrixClient {
},
getPushActionsForEvent: jest.fn(),
getRoom: jest.fn().mockImplementation(roomId => mkStubRoom(roomId, "My room", client)),
getRoom: jest.fn().mockImplementation((roomId) => mkStubRoom(roomId, "My room", client)),
getRooms: jest.fn().mockReturnValue([]),
getVisibleRooms: jest.fn().mockReturnValue([]),
loginFlows: jest.fn(),
@ -196,7 +198,7 @@ export function createTestClient(): MatrixClient {
} as unknown as MediaHandler),
uploadContent: jest.fn(),
getEventMapper: () => (opts) => new MatrixEvent(opts),
leaveRoomChain: jest.fn(roomId => ({ [roomId]: null })),
leaveRoomChain: jest.fn((roomId) => ({ [roomId]: null })),
doesServerSupportLogoutDevices: jest.fn().mockReturnValue(true),
requestPasswordEmailToken: jest.fn().mockRejectedValue({}),
setPassword: jest.fn().mockRejectedValue({}),
@ -206,7 +208,7 @@ export function createTestClient(): MatrixClient {
client.reEmitter = new ReEmitter(client);
client.canSupport = new Map();
Object.keys(Feature).forEach(feature => {
Object.keys(Feature).forEach((feature) => {
client.canSupport.set(feature as Feature, ServerSupport.Stable);
});
@ -278,16 +280,26 @@ export function mkEvent(opts: MakeEventProps): MatrixEvent {
};
if (opts.skey !== undefined) {
event.state_key = opts.skey;
} else if ([
"m.room.name", "m.room.topic", "m.room.create", "m.room.join_rules",
"m.room.power_levels", "m.room.topic", "m.room.history_visibility",
"m.room.encryption", "m.room.member", "com.example.state",
"m.room.guest_access", "m.room.tombstone",
].indexOf(opts.type) !== -1) {
} else if (
[
"m.room.name",
"m.room.topic",
"m.room.create",
"m.room.join_rules",
"m.room.power_levels",
"m.room.topic",
"m.room.history_visibility",
"m.room.encryption",
"m.room.member",
"com.example.state",
"m.room.guest_access",
"m.room.tombstone",
].indexOf(opts.type) !== -1
) {
event.state_key = "";
}
const mxEvent = opts.event ? new MatrixEvent(event) : event as unknown as MatrixEvent;
const mxEvent = opts.event ? new MatrixEvent(event) : (event as unknown as MatrixEvent);
if (!mxEvent.sender && opts.user && opts.room) {
mxEvent.sender = {
userId: opts.user,
@ -341,15 +353,17 @@ export function mkPresence(opts) {
* @param {boolean} opts.event True to make a MatrixEvent.
* @return {Object|MatrixEvent} The event
*/
export function mkMembership(opts: MakeEventPassThruProps & {
room: Room["roomId"];
mship: string;
prevMship?: string;
name?: string;
url?: string;
skey?: string;
target?: RoomMember;
}): MatrixEvent {
export function mkMembership(
opts: MakeEventPassThruProps & {
room: Room["roomId"];
mship: string;
prevMship?: string;
name?: string;
url?: string;
skey?: string;
target?: RoomMember;
},
): MatrixEvent {
const event: MakeEventProps = {
...opts,
type: "m.room.member",
@ -367,8 +381,12 @@ export function mkMembership(opts: MakeEventPassThruProps & {
if (opts.prevMship) {
event.prev_content = { membership: opts.prevMship };
}
if (opts.name) { event.content.displayname = opts.name; }
if (opts.url) { event.content.avatar_url = opts.url; }
if (opts.name) {
event.content.displayname = opts.name;
}
if (opts.url) {
event.content.avatar_url = opts.url;
}
const e = mkEvent(event);
if (opts.target) {
e.target = opts.target;
@ -406,7 +424,11 @@ export type MessageEventProps = MakeEventPassThruProps & {
* @param {string=} opts.msg Optional. The content.body for the event.
* @return {Object|MatrixEvent} The event
*/
export function mkMessage({ msg, relatesTo, ...opts }: MakeEventPassThruProps & {
export function mkMessage({
msg,
relatesTo,
...opts
}: MakeEventPassThruProps & {
room: Room["roomId"];
msg?: string;
}): MatrixEvent {
@ -420,7 +442,7 @@ export function mkMessage({ msg, relatesTo, ...opts }: MakeEventPassThruProps &
content: {
msgtype: "m.text",
body: message,
['m.relates_to']: relatesTo,
["m.relates_to"]: relatesTo,
},
};
@ -433,12 +455,12 @@ export function mkStubRoom(roomId: string = null, name: string, client: MatrixCl
roomId,
getReceiptsForEvent: jest.fn().mockReturnValue([]),
getMember: jest.fn().mockReturnValue({
userId: '@member:domain.bla',
name: 'Member',
rawDisplayName: 'Member',
userId: "@member:domain.bla",
name: "Member",
rawDisplayName: "Member",
roomId: roomId,
getAvatarUrl: () => 'mxc://avatar.url/image.png',
getMxcAvatarUrl: () => 'mxc://avatar.url/image.png',
getAvatarUrl: () => "mxc://avatar.url/image.png",
getMxcAvatarUrl: () => "mxc://avatar.url/image.png",
}),
getMembersWithMembership: jest.fn().mockReturnValue([]),
getJoinedMembers: jest.fn().mockReturnValue([]),
@ -452,12 +474,12 @@ export function mkStubRoom(roomId: string = null, name: string, client: MatrixCl
findEventById: () => null,
getAccountData: () => null,
hasMembershipState: () => null,
getVersion: () => '1',
getVersion: () => "1",
shouldUpgradeToVersion: () => null,
getMyMembership: jest.fn().mockReturnValue("join"),
maySendMessage: jest.fn().mockReturnValue(true),
currentState: {
getStateEvents: jest.fn((_type, key) => key === undefined ? [] : null),
getStateEvents: jest.fn((_type, key) => (key === undefined ? [] : null)),
getMember: jest.fn(),
mayClientSendStateEvent: jest.fn().mockReturnValue(true),
maySendStateEvent: jest.fn().mockReturnValue(true),
@ -476,8 +498,8 @@ export function mkStubRoom(roomId: string = null, name: string, client: MatrixCl
getDMInviter: jest.fn(),
name,
normalizedName: normalize(name || ""),
getAvatarUrl: () => 'mxc://avatar.url/room.png',
getMxcAvatarUrl: () => 'mxc://avatar.url/room.png',
getAvatarUrl: () => "mxc://avatar.url/room.png",
getMxcAvatarUrl: () => "mxc://avatar.url/room.png",
isSpaceRoom: jest.fn().mockReturnValue(false),
getType: jest.fn().mockReturnValue(undefined),
isElementVideoRoom: jest.fn().mockReturnValue(false),
@ -524,7 +546,7 @@ export const resetAsyncStoreWithClient = async <T = unknown>(store: AsyncStoreWi
export const mockStateEventImplementation = (events: MatrixEvent[]) => {
const stateMap = new EnhancedMap<string, Map<string, MatrixEvent>>();
events.forEach(event => {
events.forEach((event) => {
stateMap.getOrCreate(event.getType(), new Map()).set(event.getStateKey(), event);
});
@ -578,17 +600,21 @@ export const mkSpace = (
const space = mocked(mkRoom(client, spaceId, rooms));
space.isSpaceRoom.mockReturnValue(true);
space.getType.mockReturnValue(RoomType.Space);
mocked(space.currentState).getStateEvents.mockImplementation(mockStateEventImplementation(children.map(roomId =>
mkEvent({
event: true,
type: EventType.SpaceChild,
room: spaceId,
user: "@user:server",
skey: roomId,
content: { via: [] },
ts: Date.now(),
}),
)));
mocked(space.currentState).getStateEvents.mockImplementation(
mockStateEventImplementation(
children.map((roomId) =>
mkEvent({
event: true,
type: EventType.SpaceChild,
room: spaceId,
user: "@user:server",
skey: roomId,
content: { via: [] },
ts: Date.now(),
}),
),
),
);
return space;
};

View File

@ -19,18 +19,24 @@ import { Thread } from "matrix-js-sdk/src/models/thread";
import { mkMessage, MessageEventProps } from "./test-utils";
export const makeThreadEvent = ({ rootEventId, replyToEventId, ...props }: MessageEventProps & {
rootEventId: string; replyToEventId: string;
}): MatrixEvent => mkMessage({
...props,
relatesTo: {
event_id: rootEventId,
rel_type: "m.thread",
['m.in_reply_to']: {
event_id: replyToEventId,
export const makeThreadEvent = ({
rootEventId,
replyToEventId,
...props
}: MessageEventProps & {
rootEventId: string;
replyToEventId: string;
}): MatrixEvent =>
mkMessage({
...props,
relatesTo: {
event_id: rootEventId,
rel_type: "m.thread",
["m.in_reply_to"]: {
event_id: replyToEventId,
},
},
},
});
});
type MakeThreadEventsProps = {
roomId: Room["roomId"];
@ -48,13 +54,18 @@ type MakeThreadEventsProps = {
};
export const makeThreadEvents = ({
roomId, authorId, participantUserIds, length = 2, ts = 1, currentUserId,
}: MakeThreadEventsProps): { rootEvent: MatrixEvent, events: MatrixEvent[] } => {
roomId,
authorId,
participantUserIds,
length = 2,
ts = 1,
currentUserId,
}: MakeThreadEventsProps): { rootEvent: MatrixEvent; events: MatrixEvent[] } => {
const rootEvent = mkMessage({
user: authorId,
event: true,
room: roomId,
msg: 'root event message ' + Math.random(),
msg: "root event message " + Math.random(),
ts,
});
@ -65,16 +76,18 @@ export const makeThreadEvents = ({
const prevEvent = events[i - 1];
const replyToEventId = prevEvent.getId();
const user = participantUserIds[i % participantUserIds.length];
events.push(makeThreadEvent({
user,
room: roomId,
event: true,
msg: `reply ${i} by ${user}`,
rootEventId,
replyToEventId,
// replies are 1ms after each other
ts: ts + i,
}));
events.push(
makeThreadEvent({
user,
room: roomId,
event: true,
msg: `reply ${i} by ${user}`,
rootEventId,
replyToEventId,
// replies are 1ms after each other
ts: ts + i,
}),
);
}
rootEvent.setUnsigned({
@ -106,7 +119,7 @@ export const mkThread = ({
participantUserIds,
length = 2,
ts = 1,
}: MakeThreadProps): { thread: Thread, rootEvent: MatrixEvent, events: MatrixEvent[] } => {
}: MakeThreadProps): { thread: Thread; rootEvent: MatrixEvent; events: MatrixEvent[] } => {
const { rootEvent, events } = makeThreadEvents({
roomId: room.roomId,
authorId,
@ -118,9 +131,7 @@ export const mkThread = ({
expect(rootEvent).toBeTruthy();
for (const evt of events) {
room?.reEmitter.reEmit(evt, [
MatrixEventEvent.BeforeRedaction,
]);
room?.reEmitter.reEmit(evt, [MatrixEventEvent.BeforeRedaction]);
}
const thread = room.createThread(rootEvent.getId(), rootEvent, events, true);

View File

@ -22,7 +22,7 @@ import { ActionPayload } from "../../src/dispatcher/payloads";
import defaultDispatcher from "../../src/dispatcher/dispatcher";
import { DispatcherAction } from "../../src/dispatcher/actions";
export const emitPromise = (e: EventEmitter, k: string | symbol) => new Promise(r => e.once(k, r));
export const emitPromise = (e: EventEmitter, k: string | symbol) => new Promise((r) => e.once(k, r));
/**
* Waits for a certain payload to be dispatched.
@ -33,7 +33,9 @@ export const emitPromise = (e: EventEmitter, k: string | symbol) => new Promise(
* Rejects when the timeout is reached.
*/
export function untilDispatch(
waitForAction: DispatcherAction | ((payload: ActionPayload) => boolean), dispatcher=defaultDispatcher, timeout=1000,
waitForAction: DispatcherAction | ((payload: ActionPayload) => boolean),
dispatcher = defaultDispatcher,
timeout = 1000,
): Promise<ActionPayload> {
const callerLine = new Error().stack.toString().split("\n")[2];
if (typeof waitForAction === "string") {
@ -42,7 +44,7 @@ export function untilDispatch(
return payload.action === action;
};
}
const callback = waitForAction as ((payload: ActionPayload) => boolean);
const callback = waitForAction as (payload: ActionPayload) => boolean;
return new Promise((resolve, reject) => {
let fulfilled = false;
let timeoutId;
@ -58,7 +60,8 @@ export function untilDispatch(
// listen for dispatches
const token = dispatcher.register((p: ActionPayload) => {
const finishWaiting = callback(p);
if (finishWaiting || fulfilled) { // wait until we're told or we timeout
if (finishWaiting || fulfilled) {
// wait until we're told or we timeout
// if we haven't timed out, resolve now with the payload.
if (!fulfilled) {
resolve(p);
@ -84,7 +87,10 @@ export function untilDispatch(
* no callback is provided. Rejects when the timeout is reached.
*/
export function untilEmission(
emitter: EventEmitter, eventName: string, check: ((...args: any[]) => boolean)=undefined, timeout=1000,
emitter: EventEmitter,
eventName: string,
check: (...args: any[]) => boolean = undefined,
timeout = 1000,
): Promise<void> {
const callerLine = new Error().stack.toString().split("\n")[2];
return new Promise((resolve, reject) => {
@ -124,24 +130,23 @@ export function untilEmission(
export const findByAttr = (attr: string) => (component: ReactWrapper, value: string) =>
component.find(`[${attr}="${value}"]`);
export const findByTestId = findByAttr('data-test-id');
export const findById = findByAttr('id');
export const findByAriaLabel = findByAttr('aria-label');
export const findByTestId = findByAttr("data-test-id");
export const findById = findByAttr("id");
export const findByAriaLabel = findByAttr("aria-label");
const findByTagAndAttr = (attr: string) =>
(component: ReactWrapper, value: string, tag: string) =>
component.find(`${tag}[${attr}="${value}"]`);
const findByTagAndAttr = (attr: string) => (component: ReactWrapper, value: string, tag: string) =>
component.find(`${tag}[${attr}="${value}"]`);
export const findByTagAndTestId = findByTagAndAttr('data-test-id');
export const findByTagAndTestId = findByTagAndAttr("data-test-id");
export const flushPromises = async () => await new Promise(resolve => window.setTimeout(resolve));
export const flushPromises = async () => await new Promise((resolve) => window.setTimeout(resolve));
// with jest's modern fake timers process.nextTick is also mocked,
// flushing promises in the normal way then waits for some advancement
// of the fake timers
// https://gist.github.com/apieceofbart/e6dea8d884d29cf88cdb54ef14ddbcc4?permalink_comment_id=4018174#gistcomment-4018174
export const flushPromisesWithFakeTimers = async (): Promise<void> => {
const promise = new Promise(resolve => process.nextTick(resolve));
const promise = new Promise((resolve) => process.nextTick(resolve));
jest.advanceTimersByTime(1);
await promise;
};
@ -179,6 +184,6 @@ export function waitForUpdate(inst: React.Component, updates = 1): Promise<void>
* that also checks timestamps
*/
export const advanceDateAndTime = (ms: number) => {
jest.spyOn(global.Date, 'now').mockReturnValue(Date.now() + ms);
jest.spyOn(global.Date, "now").mockReturnValue(Date.now() + ms);
jest.advanceTimersByTime(ms);
};

View File

@ -17,7 +17,7 @@ limitations under the License.
import React, { RefCallback, ComponentType } from "react";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg as peg } from '../../src/MatrixClientPeg';
import { MatrixClientPeg as peg } from "../../src/MatrixClientPeg";
import MatrixClientContext from "../../src/contexts/MatrixClientContext";
import { SDKContext, SdkContextClass } from "../../src/contexts/SDKContext";
@ -33,9 +33,11 @@ export function wrapInMatrixClientContext<T>(WrappedComponent: ComponentType<T>)
}
render() {
return <MatrixClientContext.Provider value={this._matrixClient}>
<WrappedComponent ref={this.props.wrappedRef} {...this.props} />
</MatrixClientContext.Provider>;
return (
<MatrixClientContext.Provider value={this._matrixClient}>
<WrappedComponent ref={this.props.wrappedRef} {...this.props} />
</MatrixClientContext.Provider>
);
}
}
return Wrapper;
@ -47,9 +49,11 @@ export function wrapInSdkContext<T>(
): ComponentType<WrapperProps<T>> {
return class extends React.Component<WrapperProps<T>> {
render() {
return <SDKContext.Provider value={sdkContext}>
<WrappedComponent {...this.props} />
</SDKContext.Provider>;
return (
<SDKContext.Provider value={sdkContext}>
<WrappedComponent {...this.props} />
</SDKContext.Provider>
);
}
};
}