Update tests to prefer RTL over Enzyme (#10247
* Update tests to prefer RTL over Enzyme * Strict types
This commit is contained in:
parent
dd6fc124d7
commit
f40d15388c
20 changed files with 1095 additions and 632 deletions
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React, { Component } from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import ReactTestUtils from "react-dom/test-utils";
|
||||
import ReactDOM from "react-dom";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
|
|
|
@ -15,9 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { render, screen, act, fireEvent, waitFor, getByRole } from "@testing-library/react";
|
||||
import { render, screen, act, fireEvent, waitFor, getByRole, RenderResult } from "@testing-library/react";
|
||||
import { mocked, Mocked } from "jest-mock";
|
||||
import { EventType, RoomType } from "matrix-js-sdk/src/@types/event";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
|
@ -60,291 +58,7 @@ import WidgetUtils from "../../../../src/utils/WidgetUtils";
|
|||
import { ElementWidgetActions } from "../../../../src/stores/widgets/ElementWidgetActions";
|
||||
import MediaDeviceHandler, { MediaDeviceKindEnum } from "../../../../src/MediaDeviceHandler";
|
||||
|
||||
describe("RoomHeader (Enzyme)", () => {
|
||||
it("shows the room avatar in a room with only ourselves", () => {
|
||||
// When we render a non-DM room with 1 person in it
|
||||
const room = createRoom({ name: "X Room", isDm: false, userIds: [] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
||||
expect(initial.text()).toEqual("X");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
||||
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("shows the room avatar in a room with 2 people", () => {
|
||||
// When we render a non-DM room with 2 people in it
|
||||
const room = createRoom({ name: "Y Room", isDm: false, userIds: ["other"] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
||||
expect(initial.text()).toEqual("Y");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
||||
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("shows the room avatar in a room with >2 people", () => {
|
||||
// When we render a non-DM room with 3 people in it
|
||||
const room = createRoom({ name: "Z Room", isDm: false, userIds: ["other1", "other2"] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
||||
expect(initial.text()).toEqual("Z");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
||||
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("shows the room avatar in a DM with only ourselves", () => {
|
||||
// When we render a non-DM room with 1 person in it
|
||||
const room = createRoom({ name: "Z Room", isDm: true, userIds: [] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
||||
expect(initial.text()).toEqual("Z");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
||||
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("shows the user avatar in a DM with 2 people", () => {
|
||||
// Note: this is the interesting case - this is the ONLY
|
||||
// time we should use the user's avatar.
|
||||
|
||||
// When we render a DM room with only 2 people in it
|
||||
const room = createRoom({ name: "Y Room", isDm: true, userIds: ["other"] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then we use the other user's avatar as our room's image avatar
|
||||
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
||||
expect(image.prop("src")).toEqual("http://this.is.a.url/example.org/other");
|
||||
|
||||
// And there is no initial avatar
|
||||
expect(rendered.find(".mx_BaseAvatar_initial")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("shows the room avatar in a DM with >2 people", () => {
|
||||
// When we render a DM room with 3 people in it
|
||||
const room = createRoom({
|
||||
name: "Z Room",
|
||||
isDm: true,
|
||||
userIds: ["other1", "other2"],
|
||||
});
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = findSpan(rendered, ".mx_BaseAvatar_initial");
|
||||
expect(initial.text()).toEqual("Z");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = findImg(rendered, ".mx_BaseAvatar_image");
|
||||
expect(image.prop("src")).toEqual("data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("renders call buttons normally", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: ["other"] });
|
||||
const wrapper = mountHeader(room);
|
||||
|
||||
expect(wrapper.find('[aria-label="Voice call"]').hostNodes()).toHaveLength(1);
|
||||
expect(wrapper.find('[aria-label="Video call"]').hostNodes()).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("hides call buttons when the room is tombstoned", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(
|
||||
room,
|
||||
{},
|
||||
{
|
||||
tombstone: mkEvent({
|
||||
event: true,
|
||||
type: "m.room.tombstone",
|
||||
room: room.roomId,
|
||||
user: "@user1:server",
|
||||
skey: "",
|
||||
content: {},
|
||||
ts: Date.now(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
expect(wrapper.find('[aria-label="Voice call"]').hostNodes()).toHaveLength(0);
|
||||
expect(wrapper.find('[aria-label="Video call"]').hostNodes()).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should render buttons if not passing showButtons (default true)", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(room);
|
||||
expect(wrapper.find(".mx_RoomHeader_button")).not.toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should not render buttons if passing showButtons = false", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(room, { showButtons: false });
|
||||
expect(wrapper.find(".mx_RoomHeader_button")).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("should render the room options context menu if not passing enableRoomOptionsMenu (default true)", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(room);
|
||||
expect(wrapper.find(".mx_RoomHeader_name.mx_AccessibleButton")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("should not render the room options context menu if passing enableRoomOptionsMenu = false", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(room, { enableRoomOptionsMenu: false });
|
||||
expect(wrapper.find(".mx_RoomHeader_name.mx_AccessibleButton")).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
interface IRoomCreationInfo {
|
||||
name: string;
|
||||
isDm: boolean;
|
||||
userIds: string[];
|
||||
}
|
||||
|
||||
function createRoom(info: IRoomCreationInfo) {
|
||||
stubClient();
|
||||
const client: MatrixClient = MatrixClientPeg.get();
|
||||
|
||||
const roomId = "!1234567890:domain";
|
||||
const userId = client.getUserId()!;
|
||||
if (info.isDm) {
|
||||
client.getAccountData = (eventType) => {
|
||||
expect(eventType).toEqual("m.direct");
|
||||
return mkDirectEvent(roomId, userId, info.userIds);
|
||||
};
|
||||
}
|
||||
|
||||
DMRoomMap.makeShared().start();
|
||||
|
||||
const room = new Room(roomId, client, userId, {
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
});
|
||||
|
||||
const otherJoinEvents: MatrixEvent[] = [];
|
||||
for (const otherUserId of info.userIds) {
|
||||
otherJoinEvents.push(mkJoinEvent(roomId, otherUserId));
|
||||
}
|
||||
|
||||
room.currentState.setStateEvents([
|
||||
mkCreationEvent(roomId, userId),
|
||||
mkNameEvent(roomId, userId, info.name),
|
||||
mkJoinEvent(roomId, userId),
|
||||
...otherJoinEvents,
|
||||
]);
|
||||
room.recalculate();
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
function mountHeader(room: Room, propsOverride = {}, roomContext?: Partial<IRoomState>): ReactWrapper {
|
||||
const props: RoomHeaderProps = {
|
||||
room,
|
||||
inRoom: true,
|
||||
onSearchClick: () => {},
|
||||
onInviteClick: null,
|
||||
onForgetClick: () => {},
|
||||
onAppsClick: () => {},
|
||||
e2eStatus: E2EStatus.Normal,
|
||||
appsShown: true,
|
||||
searchInfo: {
|
||||
searchId: Math.random(),
|
||||
promise: new Promise<ISearchResults>(() => {}),
|
||||
term: "",
|
||||
scope: SearchScope.Room,
|
||||
count: 0,
|
||||
},
|
||||
viewingCall: false,
|
||||
activeCall: null,
|
||||
...propsOverride,
|
||||
};
|
||||
|
||||
return mount(
|
||||
<RoomContext.Provider value={{ ...roomContext, room } as IRoomState}>
|
||||
<RoomHeader {...props} />
|
||||
</RoomContext.Provider>,
|
||||
);
|
||||
}
|
||||
|
||||
function mkCreationEvent(roomId: string, userId: string): MatrixEvent {
|
||||
return mkEvent({
|
||||
event: true,
|
||||
type: "m.room.create",
|
||||
room: roomId,
|
||||
user: userId,
|
||||
content: {
|
||||
creator: userId,
|
||||
room_version: "5",
|
||||
predecessor: {
|
||||
room_id: "!prevroom",
|
||||
event_id: "$someevent",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function mkNameEvent(roomId: string, userId: string, name: string): MatrixEvent {
|
||||
return mkEvent({
|
||||
event: true,
|
||||
type: "m.room.name",
|
||||
room: roomId,
|
||||
user: userId,
|
||||
content: { name },
|
||||
});
|
||||
}
|
||||
|
||||
function mkJoinEvent(roomId: string, userId: string) {
|
||||
const ret = mkEvent({
|
||||
event: true,
|
||||
type: "m.room.member",
|
||||
room: roomId,
|
||||
user: userId,
|
||||
content: {
|
||||
membership: "join",
|
||||
avatar_url: "mxc://example.org/" + userId,
|
||||
},
|
||||
});
|
||||
ret.event.state_key = userId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function mkDirectEvent(roomId: string, userId: string, otherUsers: string[]): MatrixEvent {
|
||||
const content: Record<string, string[]> = {};
|
||||
for (const otherUserId of otherUsers) {
|
||||
content[otherUserId] = [roomId];
|
||||
}
|
||||
return mkEvent({
|
||||
event: true,
|
||||
type: "m.direct",
|
||||
room: roomId,
|
||||
user: userId,
|
||||
content,
|
||||
});
|
||||
}
|
||||
|
||||
function findSpan(wrapper: ReactWrapper, selector: string): ReactWrapper {
|
||||
const els = wrapper.find(selector).hostNodes();
|
||||
expect(els).toHaveLength(1);
|
||||
return els.at(0);
|
||||
}
|
||||
|
||||
function findImg(wrapper: ReactWrapper, selector: string): ReactWrapper {
|
||||
const els = wrapper.find(selector).hostNodes();
|
||||
expect(els).toHaveLength(1);
|
||||
return els.at(0);
|
||||
}
|
||||
|
||||
describe("RoomHeader (React Testing Library)", () => {
|
||||
describe("RoomHeader", () => {
|
||||
let client: Mocked<MatrixClient>;
|
||||
let room: Room;
|
||||
let alice: RoomMember;
|
||||
|
@ -397,6 +111,9 @@ describe("RoomHeader (React Testing Library)", () => {
|
|||
[MediaDeviceKindEnum.VideoInput]: [],
|
||||
[MediaDeviceKindEnum.AudioOutput]: [],
|
||||
});
|
||||
|
||||
DMRoomMap.makeShared();
|
||||
jest.spyOn(DMRoomMap.shared(), "getUserIdForRoomId").mockReturnValue(carol.userId);
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -879,4 +596,274 @@ describe("RoomHeader (React Testing Library)", () => {
|
|||
|
||||
expect(screen.queryByRole("button", { name: /invite/i })).toBeNull();
|
||||
});
|
||||
|
||||
it("shows the room avatar in a room with only ourselves", () => {
|
||||
// When we render a non-DM room with 1 person in it
|
||||
const room = createRoom({ name: "X Room", isDm: false, userIds: [] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = rendered.container.querySelector(".mx_BaseAvatar_initial");
|
||||
expect(initial).toHaveTextContent("X");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = rendered.container.querySelector(".mx_BaseAvatar_image");
|
||||
expect(image).toHaveAttribute("src", "data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("shows the room avatar in a room with 2 people", () => {
|
||||
// When we render a non-DM room with 2 people in it
|
||||
const room = createRoom({ name: "Y Room", isDm: false, userIds: ["other"] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = rendered.container.querySelector(".mx_BaseAvatar_initial");
|
||||
expect(initial).toHaveTextContent("Y");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = rendered.container.querySelector(".mx_BaseAvatar_image");
|
||||
expect(image).toHaveAttribute("src", "data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("shows the room avatar in a room with >2 people", () => {
|
||||
// When we render a non-DM room with 3 people in it
|
||||
const room = createRoom({ name: "Z Room", isDm: false, userIds: ["other1", "other2"] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = rendered.container.querySelector(".mx_BaseAvatar_initial");
|
||||
expect(initial).toHaveTextContent("Z");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = rendered.container.querySelector(".mx_BaseAvatar_image");
|
||||
expect(image).toHaveAttribute("src", "data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("shows the room avatar in a DM with only ourselves", () => {
|
||||
// When we render a non-DM room with 1 person in it
|
||||
const room = createRoom({ name: "Z Room", isDm: true, userIds: [] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = rendered.container.querySelector(".mx_BaseAvatar_initial");
|
||||
expect(initial).toHaveTextContent("Z");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = rendered.container.querySelector(".mx_BaseAvatar_image");
|
||||
expect(image).toHaveAttribute("src", "data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("shows the user avatar in a DM with 2 people", () => {
|
||||
// Note: this is the interesting case - this is the ONLY
|
||||
// time we should use the user's avatar.
|
||||
|
||||
// When we render a DM room with only 2 people in it
|
||||
const room = createRoom({ name: "Y Room", isDm: true, userIds: ["other"] });
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then we use the other user's avatar as our room's image avatar
|
||||
const image = rendered.container.querySelector(".mx_BaseAvatar_image");
|
||||
expect(image).toHaveAttribute("src", "http://this.is.a.url/example.org/other");
|
||||
|
||||
// And there is no initial avatar
|
||||
expect(rendered.container.querySelector(".mx_BaseAvatar_initial")).toBeFalsy();
|
||||
});
|
||||
|
||||
it("shows the room avatar in a DM with >2 people", () => {
|
||||
// When we render a DM room with 3 people in it
|
||||
const room = createRoom({
|
||||
name: "Z Room",
|
||||
isDm: true,
|
||||
userIds: ["other1", "other2"],
|
||||
});
|
||||
const rendered = mountHeader(room);
|
||||
|
||||
// Then the room's avatar is the initial of its name
|
||||
const initial = rendered.container.querySelector(".mx_BaseAvatar_initial");
|
||||
expect(initial).toHaveTextContent("Z");
|
||||
|
||||
// And there is no image avatar (because it's not set on this room)
|
||||
const image = rendered.container.querySelector(".mx_BaseAvatar_image");
|
||||
expect(image).toHaveAttribute("src", "data:image/png;base64,00");
|
||||
});
|
||||
|
||||
it("renders call buttons normally", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: ["other"] });
|
||||
const wrapper = mountHeader(room);
|
||||
|
||||
expect(wrapper.container.querySelector('[aria-label="Voice call"]')).toBeDefined();
|
||||
expect(wrapper.container.querySelector('[aria-label="Video call"]')).toBeDefined();
|
||||
});
|
||||
|
||||
it("hides call buttons when the room is tombstoned", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(
|
||||
room,
|
||||
{},
|
||||
{
|
||||
tombstone: mkEvent({
|
||||
event: true,
|
||||
type: "m.room.tombstone",
|
||||
room: room.roomId,
|
||||
user: "@user1:server",
|
||||
skey: "",
|
||||
content: {},
|
||||
ts: Date.now(),
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
expect(wrapper.container.querySelector('[aria-label="Voice call"]')).toBeFalsy();
|
||||
expect(wrapper.container.querySelector('[aria-label="Video call"]')).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should render buttons if not passing showButtons (default true)", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(room);
|
||||
expect(wrapper.container.querySelector(".mx_RoomHeader_button")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should not render buttons if passing showButtons = false", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(room, { showButtons: false });
|
||||
expect(wrapper.container.querySelector(".mx_RoomHeader_button")).toBeFalsy();
|
||||
});
|
||||
|
||||
it("should render the room options context menu if not passing enableRoomOptionsMenu (default true)", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(room);
|
||||
expect(wrapper.container.querySelector(".mx_RoomHeader_name.mx_AccessibleButton")).toBeDefined();
|
||||
});
|
||||
|
||||
it("should not render the room options context menu if passing enableRoomOptionsMenu = false", () => {
|
||||
const room = createRoom({ name: "Room", isDm: false, userIds: [] });
|
||||
const wrapper = mountHeader(room, { enableRoomOptionsMenu: false });
|
||||
expect(wrapper.container.querySelector(".mx_RoomHeader_name.mx_AccessibleButton")).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
interface IRoomCreationInfo {
|
||||
name: string;
|
||||
isDm: boolean;
|
||||
userIds: string[];
|
||||
}
|
||||
|
||||
function createRoom(info: IRoomCreationInfo) {
|
||||
stubClient();
|
||||
const client: MatrixClient = MatrixClientPeg.get();
|
||||
|
||||
const roomId = "!1234567890:domain";
|
||||
const userId = client.getUserId()!;
|
||||
if (info.isDm) {
|
||||
client.getAccountData = (eventType) => {
|
||||
expect(eventType).toEqual("m.direct");
|
||||
return mkDirectEvent(roomId, userId, info.userIds);
|
||||
};
|
||||
}
|
||||
|
||||
DMRoomMap.makeShared().start();
|
||||
|
||||
const room = new Room(roomId, client, userId, {
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
});
|
||||
|
||||
const otherJoinEvents: MatrixEvent[] = [];
|
||||
for (const otherUserId of info.userIds) {
|
||||
otherJoinEvents.push(mkJoinEvent(roomId, otherUserId));
|
||||
}
|
||||
|
||||
room.currentState.setStateEvents([
|
||||
mkCreationEvent(roomId, userId),
|
||||
mkNameEvent(roomId, userId, info.name),
|
||||
mkJoinEvent(roomId, userId),
|
||||
...otherJoinEvents,
|
||||
]);
|
||||
room.recalculate();
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
function mountHeader(room: Room, propsOverride = {}, roomContext?: Partial<IRoomState>): RenderResult {
|
||||
const props: RoomHeaderProps = {
|
||||
room,
|
||||
inRoom: true,
|
||||
onSearchClick: () => {},
|
||||
onInviteClick: null,
|
||||
onForgetClick: () => {},
|
||||
onAppsClick: () => {},
|
||||
e2eStatus: E2EStatus.Normal,
|
||||
appsShown: true,
|
||||
searchInfo: {
|
||||
searchId: Math.random(),
|
||||
promise: new Promise<ISearchResults>(() => {}),
|
||||
term: "",
|
||||
scope: SearchScope.Room,
|
||||
count: 0,
|
||||
},
|
||||
viewingCall: false,
|
||||
activeCall: null,
|
||||
...propsOverride,
|
||||
};
|
||||
|
||||
return render(
|
||||
<RoomContext.Provider value={{ ...roomContext, room } as IRoomState}>
|
||||
<RoomHeader {...props} />
|
||||
</RoomContext.Provider>,
|
||||
);
|
||||
}
|
||||
|
||||
function mkCreationEvent(roomId: string, userId: string): MatrixEvent {
|
||||
return mkEvent({
|
||||
event: true,
|
||||
type: "m.room.create",
|
||||
room: roomId,
|
||||
user: userId,
|
||||
content: {
|
||||
creator: userId,
|
||||
room_version: "5",
|
||||
predecessor: {
|
||||
room_id: "!prevroom",
|
||||
event_id: "$someevent",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function mkNameEvent(roomId: string, userId: string, name: string): MatrixEvent {
|
||||
return mkEvent({
|
||||
event: true,
|
||||
type: "m.room.name",
|
||||
room: roomId,
|
||||
user: userId,
|
||||
content: { name },
|
||||
});
|
||||
}
|
||||
|
||||
function mkJoinEvent(roomId: string, userId: string) {
|
||||
const ret = mkEvent({
|
||||
event: true,
|
||||
type: "m.room.member",
|
||||
room: roomId,
|
||||
user: userId,
|
||||
content: {
|
||||
membership: "join",
|
||||
avatar_url: "mxc://example.org/" + userId,
|
||||
},
|
||||
});
|
||||
ret.event.state_key = userId;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function mkDirectEvent(roomId: string, userId: string, otherUsers: string[]): MatrixEvent {
|
||||
const content: Record<string, string[]> = {};
|
||||
for (const otherUserId of otherUsers) {
|
||||
content[otherUserId] = [roomId];
|
||||
}
|
||||
return mkEvent({
|
||||
event: true,
|
||||
type: "m.direct",
|
||||
room: roomId,
|
||||
user: userId,
|
||||
content,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,26 +14,36 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import React, { createRef, RefObject } from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import { MatrixClient, MsgType, Room } from "matrix-js-sdk/src/matrix";
|
||||
import { mocked } from "jest-mock";
|
||||
|
||||
import VoiceRecordComposerTile from "../../../../src/components/views/rooms/VoiceRecordComposerTile";
|
||||
import { VoiceRecording } from "../../../../src/audio/VoiceRecording";
|
||||
import { doMaybeLocalRoomAction } from "../../../../src/utils/local-room";
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import { IUpload } from "../../../../src/audio/VoiceMessageRecording";
|
||||
import { IUpload, VoiceMessageRecording } from "../../../../src/audio/VoiceMessageRecording";
|
||||
import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks";
|
||||
import { VoiceRecordingStore } from "../../../../src/stores/VoiceRecordingStore";
|
||||
import { PlaybackClock } from "../../../../src/audio/PlaybackClock";
|
||||
|
||||
jest.mock("../../../../src/utils/local-room", () => ({
|
||||
doMaybeLocalRoomAction: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock("../../../../src/stores/VoiceRecordingStore", () => ({
|
||||
VoiceRecordingStore: {
|
||||
getVoiceRecordingId: jest.fn().mockReturnValue("voice-recording-id"),
|
||||
instance: {
|
||||
getActiveRecording: jest.fn(),
|
||||
disposeRecording: jest.fn(),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
describe("<VoiceRecordComposerTile/>", () => {
|
||||
let voiceRecordComposerTile: ReactWrapper<VoiceRecordComposerTile>;
|
||||
let mockRecorder: VoiceRecording;
|
||||
let voiceRecordComposerTile: RefObject<VoiceRecordComposerTile>;
|
||||
let mockRecorder: VoiceMessageRecording;
|
||||
let mockUpload: IUpload;
|
||||
let mockClient: MatrixClient;
|
||||
const roomId = "!room:example.com";
|
||||
|
@ -47,26 +57,42 @@ describe("<VoiceRecordComposerTile/>", () => {
|
|||
const room = {
|
||||
roomId,
|
||||
} as unknown as Room;
|
||||
|
||||
voiceRecordComposerTile = createRef();
|
||||
const props = {
|
||||
room,
|
||||
ref: voiceRecordComposerTile,
|
||||
permalinkCreator: new RoomPermalinkCreator(room),
|
||||
};
|
||||
mockUpload = {
|
||||
mxc: "mxc://example.com/voice",
|
||||
};
|
||||
mockRecorder = {
|
||||
on: jest.fn(),
|
||||
off: jest.fn(),
|
||||
stop: jest.fn(),
|
||||
upload: () => Promise.resolve(mockUpload),
|
||||
durationSeconds: 1337,
|
||||
contentType: "audio/ogg",
|
||||
getPlayback: () => ({
|
||||
on: jest.fn(),
|
||||
off: jest.fn(),
|
||||
prepare: jest.fn().mockResolvedValue(void 0),
|
||||
clockInfo: {
|
||||
timeSeconds: 0,
|
||||
liveData: {
|
||||
onUpdate: jest.fn(),
|
||||
},
|
||||
} as unknown as PlaybackClock,
|
||||
waveform: [1.4, 2.5, 3.6],
|
||||
waveformData: {
|
||||
onUpdate: jest.fn(),
|
||||
},
|
||||
thumbnailWaveform: [1.4, 2.5, 3.6],
|
||||
}),
|
||||
} as unknown as VoiceRecording;
|
||||
voiceRecordComposerTile = mount(<VoiceRecordComposerTile {...props} />);
|
||||
voiceRecordComposerTile.setState({
|
||||
recorder: mockRecorder,
|
||||
});
|
||||
} as unknown as VoiceMessageRecording;
|
||||
mocked(VoiceRecordingStore.instance.getActiveRecording).mockReturnValue(mockRecorder);
|
||||
render(<VoiceRecordComposerTile {...props} />);
|
||||
|
||||
mocked(doMaybeLocalRoomAction).mockImplementation(
|
||||
<T,>(roomId: string, fn: (actualRoomId: string) => Promise<T>, _client?: MatrixClient) => {
|
||||
|
@ -77,7 +103,7 @@ describe("<VoiceRecordComposerTile/>", () => {
|
|||
|
||||
describe("send", () => {
|
||||
it("should send the voice recording", async () => {
|
||||
await (voiceRecordComposerTile.instance() as VoiceRecordComposerTile).send();
|
||||
await voiceRecordComposerTile.current!.send();
|
||||
expect(mockClient.sendMessage).toHaveBeenCalledWith(roomId, {
|
||||
"body": "Voice message",
|
||||
"file": undefined,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue