From a664172a22a6cb885f7762584955b034ac7643d1 Mon Sep 17 00:00:00 2001
From: Andy Balaam <andy.balaam@matrix.org>
Date: Tue, 6 Feb 2024 14:46:15 +0000
Subject: [PATCH] Use the non-deprecated exportRoomKeys method on CryptoApi
 (#12231)

* Expand the export test to check encryptMegolmKeyFile was called

* Use the non-deprecated exportRoomKeys method on CryptoApi
---
 .../dialogs/security/ExportE2eKeysDialog.tsx  |  2 +-
 .../security/ExportE2eKeysDialog-test.tsx     | 31 ++++++++++++++++---
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx b/src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx
index 44ce270a98..5b50a0ed54 100644
--- a/src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx
+++ b/src/async-components/views/dialogs/security/ExportE2eKeysDialog.tsx
@@ -109,7 +109,7 @@ export default class ExportE2eKeysDialog extends React.Component<IProps, IState>
         // asynchronous ones.
         Promise.resolve()
             .then(() => {
-                return this.props.matrixClient.exportRoomKeys();
+                return this.props.matrixClient.getCrypto()!.exportRoomKeys();
             })
             .then((k) => {
                 return MegolmExportEncryption.encryptMegolmKeyFile(JSON.stringify(k), passphrase);
diff --git a/test/components/views/dialogs/security/ExportE2eKeysDialog-test.tsx b/test/components/views/dialogs/security/ExportE2eKeysDialog-test.tsx
index 5f0cfd2903..5f29bc1192 100644
--- a/test/components/views/dialogs/security/ExportE2eKeysDialog-test.tsx
+++ b/test/components/views/dialogs/security/ExportE2eKeysDialog-test.tsx
@@ -17,7 +17,9 @@ limitations under the License.
 import React from "react";
 import { screen, fireEvent, render, waitFor } from "@testing-library/react";
 import userEvent from "@testing-library/user-event";
+import { CryptoApi, IMegolmSessionData } from "matrix-js-sdk/src/matrix";
 
+import * as MegolmExportEncryption from "../../../../../src/utils/MegolmExportEncryption";
 import ExportE2eKeysDialog from "../../../../../src/async-components/views/dialogs/security/ExportE2eKeysDialog";
 import { createTestClient } from "../../../../test-utils";
 
@@ -60,13 +62,32 @@ describe("ExportE2eKeysDialog", () => {
     });
 
     it("should export if everything is fine", async () => {
+        // Given a client able to export keys
         const cli = createTestClient();
-        const onFinished = jest.fn();
+        const keys: IMegolmSessionData[] = [];
+        const passphrase = "ThisIsAMoreSecurePW123$$";
+        const exportRoomKeys = jest.fn().mockResolvedValue(keys);
+        cli.getCrypto = () => {
+            return {
+                exportRoomKeys,
+            } as unknown as CryptoApi;
+        };
 
-        const { container } = render(<ExportE2eKeysDialog matrixClient={cli} onFinished={onFinished} />);
-        await userEvent.type(screen.getByLabelText("Enter passphrase"), "ThisIsAMoreSecurePW123$$");
-        await userEvent.type(screen.getByLabelText("Confirm passphrase"), "ThisIsAMoreSecurePW123$$");
+        // Mock the result of encrypting the sessions. If we don't do this, the
+        // encryption process fails, possibly because we didn't initialise
+        // something.
+        jest.spyOn(MegolmExportEncryption, "encryptMegolmKeyFile").mockResolvedValue(new ArrayBuffer(3));
+
+        // When we tell the dialog to export
+        const { container } = render(<ExportE2eKeysDialog matrixClient={cli} onFinished={jest.fn()} />);
+        await userEvent.type(screen.getByLabelText("Enter passphrase"), passphrase);
+        await userEvent.type(screen.getByLabelText("Confirm passphrase"), passphrase);
         fireEvent.click(container.querySelector("[type=submit]")!);
-        await waitFor(() => expect(cli.exportRoomKeys).toHaveBeenCalled());
+
+        // Then it exports keys and encrypts them
+        await waitFor(() => expect(exportRoomKeys).toHaveBeenCalled());
+        await waitFor(() =>
+            expect(MegolmExportEncryption.encryptMegolmKeyFile).toHaveBeenCalledWith(JSON.stringify(keys), passphrase),
+        );
     });
 });