Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 153 additions & 2 deletions test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

import React from "react";
import { fireEvent, render, screen, within } from "jest-matrix-react";
import { JoinRule, MatrixError, Preset, Visibility } from "matrix-js-sdk/src/matrix";
import { type Room, JoinRule, MatrixError, Preset, Visibility } from "matrix-js-sdk/src/matrix";

import CreateRoomDialog from "../../../../../src/components/views/dialogs/CreateRoomDialog";
import { flushPromises, getMockClientWithEventEmitter, mockClientMethodsUser } from "../../../../test-utils";
import { flushPromises, getMockClientWithEventEmitter, mkSpace, mockClientMethodsUser } from "../../../../test-utils";
import SettingsStore from "../../../../../src/settings/SettingsStore";
import { UIFeature } from "../../../../../src/settings/UIFeature";

Expand Down Expand Up @@ -58,6 +58,57 @@
expect(screen.getByLabelText("Name")).toHaveDisplayValue(defaultName);
});

it("should include topic in room creation options", async () => {
const onFinished = jest.fn();
render(<CreateRoomDialog onFinished={onFinished} />);
await flushPromises();

const topic = "This is a test topic";

// Set room name and topic.
fireEvent.change(screen.getByLabelText("Name"), { target: { value: "Room with topic" } });
fireEvent.change(screen.getByLabelText("Topic (optional)"), { target: { value: topic } });

// Create the room.
fireEvent.click(screen.getByText("Create room"));
await flushPromises();

expect(onFinished).toHaveBeenCalledWith(

Check failure on line 76 in test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx

View workflow job for this annotation

GitHub Actions / Jest (1)

<CreateRoomDialog /> › should include topic in room creation options

expect(jest.fn()).toHaveBeenCalledWith(...expected) Expected: true, ObjectContaining {"createOpts": ObjectContaining {"name": "Room with topic", "topic": "This is a test topic"}} Received: true, {"createOpts": {}, "encryption": true, "name": "Room with topic", "parentSpace": undefined, "roomType": undefined, "topic": "This is a test topic"} Number of calls: 1 at Object.toHaveBeenCalledWith (test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx:76:28)
true,
expect.objectContaining({
createOpts: expect.objectContaining({
name: "Room with topic",
topic,
}),
}),
);
});

it("should include no federate option in room creation options when enabled", async () => {
const onFinished = jest.fn();
render(<CreateRoomDialog onFinished={onFinished} />);
await flushPromises();

// Set room name, and disable federation.
fireEvent.change(screen.getByLabelText("Name"), { target: { value: "NoFederate Room" } });
fireEvent.click(screen.getByLabelText("Block anyone not part of server.org from ever joining this room."));

fireEvent.click(screen.getByText("Create room"));
await flushPromises();

expect(onFinished).toHaveBeenCalledWith(

Check failure on line 99 in test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx

View workflow job for this annotation

GitHub Actions / Jest (1)

<CreateRoomDialog /> › should include no federate option in room creation options when enabled

expect(jest.fn()).toHaveBeenCalledWith(...expected) Expected: true, ObjectContaining {"createOpts": ObjectContaining {"creation_content": ObjectContaining {"m.federate": false}, "name": "NoFederate Room"}} Received: true, {"createOpts": {"creation_content": {"m.federate": false}}, "encryption": true, "name": "NoFederate Room", "parentSpace": undefined, "roomType": undefined} Number of calls: 1 at Object.toHaveBeenCalledWith (test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx:99:28)
true,
expect.objectContaining({
createOpts: expect.objectContaining({
name: "NoFederate Room",
creation_content: expect.objectContaining({
"m.federate": false,
}),
}),
}),
);
});

describe("for a private room", () => {
// default behaviour is a private room

Expand Down Expand Up @@ -189,7 +240,7 @@
const onFinished = jest.fn();
const { asFragment } = getComponent({ onFinished });
await flushPromises();
expect(asFragment()).toMatchSnapshot();

Check failure on line 243 in test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx

View workflow job for this annotation

GitHub Actions / Jest (1)

<CreateRoomDialog /> › for a private room › should create a private room

expect(received).toMatchSnapshot() Snapshot name: `<CreateRoomDialog /> for a private room should create a private room 1` - Snapshot - 8 + Received + 8 @@ -27,34 +27,34 @@ > <div class="mx_Field mx_Field_input mx_CreateRoomDialog_name" > <input - id="mx_Field_21" + id="mx_Field_25" label="Name" placeholder="Name" type="text" value="" /> <label - for="mx_Field_21" + for="mx_Field_25" > Name </label> </div> <div class="mx_Field mx_Field_input mx_CreateRoomDialog_topic" > <input - id="mx_Field_22" + id="mx_Field_26" label="Topic (optional)" placeholder="Topic (optional)" type="text" value="" /> <label - for="mx_Field_22" + for="mx_Field_26" > Topic (optional) </label> </div> <div @@ -93,19 +93,19 @@ > <span class="mx_SettingsFlag_label" > <div - id="mx_LabelledToggleSwitch_«r4m»" + id="mx_LabelledToggleSwitch_«r5i»" > Enable end-to-end encryption </div> </span> <div aria-checked="true" aria-disabled="false" - aria-labelledby="mx_LabelledToggleSwitch_«r4m»" + aria-labelledby="mx_LabelledToggleSwitch_«r5i»" class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled" role="switch" tabindex="0" > <div @@ -129,19 +129,19 @@ > <span class="mx_SettingsFlag_label" > <div - id="mx_LabelledToggleSwitch_«r4n»" + id="mx_LabelledToggleSwitch_«r5j»" > Block anyone not part of server.org from ever joining this room. </div> </span> <div aria-checked="false" aria-disabled="false" - aria-labelledby="mx_LabelledToggleSwitch_«r4n»" + aria-labelledby="mx_LabelledToggleSwitch_«r5j»" class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_enabled" role="switch" tabindex="0" > <div at Object.toMatchSnapshot (test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx:243:34)

const roomName = "Test Room Name";
fireEvent.change(screen.getByLabelText("Name"), { target: { value: roomName } });
Expand All @@ -212,7 +263,7 @@
);
const { asFragment } = getComponent();
await flushPromises();
expect(asFragment()).toMatchSnapshot();

Check failure on line 266 in test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx

View workflow job for this annotation

GitHub Actions / Jest (1)

<CreateRoomDialog /> › for a private room › should render not the advanced options when UI.advancedSettings is disabled

expect(received).toMatchSnapshot() Snapshot name: `<CreateRoomDialog /> for a private room should render not the advanced options when UI.advancedSettings is disabled 1` - Snapshot - 6 + Received + 6 @@ -27,34 +27,34 @@ > <div class="mx_Field mx_Field_input mx_CreateRoomDialog_name" > <input - id="mx_Field_23" + id="mx_Field_27" label="Name" placeholder="Name" type="text" value="" /> <label - for="mx_Field_23" + for="mx_Field_27" > Name </label> </div> <div class="mx_Field mx_Field_input mx_CreateRoomDialog_topic" > <input - id="mx_Field_24" + id="mx_Field_28" label="Topic (optional)" placeholder="Topic (optional)" type="text" value="" /> <label - for="mx_Field_24" + for="mx_Field_28" > Topic (optional) </label> </div> <div @@ -93,19 +93,19 @@ > <span class="mx_SettingsFlag_label" > <div - id="mx_LabelledToggleSwitch_«r54»" + id="mx_LabelledToggleSwitch_«r60»" > Enable end-to-end encryption </div> </span> <div aria-checked="true" aria-disabled="false" - aria-labelledby="mx_LabelledToggleSwitch_«r54»" + aria-labelledby="mx_LabelledToggleSwitch_«r60»" class="mx_AccessibleButton mx_ToggleSwitch mx_ToggleSwitch_on mx_ToggleSwitch_enabled" role="switch" tabindex="0" > <div at Object.toMatchSnapshot (test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx:266:34)
});
});

Expand Down Expand Up @@ -359,4 +410,104 @@
});
});
});

describe("for a room in a space", () => {
let parentSpace: Room;
beforeEach(() => {
parentSpace = mkSpace(mockClient, "!space:server") as unknown as Room;
});

it("should create a room with restricted join rule when selected", async () => {
const onFinished = jest.fn();
render(<CreateRoomDialog parentSpace={parentSpace} onFinished={onFinished} />);
await flushPromises();

// Set room name and visibility.
fireEvent.change(screen.getByLabelText("Name"), { target: { value: "Restricted Room" } });
fireEvent.click(screen.getByLabelText("Room visibility"));
fireEvent.click(screen.getByRole("option", { name: "Visible to space members" }));

fireEvent.click(screen.getByText("Create room"));
await flushPromises();

expect(onFinished).toHaveBeenCalledWith(

Check failure on line 433 in test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx

View workflow job for this annotation

GitHub Actions / Jest (1)

<CreateRoomDialog /> › for a room in a space › should create a room with restricted join rule when selected

expect(jest.fn()).toHaveBeenCalledWith(...expected) Expected: true, ObjectContaining {"createOpts": ObjectContaining {"name": "Restricted Room"}, "joinRule": "restricted"} Received: true, {"createOpts": {}, "encryption": true, "joinRule": "restricted", "name": "Restricted Room", "parentSpace": {"canInvite": [Function mockConstructor], "client": {"_events": {}, "_eventsCount": 0, "_maxListeners": undefined, "canSupport": Map {"Thread" => 0, "ThreadUnreadNotifications" => 0, "LoginTokenRequest" => 0, "RelationBasedRedactions" => 0, "AccountDataDeletion" => 0, "RelationsRecursion" => 0, "IntentionalMentions" => 0}, "credentials": {"userId": "@alice:server.org"}, "doesServerForceEncryptionForPreset": [Function mockConstructor], "getAccessToken": [Function mockConstructor], "getAccountData": [Function mockConstructor], "getClientWellKnown": [Function mockConstructor], "getDeviceId": [Function mockConstructor], "getDomain": [Function mockConstructor], "getRoomIdForAlias": [Function mockConstructor], "getSafeUserId": [Function mockConstructor], "getThreePids": [Function mockConstructor], "getUser": [Function mockConstructor], "getUserId": [Function mockConstructor], "isGuest": [Function mockConstructor], "mxcUrlToHttp": [Function mockConstructor], Symbol(shapeMode): false, Symbol(kCapture): false}, "createThreadsTimelineSets": [Function mockConstructor], "currentState": {"getJoinRule": [Function mockConstructor], "getMember": [Function mockConstructor], "getStateEvents": [Function mockConstructor], "mayClientSendStateEvent": [Function mockConstructor], "maySendEvent": [Function mockConstructor], "maySendRedactionForEvent": [Function mockConstructor], "maySendStateEvent": [Function mockConstructor], "members": {}, "off": [Function mockConstructor], "on": [Function mockConstructor]}, "eventShouldLiveIn": [Function mockConstructor], "fetchRoomThreads": [Function mockConstructor], "findEventById": [Function mockConstructor], "findPredecessor": [Function mockConstructor], "findThreadForEvent": [Function mockConstructor], "getAccountData": [Function getAccountData], "getAltAliases": [Function mockConstructor], "getAvatarUrl": [Function getAvatarUrl], "getBumpStamp": [Function mockConstructor], "getCanonicalAlias": [Function mockConstructor], "getDMInviter": [Function mockConstructor], "getEventReadUpTo": [Function mockConstructor], "getInvitedAndJoinedMemberCount": [Function mockConstructor], "getJoinRule": [Function mockConstructor], "getJoinedMemberCount": [Function mockConstructor], "getJoinedMembers": [Function mockConstructor], "getLastLiveEvent": [Function mockConstructor], "getLiveTimeline": [Function mockConstructor], "getMember": [Function mockConstructor], "getMembers": [Function mockConstructor], "getMembersWithMembership": [Function mockConstructor], "getMxcAvatarUrl": [Function getMxcAvatarUrl], "getMyMembership": [Function mockConstructor], "getPendingEvents": [Function getPendingEvents], "getReceiptsForEvent": [Function mockConstructor], "getRecommendedVersion": [Function mockConstructor], "getRoomUnreadNotificationCount": [Function mockConstructor], "getThreads": [Function mockConstructor], "getType": [Function mockConstructor], "getUnfilteredTimelineSet": [Function mockConstructor], "getUnreadNotificationCount": [Function mockConstructor], "getVersion": [Function mockConstructor], "hasEncryptionStateEvent": [Function mockConstructor], "hasMembershipState": [Function hasMembershipState], "isCallRoom": [Function mockConstructor], "isElementVideoRoom": [Function mockConstructor], "isSpaceRoom": [Function mockConstructor], "loadMembersIfNeeded": [Function mockConstructor], "maySendMessage": [Function mockConstructor], "myUserId": "@alice:server.org", "name": "!space:server", "normalizedName": "spaceserver", "off": [Function mockConstructor], "on": [Function mockConstructor], "removeListener": [Function mockConstructor], "roomId": "!space:server", "setBlacklistUnverifiedDevices": [Function mockConstructor], "setUnreadNotificationCount": [Function mockConstructor], "tags": {}, "timeline": []}, "roomType": undefined} Numb
true,
expect.objectContaining({
createOpts: expect.objectContaining({
name: "Restricted Room",
}),
joinRule: JoinRule.Restricted,
}),
);
});

it("should create a room with public join rule when selected", async () => {
const onFinished = jest.fn();
render(<CreateRoomDialog parentSpace={parentSpace} onFinished={onFinished} />);
await flushPromises();

// Set room name and visibility. Rooms in spaces also need an address.
fireEvent.change(screen.getByLabelText("Name"), { target: { value: "Public Room" } });
fireEvent.click(screen.getByLabelText("Room visibility"));
fireEvent.click(screen.getByRole("option", { name: "Public room" }));
fireEvent.change(screen.getByLabelText("Room address"), { target: { value: "testroom" } });

// Create the room.
fireEvent.click(screen.getByText("Create room"));
await flushPromises();

expect(onFinished).toHaveBeenCalledWith(

Check failure on line 459 in test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx

View workflow job for this annotation

GitHub Actions / Jest (1)

<CreateRoomDialog /> › for a room in a space › should create a room with public join rule when selected

expect(jest.fn()).toHaveBeenCalledWith(...expected) Expected: true, ObjectContaining {"createOpts": ObjectContaining {"name": "Public Room", "preset": "public_chat", "room_alias_name": "testroom", "visibility": "public"}, "guestAccess": false, "roomType": undefined} Received: true, {"createOpts": {"preset": "public_chat", "room_alias_name": "testroom", "visibility": "public"}, "guestAccess": false, "name": "Public Room", "parentSpace": {"canInvite": [Function mockConstructor], "client": {"_events": {}, "_eventsCount": 0, "_maxListeners": undefined, "canSupport": Map {"Thread" => 0, "ThreadUnreadNotifications" => 0, "LoginTokenRequest" => 0, "RelationBasedRedactions" => 0, "AccountDataDeletion" => 0, "RelationsRecursion" => 0, "IntentionalMentions" => 0}, "credentials": {"userId": "@alice:server.org"}, "doesServerForceEncryptionForPreset": [Function mockConstructor], "getAccessToken": [Function mockConstructor], "getAccountData": [Function mockConstructor], "getClientWellKnown": [Function mockConstructor], "getDeviceId": [Function mockConstructor], "getDomain": [Function mockConstructor], "getRoomIdForAlias": [Function mockConstructor], "getSafeUserId": [Function mockConstructor], "getThreePids": [Function mockConstructor], "getUser": [Function mockConstructor], "getUserId": [Function mockConstructor], "isGuest": [Function mockConstructor], "mxcUrlToHttp": [Function mockConstructor], Symbol(shapeMode): false, Symbol(kCapture): false}, "createThreadsTimelineSets": [Function mockConstructor], "currentState": {"getJoinRule": [Function mockConstructor], "getMember": [Function mockConstructor], "getStateEvents": [Function mockConstructor], "mayClientSendStateEvent": [Function mockConstructor], "maySendEvent": [Function mockConstructor], "maySendRedactionForEvent": [Function mockConstructor], "maySendStateEvent": [Function mockConstructor], "members": {}, "off": [Function mockConstructor], "on": [Function mockConstructor]}, "eventShouldLiveIn": [Function mockConstructor], "fetchRoomThreads": [Function mockConstructor], "findEventById": [Function mockConstructor], "findPredecessor": [Function mockConstructor], "findThreadForEvent": [Function mockConstructor], "getAccountData": [Function getAccountData], "getAltAliases": [Function mockConstructor], "getAvatarUrl": [Function getAvatarUrl], "getBumpStamp": [Function mockConstructor], "getCanonicalAlias": [Function mockConstructor], "getDMInviter": [Function mockConstructor], "getEventReadUpTo": [Function mockConstructor], "getInvitedAndJoinedMemberCount": [Function mockConstructor], "getJoinRule": [Function mockConstructor], "getJoinedMemberCount": [Function mockConstructor], "getJoinedMembers": [Function mockConstructor], "getLastLiveEvent": [Function mockConstructor], "getLiveTimeline": [Function mockConstructor], "getMember": [Function mockConstructor], "getMembers": [Function mockConstructor], "getMembersWithMembership": [Function mockConstructor], "getMxcAvatarUrl": [Function getMxcAvatarUrl], "getMyMembership": [Function mockConstructor], "getPendingEvents": [Function getPendingEvents], "getReceiptsForEvent": [Function mockConstructor], "getRecommendedVersion": [Function mockConstructor], "getRoomUnreadNotificationCount": [Function mockConstructor], "getThreads": [Function mockConstructor], "getType": [Function mockConstructor], "getUnfilteredTimelineSet": [Function mockConstructor], "getUnreadNotificationCount": [Function mockConstructor], "getVersion": [Function mockConstructor], "hasEncryptionStateEvent": [Function mockConstructor], "hasMembershipState": [Function hasMembershipState], "isCallRoom": [Function mockConstructor], "isElementVideoRoom": [Function mockConstructor], "isSpaceRoom": [Function mockConstructor], "loadMembersIfNeeded": [Function mockConstructor], "maySendMessage": [Function mockConstructor], "myUserId": "@alice:server.org", "name": "!space:server", "normalizedName": "spaceserver", "off": [Function mockConstructor], "on": [Function mockConstructor], "removeListener": [Function mockConstructor], "roomId": "!space:server", "setBlacklistUnverifiedDevices"
true,
expect.objectContaining({
createOpts: expect.objectContaining({
name: "Public Room",
room_alias_name: "testroom",
visibility: Visibility.Public,
preset: Preset.PublicChat,
}),
guestAccess: false,
roomType: undefined,
}),
);
});
});

describe("keyboard shortcuts", () => {
it("should submit the form when Enter is pressed", async () => {
const onFinished = jest.fn();
render(<CreateRoomDialog onFinished={onFinished} />);
await flushPromises();

// Simulate pressing the Enter key.
fireEvent.change(screen.getByLabelText("Name"), { target: { value: "Keyboard Room" } });
fireEvent.keyDown(screen.getByLabelText("Name"), { key: "Enter", code: "Enter", charCode: 13 });

await flushPromises();

expect(onFinished).toHaveBeenCalledWith(

Check failure on line 487 in test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx

View workflow job for this annotation

GitHub Actions / Jest (1)

<CreateRoomDialog /> › keyboard shortcuts › should submit the form when Enter is pressed

expect(jest.fn()).toHaveBeenCalledWith(...expected) Expected: true, ObjectContaining {"createOpts": ObjectContaining {"name": "Keyboard Room"}} Received: true, {"createOpts": {}, "encryption": true, "name": "Keyboard Room", "parentSpace": undefined, "roomType": undefined} Number of calls: 1 at Object.toHaveBeenCalledWith (test/unit-tests/components/views/dialogs/CreateRoomDialog-test.tsx:487:32)
true,
expect.objectContaining({
createOpts: expect.objectContaining({
name: "Keyboard Room",
}),
}),
);
});

it("should cancel the dialog when Escape is pressed", async () => {
const onFinished = jest.fn();
render(<CreateRoomDialog onFinished={onFinished} />);
await flushPromises();

// Simulate pressing the Escape key.
fireEvent.keyDown(screen.getByLabelText("Name"), { key: "Escape", code: "Escape", charCode: 27 });

await flushPromises();

// BaseDialog passes no arguments, but DialogButtons pass false - might not be desirable?
expect(onFinished).toHaveBeenCalled();
const callArgs = onFinished.mock.calls[0];
expect(callArgs.length === 0 || callArgs[0] === false).toBe(true);
});
});
});
Loading