Remove virtual rooms (#29635)

* Remove virtual rooms from the timelinePanel and RoomView

* Remove VoipUserMapper

* Remove some unneeded imports

* Remove tovirtual slash command test

* Remove getSupportsVirtualRooms and virtualLookup

* lint

* Remove PROTOCOL_SIP_NATIVE

* Remove native/virtual looks fields and fix tests

* Remove unused lookup fields
This commit is contained in:
David Langley
2025-04-16 09:36:34 +01:00
committed by GitHub
parent 8b06714a02
commit aa821a5b6f
18 changed files with 68 additions and 1047 deletions

View File

@@ -29,8 +29,6 @@ import LegacyCallHandler, {
LegacyCallHandlerEvent,
PROTOCOL_PSTN,
PROTOCOL_PSTN_PREFIXED,
PROTOCOL_SIP_NATIVE,
PROTOCOL_SIP_VIRTUAL,
} from "../../src/LegacyCallHandler";
import { mkStubRoom, stubClient, untilDispatch } from "../test-utils";
import { MatrixClientPeg } from "../../src/MatrixClientPeg";
@@ -75,9 +73,6 @@ const NATIVE_ALICE = "@alice:example.org";
const NATIVE_BOB = "@bob:example.org";
const NATIVE_CHARLIE = "@charlie:example.org";
// Virtual user for Bob
const VIRTUAL_BOB = "@virtual_bob:example.org";
//const REAL_ROOM_ID = "$room1:example.org";
// The rooms the user sees when they're communicating with these users
const NATIVE_ROOM_ALICE = "$alice_room:example.org";
@@ -86,10 +81,6 @@ const NATIVE_ROOM_CHARLIE = "$charlie_room:example.org";
const FUNCTIONAL_USER = "@bot:example.com";
// The room we use to talk to virtual Bob (but that the user does not see)
// Bob has a virtual room, but Alice doesn't
const VIRTUAL_ROOM_BOB = "$virtual_bob_room:example.org";
// Bob's phone number
const BOB_PHONE_NUMBER = "01818118181";
@@ -146,14 +137,6 @@ class FakeCall extends EventEmitter {
}
}
function untilCallHandlerEvent(callHandler: LegacyCallHandler, event: LegacyCallHandlerEvent): Promise<void> {
return new Promise<void>((resolve) => {
callHandler.addListener(event, () => {
resolve();
});
});
}
describe("LegacyCallHandler", () => {
let dmRoomMap;
let callHandler: LegacyCallHandler;
@@ -162,7 +145,6 @@ describe("LegacyCallHandler", () => {
// what addresses the app has looked up via pstn and native lookup
let pstnLookup: string | null;
let nativeLookup: string | null;
const deviceId = "my-device";
beforeEach(async () => {
@@ -180,8 +162,6 @@ describe("LegacyCallHandler", () => {
MatrixClientPeg.safeGet().getThirdpartyProtocols = () => {
return Promise.resolve({
"m.id.phone": {} as IProtocol,
"im.vector.protocol.sip_native": {} as IProtocol,
"im.vector.protocol.sip_virtual": {} as IProtocol,
});
};
@@ -193,7 +173,6 @@ describe("LegacyCallHandler", () => {
const nativeRoomAlice = mkStubDM(NATIVE_ROOM_ALICE, NATIVE_ALICE);
const nativeRoomBob = mkStubDM(NATIVE_ROOM_BOB, NATIVE_BOB);
const nativeRoomCharie = mkStubDM(NATIVE_ROOM_CHARLIE, NATIVE_CHARLIE);
const virtualBobRoom = mkStubDM(VIRTUAL_ROOM_BOB, VIRTUAL_BOB);
MatrixClientPeg.safeGet().getRoom = (roomId: string): Room | null => {
switch (roomId) {
@@ -203,8 +182,6 @@ describe("LegacyCallHandler", () => {
return nativeRoomBob;
case NATIVE_ROOM_CHARLIE:
return nativeRoomCharie;
case VIRTUAL_ROOM_BOB:
return virtualBobRoom;
}
return null;
@@ -218,8 +195,6 @@ describe("LegacyCallHandler", () => {
return NATIVE_BOB;
} else if (roomId === NATIVE_ROOM_CHARLIE) {
return NATIVE_CHARLIE;
} else if (roomId === VIRTUAL_ROOM_BOB) {
return VIRTUAL_BOB;
} else {
return null;
}
@@ -231,8 +206,6 @@ describe("LegacyCallHandler", () => {
return [NATIVE_ROOM_BOB];
} else if (userId === NATIVE_CHARLIE) {
return [NATIVE_ROOM_CHARLIE];
} else if (userId === VIRTUAL_BOB) {
return [VIRTUAL_ROOM_BOB];
} else {
return [];
}
@@ -241,52 +214,18 @@ describe("LegacyCallHandler", () => {
DMRoomMap.setShared(dmRoomMap);
pstnLookup = null;
nativeLookup = null;
MatrixClientPeg.safeGet().getThirdpartyUser = (proto: string, params: any) => {
if ([PROTOCOL_PSTN, PROTOCOL_PSTN_PREFIXED].includes(proto)) {
pstnLookup = params["m.id.phone"];
return Promise.resolve([
{
userid: VIRTUAL_BOB,
userid: NATIVE_BOB,
protocol: "m.id.phone",
fields: {
is_native: true,
lookup_success: true,
},
fields: {},
},
]);
} else if (proto === PROTOCOL_SIP_NATIVE) {
nativeLookup = params["virtual_mxid"];
if (params["virtual_mxid"] === VIRTUAL_BOB) {
return Promise.resolve([
{
userid: NATIVE_BOB,
protocol: "im.vector.protocol.sip_native",
fields: {
is_native: true,
lookup_success: true,
},
},
]);
}
return Promise.resolve([]);
} else if (proto === PROTOCOL_SIP_VIRTUAL) {
if (params["native_mxid"] === NATIVE_BOB) {
return Promise.resolve([
{
userid: VIRTUAL_BOB,
protocol: "im.vector.protocol.sip_virtual",
fields: {
is_virtual: true,
lookup_success: true,
},
},
]);
}
return Promise.resolve([]);
}
return Promise.resolve([]);
};
@@ -312,16 +251,14 @@ describe("LegacyCallHandler", () => {
await callHandler.dialNumber(BOB_PHONE_NUMBER);
expect(pstnLookup).toEqual(BOB_PHONE_NUMBER);
expect(nativeLookup).toEqual(VIRTUAL_BOB);
// we should have switched to the native room for Bob
const viewRoomPayload = await untilDispatch(Action.ViewRoom);
expect(viewRoomPayload.room_id).toEqual(NATIVE_ROOM_BOB);
// Check that a call was started: its room on the protocol level
// should be the virtual room
expect(fakeCall).not.toBeNull();
expect(fakeCall?.roomId).toEqual(VIRTUAL_ROOM_BOB);
expect(fakeCall?.roomId).toEqual(NATIVE_ROOM_BOB);
// but it should appear to the user to be in thw native room for Bob
expect(callHandler.roomIdForCall(fakeCall!)).toEqual(NATIVE_ROOM_BOB);
@@ -338,7 +275,7 @@ describe("LegacyCallHandler", () => {
expect(viewRoomPayload.room_id).toEqual(NATIVE_ROOM_BOB);
expect(fakeCall).not.toBeNull();
expect(fakeCall!.roomId).toEqual(VIRTUAL_ROOM_BOB);
expect(fakeCall!.roomId).toEqual(NATIVE_ROOM_BOB);
expect(callHandler.roomIdForCall(fakeCall!)).toEqual(NATIVE_ROOM_BOB);
});
@@ -346,8 +283,6 @@ describe("LegacyCallHandler", () => {
it("should move calls between rooms when remote asserted identity changes", async () => {
callHandler.placeCall(NATIVE_ROOM_ALICE, CallType.Voice);
await untilCallHandlerEvent(callHandler, LegacyCallHandlerEvent.CallState);
// We placed the call in Alice's room so it should start off there
expect(callHandler.getCallForRoom(NATIVE_ROOM_ALICE)).toBe(fakeCall);
@@ -517,10 +452,7 @@ describe("LegacyCallHandler without third party protocols", () => {
it("should still start a native call", async () => {
callHandler.placeCall(NATIVE_ROOM_ALICE, CallType.Voice);
await untilCallHandlerEvent(callHandler, LegacyCallHandlerEvent.CallState);
// Check that a call was started: its room on the protocol level
// should be the virtual room
expect(fakeCall).not.toBeNull();
expect(fakeCall!.roomId).toEqual(NATIVE_ROOM_ALICE);

View File

@@ -14,7 +14,6 @@ import { type Command, Commands, getCommand } from "../../src/SlashCommands";
import { createTestClient } from "../test-utils";
import { LocalRoom, LOCAL_ROOM_ID_PREFIX } from "../../src/models/LocalRoom";
import SettingsStore from "../../src/settings/SettingsStore";
import LegacyCallHandler from "../../src/LegacyCallHandler";
import { SdkContextClass } from "../../src/contexts/SDKContext";
import Modal from "../../src/Modal";
import WidgetUtils from "../../src/utils/WidgetUtils";
@@ -196,46 +195,6 @@ describe("SlashCommands", () => {
});
});
describe("/tovirtual", () => {
beforeEach(() => {
command = findCommand("tovirtual")!;
});
describe("isEnabled", () => {
describe("when virtual rooms are supported", () => {
beforeEach(() => {
jest.spyOn(LegacyCallHandler.instance, "getSupportsVirtualRooms").mockReturnValue(true);
});
it("should return true for Room", () => {
setCurrentRoom();
expect(command.isEnabled(client)).toBe(true);
});
it("should return false for LocalRoom", () => {
setCurrentLocalRoom();
expect(command.isEnabled(client)).toBe(false);
});
});
describe("when virtual rooms are not supported", () => {
beforeEach(() => {
jest.spyOn(LegacyCallHandler.instance, "getSupportsVirtualRooms").mockReturnValue(false);
});
it("should return false for Room", () => {
setCurrentRoom();
expect(command.isEnabled(client)).toBe(false);
});
it("should return false for LocalRoom", () => {
setCurrentLocalRoom();
expect(command.isEnabled(client)).toBe(false);
});
});
});
});
describe("/part", () => {
it("should part room matching alias if found", async () => {
const room1 = new Room("room-id", client, client.getSafeUserId());

View File

@@ -9,7 +9,6 @@ Please see LICENSE files in the repository root for full details.
import React, { createRef, type RefObject } from "react";
import { mocked, type MockedObject } from "jest-mock";
import {
ClientEvent,
EventTimeline,
EventType,
type IEvent,
@@ -68,7 +67,6 @@ import { DirectoryMember } from "../../../../src/utils/direct-messages";
import { createDmLocalRoom } from "../../../../src/utils/dm/createDmLocalRoom";
import { UPDATE_EVENT } from "../../../../src/stores/AsyncStore";
import { SDKContext, SdkContextClass } from "../../../../src/contexts/SDKContext";
import VoipUserMapper from "../../../../src/VoipUserMapper";
import WidgetUtils from "../../../../src/utils/WidgetUtils";
import { WidgetType } from "../../../../src/widgets/WidgetType";
import WidgetStore from "../../../../src/stores/WidgetStore";
@@ -119,7 +117,6 @@ describe("RoomView", () => {
stores.client = cli;
stores.rightPanelStore.useUnitTestClient(cli);
jest.spyOn(VoipUserMapper.sharedInstance(), "getVirtualRoomForRoom").mockResolvedValue(undefined);
crypto = cli.getCrypto()!;
jest.spyOn(cli, "getCrypto").mockReturnValue(undefined);
});
@@ -417,26 +414,6 @@ describe("RoomView", () => {
await waitFor(() => expect(container.querySelector(".mx_E2EIcon_verified")).toBeInTheDocument());
});
describe("with virtual rooms", () => {
it("checks for a virtual room on initial load", async () => {
const { container } = await renderRoomView();
expect(VoipUserMapper.sharedInstance().getVirtualRoomForRoom).toHaveBeenCalledWith(room.roomId);
// quick check that rendered without error
expect(container.querySelector(".mx_ErrorBoundary")).toBeFalsy();
});
it("checks for a virtual room on room event", async () => {
await renderRoomView();
expect(VoipUserMapper.sharedInstance().getVirtualRoomForRoom).toHaveBeenCalledWith(room.roomId);
act(() => cli.emit(ClientEvent.Room, room));
// called again after room event
expect(VoipUserMapper.sharedInstance().getVirtualRoomForRoom).toHaveBeenCalledTimes(2);
});
});
describe("video rooms", () => {
beforeEach(async () => {
await setupAsyncStoreWithClient(CallStore.instance, MatrixClientPeg.safeGet());

View File

@@ -35,7 +35,6 @@ import { forEachRight } from "lodash";
import TimelinePanel from "../../../../src/components/structures/TimelinePanel";
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
import { isCallEvent } from "../../../../src/components/structures/LegacyCallEventGrouper";
import {
filterConsole,
flushPromises,
@@ -115,22 +114,6 @@ const setupTestData = (): [MatrixClient, Room, MatrixEvent[]] => {
return [client, room, events];
};
const setupOverlayTestData = (client: MatrixClient, mainEvents: MatrixEvent[]): [Room, MatrixEvent[]] => {
const virtualRoom = mkRoom(client, "virtualRoomId");
const overlayEvents = mockEvents(virtualRoom, 5);
// Set the event order that we'll be looking for in the timeline
overlayEvents[0].localTimestamp = 1000;
mainEvents[0].localTimestamp = 2000;
overlayEvents[1].localTimestamp = 3000;
overlayEvents[2].localTimestamp = 4000;
overlayEvents[3].localTimestamp = 5000;
mainEvents[1].localTimestamp = 6000;
overlayEvents[4].localTimestamp = 7000;
return [virtualRoom, overlayEvents];
};
const expectEvents = (container: HTMLElement, events: MatrixEvent[]): void => {
const eventTiles = container.querySelectorAll(".mx_EventTile");
const eventTileIds = [...eventTiles].map((tileElement) => tileElement.getAttribute("data-event-id"));
@@ -518,298 +501,6 @@ describe("TimelinePanel", () => {
expect(paginateSpy).toHaveBeenCalledWith(EventTimeline.FORWARDS, 1, false);
});
it("advances the overlay timeline window", async () => {
const [client, room, events] = setupTestData();
const virtualRoom = mkRoom(client, "virtualRoomId");
const virtualEvents = mockEvents(virtualRoom);
const { timelineSet: overlayTimelineSet } = getProps(virtualRoom, virtualEvents);
const props = {
...getProps(room, events),
overlayTimelineSet,
};
const paginateSpy = jest.spyOn(TimelineWindow.prototype, "paginate").mockClear();
render(<TimelinePanel {...props} />);
await flushPromises();
const event = new MatrixEvent({ type: RoomEvent.Timeline, origin_server_ts: 0 });
const data = { timeline: props.timelineSet.getLiveTimeline(), liveEvent: true };
client.emit(RoomEvent.Timeline, event, room, false, false, data);
await flushPromises();
expect(paginateSpy).toHaveBeenCalledTimes(2);
});
});
describe("with overlayTimeline", () => {
it("renders merged timeline", async () => {
const [client, room, events] = setupTestData();
const virtualRoom = mkRoom(client, "virtualRoomId");
const virtualCallInvite = new MatrixEvent({
type: "m.call.invite",
room_id: virtualRoom.roomId,
event_id: `virtualCallEvent1`,
origin_server_ts: 0,
});
virtualCallInvite.localTimestamp = 2;
const virtualCallMetaEvent = new MatrixEvent({
type: "org.matrix.call.sdp_stream_metadata_changed",
room_id: virtualRoom.roomId,
event_id: `virtualCallEvent2`,
origin_server_ts: 0,
});
virtualCallMetaEvent.localTimestamp = 2;
const virtualEvents = [virtualCallInvite, ...mockEvents(virtualRoom), virtualCallMetaEvent];
const { timelineSet: overlayTimelineSet } = getProps(virtualRoom, virtualEvents);
const { container } = render(
<TimelinePanel
{...getProps(room, events)}
overlayTimelineSet={overlayTimelineSet}
overlayTimelineSetFilter={isCallEvent}
/>,
withClientContextRenderOptions(MatrixClientPeg.safeGet()),
);
await waitFor(() =>
expectEvents(container, [
// main timeline events are included
events[0],
events[1],
// virtual timeline call event is included
virtualCallInvite,
// virtual call event has no tile renderer => not rendered
]),
);
});
it.each([
["when it starts with no overlay events", true],
["to get enough overlay events", false],
])("expands the initial window %s", async (_s, startWithEmptyOverlayWindow) => {
const [client, room, events] = setupTestData();
const [virtualRoom, overlayEvents] = setupOverlayTestData(client, events);
let overlayEventsPage1: MatrixEvent[];
let overlayEventsPage2: MatrixEvent[];
let overlayEventsPage3: MatrixEvent[];
if (startWithEmptyOverlayWindow) {
overlayEventsPage1 = overlayEvents.slice(0, 3);
overlayEventsPage2 = [];
overlayEventsPage3 = overlayEvents.slice(3, 5);
} else {
overlayEventsPage1 = overlayEvents.slice(0, 2);
overlayEventsPage2 = overlayEvents.slice(2, 3);
overlayEventsPage3 = overlayEvents.slice(3, 5);
}
// Start with only page 2 of the overlay events in the window
const [overlayTimeline, overlayTimelineSet] = mkTimeline(virtualRoom, overlayEventsPage2);
setupPagination(client, overlayTimeline, overlayEventsPage1, overlayEventsPage3);
const { container } = render(
<TimelinePanel {...getProps(room, events)} overlayTimelineSet={overlayTimelineSet} />,
withClientContextRenderOptions(MatrixClientPeg.safeGet()),
);
await waitFor(() =>
expectEvents(container, [
overlayEvents[0],
events[0],
overlayEvents[1],
overlayEvents[2],
overlayEvents[3],
events[1],
overlayEvents[4],
]),
);
});
it("extends overlay window beyond main window at the start of the timeline", async () => {
const [client, room, events] = setupTestData();
const [virtualRoom, overlayEvents] = setupOverlayTestData(client, events);
// Delete event 0 so the TimelinePanel will still leave some stuff
// unloaded for us to test with
events.shift();
const overlayEventsPage1 = overlayEvents.slice(0, 2);
const overlayEventsPage2 = overlayEvents.slice(2, 5);
// Start with only page 2 of the overlay events in the window
const [overlayTimeline, overlayTimelineSet] = mkTimeline(virtualRoom, overlayEventsPage2);
setupPagination(client, overlayTimeline, overlayEventsPage1, null);
const { container } = render(
<TimelinePanel {...getProps(room, events)} overlayTimelineSet={overlayTimelineSet} />,
withClientContextRenderOptions(MatrixClientPeg.safeGet()),
);
await waitFor(() =>
expectEvents(container, [
// These first two are the newly loaded events
overlayEvents[0],
overlayEvents[1],
overlayEvents[2],
overlayEvents[3],
events[0],
overlayEvents[4],
]),
);
});
it("extends overlay window beyond main window at the end of the timeline", async () => {
const [client, room, events] = setupTestData();
const [virtualRoom, overlayEvents] = setupOverlayTestData(client, events);
// Delete event 1 so the TimelinePanel will still leave some stuff
// unloaded for us to test with
events.pop();
const overlayEventsPage1 = overlayEvents.slice(0, 2);
const overlayEventsPage2 = overlayEvents.slice(2, 5);
// Start with only page 1 of the overlay events in the window
const [overlayTimeline, overlayTimelineSet] = mkTimeline(virtualRoom, overlayEventsPage1);
setupPagination(client, overlayTimeline, null, overlayEventsPage2);
const { container } = render(
<TimelinePanel {...getProps(room, events)} overlayTimelineSet={overlayTimelineSet} />,
withClientContextRenderOptions(MatrixClientPeg.safeGet()),
);
await waitFor(() =>
expectEvents(container, [
overlayEvents[0],
events[0],
overlayEvents[1],
// These are the newly loaded events
overlayEvents[2],
overlayEvents[3],
overlayEvents[4],
]),
);
});
it("paginates", async () => {
const [client, room, events] = setupTestData();
const [virtualRoom, overlayEvents] = setupOverlayTestData(client, events);
const eventsPage1 = events.slice(0, 1);
const eventsPage2 = events.slice(1, 2);
// Start with only page 1 of the main events in the window
const [timeline, timelineSet] = mkTimeline(room, eventsPage1);
const [, overlayTimelineSet] = mkTimeline(virtualRoom, overlayEvents);
setupPagination(client, timeline, null, eventsPage2);
await withScrollPanelMountSpy(async (mountSpy) => {
const { container } = render(
<TimelinePanel
{...getProps(room, events)}
timelineSet={timelineSet}
overlayTimelineSet={overlayTimelineSet}
/>,
withClientContextRenderOptions(MatrixClientPeg.safeGet()),
);
await waitFor(() => expectEvents(container, [overlayEvents[0], events[0]]));
// ScrollPanel has no chance of working in jsdom, so we've no choice
// but to do some shady stuff to trigger the fill callback by hand
const scrollPanel = mountSpy.mock.contexts[0] as ScrollPanel;
scrollPanel.props.onFillRequest!(false);
await waitFor(() =>
expectEvents(container, [
overlayEvents[0],
events[0],
overlayEvents[1],
overlayEvents[2],
overlayEvents[3],
events[1],
overlayEvents[4],
]),
);
});
});
it.each([
["down", "main", true, false],
["down", "overlay", true, true],
["up", "main", false, false],
["up", "overlay", false, true],
])("unpaginates %s to an event from the %s timeline", async (_s1, _s2, backwards, fromOverlay) => {
const [client, room, events] = setupTestData();
const [virtualRoom, overlayEvents] = setupOverlayTestData(client, events);
let marker: MatrixEvent;
let expectedEvents: MatrixEvent[];
if (backwards) {
if (fromOverlay) {
marker = overlayEvents[1];
// Overlay events 01 and event 0 should be unpaginated
// Overlay events 23 should be hidden since they're at the edge of the window
expectedEvents = [events[1], overlayEvents[4]];
} else {
marker = events[0];
// Overlay event 0 and event 0 should be unpaginated
// Overlay events 13 should be hidden since they're at the edge of the window
expectedEvents = [events[1], overlayEvents[4]];
}
} else {
if (fromOverlay) {
marker = overlayEvents[4];
// Only the last overlay event should be unpaginated
expectedEvents = [
overlayEvents[0],
events[0],
overlayEvents[1],
overlayEvents[2],
overlayEvents[3],
events[1],
];
} else {
// Get rid of overlay event 4 so we can test the case where no overlay events get unpaginated
overlayEvents.pop();
marker = events[1];
// Only event 1 should be unpaginated
// Overlay events 12 should be hidden since they're at the edge of the window
expectedEvents = [overlayEvents[0], events[0]];
}
}
const [, overlayTimelineSet] = mkTimeline(virtualRoom, overlayEvents);
await withScrollPanelMountSpy(async (mountSpy) => {
const { container } = render(
<TimelinePanel {...getProps(room, events)} overlayTimelineSet={overlayTimelineSet} />,
withClientContextRenderOptions(MatrixClientPeg.safeGet()),
);
await waitFor(() =>
expectEvents(container, [
overlayEvents[0],
events[0],
overlayEvents[1],
overlayEvents[2],
overlayEvents[3],
events[1],
...(!backwards && !fromOverlay ? [] : [overlayEvents[4]]),
]),
);
// ScrollPanel has no chance of working in jsdom, so we've no choice
// but to do some shady stuff to trigger the unfill callback by hand
const scrollPanel = mountSpy.mock.contexts[0] as ScrollPanel;
scrollPanel.props.onUnfillRequest!(backwards, marker.getId()!);
await waitFor(() => expectEvents(container, expectedEvents));
});
});
});
describe("when a thread updates", () => {

View File

@@ -1952,7 +1952,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
aria-label="Open room settings"
aria-live="off"
class="_avatar_1qbcf_8 mx_BaseAvatar _avatar-imageless_1qbcf_52"
data-color="5"
data-color="3"
data-testid="avatar-img"
data-type="round"
role="button"
@@ -1979,7 +1979,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
<span
class="mx_RoomHeader_truncated mx_lineClamp"
>
!18:example.org
!16:example.org
</span>
</div>
</div>

View File

@@ -10,22 +10,10 @@ import { mocked } from "jest-mock";
import { type Room, RoomType } from "matrix-js-sdk/src/matrix";
import { VisibilityProvider } from "../../../../../src/stores/room-list/filters/VisibilityProvider";
import LegacyCallHandler from "../../../../../src/LegacyCallHandler";
import VoipUserMapper from "../../../../../src/VoipUserMapper";
import { LocalRoom, LOCAL_ROOM_ID_PREFIX } from "../../../../../src/models/LocalRoom";
import { RoomListCustomisations } from "../../../../../src/customisations/RoomList";
import { createTestClient } from "../../../../test-utils";
jest.mock("../../../../../src/VoipUserMapper", () => ({
sharedInstance: jest.fn(),
}));
jest.mock("../../../../../src/LegacyCallHandler", () => ({
instance: {
getSupportsVirtualRooms: jest.fn(),
},
}));
jest.mock("../../../../../src/customisations/RoomList", () => ({
RoomListCustomisations: {
isRoomVisible: jest.fn(),
@@ -46,16 +34,6 @@ const createLocalRoom = (): LocalRoom => {
};
describe("VisibilityProvider", () => {
let mockVoipUserMapper: VoipUserMapper;
beforeEach(() => {
mockVoipUserMapper = {
onNewInvitedRoom: jest.fn(),
isVirtualRoom: jest.fn(),
} as unknown as VoipUserMapper;
mocked(VoipUserMapper.sharedInstance).mockReturnValue(mockVoipUserMapper);
});
describe("instance", () => {
it("should return an instance", () => {
const visibilityProvider = VisibilityProvider.instance;
@@ -64,28 +42,7 @@ describe("VisibilityProvider", () => {
});
});
describe("onNewInvitedRoom", () => {
it("should call onNewInvitedRoom on VoipUserMapper.sharedInstance", async () => {
const room = {} as unknown as Room;
await VisibilityProvider.instance.onNewInvitedRoom(room);
expect(mockVoipUserMapper.onNewInvitedRoom).toHaveBeenCalledWith(room);
});
});
describe("isRoomVisible", () => {
describe("for a virtual room", () => {
beforeEach(() => {
mocked(LegacyCallHandler.instance.getSupportsVirtualRooms).mockReturnValue(true);
mocked(mockVoipUserMapper.isVirtualRoom).mockReturnValue(true);
});
it("should return return false", () => {
const room = createRoom();
expect(VisibilityProvider.instance.isRoomVisible(room)).toBe(false);
expect(mockVoipUserMapper.isVirtualRoom).toHaveBeenCalledWith(room);
});
});
it("should return false without room", () => {
expect(VisibilityProvider.instance.isRoomVisible()).toBe(false);
});