From 7193998905f2e83b2938654dbda0c1c74ccd2a69 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Wed, 18 Dec 2024 10:43:59 +0100 Subject: [PATCH] Add tests to `ChangeRecoveryKey` --- .../encryption/ChangeRecoveryKey-test.tsx | 117 +++ .../ChangeRecoveryKey-test.tsx.snap | 725 ++++++++++++++++++ 2 files changed, 842 insertions(+) create mode 100644 test/unit-tests/components/views/settings/encryption/ChangeRecoveryKey-test.tsx create mode 100644 test/unit-tests/components/views/settings/encryption/__snapshots__/ChangeRecoveryKey-test.tsx.snap diff --git a/test/unit-tests/components/views/settings/encryption/ChangeRecoveryKey-test.tsx b/test/unit-tests/components/views/settings/encryption/ChangeRecoveryKey-test.tsx new file mode 100644 index 0000000000..5d67b4e6b3 --- /dev/null +++ b/test/unit-tests/components/views/settings/encryption/ChangeRecoveryKey-test.tsx @@ -0,0 +1,117 @@ +/* + * Copyright 2024 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only + * Please see LICENSE files in the repository root for full details. + */ + +import React from "react"; +import { render, screen, waitFor } from "jest-matrix-react"; +import { MatrixClient } from "matrix-js-sdk/src/matrix"; +import userEvent from "@testing-library/user-event"; + +import { ChangeRecoveryKey } from "../../../../../../src/components/views/settings/encryption/ChangeRecoveryKey"; +import { createTestClient, withClientContextRenderOptions } from "../../../../../test-utils"; +import { copyPlaintext } from "../../../../../../src/utils/strings"; + +jest.mock("../../../../../../src/utils/strings", () => ({ + copyPlaintext: jest.fn(), +})); + +describe("", () => { + let matrixClient: MatrixClient; + + beforeEach(() => { + matrixClient = createTestClient(); + }); + + function renderComponent(isSetupFlow = false, onFinish = jest.fn(), onCancelClick = jest.fn()) { + return render( + , + withClientContextRenderOptions(matrixClient), + ); + } + + describe("flow to setup a recovery key", () => { + it("should display information about the recovery key", async () => { + const user = userEvent.setup(); + + const onCancelClick = jest.fn(); + const { asFragment } = renderComponent(true, jest.fn(), onCancelClick); + await waitFor(() => + expect( + screen.getByText( + "Your key storage is protected by a recovery key. If you need a new recovery key after setup, you can recreate it by selecting ‘Change recovery key’.", + ), + ).toBeInTheDocument(), + ); + expect(asFragment()).toMatchSnapshot(); + + await user.click(screen.getByRole("button", { name: "Cancel" })); + expect(onCancelClick).toHaveBeenCalled(); + }); + + it("should display the recovery key", async () => { + const user = userEvent.setup(); + + const onCancelClick = jest.fn(); + const { asFragment } = renderComponent(true, jest.fn(), onCancelClick); + await waitFor(() => user.click(screen.getByRole("button", { name: "Continue" }))); + + expect(screen.getByText("Save your recovery key somewhere safe")).toBeInTheDocument(); + expect(screen.getByText("encoded private key")).toBeInTheDocument(); + expect(asFragment()).toMatchSnapshot(); + + // Test copy button + await user.click(screen.getByRole("button", { name: "Copy" })); + expect(copyPlaintext).toHaveBeenCalled(); + + await user.click(screen.getByRole("button", { name: "Cancel" })); + expect(onCancelClick).toHaveBeenCalled(); + }); + + it("should ask the user to enter the recovery key", async () => { + const user = userEvent.setup(); + + const onFinish = jest.fn(); + const { asFragment } = renderComponent(true, onFinish); + // Display the recovery key to save + await waitFor(() => user.click(screen.getByRole("button", { name: "Continue" }))); + // Display the form to confirm the recovery key + await waitFor(() => user.click(screen.getByRole("button", { name: "Continue" }))); + + await waitFor(() => expect(screen.getByText("Enter your recovery key to confirm")).toBeInTheDocument()); + expect(asFragment()).toMatchSnapshot(); + + // The finish button should be disabled by default + const finishButton = screen.getByRole("button", { name: "Finish set up" }); + expect(finishButton).toHaveAttribute("aria-disabled", "true"); + + const input = screen.getByRole("textbox"); + // If the user enters an incorrect recovery key, the finish button should be disabled + // and we display an error message + await userEvent.type(input, "wrong recovery key"); + expect(finishButton).toHaveAttribute("aria-disabled", "true"); + expect(screen.getByText("The recovery key you entered is not correct.")).toBeInTheDocument(); + expect(asFragment()).toMatchSnapshot(); + + await userEvent.clear(input); + // If the user enters the correct recovery key, the finish button should be enabled + await userEvent.type(input, "encoded private key"); + await waitFor(() => expect(finishButton).not.toHaveAttribute("aria-disabled", "true")); + + await user.click(finishButton); + expect(onFinish).toHaveBeenCalledWith(); + }); + }); + + describe("flow to change the recovery key", () => { + it("should display the recovery key", async () => { + const { asFragment } = renderComponent(); + + await waitFor(() => expect(screen.getByText("Change recovery key?")).toBeInTheDocument()); + expect(screen.getByText("encoded private key")).toBeInTheDocument(); + expect(asFragment()).toMatchSnapshot(); + }); + }); +}); diff --git a/test/unit-tests/components/views/settings/encryption/__snapshots__/ChangeRecoveryKey-test.tsx.snap b/test/unit-tests/components/views/settings/encryption/__snapshots__/ChangeRecoveryKey-test.tsx.snap new file mode 100644 index 0000000000..ee18396e44 --- /dev/null +++ b/test/unit-tests/components/views/settings/encryption/__snapshots__/ChangeRecoveryKey-test.tsx.snap @@ -0,0 +1,725 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` flow to change the recovery key should display the recovery key 1`] = ` + + +
+
+
+ + + +
+

+ Change recovery key? +

+ + Get a new recovery key if you've lost your existing one. After changing your recovery key, your old one will no longer work. + +
+
+ + Recovery key + +
+ + encoded private key + + + Do not share this with anyone! + +
+ +
+ +
+
+`; + +exports[` flow to setup a recovery key should ask the user to enter the recovery key 1`] = ` + + +
+
+
+ + + +
+

+ Enter your recovery key to confirm +

+ + Enter the recovery key shown on the previous screen to finish setting up recovery. + +
+
+
+ + +
+ +
+
+
+`; + +exports[` flow to setup a recovery key should ask the user to enter the recovery key 2`] = ` + + +
+
+
+ + + +
+

+ Enter your recovery key to confirm +

+ + Enter the recovery key shown on the previous screen to finish setting up recovery. + +
+
+
+ + + + + + + The recovery key you entered is not correct. + +
+ +
+
+
+`; + +exports[` flow to setup a recovery key should display information about the recovery key 1`] = ` + + +
+
+
+ + + +
+

+ Set up recovery +

+ + Your key storage is protected by a recovery key. If you need a new recovery key after setup, you can recreate it by selecting ‘Change recovery key’. + +
+ + After clicking continue, we’ll generate a recovery key for you. + + +
+
+`; + +exports[` flow to setup a recovery key should display the recovery key 1`] = ` + + +
+
+
+ + + +
+

+ Save your recovery key somewhere safe +

+ + Write down this recovery key somewhere safe, like a password manager, encrypted note, or a physical safe. + +
+
+ + Recovery key + +
+ + encoded private key + + + Do not share this with anyone! + +
+ +
+ +
+
+`;