Files
ThreadNet-Web/apps/web/src/components/structures/auth/CompleteSecurity.test.tsx
T
Michael TelatynskiandGitHub 27906ce6e7 Migrate more tests to vitest (#34355)
* Remove doubled-up I18n Provider. ModalManager already provides this.

* Reconfigure svgr into a vite-friendly `?react` resource query

* Move InviteDialog test to vitest

* Move RoomHeader tests to Vitest

* Share serializer between Jest & Vitest

* Attempt to stabilise InviteDialog test

* Fix async leaks

* Migrate more tests to vitest

* Migrate MatrixChat test to vitest

* Deflake

* Iterate

* Iterate

* Iterate
2026-07-30 09:11:29 +00:00

151 lines
6.0 KiB
TypeScript

/*
Copyright 2024 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.
*/
// @vitest-environment happy-dom
import { vi, describe, it, expect, beforeEach, afterEach } from "vitest";
import React from "react";
import { act, render, screen } from "test-utils-rtl";
import EventEmitter from "events";
import { stubClient } from "test-utils";
import CompleteSecurity from "./CompleteSecurity";
import { Phase, SetupEncryptionStore } from "../../../stores/SetupEncryptionStore";
import SdkConfig from "../../../SdkConfig";
class MockSetupEncryptionStore extends EventEmitter {
public phase: Phase = Phase.Intro;
public lostKeys(): boolean {
return false;
}
public start: () => void = vi.fn();
public stop: () => void = vi.fn();
}
describe("CompleteSecurity", () => {
beforeEach(() => {
const client = stubClient();
const deviceIdToDevice = new Map();
deviceIdToDevice.set("DEVICE_ID", {
deviceId: "DEVICE_ID",
userId: "USER_ID",
});
const userIdToDevices = new Map();
userIdToDevices.set("USER_ID", deviceIdToDevice);
vi.mocked(client.getCrypto()!.getUserDeviceInfo).mockResolvedValue(userIdToDevices);
const mockSetupEncryptionStore = new MockSetupEncryptionStore();
vi.spyOn(SetupEncryptionStore, "sharedInstance").mockReturnValue(
mockSetupEncryptionStore as SetupEncryptionStore,
);
});
afterEach(() => {
vi.restoreAllMocks();
});
it("Renders with a cancel button by default", () => {
render(<CompleteSecurity onFinished={() => {}} />);
expect(screen.getByRole("button", { name: "Skip verification for now" })).toBeInTheDocument();
});
it("Renders with a cancel button if forceVerification false", () => {
vi.spyOn(SdkConfig, "get").mockImplementation((key: string) => {
if (key === "forceVerification") {
return false;
}
});
render(<CompleteSecurity onFinished={() => {}} />);
expect(screen.getByRole("button", { name: "Skip verification for now" })).toBeInTheDocument();
});
it("Renders without a cancel button if forceVerification true", () => {
vi.spyOn(SdkConfig, "get").mockImplementation((key: string) => {
if (key === "force_verification") {
return true;
}
});
render(<CompleteSecurity onFinished={() => {}} />);
expect(screen.queryByRole("button", { name: "Skip verification for now" })).not.toBeInTheDocument();
});
it("Renders a warning if user hits Reset", async () => {
// Given a store and a dialog based on it
const store = new SetupEncryptionStore();
vi.spyOn(SetupEncryptionStore, "sharedInstance").mockReturnValue(store);
const panel = await act(() => render(<CompleteSecurity onFinished={() => {}} />));
// No recovery methods are available, so only the "Can't confirm?" button should be visible
expect(screen.queryByRole("button", { name: "Can't confirm?" })).toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Use another device" })).not.toBeInTheDocument();
expect(screen.queryByRole("button", { name: "Use recovery key" })).not.toBeInTheDocument();
// When we hit reset
await act(async () => panel.getByRole("button", { name: "Can't confirm?" }).click());
// Then the reset identity dialog appears
expect(screen.getByRole("heading", { name: "You need to reset your digital identity" })).toBeInTheDocument();
expect(panel.getByRole("button", { name: "Continue" })).toBeInTheDocument();
});
it("Allows verifying with another device if one is available", async () => {
// Given a store and a dialog based on it
const store = new SetupEncryptionStore();
vi.spyOn(store, "fetchKeyInfo").mockImplementation(async () => {
store.hasDevicesToVerifyAgainst = true;
store.phase = Phase.Intro;
store.emit("update");
});
vi.spyOn(SetupEncryptionStore, "sharedInstance").mockReturnValue(store);
const panel = await act(() => render(<CompleteSecurity onFinished={() => {}} />));
// The snapshot should have "Use another device" and "Can't confirm?"
// buttons, but no "Use recovery key".
expect(panel.asFragment()).toMatchSnapshot();
// When we hit reset
await act(async () => panel.getByRole("button", { name: "Can't confirm?" }).click());
// Then the reset identity dialog appears, and should have a different
// title from when there were no verification methods available.
expect(
screen.getByRole("heading", { name: "Are you sure you want to reset your digital identity?" }),
).toBeInTheDocument();
});
it("Allows verifying with recovery key if one is available", async () => {
// Given a store and a dialog based on it
const store = new SetupEncryptionStore();
vi.spyOn(store, "fetchKeyInfo").mockImplementation(async () => {
store.keyInfo = {} as any;
store.phase = Phase.Intro;
store.emit("update");
});
vi.spyOn(SetupEncryptionStore, "sharedInstance").mockReturnValue(store);
const panel = await act(() => render(<CompleteSecurity onFinished={() => {}} />));
// The snapshot should have "Use recovery key" and "Can't confirm?"
// buttons, but no "Use another device".
expect(panel.asFragment()).toMatchSnapshot();
// When we hit reset
await act(async () => panel.getByRole("button", { name: "Can't confirm?" }).click());
// Then the reset identity dialog appears, and should have a different
// title from when there were no verification methods available.
expect(
screen.getByRole("heading", { name: "Are you sure you want to reset your digital identity?" }),
).toBeInTheDocument();
});
});