/* * Copyright 2025 New Vector Ltd. * * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial * Please see LICENSE files in the repository root for full details. */ import React from "react"; import { render, screen } from "jest-matrix-react"; import userEvent from "@testing-library/user-event"; import { mocked } from "jest-mock"; import { type MatrixClient } from "matrix-js-sdk/src/matrix"; import { RecoveryPanelOutOfSync } from "../../../../../../src/components/views/settings/encryption/RecoveryPanelOutOfSync"; import { AccessCancelledError, accessSecretStorage } from "../../../../../../src/SecurityManager"; import DeviceListener from "../../../../../../src/DeviceListener"; import { createTestClient, withClientContextRenderOptions } from "../../../../../test-utils"; jest.mock("../../../../../../src/SecurityManager", () => { const originalModule = jest.requireActual("../../../../../../src/SecurityManager"); return { ...originalModule, accessSecretStorage: jest.fn(), }; }); describe("", () => { let matrixClient: MatrixClient; function renderComponent( onFinish = jest.fn(), onForgotRecoveryKey = jest.fn(), onAccessSecretStorageFailed = jest.fn(), ) { matrixClient = createTestClient(); return render( , withClientContextRenderOptions(matrixClient), ); } afterEach(() => { jest.clearAllMocks(); }); it("should render", () => { const { asFragment } = renderComponent(); expect(asFragment()).toMatchSnapshot(); }); it("should call onForgotRecoveryKey when the 'Forgot recovery key?' is clicked", async () => { const user = userEvent.setup(); const onForgotRecoveryKey = jest.fn(); renderComponent(jest.fn(), onForgotRecoveryKey); await user.click(screen.getByRole("button", { name: "Forgot recovery key?" })); expect(onForgotRecoveryKey).toHaveBeenCalled(); }); it("should access to 4S and call onFinish when 'Enter recovery key' is clicked", async () => { jest.spyOn(DeviceListener.sharedInstance(), "keyStorageOutOfSyncNeedsBackupReset").mockResolvedValue(false); const user = userEvent.setup(); mocked(accessSecretStorage).mockImplementation(async (func = async (): Promise => {}) => { return await func(); }); const onFinish = jest.fn(); renderComponent(onFinish); await user.click(screen.getByRole("button", { name: "Enter recovery key" })); expect(accessSecretStorage).toHaveBeenCalled(); expect(onFinish).toHaveBeenCalled(); expect(matrixClient.getCrypto()!.resetKeyBackup).not.toHaveBeenCalled(); }); it("should reset key backup if needed", async () => { jest.spyOn(DeviceListener.sharedInstance(), "keyStorageOutOfSyncNeedsBackupReset").mockResolvedValue(true); const user = userEvent.setup(); mocked(accessSecretStorage).mockImplementation(async (func = async (): Promise => {}) => { return await func(); }); const onFinish = jest.fn(); renderComponent(onFinish); await user.click(screen.getByRole("button", { name: "Enter recovery key" })); expect(accessSecretStorage).toHaveBeenCalled(); expect(onFinish).toHaveBeenCalled(); expect(matrixClient.getCrypto()!.resetKeyBackup).toHaveBeenCalled(); }); it("should call onAccessSecretStorageFailed on failure", async () => { jest.spyOn(DeviceListener.sharedInstance(), "keyStorageOutOfSyncNeedsBackupReset").mockResolvedValue(true); const user = userEvent.setup(); mocked(accessSecretStorage).mockImplementation(async (func = async (): Promise => {}) => { throw new Error("Error"); }); const onAccessSecretStorageFailed = jest.fn(); renderComponent(jest.fn(), jest.fn(), onAccessSecretStorageFailed); await user.click(screen.getByRole("button", { name: "Enter recovery key" })); expect(accessSecretStorage).toHaveBeenCalled(); expect(onAccessSecretStorageFailed).toHaveBeenCalled(); }); it("should not call onAccessSecretStorageFailed when cancelled", async () => { jest.spyOn(DeviceListener.sharedInstance(), "keyStorageOutOfSyncNeedsBackupReset").mockResolvedValue(true); const user = userEvent.setup(); mocked(accessSecretStorage).mockImplementation(async (func = async (): Promise => {}) => { throw new AccessCancelledError(); }); const onFinish = jest.fn(); const onAccessSecretStorageFailed = jest.fn(); renderComponent(onFinish, jest.fn(), onAccessSecretStorageFailed); await user.click(screen.getByRole("button", { name: "Enter recovery key" })); expect(accessSecretStorage).toHaveBeenCalled(); expect(onFinish).not.toHaveBeenCalled(); expect(onAccessSecretStorageFailed).not.toHaveBeenCalled(); }); });