diff --git a/test/components/views/dialogs/CreateRoomDialog-test.tsx b/test/components/views/dialogs/CreateRoomDialog-test.tsx new file mode 100644 index 0000000000..a18cf50adc --- /dev/null +++ b/test/components/views/dialogs/CreateRoomDialog-test.tsx @@ -0,0 +1,215 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from "react"; +import { fireEvent, render, screen, within } from "@testing-library/react"; +import { Preset, Visibility } from "matrix-js-sdk/src/matrix"; + +import CreateRoomDialog from "../../../../src/components/views/dialogs/CreateRoomDialog"; +import { flushPromises, getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../test-utils"; + +describe("", () => { + const userId = "@alice:server.org"; + const mockClient = getMockClientWithEventEmitter({ + ...mockClientMethodsUser(userId), + getDomain: jest.fn().mockReturnValue("server.org"), + getClientWellKnown: jest.fn(), + doesServerForceEncryptionForPreset: jest.fn(), + // make every alias available + getRoomIdForAlias: jest.fn().mockRejectedValue({ errcode: "M_NOT_FOUND" }), + }); + + const getE2eeEnableToggleInputElement = () => screen.getByLabelText("Enable end-to-end encryption"); + // labelled toggle switch doesn't set the disabled attribute, only aria-disabled + const getE2eeEnableToggleIsDisabled = () => + getE2eeEnableToggleInputElement().getAttribute("aria-disabled") === "true"; + + beforeEach(() => { + mockClient.doesServerForceEncryptionForPreset.mockResolvedValue(false); + mockClient.getClientWellKnown.mockReturnValue({}); + }); + + const getComponent = (props = {}) => render(); + + it("should default to private room", async () => { + getComponent(); + await flushPromises(); + + expect(screen.getByText("Create a private room")).toBeInTheDocument(); + }); + + it("should use defaultName from props", async () => { + const defaultName = "My test room"; + getComponent({ defaultName }); + await flushPromises(); + + expect(screen.getByLabelText("Name")).toHaveDisplayValue(defaultName); + }); + + describe("for a private room", () => { + // default behaviour is a private room + + it("should use server .well-known default for encryption setting", async () => { + // default to off + mockClient.getClientWellKnown.mockReturnValue({ + "io.element.e2ee": { + default: false, + }, + }); + getComponent(); + await flushPromises(); + + expect(getE2eeEnableToggleInputElement()).not.toBeChecked(); + expect(getE2eeEnableToggleIsDisabled()).toBeFalsy(); + expect( + screen.getByText( + "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.", + ), + ); + }); + + it("should use defaultEncrypted prop", async () => { + // default to off in server wk + mockClient.getClientWellKnown.mockReturnValue({ + "io.element.e2ee": { + default: false, + }, + }); + // but pass defaultEncrypted prop + getComponent({ defaultEncrypted: true }); + await flushPromises(); + // encryption enabled + expect(getE2eeEnableToggleInputElement()).toBeChecked(); + expect(getE2eeEnableToggleIsDisabled()).toBeFalsy(); + }); + + it("should enable encryption toggle and disable field when server forces encryption", async () => { + mockClient.doesServerForceEncryptionForPreset.mockResolvedValue(true); + getComponent(); + + await flushPromises(); + expect(getE2eeEnableToggleInputElement()).toBeChecked(); + expect(getE2eeEnableToggleIsDisabled()).toBeTruthy(); + + expect(screen.getByText("Your server requires encryption to be enabled in private rooms.")); + }); + + it("should warn when trying to create a room with an invalid form", async () => { + const onFinished = jest.fn(); + getComponent({ onFinished }); + await flushPromises(); + + fireEvent.click(screen.getByText("Create room")); + await flushPromises(); + + // didn't submit room + expect(onFinished).not.toHaveBeenCalled(); + }); + + it("should create a private room", async () => { + const onFinished = jest.fn(); + getComponent({ onFinished }); + await flushPromises(); + + const roomName = "Test Room Name"; + fireEvent.change(screen.getByLabelText("Name"), { target: { value: roomName } }); + + fireEvent.click(screen.getByText("Create room")); + await flushPromises(); + + expect(onFinished).toHaveBeenCalledWith(true, { + createOpts: { + name: roomName, + }, + encryption: true, + parentSpace: undefined, + roomType: undefined, + }); + }); + }); + + describe("for a public room", () => { + it("should set join rule to public defaultPublic is truthy", async () => { + const onFinished = jest.fn(); + getComponent({ defaultPublic: true, onFinished }); + await flushPromises(); + + expect(screen.getByText("Create a public room")).toBeInTheDocument(); + + // e2e section is not rendered + expect(screen.queryByText("Enable end-to-end encryption")).not.toBeInTheDocument(); + + const roomName = "Test Room Name"; + fireEvent.change(screen.getByLabelText("Name"), { target: { value: roomName } }); + }); + + it("should not create a public room without an alias", async () => { + const onFinished = jest.fn(); + getComponent({ onFinished }); + await flushPromises(); + + // set to public + fireEvent.click(screen.getByLabelText("Room visibility")); + fireEvent.click(screen.getByText("Public room")); + expect(within(screen.getByLabelText("Room visibility")).findByText("Public room")).toBeTruthy(); + expect(screen.getByText("Create a public room")).toBeInTheDocument(); + + // set name + const roomName = "Test Room Name"; + fireEvent.change(screen.getByLabelText("Name"), { target: { value: roomName } }); + + // try to create the room + fireEvent.click(screen.getByText("Create room")); + await flushPromises(); + + // alias field invalid + expect(screen.getByLabelText("Room address").parentElement!).toHaveClass("mx_Field_invalid"); + + // didn't submit + expect(onFinished).not.toHaveBeenCalled(); + }); + + it("should create a public room", async () => { + const onFinished = jest.fn(); + getComponent({ onFinished, defaultPublic: true }); + await flushPromises(); + + // set name + const roomName = "Test Room Name"; + fireEvent.change(screen.getByLabelText("Name"), { target: { value: roomName } }); + + const roomAlias = "test"; + + fireEvent.change(screen.getByLabelText("Room address"), { target: { value: roomAlias } }); + + // try to create the room + fireEvent.click(screen.getByText("Create room")); + await flushPromises(); + + expect(onFinished).toHaveBeenCalledWith(true, { + createOpts: { + name: roomName, + preset: Preset.PublicChat, + room_alias_name: roomAlias, + visibility: Visibility.Public, + }, + guestAccess: false, + parentSpace: undefined, + roomType: undefined, + }); + }); + }); +});