mirror of
https://github.com/vector-im/element-web.git
synced 2025-11-08 20:21:42 +01:00
* update key storage toggle when key storage status changes Listen for the CryptoEvent.KeyBackupStatus event and update the state when it changes. * fixup! update key storage toggle when key storage status changes * add comment about handling event
150 lines
5.5 KiB
TypeScript
150 lines
5.5 KiB
TypeScript
/*
|
|
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 { renderHook, waitFor } from "jest-matrix-react";
|
|
import { act } from "react";
|
|
import { mocked } from "jest-mock";
|
|
import { CryptoEvent } from "matrix-js-sdk/src/crypto-api";
|
|
|
|
import type { MatrixClient } from "matrix-js-sdk/src/matrix";
|
|
import type { BackupTrustInfo, KeyBackupCheck, KeyBackupInfo } from "matrix-js-sdk/src/crypto-api";
|
|
import { useKeyStoragePanelViewModel } from "../../../../../../src/components/viewmodels/settings/encryption/KeyStoragePanelViewModel";
|
|
import { createTestClient, withClientContextRenderOptions } from "../../../../../test-utils";
|
|
|
|
describe("KeyStoragePanelViewModel", () => {
|
|
let matrixClient: MatrixClient;
|
|
|
|
beforeEach(() => {
|
|
matrixClient = createTestClient();
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
it("should update the pending value immediately", async () => {
|
|
const { result } = renderHook(
|
|
() => useKeyStoragePanelViewModel(),
|
|
withClientContextRenderOptions(matrixClient),
|
|
);
|
|
act(() => {
|
|
result.current.setEnabled(true);
|
|
});
|
|
expect(result.current.isEnabled).toBe(true);
|
|
expect(result.current.busy).toBe(true);
|
|
});
|
|
|
|
it("should update if a KeyBackupStatus event is received", async () => {
|
|
const { result } = renderHook(
|
|
() => useKeyStoragePanelViewModel(),
|
|
withClientContextRenderOptions(matrixClient),
|
|
);
|
|
await waitFor(() => expect(result.current.isEnabled).toBe(false));
|
|
|
|
const mock = mocked(matrixClient.getCrypto()!.getActiveSessionBackupVersion);
|
|
mock.mockResolvedValue("1");
|
|
matrixClient.emit(CryptoEvent.KeyBackupStatus, true);
|
|
await waitFor(() => expect(result.current.isEnabled).toBe(true));
|
|
|
|
mock.mockResolvedValue(null);
|
|
matrixClient.emit(CryptoEvent.KeyBackupStatus, false);
|
|
await waitFor(() => expect(result.current.isEnabled).toBe(false));
|
|
});
|
|
|
|
it("should call resetKeyBackup if there is no backup currently", async () => {
|
|
mocked(matrixClient.getCrypto()!.checkKeyBackupAndEnable).mockResolvedValue(null);
|
|
|
|
const { result } = renderHook(
|
|
() => useKeyStoragePanelViewModel(),
|
|
withClientContextRenderOptions(matrixClient),
|
|
);
|
|
|
|
await result.current.setEnabled(true);
|
|
expect(mocked(matrixClient.getCrypto()!.resetKeyBackup)).toHaveBeenCalled();
|
|
});
|
|
|
|
it.each<BackupTrustInfo>([
|
|
{ trusted: true, matchesDecryptionKey: false },
|
|
{ trusted: false, matchesDecryptionKey: true },
|
|
{ trusted: true, matchesDecryptionKey: true },
|
|
])("should not call resetKeyBackup if there is a backup currently and it is trusted", async (trustInfo) => {
|
|
mocked(matrixClient.getCrypto()!.checkKeyBackupAndEnable).mockResolvedValue({
|
|
backupInfo: {
|
|
version: "1",
|
|
algorithm: "foobar",
|
|
auth_data: {
|
|
public_key: "foobar",
|
|
},
|
|
},
|
|
trustInfo,
|
|
});
|
|
|
|
const { result } = renderHook(
|
|
() => useKeyStoragePanelViewModel(),
|
|
withClientContextRenderOptions(matrixClient),
|
|
);
|
|
|
|
await result.current.setEnabled(true);
|
|
expect(mocked(matrixClient.getCrypto()!.resetKeyBackup)).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("should call resetKeyBackup if there is a backup currently but it is not trusted", async () => {
|
|
mocked(matrixClient.getCrypto()!.checkKeyBackupAndEnable).mockResolvedValue({
|
|
backupInfo: {
|
|
version: "1",
|
|
algorithm: "foobar",
|
|
auth_data: {
|
|
public_key: "foobar",
|
|
},
|
|
},
|
|
trustInfo: {
|
|
trusted: false,
|
|
matchesDecryptionKey: false,
|
|
},
|
|
});
|
|
|
|
const { result } = renderHook(
|
|
() => useKeyStoragePanelViewModel(),
|
|
withClientContextRenderOptions(matrixClient),
|
|
);
|
|
|
|
await result.current.setEnabled(true);
|
|
expect(mocked(matrixClient.getCrypto()!.resetKeyBackup)).toHaveBeenCalled();
|
|
});
|
|
|
|
it("should set account data flag when enabling", async () => {
|
|
mocked(matrixClient.getCrypto()!.checkKeyBackupAndEnable).mockResolvedValue(null);
|
|
|
|
const { result } = renderHook(
|
|
() => useKeyStoragePanelViewModel(),
|
|
withClientContextRenderOptions(matrixClient),
|
|
);
|
|
|
|
await result.current.setEnabled(true);
|
|
expect(mocked(matrixClient.setAccountData)).toHaveBeenCalledWith("m.org.matrix.custom.backup_disabled", {
|
|
disabled: false,
|
|
});
|
|
});
|
|
|
|
it("should delete key storage when disabling", async () => {
|
|
mocked(matrixClient.getCrypto()!.checkKeyBackupAndEnable).mockResolvedValue({} as KeyBackupCheck);
|
|
mocked(matrixClient.getCrypto()!.getKeyBackupInfo).mockResolvedValue({ version: "99" } as KeyBackupInfo);
|
|
|
|
const { result } = renderHook(
|
|
() => useKeyStoragePanelViewModel(),
|
|
withClientContextRenderOptions(matrixClient),
|
|
);
|
|
|
|
await result.current.setEnabled(false);
|
|
|
|
expect(mocked(matrixClient.getCrypto()!.disableKeyStorage)).toHaveBeenCalled();
|
|
expect(mocked(matrixClient.setAccountData)).toHaveBeenCalledWith("m.org.matrix.custom.backup_disabled", {
|
|
disabled: true,
|
|
});
|
|
});
|
|
});
|