include test/test-utils in tsconfig (#8000)

* move js utils into directory

Signed-off-by: Kerry Archibald <kerrya@element.io>

* typescripterize js test-utils

Signed-off-by: Kerry Archibald <kerrya@element.io>

* move test utils to directory

Signed-off-by: Kerry Archibald <kerrya@element.io>

* move remaining mock functions to directory

Signed-off-by: Kerry Archibald <kerrya@element.io>

* update imports

Signed-off-by: Kerry Archibald <kerrya@element.io>

* missed copyright

Signed-off-by: Kerry Archibald <kerrya@element.io>

* type wait for update

Signed-off-by: Kerry Archibald <kerrya@element.io>

* add tests/test-utils to tsconfig

* lint

Signed-off-by: Kerry Archibald <kerrya@element.io>

* fix wrapper type

Signed-off-by: Kerry Archibald <kerrya@element.io>
This commit is contained in:
Kerry 2022-03-09 14:23:58 +01:00 committed by GitHub
parent a71009fca0
commit 2ab8b46ba3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 31 deletions

View file

@ -21,6 +21,7 @@ import dis from '../../src/dispatcher/dispatcher';
import { makeType } from "../../src/utils/TypeUtils"; import { makeType } from "../../src/utils/TypeUtils";
import { ValidatedServerConfig } from "../../src/utils/AutoDiscoveryUtils"; import { ValidatedServerConfig } from "../../src/utils/AutoDiscoveryUtils";
import { EnhancedMap } from "../../src/utils/maps"; import { EnhancedMap } from "../../src/utils/maps";
import { AsyncStoreWithClient } from "../../src/stores/AsyncStoreWithClient";
import MatrixClientBackedSettingsHandler from "../../src/settings/handlers/MatrixClientBackedSettingsHandler"; import MatrixClientBackedSettingsHandler from "../../src/settings/handlers/MatrixClientBackedSettingsHandler";
/** /**
@ -38,11 +39,9 @@ export function stubClient() {
// //
// 'sandbox.restore()' doesn't work correctly on inherited methods, // 'sandbox.restore()' doesn't work correctly on inherited methods,
// so we do this for each method // so we do this for each method
const methods = ['get', 'unset', 'replaceUsingCreds']; jest.spyOn(peg, 'get');
for (let i = 0; i < methods.length; i++) { jest.spyOn(peg, 'unset');
const methodName = methods[i]; jest.spyOn(peg, 'replaceUsingCreds');
peg[methods[i]] = jest.spyOn(peg, methodName);
}
// MatrixClientPeg.get() is called a /lot/, so implement it with our own // MatrixClientPeg.get() is called a /lot/, so implement it with our own
// fast stub function rather than a sinon stub // fast stub function rather than a sinon stub
peg.get = function() { return client; }; peg.get = function() { return client; };
@ -54,7 +53,7 @@ export function stubClient() {
* *
* @returns {object} MatrixClient stub * @returns {object} MatrixClient stub
*/ */
export function createTestClient() { export function createTestClient(): MatrixClient {
const eventEmitter = new EventEmitter(); const eventEmitter = new EventEmitter();
return { return {
@ -76,7 +75,7 @@ export function createTestClient() {
removeListener: eventEmitter.removeListener.bind(eventEmitter), removeListener: eventEmitter.removeListener.bind(eventEmitter),
emit: eventEmitter.emit.bind(eventEmitter), emit: eventEmitter.emit.bind(eventEmitter),
isRoomEncrypted: jest.fn().mockReturnValue(false), isRoomEncrypted: jest.fn().mockReturnValue(false),
peekInRoom: jest.fn().mockResolvedValue(mkStubRoom()), peekInRoom: jest.fn().mockResolvedValue(mkStubRoom(undefined, undefined, undefined)),
paginateEventTimeline: jest.fn().mockResolvedValue(undefined), paginateEventTimeline: jest.fn().mockResolvedValue(undefined),
sendReadReceipt: jest.fn().mockResolvedValue(undefined), sendReadReceipt: jest.fn().mockResolvedValue(undefined),
@ -90,6 +89,8 @@ export function createTestClient() {
getThirdpartyUser: jest.fn().mockResolvedValue([]), getThirdpartyUser: jest.fn().mockResolvedValue([]),
getAccountData: (type) => { getAccountData: (type) => {
return mkEvent({ return mkEvent({
user: undefined,
room: undefined,
type, type,
event: true, event: true,
content: {}, content: {},
@ -100,11 +101,10 @@ export function createTestClient() {
setRoomAccountData: jest.fn(), setRoomAccountData: jest.fn(),
sendTyping: jest.fn().mockResolvedValue({}), sendTyping: jest.fn().mockResolvedValue({}),
sendMessage: () => jest.fn().mockResolvedValue({}), sendMessage: () => jest.fn().mockResolvedValue({}),
sendStateEvent: jest.fn().mockResolvedValue(), sendStateEvent: jest.fn().mockResolvedValue(undefined),
getSyncState: () => "SYNCING", getSyncState: () => "SYNCING",
generateClientSecret: () => "t35tcl1Ent5ECr3T", generateClientSecret: () => "t35tcl1Ent5ECr3T",
isGuest: jest.fn().mockReturnValue(false), isGuest: jest.fn().mockReturnValue(false),
isCryptoEnabled: () => false,
getRoomHierarchy: jest.fn().mockReturnValue({ getRoomHierarchy: jest.fn().mockReturnValue({
rooms: [], rooms: [],
}), }),
@ -122,23 +122,24 @@ export function createTestClient() {
getCapabilities: jest.fn().mockResolvedValue({}), getCapabilities: jest.fn().mockResolvedValue({}),
supportsExperimentalThreads: () => false, supportsExperimentalThreads: () => false,
getRoomUpgradeHistory: jest.fn().mockReturnValue([]), getRoomUpgradeHistory: jest.fn().mockReturnValue([]),
getOpenIdToken: jest.fn().mockResolvedValue(), getOpenIdToken: jest.fn().mockResolvedValue(undefined),
registerWithIdentityServer: jest.fn().mockResolvedValue({}), registerWithIdentityServer: jest.fn().mockResolvedValue({}),
getIdentityAccount: jest.fn().mockResolvedValue({}), getIdentityAccount: jest.fn().mockResolvedValue({}),
getTerms: jest.fn().mockResolvedValueOnce(), getTerms: jest.fn().mockResolvedValueOnce(undefined),
doesServerSupportUnstableFeature: jest.fn().mockResolvedValue(), doesServerSupportUnstableFeature: jest.fn().mockResolvedValue(undefined),
getPushRules: jest.fn().mockResolvedValue(), getPushRules: jest.fn().mockResolvedValue(undefined),
getPushers: jest.fn().mockResolvedValue({ pushers: [] }), getPushers: jest.fn().mockResolvedValue({ pushers: [] }),
getThreePids: jest.fn().mockResolvedValue({ threepids: [] }), getThreePids: jest.fn().mockResolvedValue({ threepids: [] }),
setPusher: jest.fn().mockResolvedValue(), setPusher: jest.fn().mockResolvedValue(undefined),
setPushRuleEnabled: jest.fn().mockResolvedValue(), setPushRuleEnabled: jest.fn().mockResolvedValue(undefined),
setPushRuleActions: jest.fn().mockResolvedValue(), setPushRuleActions: jest.fn().mockResolvedValue(undefined),
isCryptoEnabled: jest.fn().mockReturnValue(false), isCryptoEnabled: jest.fn().mockReturnValue(false),
}; } as unknown as MatrixClient;
} }
type MakeEventPassThruProps = { type MakeEventPassThruProps = {
user: User["userId"]; user: User["userId"];
relatesTo?: IEventRelation;
event?: boolean; event?: boolean;
ts?: number; ts?: number;
skey?: string; skey?: string;
@ -282,9 +283,10 @@ export type MessageEventProps = MakeEventPassThruProps & {
* @param {string=} opts.msg Optional. The content.body for the event. * @param {string=} opts.msg Optional. The content.body for the event.
* @return {Object|MatrixEvent} The event * @return {Object|MatrixEvent} The event
*/ */
export function mkMessage({ export function mkMessage({ msg, relatesTo, ...opts }: MakeEventPassThruProps & {
msg, relatesTo, ...opts room: Room["roomId"];
}: MessageEventProps): MatrixEvent { msg?: string;
}): MatrixEvent {
if (!opts.room || !opts.user) { if (!opts.room || !opts.user) {
throw new Error("Missing .room or .user from options"); throw new Error("Missing .room or .user from options");
} }
@ -302,7 +304,7 @@ export function mkMessage({
return mkEvent(event); return mkEvent(event);
} }
export function mkStubRoom(roomId = null, name: string, client: MatrixClient): Room { export function mkStubRoom(roomId: string = null, name: string, client: MatrixClient): Room {
const stubTimeline = { getEvents: () => [] } as unknown as EventTimeline; const stubTimeline = { getEvents: () => [] } as unknown as EventTimeline;
return { return {
roomId, roomId,
@ -385,30 +387,34 @@ export function getDispatchForStore(store) {
// These methods make some use of some private methods on the AsyncStoreWithClient to simplify getting into a consistent // These methods make some use of some private methods on the AsyncStoreWithClient to simplify getting into a consistent
// ready state without needing to wire up a dispatcher and pretend to be a js-sdk client. // ready state without needing to wire up a dispatcher and pretend to be a js-sdk client.
export const setupAsyncStoreWithClient = async (store: AsyncStoreWithClient<any>, client: MatrixClient) => { export const setupAsyncStoreWithClient = async <T = unknown>(store: AsyncStoreWithClient<T>, client: MatrixClient) => {
// @ts-ignore // @ts-ignore
store.readyStore.useUnitTestClient(client); store.readyStore.useUnitTestClient(client);
// @ts-ignore // @ts-ignore
await store.onReady(); await store.onReady();
}; };
export const resetAsyncStoreWithClient = async (store: AsyncStoreWithClient<any>) => { export const resetAsyncStoreWithClient = async <T = unknown>(store: AsyncStoreWithClient<T>) => {
// @ts-ignore // @ts-ignore
await store.onNotReady(); await store.onNotReady();
}; };
export const mockStateEventImplementation = (events: MatrixEvent[]): typeof RoomState['getStateEvents'] => { export const mockStateEventImplementation = (events: MatrixEvent[]) => {
const stateMap = new EnhancedMap<string, Map<string, 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); stateMap.getOrCreate(event.getType(), new Map()).set(event.getStateKey(), event);
}); });
return (eventType: string, stateKey?: string) => { // recreate the overloading in RoomState
function getStateEvents(eventType: EventType | string): MatrixEvent[];
function getStateEvents(eventType: EventType | string, stateKey: string): MatrixEvent;
function getStateEvents(eventType: EventType | string, stateKey?: string) {
if (stateKey || stateKey === "") { if (stateKey || stateKey === "") {
return stateMap.get(eventType)?.get(stateKey) || null; return stateMap.get(eventType)?.get(stateKey) || null;
} }
return Array.from(stateMap.get(eventType)?.values() || []); return Array.from(stateMap.get(eventType)?.values() || []);
}; }
return getStateEvents;
}; };
export const mkRoom = (client: MatrixClient, roomId: string, rooms?: ReturnType<typeof mkStubRoom>[]) => { export const mkRoom = (client: MatrixClient, roomId: string, rooms?: ReturnType<typeof mkStubRoom>[]) => {

View file

@ -20,8 +20,10 @@ 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 MatrixClientContext from "../../src/contexts/MatrixClientContext";
export function wrapInMatrixClientContext(WrappedComponent) { type WrapperType<T> = React.Component<{ wrappedRef?: RefCallback<T> }>;
class Wrapper extends React.Component<{ wrappedRef?: RefCallback }> {
export function wrapInMatrixClientContext<T>(WrappedComponent): WrapperType<T> {
class Wrapper extends React.Component<{ wrappedRef?: RefCallback<T> }> {
_matrixClient: MatrixClient; _matrixClient: MatrixClient;
constructor(props) { constructor(props) {
super(props); super(props);
@ -35,5 +37,5 @@ export function wrapInMatrixClientContext(WrappedComponent) {
</MatrixClientContext.Provider>; </MatrixClientContext.Provider>;
} }
} }
return Wrapper; return Wrapper as unknown as WrapperType<T>;
} }

View file

@ -21,6 +21,8 @@
}, },
"include": [ "include": [
"./src/**/*.ts", "./src/**/*.ts",
"./src/**/*.tsx" "./src/**/*.tsx" ,
"./test/test-utils/**/*.ts",
"./test/test-utils/**/*.tsx",
], ],
} }