Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Make tests more resilient for React 18 upgrade (#12861)
Browse files Browse the repository at this point in the history
* Make tests more resilient for React 18 upgrade

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Iterate

Signed-off-by: Michael Telatynski <[email protected]>

* Delint

Signed-off-by: Michael Telatynski <[email protected]>

---------

Signed-off-by: Michael Telatynski <[email protected]>
  • Loading branch information
t3chguy authored Aug 6, 2024
1 parent 4e4c5c7 commit 8285283
Show file tree
Hide file tree
Showing 35 changed files with 311 additions and 288 deletions.
1 change: 0 additions & 1 deletion test/components/structures/MatrixChat-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1380,7 +1380,6 @@ describe("<MatrixChat />", () => {

it("while we are checking the sync store", async () => {
const rendered = getComponent({});
await flushPromises();
expect(rendered.getByTestId("spinner")).toBeInTheDocument();

// now a third session starts
Expand Down
6 changes: 3 additions & 3 deletions test/components/structures/UserMenu-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ describe("<UserMenu>", () => {

const spy = jest.spyOn(defaultDispatcher, "dispatch");
screen.getByRole("button", { name: /User menu/i }).click();
screen.getByRole("menuitem", { name: /Sign out/i }).click();
(await screen.findByRole("menuitem", { name: /Sign out/i })).click();
await waitFor(() => {
expect(spy).toHaveBeenCalledWith({ action: "logout" });
});
Expand All @@ -152,7 +152,7 @@ describe("<UserMenu>", () => {

const spy = jest.spyOn(defaultDispatcher, "dispatch");
screen.getByRole("button", { name: /User menu/i }).click();
screen.getByRole("menuitem", { name: /Sign out/i }).click();
(await screen.findByRole("menuitem", { name: /Sign out/i })).click();
await waitFor(() => {
expect(spy).toHaveBeenCalledWith({ action: "logout" });
});
Expand All @@ -178,7 +178,7 @@ describe("<UserMenu>", () => {

const spy = jest.spyOn(Modal, "createDialog");
screen.getByRole("button", { name: /User menu/i }).click();
screen.getByRole("menuitem", { name: /Sign out/i }).click();
(await screen.findByRole("menuitem", { name: /Sign out/i })).click();

await waitFor(() => {
expect(spy).toHaveBeenCalledWith(LogoutDialog);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,11 @@ describe("AccessSecretStorageDialog", () => {
expect(screen.getByPlaceholderText("Security Phrase")).toHaveValue(securityKey);
await submitDialog();

expect(
screen.getByText(
await expect(
screen.findByText(
"👎 Unable to access secret storage. Please verify that you entered the correct Security Phrase.",
),
).toBeInTheDocument();
).resolves.toBeInTheDocument();

expect(screen.getByPlaceholderText("Security Phrase")).toHaveFocus();
});
Expand Down
2 changes: 1 addition & 1 deletion test/components/views/dialogs/InviteDialog-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ describe("InviteDialog", () => {

describe("when clicking »Start DM anyway«", () => {
beforeEach(async () => {
await userEvent.click(screen.getByRole("button", { name: "Start DM anyway", exact: true }));
await userEvent.click(screen.getByRole("button", { name: "Start DM anyway" }));
});

it("should start the DM", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ limitations under the License.
*/

import React from "react";
import { render, RenderResult } from "@testing-library/react";
import { render, RenderResult, waitForElementToBeRemoved } from "@testing-library/react";
import { EventType, MatrixEvent } from "matrix-js-sdk/src/matrix";

import type { MatrixClient } from "matrix-js-sdk/src/matrix";
Expand All @@ -39,6 +39,7 @@ describe("<MessageEditHistory />", () => {

async function renderComponent(): Promise<RenderResult> {
const result = render(<MessageEditHistoryDialog mxEvent={event} onFinished={jest.fn()} />);
await waitForElementToBeRemoved(() => result.queryByRole("progressbar"));
await flushPromises();
return result;
}
Expand Down
8 changes: 5 additions & 3 deletions test/components/views/dialogs/RoomSettingsDialog-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ limitations under the License.
*/

import React from "react";
import { fireEvent, render, screen } from "@testing-library/react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import {
EventTimeline,
EventType,
Expand Down Expand Up @@ -129,7 +129,7 @@ describe("<RoomSettingsDialog />", () => {
expect(screen.getByTestId("settings-tab-ROOM_PEOPLE_TAB")).toBeInTheDocument();
});

it("re-renders on room join rule changes", () => {
it("re-renders on room join rule changes", async () => {
jest.spyOn(SettingsStore, "getValue").mockImplementation(
(setting) => setting === "feature_ask_to_join",
);
Expand All @@ -142,7 +142,9 @@ describe("<RoomSettingsDialog />", () => {
room.getLiveTimeline().getState(EventTimeline.FORWARDS)!,
null,
);
expect(screen.queryByTestId("settings-tab-ROOM_PEOPLE_TAB")).not.toBeInTheDocument();
await waitFor(() =>
expect(screen.queryByTestId("settings-tab-ROOM_PEOPLE_TAB")).not.toBeInTheDocument(),
);
});
});

Expand Down
38 changes: 14 additions & 24 deletions test/components/views/dialogs/UserSettingsDialog-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,9 @@ jest.mock("../../../../src/settings/SettingsStore", () => ({
settingIsOveriddenAtConfigLevel: jest.fn(),
}));

jest.mock("../../../../src/SdkConfig", () => ({
get: jest.fn(),
}));

describe("<UserSettingsDialog />", () => {
const userId = "@alice:server.org";
const mockSettingsStore = mocked(SettingsStore);
const mockSdkConfig = mocked(SdkConfig);
let mockClient!: MockedObject<MatrixClient>;

let sdkContext: SdkContextClass;
Expand All @@ -89,7 +84,8 @@ describe("<UserSettingsDialog />", () => {
mockSettingsStore.getValue.mockReturnValue(false);
mockSettingsStore.getValueAt.mockReturnValue(false);
mockSettingsStore.getFeatureSettingNames.mockReturnValue([]);
mockSdkConfig.get.mockReturnValue({ brand: "Test" });
SdkConfig.reset();
SdkConfig.put({ brand: "Test" });
});

const getActiveTabLabel = (container: Element) =>
Expand All @@ -115,6 +111,9 @@ describe("<UserSettingsDialog />", () => {
});

it("renders tabs correctly", () => {
SdkConfig.add({
show_labs_settings: true,
});
const { container } = render(getComponent());
expect(container.querySelectorAll(".mx_TabbedView_tabLabel")).toMatchSnapshot();
});
Expand Down Expand Up @@ -181,26 +180,16 @@ describe("<UserSettingsDialog />", () => {
expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent("Settings: Voice & Video");
});

it("renders with secutity tab selected", () => {
it("renders with security tab selected", () => {
const { container } = render(getComponent({ initialTabId: UserTab.Security }));

expect(getActiveTabLabel(container)).toEqual("Security & Privacy");
expect(screen.getByRole("heading", { level: 1 })).toHaveTextContent("Settings: Security & Privacy");
});

it("renders with labs tab selected", () => {
// @ts-ignore I give up trying to get the types right here
// why do we have functions that return different things depending on what they're passed?
mockSdkConfig.get.mockImplementation((x) => {
const mockConfig = { show_labs_settings: true, brand: "Test" };
switch (x) {
case "show_labs_settings":
case "brand":
// @ts-ignore
return mockConfig[x];
default:
return mockConfig;
}
SdkConfig.add({
show_labs_settings: true,
});
const { container } = render(getComponent({ initialTabId: UserTab.Labs }));

Expand All @@ -223,8 +212,9 @@ describe("<UserSettingsDialog />", () => {
});

it("renders labs tab when show_labs_settings is enabled in config", () => {
// @ts-ignore simplified test stub
mockSdkConfig.get.mockImplementation((configName) => configName === "show_labs_settings");
SdkConfig.add({
show_labs_settings: true,
});
const { getByTestId } = render(getComponent());
expect(getByTestId(`settings-tab-${UserTab.Labs}`)).toBeTruthy();
});
Expand All @@ -238,7 +228,7 @@ describe("<UserSettingsDialog />", () => {
expect(getByTestId(`settings-tab-${UserTab.Labs}`)).toBeTruthy();
});

it("watches settings", () => {
it("watches settings", async () => {
const watchSettingCallbacks: Record<string, CallbackFn> = {};

mockSettingsStore.watchSetting.mockImplementation((settingName, roomId, callback) => {
Expand All @@ -247,7 +237,7 @@ describe("<UserSettingsDialog />", () => {
});
mockSettingsStore.getValue.mockReturnValue(false);

const { queryByTestId, unmount } = render(getComponent());
const { queryByTestId, findByTestId, unmount } = render(getComponent());
expect(queryByTestId(`settings-tab-${UserTab.Mjolnir}`)).toBeFalsy();

expect(mockSettingsStore.watchSetting).toHaveBeenCalledWith("feature_mjolnir", null, expect.anything());
Expand All @@ -257,7 +247,7 @@ describe("<UserSettingsDialog />", () => {
watchSettingCallbacks["feature_mjolnir"]("feature_mjolnir", "", SettingLevel.ACCOUNT, true, true);

// tab is rendered now
expect(queryByTestId(`settings-tab-${UserTab.Mjolnir}`)).toBeTruthy();
await expect(findByTestId(`settings-tab-${UserTab.Mjolnir}`)).resolves.toBeTruthy();

unmount();

Expand Down
20 changes: 7 additions & 13 deletions test/components/views/elements/Field-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ limitations under the License.
*/

import React from "react";
import { act, fireEvent, render, screen } from "@testing-library/react";
import { fireEvent, render, screen } from "@testing-library/react";

import Field from "../../../../src/components/views/elements/Field";

Expand Down Expand Up @@ -63,12 +63,10 @@ describe("Field", () => {
);

// When invalid
await act(async () => {
fireEvent.focus(screen.getByRole("textbox"));
});
fireEvent.focus(screen.getByRole("textbox"));

// Expect 'alert' role
expect(screen.queryByRole("alert")).toBeInTheDocument();
await expect(screen.findByRole("alert")).resolves.toBeInTheDocument();

// Close the feedback is Escape is pressed
fireEvent.keyDown(screen.getByRole("textbox"), { key: "Escape" });
Expand All @@ -85,12 +83,10 @@ describe("Field", () => {
);

// When valid
await act(async () => {
fireEvent.focus(screen.getByRole("textbox"));
});
fireEvent.focus(screen.getByRole("textbox"));

// Expect 'status' role
expect(screen.queryByRole("status")).toBeInTheDocument();
await expect(screen.findByRole("status")).resolves.toBeInTheDocument();

// Close the feedback is Escape is pressed
fireEvent.keyDown(screen.getByRole("textbox"), { key: "Escape" });
Expand All @@ -108,12 +104,10 @@ describe("Field", () => {
);

// When valid or invalid and 'tooltipContent' set
await act(async () => {
fireEvent.focus(screen.getByRole("textbox"));
});
fireEvent.focus(screen.getByRole("textbox"));

// Expect 'tooltip' role
expect(screen.queryByRole("tooltip")).toBeInTheDocument();
await expect(screen.findByRole("tooltip")).resolves.toBeInTheDocument();

// Close the feedback is Escape is pressed
fireEvent.keyDown(screen.getByRole("textbox"), { key: "Escape" });
Expand Down
4 changes: 2 additions & 2 deletions test/components/views/elements/SearchWarning-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ describe("<SearchWarning />", () => {
});

it("renders with a logo by default", () => {
const { asFragment, queryByRole } = render(
const { asFragment, getByRole } = render(
<SearchWarning isRoomEncrypted={true} kind={WarningKind.Search} />,
);
expect(queryByRole("img")).toBeInTheDocument();
expect(getByRole("img")).toHaveAttribute("src", "https://logo");
expect(asFragment()).toMatchSnapshot();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ import PlatformPeg from "../../../../src/PlatformPeg";

describe("<SpellCheckLanguagesDropdown />", () => {
it("renders as expected", async () => {
const platform: any = { getAvailableSpellCheckLanguages: jest.fn().mockResolvedValue(["en", "de", "qq"]) };
const platform: any = {
getAvailableSpellCheckLanguages: jest.fn().mockResolvedValue(["en", "de", "qq"]),
supportsSetting: jest.fn(),
};
PlatformPeg.set(platform);

const { asFragment } = render(
Expand Down
2 changes: 1 addition & 1 deletion test/components/views/messages/MImageBody-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ describe("<MImageBody/>", () => {
it("should generate a thumbnail if one isn't included for animated media", async () => {
Object.defineProperty(global.Image.prototype, "src", {
set(src) {
window.setTimeout(() => this.onload());
window.setTimeout(() => this.onload?.());
},
});
Object.defineProperty(global.Image.prototype, "height", {
Expand Down
14 changes: 9 additions & 5 deletions test/components/views/messages/MLocationBody-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { fireEvent, render, waitFor } from "@testing-library/react";
import { LocationAssetType, ClientEvent, RoomMember, SyncState } from "matrix-js-sdk/src/matrix";
import * as maplibregl from "maplibre-gl";
import { logger } from "matrix-js-sdk/src/logger";
import { sleep } from "matrix-js-sdk/src/utils";

import MLocationBody from "../../../../src/components/views/messages/MLocationBody";
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
Expand Down Expand Up @@ -64,9 +65,11 @@ describe("MLocationBody", () => {
});
const component = getComponent();

// simulate error initialising map in maplibregl
// @ts-ignore
mockMap.emit("error", { status: 404 });
sleep(10).then(() => {
// simulate error initialising map in maplibregl
// @ts-ignore
mockMap.emit("error", { status: 404 });
});

return component;
};
Expand Down Expand Up @@ -100,9 +103,10 @@ describe("MLocationBody", () => {
expect(component.container.querySelector(".mx_EventTile_body")).toMatchSnapshot();
});

it("displays correct fallback content when map_style_url is misconfigured", () => {
it("displays correct fallback content when map_style_url is misconfigured", async () => {
const component = getMapErrorComponent();
expect(component.container.querySelector(".mx_EventTile_body")).toMatchSnapshot();
await waitFor(() => expect(component.container.querySelector(".mx_EventTile_body")).toBeTruthy());
await waitFor(() => expect(component.container.querySelector(".mx_EventTile_body")).toMatchSnapshot());
});

it("should clear the error on reconnect", () => {
Expand Down
7 changes: 3 additions & 4 deletions test/components/views/messages/MPollEndBody-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ limitations under the License.
*/

import React from "react";
import { render } from "@testing-library/react";
import { render, waitFor } from "@testing-library/react";
import { EventTimeline, MatrixEvent, Room, M_TEXT } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger";

Expand Down Expand Up @@ -129,13 +129,12 @@ describe("<MPollEndBody />", () => {
describe("when poll start event does not exist in current timeline", () => {
it("fetches the related poll start event and displays a poll tile", async () => {
await setupRoomWithEventsTimeline(pollEndEvent);
const { container, getByTestId } = getComponent();
const { container, getByTestId, getByRole } = getComponent();

// while fetching event, only icon is shown
expect(container).toMatchSnapshot();

// flush the fetch event promise
await flushPromises();
await waitFor(() => expect(getByRole("progressbar")).toBeInTheDocument());

expect(mockClient.fetchRoomEvent).toHaveBeenCalledWith(roomId, pollStartEvent.getId());

Expand Down
Loading

0 comments on commit 8285283

Please sign in to comment.