diff --git a/test/components/views/settings/tabs/room/AdvancedRoomSettingsTab-test.tsx b/test/components/views/settings/tabs/room/AdvancedRoomSettingsTab-test.tsx new file mode 100644 index 0000000000..dafd555966 --- /dev/null +++ b/test/components/views/settings/tabs/room/AdvancedRoomSettingsTab-test.tsx @@ -0,0 +1,104 @@ +/* +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, RenderResult } from "@testing-library/react"; +import { MatrixClient } from "matrix-js-sdk/src/client"; +import { Room } from "matrix-js-sdk/src/models/room"; +import { mocked } from "jest-mock"; +import { EventType, MatrixEvent } from "matrix-js-sdk/src/matrix"; + +import AdvancedRoomSettingsTab from "../../../../../../src/components/views/settings/tabs/room/AdvancedRoomSettingsTab"; +import { mkEvent, mkStubRoom, stubClient } from "../../../../../test-utils"; +import dis from "../../../../../../src/dispatcher/dispatcher"; +import { Action } from "../../../../../../src/dispatcher/actions"; +import { MatrixClientPeg } from "../../../../../../src/MatrixClientPeg"; + +jest.mock("../../../../../../src/dispatcher/dispatcher"); + +describe("AdvancedRoomSettingsTab", () => { + const roomId = "!room:example.com"; + let cli: MatrixClient; + let room: Room; + + const renderTab = (): RenderResult => { + return render(); + }; + + beforeEach(() => { + stubClient(); + cli = MatrixClientPeg.get(); + room = mkStubRoom(roomId, "test room", cli); + mocked(cli.getRoom).mockReturnValue(room); + }); + + it("should render as expected", () => { + const tab = renderTab(); + expect(tab.asFragment()).toMatchSnapshot(); + }); + + it("should display room ID", () => { + const tab = renderTab(); + tab.getByText(roomId); + }); + + it("should display room version", () => { + mocked(room.getVersion).mockReturnValue("custom_room_version_1"); + + const tab = renderTab(); + tab.getByText("custom_room_version_1"); + }); + + function mockStateEvents(room: Room) { + const createEvent = mkEvent({ + event: true, + user: "@a:b.com", + type: EventType.RoomCreate, + content: { predecessor: { room_id: "old_room_id", event_id: "tombstone_event_id" } }, + room: room.roomId, + }); + + type GetStateEvents2Args = (eventType: EventType | string, stateKey: string) => MatrixEvent | null; + + const getStateEvents = jest.spyOn( + room.currentState, + "getStateEvents", + ) as unknown as jest.MockedFunction; + + getStateEvents.mockImplementation((eventType: string | null, _key: string) => { + switch (eventType) { + case EventType.RoomCreate: + return createEvent; + default: + return null; + } + }); + } + + it("should link to predecessor room", async () => { + mockStateEvents(room); + const tab = renderTab(); + const link = await tab.findByText("View older messages in test room."); + fireEvent.click(link); + expect(dis.dispatch).toHaveBeenCalledWith({ + action: Action.ViewRoom, + event_id: "tombstone_event_id", + room_id: "old_room_id", + metricsTrigger: "WebPredecessorSettings", + metricsViaKeyboard: false, + }); + }); +}); diff --git a/test/components/views/settings/tabs/room/__snapshots__/AdvancedRoomSettingsTab-test.tsx.snap b/test/components/views/settings/tabs/room/__snapshots__/AdvancedRoomSettingsTab-test.tsx.snap new file mode 100644 index 0000000000..fa0aa0338e --- /dev/null +++ b/test/components/views/settings/tabs/room/__snapshots__/AdvancedRoomSettingsTab-test.tsx.snap @@ -0,0 +1,55 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`AdvancedRoomSettingsTab should render as expected 1`] = ` + +
+
+ Advanced +
+
+ + Room information + +
+ + Internal room ID + +
+ !room:example.com +
+
+
+
+
+ + Room version + +
+ + Room version: + +  1 +
+
+
+ +`; diff --git a/test/test-utils/test-utils.ts b/test/test-utils/test-utils.ts index 25a581ba6f..ef7bc1dcef 100644 --- a/test/test-utils/test-utils.ts +++ b/test/test-utils/test-utils.ts @@ -40,6 +40,7 @@ import { MediaHandler } from "matrix-js-sdk/src/webrtc/mediaHandler"; import { Feature, ServerSupport } from "matrix-js-sdk/src/feature"; import { CryptoBackend } from "matrix-js-sdk/src/common-crypto/CryptoBackend"; import { IEventDecryptionResult } from "matrix-js-sdk/src/@types/crypto"; +import { MapperOpts } from "matrix-js-sdk/src/event-mapper"; import type { GroupCall } from "matrix-js-sdk/src/webrtc/groupCall"; import { MatrixClientPeg as peg } from "../../src/MatrixClientPeg"; @@ -145,7 +146,7 @@ export function createTestClient(): MatrixClient { content: {}, }); }), - mxcUrlToHttp: (mxc) => `http://this.is.a.url/${mxc.substring(6)}`, + mxcUrlToHttp: (mxc: string) => `http://this.is.a.url/${mxc.substring(6)}`, setAccountData: jest.fn(), setRoomAccountData: jest.fn(), setRoomTopic: jest.fn(), @@ -200,7 +201,7 @@ export function createTestClient(): MatrixClient { stopAllStreams: jest.fn(), } as unknown as MediaHandler), uploadContent: jest.fn(), - getEventMapper: () => (opts) => new MatrixEvent(opts), + getEventMapper: (_options?: MapperOpts) => (event: Partial) => new MatrixEvent(event), leaveRoomChain: jest.fn((roomId) => ({ [roomId]: null })), doesServerSupportLogoutDevices: jest.fn().mockReturnValue(true), requestPasswordEmailToken: jest.fn().mockRejectedValue({}), @@ -476,34 +477,11 @@ export function mkMessage({ } export function mkStubRoom(roomId: string = null, name: string, client: MatrixClient): Room { - const stubTimeline = { getEvents: () => [] } as unknown as EventTimeline; + const stubTimeline = { getEvents: () => [] as MatrixEvent[] } as unknown as EventTimeline; return { - roomId, - getReceiptsForEvent: jest.fn().mockReturnValue([]), - getMember: jest.fn().mockReturnValue({ - userId: "@member:domain.bla", - name: "Member", - rawDisplayName: "Member", - roomId: roomId, - getAvatarUrl: () => "mxc://avatar.url/image.png", - getMxcAvatarUrl: () => "mxc://avatar.url/image.png", - }), - getMembersWithMembership: jest.fn().mockReturnValue([]), - getJoinedMembers: jest.fn().mockReturnValue([]), - getJoinedMemberCount: jest.fn().mockReturnValue(1), - getInvitedAndJoinedMemberCount: jest.fn().mockReturnValue(1), - setUnreadNotificationCount: jest.fn(), - getMembers: jest.fn().mockReturnValue([]), - getPendingEvents: () => [], - getLiveTimeline: jest.fn().mockReturnValue(stubTimeline), - getUnfilteredTimelineSet: jest.fn(), - findEventById: () => null, - getAccountData: () => null, - hasMembershipState: () => null, - getVersion: () => "1", - shouldUpgradeToVersion: () => null, - getMyMembership: jest.fn().mockReturnValue("join"), - maySendMessage: jest.fn().mockReturnValue(true), + canInvite: jest.fn(), + client, + createThreadsTimelineSets: jest.fn().mockReturnValue(new Promise(() => {})), currentState: { getStateEvents: jest.fn((_type, key) => (key === undefined ? [] : null)), getMember: jest.fn(), @@ -516,37 +494,62 @@ export function mkStubRoom(roomId: string = null, name: string, client: MatrixCl on: jest.fn(), off: jest.fn(), } as unknown as RoomState, - tags: {}, - setBlacklistUnverifiedDevices: jest.fn(), - on: jest.fn(), - off: jest.fn(), - removeListener: jest.fn(), + eventShouldLiveIn: jest.fn().mockReturnValue({}), + fetchRoomThreads: jest.fn().mockReturnValue(Promise.resolve()), + findEventById: (_: string) => undefined as MatrixEvent | undefined, + findPredecessor: jest.fn().mockReturnValue({ roomId: "", eventId: null }), + getAccountData: (_: EventType | string) => undefined as MatrixEvent | undefined, + getAltAliases: jest.fn().mockReturnValue([]), + getAvatarUrl: () => "mxc://avatar.url/room.png", + getCanonicalAlias: jest.fn(), getDMInviter: jest.fn(), + getEventReadUpTo: jest.fn(() => null), + getInvitedAndJoinedMemberCount: jest.fn().mockReturnValue(1), + getJoinRule: jest.fn().mockReturnValue("invite"), + getJoinedMemberCount: jest.fn().mockReturnValue(1), + getJoinedMembers: jest.fn().mockReturnValue([]), + getLiveTimeline: jest.fn().mockReturnValue(stubTimeline), + getMember: jest.fn().mockReturnValue({ + userId: "@member:domain.bla", + name: "Member", + rawDisplayName: "Member", + roomId: roomId, + getAvatarUrl: () => "mxc://avatar.url/image.png", + getMxcAvatarUrl: () => "mxc://avatar.url/image.png", + }), + getMembers: jest.fn().mockReturnValue([]), + getMembersWithMembership: jest.fn().mockReturnValue([]), + getMxcAvatarUrl: () => "mxc://avatar.url/room.png", + getMyMembership: jest.fn().mockReturnValue("join"), + getPendingEvents: () => [] as MatrixEvent[], + getReceiptsForEvent: jest.fn().mockReturnValue([]), + getRecommendedVersion: jest.fn().mockReturnValue(Promise.resolve("")), + getThreads: jest.fn().mockReturnValue([]), + getType: jest.fn().mockReturnValue(undefined), + getUnfilteredTimelineSet: jest.fn(), + getUnreadNotificationCount: jest.fn(() => 0), + getVersion: jest.fn().mockReturnValue("1"), + hasMembershipState: () => false, + isElementVideoRoom: jest.fn().mockReturnValue(false), + isSpaceRoom: jest.fn().mockReturnValue(false), + loadMembersIfNeeded: jest.fn(), + maySendMessage: jest.fn().mockReturnValue(true), + myUserId: client?.getUserId(), name, normalizedName: normalize(name || ""), - getAvatarUrl: () => "mxc://avatar.url/room.png", - getMxcAvatarUrl: () => "mxc://avatar.url/room.png", - isSpaceRoom: jest.fn().mockReturnValue(false), - getType: jest.fn().mockReturnValue(undefined), - isElementVideoRoom: jest.fn().mockReturnValue(false), - getUnreadNotificationCount: jest.fn(() => 0), - getEventReadUpTo: jest.fn(() => null), - getCanonicalAlias: jest.fn(), - getAltAliases: jest.fn().mockReturnValue([]), + off: jest.fn(), + on: jest.fn(), + removeListener: jest.fn(), + roomId, + setBlacklistUnverifiedDevices: jest.fn(), + setUnreadNotificationCount: jest.fn(), + shouldUpgradeToVersion: (() => null) as () => string | null, + tags: {}, timeline: [], - getJoinRule: jest.fn().mockReturnValue("invite"), - loadMembersIfNeeded: jest.fn(), - client, - myUserId: client?.getUserId(), - canInvite: jest.fn(), - getThreads: jest.fn().mockReturnValue([]), - eventShouldLiveIn: jest.fn().mockReturnValue({}), - createThreadsTimelineSets: jest.fn().mockReturnValue(new Promise(() => {})), - fetchRoomThreads: jest.fn().mockReturnValue(new Promise(() => {})), } as unknown as Room; } -export function mkServerConfig(hsUrl, isUrl) { +export function mkServerConfig(hsUrl: string, isUrl: string) { return makeType(ValidatedServerConfig, { hsUrl, hsName: "TEST_ENVIRONMENT",