diff --git a/src/components/views/rooms/NewRoomIntro.tsx b/src/components/views/rooms/NewRoomIntro.tsx index 05912c482e..7b5e72d45c 100644 --- a/src/components/views/rooms/NewRoomIntro.tsx +++ b/src/components/views/rooms/NewRoomIntro.tsx @@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details. import React, { useContext } from "react"; import { EventType, Room, User, MatrixClient } from "matrix-js-sdk/src/matrix"; import { KnownMembership } from "matrix-js-sdk/src/types"; +import { InlineSpinner } from "@vector-im/compound-web"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import RoomContext from "../../../contexts/RoomContext"; @@ -30,9 +31,9 @@ import { UIComponent } from "../../../settings/UIFeature"; import { privateShouldBeEncrypted } from "../../../utils/rooms"; import { LocalRoom } from "../../../models/LocalRoom"; import { shouldEncryptRoomWithSingle3rdPartyInvite } from "../../../utils/room/shouldEncryptRoomWithSingle3rdPartyInvite"; +import { useIsEncrypted } from "../../../hooks/useIsEncrypted.ts"; -function hasExpectedEncryptionSettings(matrixClient: MatrixClient, room: Room): boolean { - const isEncrypted: boolean = matrixClient.isRoomEncrypted(room.roomId); +function hasExpectedEncryptionSettings(matrixClient: MatrixClient, room: Room, isEncrypted: boolean): boolean { const isPublic: boolean = room.getJoinRule() === "public"; return isPublic || !privateShouldBeEncrypted(matrixClient) || isEncrypted; } @@ -52,11 +53,15 @@ const determineIntroMessage = (room: Room, encryptedSingle3rdPartyInvite: boolea const NewRoomIntro: React.FC = () => { const cli = useContext(MatrixClientContext); const { room, roomId } = useContext(RoomContext); + const isEncrypted = useIsEncrypted(cli, room); + const isEncryptionLoading = isEncrypted === null; if (!room || !roomId) { throw new Error("Unable to create a NewRoomIntro without room and roomId"); } + if (isEncryptionLoading) return ; + const isLocalRoom = room instanceof LocalRoom; const dmPartner = isLocalRoom ? room.targets[0]?.userId : DMRoomMap.shared().getUserIdForRoomId(roomId); @@ -282,7 +287,7 @@ const NewRoomIntro: React.FC = () => { return (
  • - {!hasExpectedEncryptionSettings(cli, room) && ( + {!hasExpectedEncryptionSettings(cli, room, isEncrypted) && ( { }); describe("in state NEW", () => { + beforeEach(() => { + jest.spyOn(cli, "getCrypto").mockReturnValue(crypto); + jest.spyOn(cli.getCrypto()!, "getUserVerificationStatus").mockResolvedValue( + new UserVerificationStatus(false, true, false), + ); + }); + it("should match the snapshot", async () => { const { container } = await renderRoomView(); expect(container).toMatchSnapshot(); @@ -362,11 +369,7 @@ describe("RoomView", () => { beforeEach(() => { // Not all the calls to cli.isRoomEncrypted are migrated, so we need to mock both. mocked(cli.isRoomEncrypted).mockReturnValue(true); - jest.spyOn(cli, "getCrypto").mockReturnValue(crypto); jest.spyOn(cli.getCrypto()!, "isEncryptionEnabledInRoom").mockResolvedValue(true); - jest.spyOn(cli.getCrypto()!, "getUserVerificationStatus").mockResolvedValue( - new UserVerificationStatus(false, true, false), - ); localRoom.encrypted = true; localRoom.currentState.setStateEvents([ new MatrixEvent({ @@ -399,6 +402,11 @@ describe("RoomView", () => { describe("in state ERROR", () => { beforeEach(async () => { localRoom.state = LocalRoomState.ERROR; + + jest.spyOn(cli, "getCrypto").mockReturnValue(crypto); + jest.spyOn(cli.getCrypto()!, "getUserVerificationStatus").mockResolvedValue( + new UserVerificationStatus(false, true, false), + ); }); it("should match the snapshot", async () => { diff --git a/test/unit-tests/components/views/rooms/NewRoomIntro-test.tsx b/test/unit-tests/components/views/rooms/NewRoomIntro-test.tsx index 291d28c967..081cb8b215 100644 --- a/test/unit-tests/components/views/rooms/NewRoomIntro-test.tsx +++ b/test/unit-tests/components/views/rooms/NewRoomIntro-test.tsx @@ -10,6 +10,7 @@ Please see LICENSE files in the repository root for full details. import React from "react"; import { render, screen } from "jest-matrix-react"; import { MatrixClient, Room } from "matrix-js-sdk/src/matrix"; +import { waitFor } from "@testing-library/dom"; import { LocalRoom } from "../../../../../src/models/LocalRoom"; import { filterConsole, mkRoomMemberJoinEvent, mkThirdPartyInviteEvent, stubClient } from "../../../../test-utils"; @@ -50,13 +51,15 @@ describe("NewRoomIntro", () => { renderNewRoomIntro(client, room); }); - it("should render the expected intro", () => { + it("should render the expected intro", async () => { const expected = `This is the beginning of your direct message history with test_room.`; - screen.getByText((id, element) => element?.tagName === "SPAN" && element?.textContent === expected); + await waitFor(() => + screen.getByText((id, element) => element?.tagName === "SPAN" && element?.textContent === expected), + ); }); }); - it("should render as expected for a DM room with a single third-party invite", () => { + it("should render as expected for a DM room with a single third-party invite", async () => { const room = new Room(roomId, client, client.getSafeUserId()); room.currentState.setStateEvents([ mkRoomMemberJoinEvent(client.getSafeUserId(), room.roomId), @@ -66,7 +69,9 @@ describe("NewRoomIntro", () => { jest.spyOn(DMRoomMap.shared(), "getRoomIds").mockReturnValue(new Set([room.roomId])); renderNewRoomIntro(client, room); - expect(screen.getByText("Once everyone has joined, you’ll be able to chat")).toBeInTheDocument(); + await waitFor(() => + expect(screen.getByText("Once everyone has joined, you’ll be able to chat")).toBeInTheDocument(), + ); expect( screen.queryByText( "Only the two of you are in this conversation, unless either of you invites anyone to join.", @@ -83,9 +88,11 @@ describe("NewRoomIntro", () => { renderNewRoomIntro(client, localRoom); }); - it("should render the expected intro", () => { + it("should render the expected intro", async () => { const expected = `Send your first message to invite test_room to chat`; - screen.getByText((id, element) => element?.tagName === "SPAN" && element?.textContent === expected); + await waitFor(() => + screen.getByText((id, element) => element?.tagName === "SPAN" && element?.textContent === expected), + ); }); }); });