1
0
mirror of https://github.com/matrix-org/matrix-react-sdk.git synced 2025-08-06 10:22:45 +03:00
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2024-08-01 16:15:53 +01:00
parent e6bb0f34d4
commit 07670a75ce
13 changed files with 871 additions and 861 deletions

View File

@@ -248,7 +248,9 @@ export default class Registration extends React.Component<IProps, IState> {
logger.error("Failed to get login flows to check for SSO support", e); logger.error("Failed to get login flows to check for SSO support", e);
} }
this.setState(({ flows }) => ({ await new Promise<void>((resolve) => {
this.setState(
({ flows }) => ({
matrixClient: cli, matrixClient: cli,
ssoFlow, ssoFlow,
oidcNativeFlow, oidcNativeFlow,
@@ -256,7 +258,10 @@ export default class Registration extends React.Component<IProps, IState> {
// so set an empty array to indicate flows are no longer loading // so set an empty array to indicate flows are no longer loading
flows: oidcNativeFlow ? [] : flows, flows: oidcNativeFlow ? [] : flows,
busy: false, busy: false,
})); }),
resolve,
);
});
// don't need to check with homeserver for login flows // don't need to check with homeserver for login flows
// since we are going to use OIDC native flow // since we are going to use OIDC native flow

View File

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

View File

@@ -16,7 +16,7 @@ limitations under the License.
import React from "react"; import React from "react";
import { mocked } from "jest-mock"; import { mocked } from "jest-mock";
import { act, render, RenderResult, screen } from "@testing-library/react"; import { act, render, RenderResult, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
import { MatrixClient, createClient } from "matrix-js-sdk/src/matrix"; import { MatrixClient, createClient } from "matrix-js-sdk/src/matrix";

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/ */
import React, { ReactElement } from "react"; import React, { ReactElement } from "react";
import { render, screen } from "@testing-library/react"; import { render, screen, waitFor } from "@testing-library/react";
import { mocked, MockedObject } from "jest-mock"; import { mocked, MockedObject } from "jest-mock";
import { MatrixClient } from "matrix-js-sdk/src/matrix"; import { MatrixClient } from "matrix-js-sdk/src/matrix";
@@ -238,7 +238,7 @@ describe("<UserSettingsDialog />", () => {
expect(getByTestId(`settings-tab-${UserTab.Labs}`)).toBeTruthy(); expect(getByTestId(`settings-tab-${UserTab.Labs}`)).toBeTruthy();
}); });
it("watches settings", () => { it("watches settings", async () => {
const watchSettingCallbacks: Record<string, CallbackFn> = {}; const watchSettingCallbacks: Record<string, CallbackFn> = {};
mockSettingsStore.watchSetting.mockImplementation((settingName, roomId, callback) => { mockSettingsStore.watchSetting.mockImplementation((settingName, roomId, callback) => {
@@ -257,7 +257,7 @@ describe("<UserSettingsDialog />", () => {
watchSettingCallbacks["feature_mjolnir"]("feature_mjolnir", "", SettingLevel.ACCOUNT, true, true); watchSettingCallbacks["feature_mjolnir"]("feature_mjolnir", "", SettingLevel.ACCOUNT, true, true);
// tab is rendered now // tab is rendered now
expect(queryByTestId(`settings-tab-${UserTab.Mjolnir}`)).toBeTruthy(); await waitFor(() => expect(queryByTestId(`settings-tab-${UserTab.Mjolnir}`)).toBeTruthy());
unmount(); unmount();

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/ */
import React from "react"; import React from "react";
import { render } from "@testing-library/react"; import { render, waitForElementToBeRemoved } from "@testing-library/react";
import { EventTimeline, MatrixEvent, Room, M_TEXT } from "matrix-js-sdk/src/matrix"; import { EventTimeline, MatrixEvent, Room, M_TEXT } from "matrix-js-sdk/src/matrix";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
@@ -129,13 +129,14 @@ describe("<MPollEndBody />", () => {
describe("when poll start event does not exist in current timeline", () => { describe("when poll start event does not exist in current timeline", () => {
it("fetches the related poll start event and displays a poll tile", async () => { it("fetches the related poll start event and displays a poll tile", async () => {
await setupRoomWithEventsTimeline(pollEndEvent); await setupRoomWithEventsTimeline(pollEndEvent);
const { container, getByTestId } = getComponent(); const { container, getByTestId, queryByRole } = getComponent();
// while fetching event, only icon is shown // while fetching event, only icon is shown
expect(container).toMatchSnapshot(); expect(container).toMatchSnapshot();
// flush the fetch event promise // flush the fetch event promise
await flushPromises(); await flushPromises();
await waitForElementToBeRemoved(() => queryByRole("progressbar"));
expect(mockClient.fetchRoomEvent).toHaveBeenCalledWith(roomId, pollStartEvent.getId()); expect(mockClient.fetchRoomEvent).toHaveBeenCalledWith(roomId, pollStartEvent.getId());

View File

@@ -24,6 +24,7 @@ import {
getMockClientWithEventEmitter, getMockClientWithEventEmitter,
makePollEndEvent, makePollEndEvent,
makePollStartEvent, makePollStartEvent,
mockClientMethodsRooms,
mockClientMethodsUser, mockClientMethodsUser,
mockIntlDateTimeFormat, mockIntlDateTimeFormat,
setupRoomWithPollEvents, setupRoomWithPollEvents,
@@ -41,7 +42,7 @@ describe("<PollHistory />", () => {
const roomId = "!room:domain.org"; const roomId = "!room:domain.org";
const mockClient = getMockClientWithEventEmitter({ const mockClient = getMockClientWithEventEmitter({
...mockClientMethodsUser(userId), ...mockClientMethodsUser(userId),
getRoom: jest.fn(), ...mockClientMethodsRooms([]),
relations: jest.fn(), relations: jest.fn(),
decryptEventIfNeeded: jest.fn(), decryptEventIfNeeded: jest.fn(),
getOrCreateFilter: jest.fn(), getOrCreateFilter: jest.fn(),

View File

@@ -15,10 +15,9 @@ limitations under the License.
*/ */
import React, { ComponentProps } from "react"; import React, { ComponentProps } from "react";
import { render, fireEvent, RenderResult, waitFor } from "@testing-library/react"; import { render, fireEvent, RenderResult, waitFor, waitForElementToBeRemoved } from "@testing-library/react";
import { Room, RoomMember, MatrixError, IContent } from "matrix-js-sdk/src/matrix"; import { Room, RoomMember, MatrixError, IContent } from "matrix-js-sdk/src/matrix";
import { KnownMembership } from "matrix-js-sdk/src/types"; import { KnownMembership } from "matrix-js-sdk/src/types";
import { sleep } from "matrix-js-sdk/src/utils";
import { withClientContextRenderOptions, stubClient } from "../../../test-utils"; import { withClientContextRenderOptions, stubClient } from "../../../test-utils";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
@@ -374,8 +373,7 @@ describe("<RoomPreviewBar />", () => {
const onJoinClick = jest.fn(); const onJoinClick = jest.fn();
const onRejectClick = jest.fn(); const onRejectClick = jest.fn();
const component = getComponent({ ...props, onJoinClick, onRejectClick }); const component = getComponent({ ...props, onJoinClick, onRejectClick });
await sleep(0); await waitFor(() => expect(getPrimaryActionButton(component)).toBeTruthy());
expect(getPrimaryActionButton(component)).toBeTruthy();
if (expectSecondaryButton) expect(getSecondaryActionButton(component)).toBeFalsy(); if (expectSecondaryButton) expect(getSecondaryActionButton(component)).toBeFalsy();
fireEvent.click(getPrimaryActionButton(component)!); fireEvent.click(getPrimaryActionButton(component)!);
expect(onJoinClick).toHaveBeenCalled(); expect(onJoinClick).toHaveBeenCalled();
@@ -388,7 +386,7 @@ describe("<RoomPreviewBar />", () => {
it("renders error message", async () => { it("renders error message", async () => {
const component = getComponent({ inviterName, invitedEmail }); const component = getComponent({ inviterName, invitedEmail });
await sleep(0); await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot(); expect(getMessage(component)).toMatchSnapshot();
}); });
@@ -405,7 +403,7 @@ describe("<RoomPreviewBar />", () => {
it("renders invite message with invited email", async () => { it("renders invite message with invited email", async () => {
const component = getComponent({ inviterName, invitedEmail }); const component = getComponent({ inviterName, invitedEmail });
await sleep(0); await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot(); expect(getMessage(component)).toMatchSnapshot();
}); });
@@ -421,7 +419,7 @@ describe("<RoomPreviewBar />", () => {
it("renders invite message with invited email", async () => { it("renders invite message with invited email", async () => {
const component = getComponent({ inviterName, invitedEmail }); const component = getComponent({ inviterName, invitedEmail });
await sleep(0); await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot(); expect(getMessage(component)).toMatchSnapshot();
}); });
@@ -439,7 +437,7 @@ describe("<RoomPreviewBar />", () => {
it("renders email mismatch message when invite email mxid doesnt match", async () => { it("renders email mismatch message when invite email mxid doesnt match", async () => {
MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockReturnValue({ mxid: "not userid" }); MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockReturnValue({ mxid: "not userid" });
const component = getComponent({ inviterName, invitedEmail }); const component = getComponent({ inviterName, invitedEmail });
await sleep(0); await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot(); expect(getMessage(component)).toMatchSnapshot();
expect(MatrixClientPeg.safeGet().lookupThreePid).toHaveBeenCalledWith( expect(MatrixClientPeg.safeGet().lookupThreePid).toHaveBeenCalledWith(
@@ -453,7 +451,7 @@ describe("<RoomPreviewBar />", () => {
it("renders invite message when invite email mxid match", async () => { it("renders invite message when invite email mxid match", async () => {
MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockReturnValue({ mxid: userId }); MatrixClientPeg.safeGet().lookupThreePid = jest.fn().mockReturnValue({ mxid: userId });
const component = getComponent({ inviterName, invitedEmail }); const component = getComponent({ inviterName, invitedEmail });
await sleep(0); await waitForElementToBeRemoved(() => component.queryByRole("progressbar"));
expect(getMessage(component)).toMatchSnapshot(); expect(getMessage(component)).toMatchSnapshot();
await testJoinButton({ inviterName, invitedEmail }, false)(); await testJoinButton({ inviterName, invitedEmail }, false)();

View File

@@ -15,7 +15,7 @@ limitations under the License.
*/ */
import React from "react"; import React from "react";
import { fireEvent, render, screen, within } from "@testing-library/react"; import { fireEvent, render, screen, waitFor, within } from "@testing-library/react";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext"; import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
@@ -99,6 +99,6 @@ describe("SetIntegrationManager", () => {
expect(logger.error).toHaveBeenCalledWith("Error changing integration manager provisioning"); expect(logger.error).toHaveBeenCalledWith("Error changing integration manager provisioning");
expect(logger.error).toHaveBeenCalledWith("oups"); expect(logger.error).toHaveBeenCalledWith("oups");
expect(within(integrationSection).getByRole("switch")).not.toBeChecked(); await waitFor(() => expect(within(integrationSection).getByRole("switch")).not.toBeChecked());
}); });
}); });

View File

@@ -46,7 +46,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
<input <input
class="_input_1vw5h_26" class="_input_1vw5h_26"
disabled="" disabled=""
id="radix-0" id="radix-:r0:"
name="themeSelector" name="themeSelector"
title="" title=""
type="radio" type="radio"
@@ -62,7 +62,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
> >
<label <label
class="_label_dgy0u_67 mx_ThemeChoicePanel_themeSelector_Label" class="_label_dgy0u_67 mx_ThemeChoicePanel_themeSelector_Label"
for="radix-0" for="radix-:r0:"
> >
Light Light
</label> </label>
@@ -80,7 +80,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
<input <input
class="_input_1vw5h_26" class="_input_1vw5h_26"
disabled="" disabled=""
id="radix-1" id="radix-:r1:"
name="themeSelector" name="themeSelector"
title="" title=""
type="radio" type="radio"
@@ -96,7 +96,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
> >
<label <label
class="_label_dgy0u_67 mx_ThemeChoicePanel_themeSelector_Label" class="_label_dgy0u_67 mx_ThemeChoicePanel_themeSelector_Label"
for="radix-1" for="radix-:r1:"
> >
Dark Dark
</label> </label>
@@ -114,7 +114,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
<input <input
class="_input_1vw5h_26" class="_input_1vw5h_26"
disabled="" disabled=""
id="radix-2" id="radix-:r2:"
name="themeSelector" name="themeSelector"
title="" title=""
type="radio" type="radio"
@@ -130,7 +130,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
> >
<label <label
class="_label_dgy0u_67 mx_ThemeChoicePanel_themeSelector_Label" class="_label_dgy0u_67 mx_ThemeChoicePanel_themeSelector_Label"
for="radix-2" for="radix-:r2:"
> >
High contrast High contrast
</label> </label>
@@ -170,7 +170,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
<label <label
aria-label="Modern" aria-label="Modern"
class="_label_dgy0u_67" class="_label_dgy0u_67"
for="radix-3" for="radix-:r3:"
> >
<div <div
class="mxLayoutSwitcher_LayoutSelector_LayoutRadio_inline" class="mxLayoutSwitcher_LayoutSelector_LayoutRadio_inline"
@@ -181,7 +181,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
<input <input
checked="" checked=""
class="_input_1vw5h_26" class="_input_1vw5h_26"
id="radix-3" id="radix-:r3:"
name="layout" name="layout"
title="" title=""
type="radio" type="radio"
@@ -287,7 +287,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
<label <label
aria-label="Message bubbles" aria-label="Message bubbles"
class="_label_dgy0u_67" class="_label_dgy0u_67"
for="radix-4" for="radix-:rc:"
> >
<div <div
class="mxLayoutSwitcher_LayoutSelector_LayoutRadio_inline" class="mxLayoutSwitcher_LayoutSelector_LayoutRadio_inline"
@@ -297,7 +297,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
> >
<input <input
class="_input_1vw5h_26" class="_input_1vw5h_26"
id="radix-4" id="radix-:rc:"
name="layout" name="layout"
title="" title=""
type="radio" type="radio"
@@ -403,7 +403,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
<label <label
aria-label="IRC (experimental)" aria-label="IRC (experimental)"
class="_label_dgy0u_67" class="_label_dgy0u_67"
for="radix-5" for="radix-:rl:"
> >
<div <div
class="mxLayoutSwitcher_LayoutSelector_LayoutRadio_inline" class="mxLayoutSwitcher_LayoutSelector_LayoutRadio_inline"
@@ -413,7 +413,7 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
> >
<input <input
class="_input_1vw5h_26" class="_input_1vw5h_26"
id="radix-5" id="radix-:rl:"
name="layout" name="layout"
title="" title=""
type="radio" type="radio"
@@ -527,9 +527,9 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
class="_container_qnvru_18" class="_container_qnvru_18"
> >
<input <input
aria-describedby="radix-6" aria-describedby="radix-:rv:"
class="_input_qnvru_32" class="_input_qnvru_32"
id="radix-7" id="radix-:ru:"
name="compactLayout" name="compactLayout"
title="" title=""
type="checkbox" type="checkbox"
@@ -544,13 +544,13 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
> >
<label <label
class="_label_dgy0u_67" class="_label_dgy0u_67"
for="radix-7" for="radix-:ru:"
> >
Show compact text and messages Show compact text and messages
</label> </label>
<span <span
class="_message_dgy0u_98 _help-message_dgy0u_104" class="_message_dgy0u_98 _help-message_dgy0u_104"
id="radix-6" id="radix-:rv:"
> >
Modern layout must be selected to use this feature. Modern layout must be selected to use this feature.
</span> </span>

View File

@@ -142,9 +142,8 @@ describe("languageHandler", () => {
it("includes English message and localized translated message", async () => { it("includes English message and localized translated message", async () => {
await setLanguage("de"); await setLanguage("de");
const friendlyError = new UserFriendlyError(testErrorMessage, { const friendlyError = new UserFriendlyError(testErrorMessage, undefined, {
email: "test@example.com", email: "test@example.com",
cause: undefined,
}); });
// Ensure message is in English so it's readable in the logs // Ensure message is in English so it's readable in the logs
@@ -159,9 +158,8 @@ describe("languageHandler", () => {
await setLanguage("de"); await setLanguage("de");
const underlyingError = new Error("Fake underlying error"); const underlyingError = new Error("Fake underlying error");
const friendlyError = new UserFriendlyError(testErrorMessage, { const friendlyError = new UserFriendlyError(testErrorMessage, underlyingError, {
email: "test@example.com", email: "test@example.com",
cause: underlyingError,
}); });
expect(friendlyError.cause).toStrictEqual(underlyingError); expect(friendlyError.cause).toStrictEqual(underlyingError);

View File

@@ -21,6 +21,12 @@ import { mocked } from "jest-mock";
import { PredictableRandom } from "./predictableRandom"; // https://github.com/jsdom/jsdom/issues/2555 import { PredictableRandom } from "./predictableRandom"; // https://github.com/jsdom/jsdom/issues/2555
declare global {
var IS_REACT_ACT_ENVIRONMENT: boolean;
}
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
// Fake random strings to give a predictable snapshot for IDs // Fake random strings to give a predictable snapshot for IDs
jest.mock("matrix-js-sdk/src/randomstring"); jest.mock("matrix-js-sdk/src/randomstring");
beforeEach(() => { beforeEach(() => {

View File

@@ -181,4 +181,5 @@ export const mockClientMethodsCrypto = (): Partial<
export const mockClientMethodsRooms = (rooms: Room[] = []): Partial<Record<MethodLikeKeys<MatrixClient>, unknown>> => ({ export const mockClientMethodsRooms = (rooms: Room[] = []): Partial<Record<MethodLikeKeys<MatrixClient>, unknown>> => ({
getRooms: jest.fn().mockReturnValue(rooms), getRooms: jest.fn().mockReturnValue(rooms),
getRoom: jest.fn((roomId) => rooms.find((r) => r.roomId === roomId) ?? null), getRoom: jest.fn((roomId) => rooms.find((r) => r.roomId === roomId) ?? null),
isRoomEncrypted: jest.fn(),
}); });