From c203f0273153c49875889514991fbd829b172d86 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Thu, 20 Nov 2025 18:17:51 +0000 Subject: [PATCH] Rename callback on E2eSetup component (#31274) * Rename callback on E2eSetup component `BaseDialog.onFinished` is unused when `hasCancel=false`, so this callback is only used when the user clicks cancel. For clarity, rename it. * Test for cancellation behaviour --- src/components/structures/MatrixChat.tsx | 2 +- src/components/structures/auth/E2eSetup.tsx | 8 +++-- .../security/InitialCryptoSetupDialog.tsx | 17 ++++----- .../structures/auth/E2eSetup-test.tsx | 35 +++++++++++++++++++ .../InitialCryptoSetupDialog-test.tsx | 9 ++--- 5 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 test/unit-tests/components/structures/auth/E2eSetup-test.tsx diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index cd975a7ef2..218f31e889 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -2101,7 +2101,7 @@ export default class MatrixChat extends React.PureComponent { } else if (this.state.view === Views.COMPLETE_SECURITY) { view = ; } else if (this.state.view === Views.E2E_SETUP) { - view = ; + view = ; } else if (this.state.view === Views.LOGGED_IN) { // `ready` and `view==LOGGED_IN` may be set before `page_type` (because the // latter is set via the dispatcher). If we don't yet have a `page_type`, diff --git a/src/components/structures/auth/E2eSetup.tsx b/src/components/structures/auth/E2eSetup.tsx index 0fcacca66a..af3003dd27 100644 --- a/src/components/structures/auth/E2eSetup.tsx +++ b/src/components/structures/auth/E2eSetup.tsx @@ -13,15 +13,19 @@ import CompleteSecurityBody from "../../views/auth/CompleteSecurityBody"; import { InitialCryptoSetupDialog } from "../../views/dialogs/security/InitialCryptoSetupDialog"; interface IProps { - onFinished: () => void; + /** Callback which is called if the crypto setup failed, and the user clicked the 'cancel' button */ + onCancelled: () => void; } +/** + * An {@link AuthPage} which shows the {@link InitialCryptoSetupDialog}. + */ export default class E2eSetup extends React.Component { public render(): React.ReactNode { return ( - + ); diff --git a/src/components/views/dialogs/security/InitialCryptoSetupDialog.tsx b/src/components/views/dialogs/security/InitialCryptoSetupDialog.tsx index bda09f02a6..a4c9e3a4c8 100644 --- a/src/components/views/dialogs/security/InitialCryptoSetupDialog.tsx +++ b/src/components/views/dialogs/security/InitialCryptoSetupDialog.tsx @@ -16,23 +16,21 @@ import Spinner from "../../elements/Spinner"; import { InitialCryptoSetupStore, useInitialCryptoSetupStatus } from "../../../../stores/InitialCryptoSetupStore"; interface Props { - onFinished: (success?: boolean) => void; + /** Callback which is called if the crypto setup failed, and the user clicked the 'cancel' button */ + onCancelled: () => void; } -/* - * Walks the user through the process of creating a cross-signing keys. +/** + * Walks the user through the process of creating cross-signing keys. + * * In most cases, only a spinner is shown, but for more * complex auth like SSO, the user may need to complete some steps to proceed. */ -export const InitialCryptoSetupDialog: React.FC = ({ onFinished }) => { +export const InitialCryptoSetupDialog: React.FC = ({ onCancelled }) => { const onRetryClick = useCallback(() => { InitialCryptoSetupStore.sharedInstance().retry(); }, []); - const onCancelClick = useCallback(() => { - onFinished(false); - }, [onFinished]); - const status = useInitialCryptoSetupStatus(InitialCryptoSetupStore.sharedInstance()); let content; @@ -44,7 +42,7 @@ export const InitialCryptoSetupDialog: React.FC = ({ onFinished }) => { @@ -60,7 +58,6 @@ export const InitialCryptoSetupDialog: React.FC = ({ onFinished }) => { return ( jest.restoreAllMocks()); + +describe("LeftPanel", () => { + it("should call `onCancelled` when the user clicks the cancel button", () => { + const mockInitialCryptoSetupStore = { + getStatus: jest.fn(), + on: jest.fn(), + off: jest.fn(), + }; + jest.spyOn(InitialCryptoSetupStore, "sharedInstance").mockReturnValue(mockInitialCryptoSetupStore as any); + + // We need the setup process to have failed, for the dialog to present a cancel button. + mocked(mockInitialCryptoSetupStore.getStatus).mockReturnValue("error"); + + const onCancelled = jest.fn(); + const { getByRole } = render(); + + getByRole("button", { name: "Cancel" }).click(); + expect(onCancelled).toHaveBeenCalled(); + }); +}); diff --git a/test/unit-tests/components/views/dialogs/security/InitialCryptoSetupDialog-test.tsx b/test/unit-tests/components/views/dialogs/security/InitialCryptoSetupDialog-test.tsx index 40459f10e0..5a3bdd83c6 100644 --- a/test/unit-tests/components/views/dialogs/security/InitialCryptoSetupDialog-test.tsx +++ b/test/unit-tests/components/views/dialogs/security/InitialCryptoSetupDialog-test.tsx @@ -31,11 +31,9 @@ describe("InitialCryptoSetupDialog", () => { }); it("should show a spinner while the setup is in progress", async () => { - const onFinished = jest.fn(); - storeMock.getStatus.mockReturnValue("in_progress"); - render(); + render(); expect(screen.getByTestId("spinner")).toBeInTheDocument(); }); @@ -43,16 +41,15 @@ describe("InitialCryptoSetupDialog", () => { it("should display an error if setup has failed", async () => { storeMock.getStatus.mockReturnValue("error"); - render(); + render(); await expect(await screen.findByRole("button", { name: "Retry" })).toBeInTheDocument(); }); it("calls retry when retry button pressed", async () => { - const onFinished = jest.fn(); storeMock.getStatus.mockReturnValue("error"); - render(); + render(); await userEvent.click(await screen.findByRole("button", { name: "Retry" }));