Migrate AppTile-Test to RTL (#9838)

This commit is contained in:
Michael Weimann 2022-12-30 11:33:10 +01:00 committed by GitHub
parent b0dd0b8aef
commit 3ce064731b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -15,13 +15,14 @@ limitations under the License.
*/ */
import React from "react"; import React from "react";
import TestRenderer from "react-test-renderer";
import { jest } from "@jest/globals"; import { jest } from "@jest/globals";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { ClientWidgetApi, MatrixWidgetType } from "matrix-widget-api"; import { ClientWidgetApi, MatrixWidgetType } from "matrix-widget-api";
// eslint-disable-next-line deprecate/import
import { mount, ReactWrapper } from "enzyme";
import { Optional } from "matrix-events-sdk"; import { Optional } from "matrix-events-sdk";
import { act, render, RenderResult } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { SpiedFunction } from "jest-mock";
import RightPanel from "../../../../src/components/structures/RightPanel"; import RightPanel from "../../../../src/components/structures/RightPanel";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
@ -45,7 +46,7 @@ import { ElementWidget } from "../../../../src/stores/widgets/StopGapWidget";
import { WidgetMessagingStore } from "../../../../src/stores/widgets/WidgetMessagingStore"; import { WidgetMessagingStore } from "../../../../src/stores/widgets/WidgetMessagingStore";
describe("AppTile", () => { describe("AppTile", () => {
let cli; let cli: MatrixClient;
let r1: Room; let r1: Room;
let r2: Room; let r2: Room;
const resizeNotifier = new ResizeNotifier(); const resizeNotifier = new ResizeNotifier();
@ -90,7 +91,7 @@ describe("AppTile", () => {
type: MatrixWidgetType.Custom, type: MatrixWidgetType.Custom,
url: "https://example.com", url: "https://example.com",
name: "Example 1", name: "Example 1",
creatorUserId: cli.getUserId(), creatorUserId: cli.getSafeUserId(),
avatar_url: undefined, avatar_url: undefined,
}; };
app2 = { app2 = {
@ -100,12 +101,13 @@ describe("AppTile", () => {
type: MatrixWidgetType.Custom, type: MatrixWidgetType.Custom,
url: "https://example.com", url: "https://example.com",
name: "Example 2", name: "Example 2",
creatorUserId: cli.getUserId(), creatorUserId: cli.getSafeUserId(),
avatar_url: undefined, avatar_url: undefined,
}; };
jest.spyOn(WidgetStore.instance, "getApps").mockImplementation((roomId) => { jest.spyOn(WidgetStore.instance, "getApps").mockImplementation((roomId: string): Array<IApp> => {
if (roomId === "r1") return [app1]; if (roomId === "r1") return [app1];
if (roomId === "r2") return [app2]; if (roomId === "r2") return [app2];
return [];
}); });
// Wake up various stores we rely on // Wake up various stores we rely on
@ -143,7 +145,7 @@ describe("AppTile", () => {
}); });
// Run initial render with room 1, and also running lifecycle methods // Run initial render with room 1, and also running lifecycle methods
const renderer = TestRenderer.create( const renderResult = render(
<MatrixClientContext.Provider value={cli}> <MatrixClientContext.Provider value={cli}>
<RightPanel room={r1} resizeNotifier={resizeNotifier} /> <RightPanel room={r1} resizeNotifier={resizeNotifier} />
</MatrixClientContext.Provider>, </MatrixClientContext.Provider>,
@ -156,25 +158,25 @@ describe("AppTile", () => {
}); });
await rpsUpdated; await rpsUpdated;
expect(renderResult.getByText("Example 1")).toBeInTheDocument();
expect(ActiveWidgetStore.instance.isLive("1", "r1")).toBe(true); expect(ActiveWidgetStore.instance.isLive("1", "r1")).toBe(true);
// We want to verify that as we change to room 2, we should close the // We want to verify that as we change to room 2, we should close the
// right panel and destroy the widget. // right panel and destroy the widget.
const instance = renderer.root.findByType(AppTile).instance;
const endWidgetActions = jest.spyOn(instance, "endWidgetActions");
// Switch to room 2 // Switch to room 2
dis.dispatch({ dis.dispatch({
action: Action.ViewRoom, action: Action.ViewRoom,
room_id: "r2", room_id: "r2",
}); });
renderer.update(
renderResult.rerender(
<MatrixClientContext.Provider value={cli}> <MatrixClientContext.Provider value={cli}>
<RightPanel room={r2} resizeNotifier={resizeNotifier} /> <RightPanel room={r2} resizeNotifier={resizeNotifier} />
</MatrixClientContext.Provider>, </MatrixClientContext.Provider>,
); );
expect(endWidgetActions.mock.calls.length).toBe(1); expect(renderResult.queryByText("Example 1")).not.toBeInTheDocument();
expect(ActiveWidgetStore.instance.isLive("1", "r1")).toBe(false); expect(ActiveWidgetStore.instance.isLive("1", "r1")).toBe(false);
mockSettings.mockRestore(); mockSettings.mockRestore();
@ -204,7 +206,7 @@ describe("AppTile", () => {
}); });
// Run initial render with room 1, and also running lifecycle methods // Run initial render with room 1, and also running lifecycle methods
const renderer = TestRenderer.create( const renderResult = render(
<MatrixClientContext.Provider value={cli}> <MatrixClientContext.Provider value={cli}>
<RightPanel room={r1} resizeNotifier={resizeNotifier} /> <RightPanel room={r1} resizeNotifier={resizeNotifier} />
</MatrixClientContext.Provider>, </MatrixClientContext.Provider>,
@ -246,7 +248,7 @@ describe("AppTile", () => {
action: Action.ViewRoom, action: Action.ViewRoom,
room_id: "r2", room_id: "r2",
}); });
renderer.update( renderResult.rerender(
<MatrixClientContext.Provider value={cli}> <MatrixClientContext.Provider value={cli}>
<RightPanel room={r2} resizeNotifier={resizeNotifier} /> <RightPanel room={r2} resizeNotifier={resizeNotifier} />
</MatrixClientContext.Provider>, </MatrixClientContext.Provider>,
@ -274,33 +276,31 @@ describe("AppTile", () => {
return null; return null;
}); });
TestRenderer.act(() => { act(() => {
WidgetLayoutStore.instance.recalculateRoom(r1); WidgetLayoutStore.instance.recalculateRoom(r1);
}); });
// Run initial render with room 1, and also running lifecycle methods // Run initial render with room 1, and also running lifecycle methods
const renderer = TestRenderer.create( const renderResult = render(
<MatrixClientContext.Provider value={cli}> <MatrixClientContext.Provider value={cli}>
<AppsDrawer userId={cli.getUserId()} room={r1} resizeNotifier={resizeNotifier} /> <AppsDrawer userId={cli.getSafeUserId()} room={r1} resizeNotifier={resizeNotifier} />
</MatrixClientContext.Provider>, </MatrixClientContext.Provider>,
); );
expect(renderResult.getByText("Example 1")).toBeInTheDocument();
expect(ActiveWidgetStore.instance.isLive("1", "r1")).toBe(true); expect(ActiveWidgetStore.instance.isLive("1", "r1")).toBe(true);
// We want to verify that as we move the widget to the center container, // We want to verify that as we move the widget to the center container,
// the widget frame remains running. // the widget frame remains running.
const instance = renderer.root.findByType(AppTile).instance;
const endWidgetActions = jest.spyOn(instance, "endWidgetActions");
// Move widget to center
// Stop mocking settings so that the widget move can take effect // Stop mocking settings so that the widget move can take effect
mockSettings.mockRestore(); mockSettings.mockRestore();
TestRenderer.act(() => { act(() => {
// Move widget to center
WidgetLayoutStore.instance.moveToContainer(r1, app1, Container.Center); WidgetLayoutStore.instance.moveToContainer(r1, app1, Container.Center);
}); });
expect(endWidgetActions.mock.calls.length).toBe(0); expect(renderResult.getByText("Example 1")).toBeInTheDocument();
expect(ActiveWidgetStore.instance.isLive("1", "r1")).toBe(true); expect(ActiveWidgetStore.instance.isLive("1", "r1")).toBe(true);
}); });
@ -313,11 +313,11 @@ describe("AppTile", () => {
}); });
describe("for a pinned widget", () => { describe("for a pinned widget", () => {
let wrapper: ReactWrapper; let renderResult: RenderResult;
let moveToContainerSpy; let moveToContainerSpy: SpiedFunction<typeof WidgetLayoutStore.instance.moveToContainer>;
beforeEach(() => { beforeEach(() => {
wrapper = mount( renderResult = render(
<MatrixClientContext.Provider value={cli}> <MatrixClientContext.Provider value={cli}>
<AppTile key={app1.id} app={app1} room={r1} /> <AppTile key={app1.id} app={app1} room={r1} />
</MatrixClientContext.Provider>, </MatrixClientContext.Provider>,
@ -326,19 +326,17 @@ describe("AppTile", () => {
moveToContainerSpy = jest.spyOn(WidgetLayoutStore.instance, "moveToContainer"); moveToContainerSpy = jest.spyOn(WidgetLayoutStore.instance, "moveToContainer");
}); });
it("requiresClient should be true", () => { it("should not display the »Popout widget« button", () => {
expect(wrapper.state("requiresClient")).toBe(true); expect(renderResult.queryByLabelText("Popout widget")).not.toBeInTheDocument();
}); });
it("clicking 'minimise' should send the widget to the right", () => { it("clicking 'minimise' should send the widget to the right", async () => {
const minimiseButton = wrapper.find(".mx_AppTileMenuBar_iconButton_minimise"); await userEvent.click(renderResult.getByTitle("Minimise"));
minimiseButton.first().simulate("click");
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Right); expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Right);
}); });
it("clicking 'maximise' should send the widget to the center", () => { it("clicking 'maximise' should send the widget to the center", async () => {
const minimiseButton = wrapper.find(".mx_AppTileMenuBar_iconButton_maximise"); await userEvent.click(renderResult.getByTitle("Maximise"));
minimiseButton.first().simulate("click");
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Center); expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Center);
}); });
@ -351,36 +349,34 @@ describe("AppTile", () => {
); );
}); });
it("clicking 'un-maximise' should send the widget to the top", () => { it("clicking 'un-maximise' should send the widget to the top", async () => {
const unMaximiseButton = wrapper.find(".mx_AppTileMenuBar_iconButton_collapse"); await userEvent.click(renderResult.getByTitle("Un-maximise"));
unMaximiseButton.first().simulate("click");
expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Top); expect(moveToContainerSpy).toHaveBeenCalledWith(r1, app1, Container.Top);
}); });
}); });
describe("with an existing widgetApi holding requiresClient = false", () => { describe("with an existing widgetApi with requiresClient = false", () => {
let wrapper: ReactWrapper;
beforeEach(() => { beforeEach(() => {
const api = { const api = {
hasCapability: (capability: ElementWidgetCapabilities): boolean => { hasCapability: (capability: ElementWidgetCapabilities): boolean => {
return !(capability === ElementWidgetCapabilities.RequiresClient); return !(capability === ElementWidgetCapabilities.RequiresClient);
}, },
once: () => {}, once: () => {},
stop: () => {},
} as unknown as ClientWidgetApi; } as unknown as ClientWidgetApi;
const mockWidget = new ElementWidget(app1); const mockWidget = new ElementWidget(app1);
WidgetMessagingStore.instance.storeMessaging(mockWidget, r1.roomId, api); WidgetMessagingStore.instance.storeMessaging(mockWidget, r1.roomId, api);
wrapper = mount( renderResult = render(
<MatrixClientContext.Provider value={cli}> <MatrixClientContext.Provider value={cli}>
<AppTile key={app1.id} app={app1} room={r1} /> <AppTile key={app1.id} app={app1} room={r1} />
</MatrixClientContext.Provider>, </MatrixClientContext.Provider>,
); );
}); });
it("requiresClient should be false", () => { it("should display the »Popout widget« button", () => {
expect(wrapper.state("requiresClient")).toBe(false); expect(renderResult.getByTitle("Popout widget")).toBeInTheDocument();
}); });
}); });
}); });