Apply prettier formatting
This commit is contained in:
parent
1cac306093
commit
526645c791
1576 changed files with 65385 additions and 62478 deletions
|
@ -27,10 +27,13 @@ describe("<ContextMenu />", () => {
|
|||
// Hardcode window and menu dimensions
|
||||
const windowSize = 300;
|
||||
const menuSize = 200;
|
||||
jest.spyOn(UIStore, "instance", "get").mockImplementation(() => ({
|
||||
windowWidth: windowSize,
|
||||
windowHeight: windowSize,
|
||||
}) as unknown as UIStore);
|
||||
jest.spyOn(UIStore, "instance", "get").mockImplementation(
|
||||
() =>
|
||||
({
|
||||
windowWidth: windowSize,
|
||||
windowHeight: windowSize,
|
||||
} as unknown as UIStore),
|
||||
);
|
||||
window.Element.prototype.getBoundingClientRect = jest.fn().mockReturnValue({
|
||||
width: menuSize,
|
||||
height: menuSize,
|
||||
|
|
|
@ -14,33 +14,33 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount, ReactWrapper } from 'enzyme';
|
||||
import { EventStatus, MatrixEvent } from 'matrix-js-sdk/src/models/event';
|
||||
import { Room } from 'matrix-js-sdk/src/models/room';
|
||||
import { mount, ReactWrapper } from "enzyme";
|
||||
import { EventStatus, MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
import {
|
||||
PendingEventOrdering,
|
||||
BeaconIdentifier,
|
||||
Beacon,
|
||||
getBeaconInfoIdentifier,
|
||||
EventType,
|
||||
} from 'matrix-js-sdk/src/matrix';
|
||||
import { ExtensibleEvent, MessageEvent, M_POLL_KIND_DISCLOSED, PollStartEvent } from 'matrix-events-sdk';
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { ExtensibleEvent, MessageEvent, M_POLL_KIND_DISCLOSED, PollStartEvent } from "matrix-events-sdk";
|
||||
import { FeatureSupport, Thread } from "matrix-js-sdk/src/models/thread";
|
||||
import { mocked } from "jest-mock";
|
||||
import { act } from '@testing-library/react';
|
||||
import { act } from "@testing-library/react";
|
||||
|
||||
import { MatrixClientPeg } from '../../../../src/MatrixClientPeg';
|
||||
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
||||
import RoomContext, { TimelineRenderingType } from "../../../../src/contexts/RoomContext";
|
||||
import { IRoomState } from "../../../../src/components/structures/RoomView";
|
||||
import { canEditContent } from "../../../../src/utils/EventUtils";
|
||||
import { copyPlaintext, getSelectedText } from "../../../../src/utils/strings";
|
||||
import MessageContextMenu from "../../../../src/components/views/context_menus/MessageContextMenu";
|
||||
import { makeBeaconEvent, makeBeaconInfoEvent, makeLocationEvent, stubClient } from '../../../test-utils';
|
||||
import dispatcher from '../../../../src/dispatcher/dispatcher';
|
||||
import SettingsStore from '../../../../src/settings/SettingsStore';
|
||||
import { ReadPinsEventId } from '../../../../src/components/views/right_panel/types';
|
||||
import { makeBeaconEvent, makeBeaconInfoEvent, makeLocationEvent, stubClient } from "../../../test-utils";
|
||||
import dispatcher from "../../../../src/dispatcher/dispatcher";
|
||||
import SettingsStore from "../../../../src/settings/SettingsStore";
|
||||
import { ReadPinsEventId } from "../../../../src/components/views/right_panel/types";
|
||||
import { Action } from "../../../../src/dispatcher/actions";
|
||||
|
||||
jest.mock("../../../../src/utils/strings", () => ({
|
||||
|
@ -52,17 +52,17 @@ jest.mock("../../../../src/utils/EventUtils", () => ({
|
|||
...jest.requireActual("../../../../src/utils/EventUtils"),
|
||||
canEditContent: jest.fn(),
|
||||
}));
|
||||
jest.mock('../../../../src/dispatcher/dispatcher');
|
||||
jest.mock("../../../../src/dispatcher/dispatcher");
|
||||
|
||||
const roomId = 'roomid';
|
||||
const roomId = "roomid";
|
||||
|
||||
describe('MessageContextMenu', () => {
|
||||
describe("MessageContextMenu", () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
stubClient();
|
||||
});
|
||||
|
||||
it('does show copy link button when supplied a link', () => {
|
||||
it("does show copy link button when supplied a link", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const props = {
|
||||
link: "https://google.com/",
|
||||
|
@ -73,119 +73,123 @@ describe('MessageContextMenu', () => {
|
|||
expect(copyLinkButton.props().href).toBe(props.link);
|
||||
});
|
||||
|
||||
it('does not show copy link button when not supplied a link', () => {
|
||||
it("does not show copy link button when not supplied a link", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const menu = createMenuWithContent(eventContent);
|
||||
const copyLinkButton = menu.find('a[aria-label="Copy link"]');
|
||||
expect(copyLinkButton).toHaveLength(0);
|
||||
});
|
||||
|
||||
describe('message pinning', () => {
|
||||
describe("message pinning", () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(SettingsStore, 'getValue').mockReturnValue(true);
|
||||
jest.spyOn(SettingsStore, "getValue").mockReturnValue(true);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.spyOn(SettingsStore, 'getValue').mockRestore();
|
||||
jest.spyOn(SettingsStore, "getValue").mockRestore();
|
||||
});
|
||||
|
||||
it('does not show pin option when user does not have rights to pin', () => {
|
||||
it("does not show pin option when user does not have rights to pin", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const event = new MatrixEvent(eventContent.serialize());
|
||||
|
||||
const room = makeDefaultRoom();
|
||||
// mock permission to disallow adding pinned messages to room
|
||||
jest.spyOn(room.currentState, 'mayClientSendStateEvent').mockReturnValue(false);
|
||||
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(false);
|
||||
|
||||
const menu = createMenu(event, {}, {}, undefined, room);
|
||||
|
||||
expect(menu.find('div[aria-label="Pin"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('does not show pin option for beacon_info event', () => {
|
||||
const deadBeaconEvent = makeBeaconInfoEvent('@alice:server.org', roomId, { isLive: false });
|
||||
it("does not show pin option for beacon_info event", () => {
|
||||
const deadBeaconEvent = makeBeaconInfoEvent("@alice:server.org", roomId, { isLive: false });
|
||||
|
||||
const room = makeDefaultRoom();
|
||||
// mock permission to allow adding pinned messages to room
|
||||
jest.spyOn(room.currentState, 'mayClientSendStateEvent').mockReturnValue(true);
|
||||
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
|
||||
|
||||
const menu = createMenu(deadBeaconEvent, {}, {}, undefined, room);
|
||||
|
||||
expect(menu.find('div[aria-label="Pin"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('does not show pin option when pinning feature is disabled', () => {
|
||||
it("does not show pin option when pinning feature is disabled", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const pinnableEvent = new MatrixEvent({ ...eventContent.serialize(), room_id: roomId });
|
||||
|
||||
const room = makeDefaultRoom();
|
||||
// mock permission to allow adding pinned messages to room
|
||||
jest.spyOn(room.currentState, 'mayClientSendStateEvent').mockReturnValue(true);
|
||||
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
|
||||
// disable pinning feature
|
||||
jest.spyOn(SettingsStore, 'getValue').mockReturnValue(false);
|
||||
jest.spyOn(SettingsStore, "getValue").mockReturnValue(false);
|
||||
|
||||
const menu = createMenu(pinnableEvent, {}, {}, undefined, room);
|
||||
|
||||
expect(menu.find('div[aria-label="Pin"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('shows pin option when pinning feature is enabled', () => {
|
||||
it("shows pin option when pinning feature is enabled", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const pinnableEvent = new MatrixEvent({ ...eventContent.serialize(), room_id: roomId });
|
||||
|
||||
const room = makeDefaultRoom();
|
||||
// mock permission to allow adding pinned messages to room
|
||||
jest.spyOn(room.currentState, 'mayClientSendStateEvent').mockReturnValue(true);
|
||||
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
|
||||
|
||||
const menu = createMenu(pinnableEvent, {}, {}, undefined, room);
|
||||
|
||||
expect(menu.find('div[aria-label="Pin"]')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('pins event on pin option click', () => {
|
||||
it("pins event on pin option click", () => {
|
||||
const onFinished = jest.fn();
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const pinnableEvent = new MatrixEvent({ ...eventContent.serialize(), room_id: roomId });
|
||||
pinnableEvent.event.event_id = '!3';
|
||||
pinnableEvent.event.event_id = "!3";
|
||||
const client = MatrixClientPeg.get();
|
||||
const room = makeDefaultRoom();
|
||||
|
||||
// mock permission to allow adding pinned messages to room
|
||||
jest.spyOn(room.currentState, 'mayClientSendStateEvent').mockReturnValue(true);
|
||||
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
|
||||
|
||||
// mock read pins account data
|
||||
const pinsAccountData = new MatrixEvent({ content: { event_ids: ['!1', '!2'] } });
|
||||
jest.spyOn(room, 'getAccountData').mockReturnValue(pinsAccountData);
|
||||
const pinsAccountData = new MatrixEvent({ content: { event_ids: ["!1", "!2"] } });
|
||||
jest.spyOn(room, "getAccountData").mockReturnValue(pinsAccountData);
|
||||
|
||||
const menu = createMenu(pinnableEvent, { onFinished }, {}, undefined, room);
|
||||
|
||||
act(() => {
|
||||
menu.find('div[aria-label="Pin"]').simulate('click');
|
||||
menu.find('div[aria-label="Pin"]').simulate("click");
|
||||
});
|
||||
|
||||
// added to account data
|
||||
expect(client.setRoomAccountData).toHaveBeenCalledWith(
|
||||
roomId,
|
||||
ReadPinsEventId,
|
||||
{ event_ids: [
|
||||
expect(client.setRoomAccountData).toHaveBeenCalledWith(roomId, ReadPinsEventId, {
|
||||
event_ids: [
|
||||
// from account data
|
||||
'!1', '!2',
|
||||
"!1",
|
||||
"!2",
|
||||
pinnableEvent.getId(),
|
||||
],
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
// add to room's pins
|
||||
expect(client.sendStateEvent).toHaveBeenCalledWith(roomId, EventType.RoomPinnedEvents, {
|
||||
pinned: [pinnableEvent.getId()] }, "");
|
||||
expect(client.sendStateEvent).toHaveBeenCalledWith(
|
||||
roomId,
|
||||
EventType.RoomPinnedEvents,
|
||||
{
|
||||
pinned: [pinnableEvent.getId()],
|
||||
},
|
||||
"",
|
||||
);
|
||||
|
||||
expect(onFinished).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('unpins event on pin option click when event is pinned', () => {
|
||||
it("unpins event on pin option click when event is pinned", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const pinnableEvent = new MatrixEvent({ ...eventContent.serialize(), room_id: roomId });
|
||||
pinnableEvent.event.event_id = '!3';
|
||||
pinnableEvent.event.event_id = "!3";
|
||||
const client = MatrixClientPeg.get();
|
||||
const room = makeDefaultRoom();
|
||||
|
||||
|
@ -194,52 +198,53 @@ describe('MessageContextMenu', () => {
|
|||
type: EventType.RoomPinnedEvents,
|
||||
room_id: roomId,
|
||||
state_key: "",
|
||||
content: { pinned: [pinnableEvent.getId(), '!another-event'] },
|
||||
content: { pinned: [pinnableEvent.getId(), "!another-event"] },
|
||||
});
|
||||
room.currentState.setStateEvents([pinEvent]);
|
||||
|
||||
// mock permission to allow adding pinned messages to room
|
||||
jest.spyOn(room.currentState, 'mayClientSendStateEvent').mockReturnValue(true);
|
||||
jest.spyOn(room.currentState, "mayClientSendStateEvent").mockReturnValue(true);
|
||||
|
||||
// mock read pins account data
|
||||
const pinsAccountData = new MatrixEvent({ content: { event_ids: ['!1', '!2'] } });
|
||||
jest.spyOn(room, 'getAccountData').mockReturnValue(pinsAccountData);
|
||||
const pinsAccountData = new MatrixEvent({ content: { event_ids: ["!1", "!2"] } });
|
||||
jest.spyOn(room, "getAccountData").mockReturnValue(pinsAccountData);
|
||||
|
||||
const menu = createMenu(pinnableEvent, {}, {}, undefined, room);
|
||||
|
||||
act(() => {
|
||||
menu.find('div[aria-label="Unpin"]').simulate('click');
|
||||
menu.find('div[aria-label="Unpin"]').simulate("click");
|
||||
});
|
||||
|
||||
expect(client.setRoomAccountData).not.toHaveBeenCalled();
|
||||
|
||||
// add to room's pins
|
||||
expect(client.sendStateEvent).toHaveBeenCalledWith(
|
||||
roomId, EventType.RoomPinnedEvents,
|
||||
roomId,
|
||||
EventType.RoomPinnedEvents,
|
||||
// pinnableEvent's id removed, other pins intact
|
||||
{ pinned: ['!another-event'] },
|
||||
{ pinned: ["!another-event"] },
|
||||
"",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('message forwarding', () => {
|
||||
it('allows forwarding a room message', () => {
|
||||
describe("message forwarding", () => {
|
||||
it("allows forwarding a room message", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const menu = createMenuWithContent(eventContent);
|
||||
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('does not allow forwarding a poll', () => {
|
||||
it("does not allow forwarding a poll", () => {
|
||||
const eventContent = PollStartEvent.from("why?", ["42"], M_POLL_KIND_DISCLOSED);
|
||||
const menu = createMenuWithContent(eventContent);
|
||||
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
describe('forwarding beacons', () => {
|
||||
describe("forwarding beacons", () => {
|
||||
const aliceId = "@alice:server.org";
|
||||
|
||||
it('does not allow forwarding a beacon that is not live', () => {
|
||||
it("does not allow forwarding a beacon that is not live", () => {
|
||||
const deadBeaconEvent = makeBeaconInfoEvent(aliceId, roomId, { isLive: false });
|
||||
const beacon = new Beacon(deadBeaconEvent);
|
||||
const beacons = new Map<BeaconIdentifier, Beacon>();
|
||||
|
@ -248,11 +253,12 @@ describe('MessageContextMenu', () => {
|
|||
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('does not allow forwarding a beacon that is not live but has a latestLocation', () => {
|
||||
it("does not allow forwarding a beacon that is not live but has a latestLocation", () => {
|
||||
const deadBeaconEvent = makeBeaconInfoEvent(aliceId, roomId, { isLive: false });
|
||||
const beaconLocation = makeBeaconEvent(
|
||||
aliceId, { beaconInfoId: deadBeaconEvent.getId(), geoUri: 'geo:51,41' },
|
||||
);
|
||||
const beaconLocation = makeBeaconEvent(aliceId, {
|
||||
beaconInfoId: deadBeaconEvent.getId(),
|
||||
geoUri: "geo:51,41",
|
||||
});
|
||||
const beacon = new Beacon(deadBeaconEvent);
|
||||
// @ts-ignore illegally set private prop
|
||||
beacon._latestLocationEvent = beaconLocation;
|
||||
|
@ -262,7 +268,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('does not allow forwarding a live beacon that does not have a latestLocation', () => {
|
||||
it("does not allow forwarding a live beacon that does not have a latestLocation", () => {
|
||||
const beaconEvent = makeBeaconInfoEvent(aliceId, roomId, { isLive: true });
|
||||
|
||||
const beacon = new Beacon(beaconEvent);
|
||||
|
@ -272,11 +278,12 @@ describe('MessageContextMenu', () => {
|
|||
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('allows forwarding a live beacon that has a location', () => {
|
||||
it("allows forwarding a live beacon that has a location", () => {
|
||||
const liveBeaconEvent = makeBeaconInfoEvent(aliceId, roomId, { isLive: true });
|
||||
const beaconLocation = makeBeaconEvent(
|
||||
aliceId, { beaconInfoId: liveBeaconEvent.getId(), geoUri: 'geo:51,41' },
|
||||
);
|
||||
const beaconLocation = makeBeaconEvent(aliceId, {
|
||||
beaconInfoId: liveBeaconEvent.getId(),
|
||||
geoUri: "geo:51,41",
|
||||
});
|
||||
const beacon = new Beacon(liveBeaconEvent);
|
||||
// @ts-ignore illegally set private prop
|
||||
beacon._latestLocationEvent = beaconLocation;
|
||||
|
@ -286,12 +293,13 @@ describe('MessageContextMenu', () => {
|
|||
expect(menu.find('div[aria-label="Forward"]')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('opens forward dialog with correct event', () => {
|
||||
const dispatchSpy = jest.spyOn(dispatcher, 'dispatch');
|
||||
it("opens forward dialog with correct event", () => {
|
||||
const dispatchSpy = jest.spyOn(dispatcher, "dispatch");
|
||||
const liveBeaconEvent = makeBeaconInfoEvent(aliceId, roomId, { isLive: true });
|
||||
const beaconLocation = makeBeaconEvent(
|
||||
aliceId, { beaconInfoId: liveBeaconEvent.getId(), geoUri: 'geo:51,41' },
|
||||
);
|
||||
const beaconLocation = makeBeaconEvent(aliceId, {
|
||||
beaconInfoId: liveBeaconEvent.getId(),
|
||||
geoUri: "geo:51,41",
|
||||
});
|
||||
const beacon = new Beacon(liveBeaconEvent);
|
||||
// @ts-ignore illegally set private prop
|
||||
beacon._latestLocationEvent = beaconLocation;
|
||||
|
@ -300,26 +308,28 @@ describe('MessageContextMenu', () => {
|
|||
const menu = createMenu(liveBeaconEvent, {}, {}, beacons);
|
||||
|
||||
act(() => {
|
||||
menu.find('div[aria-label="Forward"]').simulate('click');
|
||||
menu.find('div[aria-label="Forward"]').simulate("click");
|
||||
});
|
||||
|
||||
// called with forwardableEvent, not beaconInfo event
|
||||
expect(dispatchSpy).toHaveBeenCalledWith(expect.objectContaining({
|
||||
event: beaconLocation,
|
||||
}));
|
||||
expect(dispatchSpy).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
event: beaconLocation,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('open as map link', () => {
|
||||
it('does not allow opening a plain message in open street maps', () => {
|
||||
describe("open as map link", () => {
|
||||
it("does not allow opening a plain message in open street maps", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const menu = createMenuWithContent(eventContent);
|
||||
expect(menu.find('a[aria-label="Open in OpenStreetMap"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('does not allow opening a beacon that does not have a shareable location event', () => {
|
||||
const deadBeaconEvent = makeBeaconInfoEvent('@alice', roomId, { isLive: false });
|
||||
it("does not allow opening a beacon that does not have a shareable location event", () => {
|
||||
const deadBeaconEvent = makeBeaconInfoEvent("@alice", roomId, { isLive: false });
|
||||
const beacon = new Beacon(deadBeaconEvent);
|
||||
const beacons = new Map<BeaconIdentifier, Beacon>();
|
||||
beacons.set(getBeaconInfoIdentifier(deadBeaconEvent), beacon);
|
||||
|
@ -327,20 +337,21 @@ describe('MessageContextMenu', () => {
|
|||
expect(menu.find('a[aria-label="Open in OpenStreetMap"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('allows opening a location event in open street map', () => {
|
||||
const locationEvent = makeLocationEvent('geo:50,50');
|
||||
it("allows opening a location event in open street map", () => {
|
||||
const locationEvent = makeLocationEvent("geo:50,50");
|
||||
const menu = createMenu(locationEvent);
|
||||
// exists with a href with the lat/lon from the location event
|
||||
expect(
|
||||
menu.find('a[aria-label="Open in OpenStreetMap"]').at(0).props().href,
|
||||
).toEqual('https://www.openstreetmap.org/?mlat=50&mlon=50#map=16/50/50');
|
||||
expect(menu.find('a[aria-label="Open in OpenStreetMap"]').at(0).props().href).toEqual(
|
||||
"https://www.openstreetmap.org/?mlat=50&mlon=50#map=16/50/50",
|
||||
);
|
||||
});
|
||||
|
||||
it('allows opening a beacon that has a shareable location event', () => {
|
||||
const liveBeaconEvent = makeBeaconInfoEvent('@alice', roomId, { isLive: true });
|
||||
const beaconLocation = makeBeaconEvent(
|
||||
'@alice', { beaconInfoId: liveBeaconEvent.getId(), geoUri: 'geo:51,41' },
|
||||
);
|
||||
it("allows opening a beacon that has a shareable location event", () => {
|
||||
const liveBeaconEvent = makeBeaconInfoEvent("@alice", roomId, { isLive: true });
|
||||
const beaconLocation = makeBeaconEvent("@alice", {
|
||||
beaconInfoId: liveBeaconEvent.getId(),
|
||||
geoUri: "geo:51,41",
|
||||
});
|
||||
const beacon = new Beacon(liveBeaconEvent);
|
||||
// @ts-ignore illegally set private prop
|
||||
beacon._latestLocationEvent = beaconLocation;
|
||||
|
@ -348,14 +359,14 @@ describe('MessageContextMenu', () => {
|
|||
beacons.set(getBeaconInfoIdentifier(liveBeaconEvent), beacon);
|
||||
const menu = createMenu(liveBeaconEvent, {}, {}, beacons);
|
||||
// exists with a href with the lat/lon from the location event
|
||||
expect(
|
||||
menu.find('a[aria-label="Open in OpenStreetMap"]').at(0).props().href,
|
||||
).toEqual('https://www.openstreetmap.org/?mlat=51&mlon=41#map=16/51/41');
|
||||
expect(menu.find('a[aria-label="Open in OpenStreetMap"]').at(0).props().href).toEqual(
|
||||
"https://www.openstreetmap.org/?mlat=51&mlon=41#map=16/51/41",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("right click", () => {
|
||||
it('copy button does work as expected', () => {
|
||||
it("copy button does work as expected", () => {
|
||||
const text = "hello";
|
||||
const eventContent = MessageEvent.from(text);
|
||||
mocked(getSelectedText).mockReturnValue(text);
|
||||
|
@ -366,7 +377,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(copyPlaintext).toHaveBeenCalledWith(text);
|
||||
});
|
||||
|
||||
it('copy button is not shown when there is nothing to copy', () => {
|
||||
it("copy button is not shown when there is nothing to copy", () => {
|
||||
const text = "hello";
|
||||
const eventContent = MessageEvent.from(text);
|
||||
mocked(getSelectedText).mockReturnValue("");
|
||||
|
@ -376,7 +387,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(copyButton).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('shows edit button when we can edit', () => {
|
||||
it("shows edit button when we can edit", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
mocked(canEditContent).mockReturnValue(true);
|
||||
|
||||
|
@ -385,7 +396,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(editButton).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('does not show edit button when we cannot edit', () => {
|
||||
it("does not show edit button when we cannot edit", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
mocked(canEditContent).mockReturnValue(false);
|
||||
|
||||
|
@ -394,7 +405,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(editButton).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('shows reply button when we can reply', () => {
|
||||
it("shows reply button when we can reply", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const context = {
|
||||
canSendMessages: true,
|
||||
|
@ -405,7 +416,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(replyButton).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('does not show reply button when we cannot reply', () => {
|
||||
it("does not show reply button when we cannot reply", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const context = {
|
||||
canSendMessages: true,
|
||||
|
@ -419,7 +430,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(replyButton).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('shows react button when we can react', () => {
|
||||
it("shows react button when we can react", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const context = {
|
||||
canReact: true,
|
||||
|
@ -430,7 +441,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(reactButton).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('does not show react button when we cannot react', () => {
|
||||
it("does not show react button when we cannot react", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const context = {
|
||||
canReact: false,
|
||||
|
@ -441,10 +452,10 @@ describe('MessageContextMenu', () => {
|
|||
expect(reactButton).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('shows view in room button when the event is a thread root', () => {
|
||||
it("shows view in room button when the event is a thread root", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const mxEvent = new MatrixEvent(eventContent.serialize());
|
||||
mxEvent.getThread = () => ({ rootEvent: mxEvent }) as Thread;
|
||||
mxEvent.getThread = () => ({ rootEvent: mxEvent } as Thread);
|
||||
const props = {
|
||||
rightClick: true,
|
||||
};
|
||||
|
@ -457,7 +468,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(reactButton).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('does not show view in room button when the event is not a thread root', () => {
|
||||
it("does not show view in room button when the event is not a thread root", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
|
||||
const menu = createRightClickMenuWithContent(eventContent);
|
||||
|
@ -465,7 +476,7 @@ describe('MessageContextMenu', () => {
|
|||
expect(reactButton).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('creates a new thread on reply in thread click', () => {
|
||||
it("creates a new thread on reply in thread click", () => {
|
||||
const eventContent = MessageEvent.from("hello");
|
||||
const mxEvent = new MatrixEvent(eventContent.serialize());
|
||||
|
||||
|
@ -473,7 +484,7 @@ describe('MessageContextMenu', () => {
|
|||
const context = {
|
||||
canSendMessages: true,
|
||||
};
|
||||
jest.spyOn(SettingsStore, 'getValue').mockReturnValue(true);
|
||||
jest.spyOn(SettingsStore, "getValue").mockReturnValue(true);
|
||||
|
||||
const menu = createRightClickMenu(mxEvent, context);
|
||||
|
||||
|
@ -490,10 +501,7 @@ describe('MessageContextMenu', () => {
|
|||
});
|
||||
});
|
||||
|
||||
function createRightClickMenuWithContent(
|
||||
eventContent: ExtensibleEvent,
|
||||
context?: Partial<IRoomState>,
|
||||
): ReactWrapper {
|
||||
function createRightClickMenuWithContent(eventContent: ExtensibleEvent, context?: Partial<IRoomState>): ReactWrapper {
|
||||
return createMenuWithContent(eventContent, { rightClick: true }, context);
|
||||
}
|
||||
|
||||
|
@ -511,14 +519,9 @@ function createMenuWithContent(
|
|||
}
|
||||
|
||||
function makeDefaultRoom(): Room {
|
||||
return new Room(
|
||||
roomId,
|
||||
MatrixClientPeg.get(),
|
||||
"@user:example.com",
|
||||
{
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
},
|
||||
);
|
||||
return new Room(roomId, MatrixClientPeg.get(), "@user:example.com", {
|
||||
pendingEventOrdering: PendingEventOrdering.Detached,
|
||||
});
|
||||
}
|
||||
|
||||
function createMenu(
|
||||
|
@ -540,12 +543,7 @@ function createMenu(
|
|||
|
||||
return mount(
|
||||
<RoomContext.Provider value={context as IRoomState}>
|
||||
<MessageContextMenu
|
||||
chevronFace={null}
|
||||
mxEvent={mxEvent}
|
||||
onFinished={jest.fn()}
|
||||
{...props}
|
||||
/>
|
||||
<MessageContextMenu chevronFace={null} mxEvent={mxEvent} onFinished={jest.fn()} {...props} />
|
||||
</RoomContext.Provider>,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,33 +14,33 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React from "react";
|
||||
// eslint-disable-next-line deprecate/import
|
||||
import { mount } from 'enzyme';
|
||||
import { Room } from 'matrix-js-sdk/src/matrix';
|
||||
import { mocked } from 'jest-mock';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import 'focus-visible'; // to fix context menus
|
||||
import { mount } from "enzyme";
|
||||
import { Room } from "matrix-js-sdk/src/matrix";
|
||||
import { mocked } from "jest-mock";
|
||||
import { act } from "react-dom/test-utils";
|
||||
import "focus-visible"; // to fix context menus
|
||||
|
||||
import SpaceContextMenu from '../../../../src/components/views/context_menus/SpaceContextMenu';
|
||||
import MatrixClientContext from '../../../../src/contexts/MatrixClientContext';
|
||||
import { findByTestId } from '../../../test-utils';
|
||||
import SpaceContextMenu from "../../../../src/components/views/context_menus/SpaceContextMenu";
|
||||
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
||||
import { findByTestId } from "../../../test-utils";
|
||||
import {
|
||||
shouldShowSpaceSettings,
|
||||
showCreateNewRoom,
|
||||
showCreateNewSubspace,
|
||||
showSpaceInvite,
|
||||
showSpaceSettings,
|
||||
} from '../../../../src/utils/space';
|
||||
} from "../../../../src/utils/space";
|
||||
import { leaveSpace } from "../../../../src/utils/leave-behaviour";
|
||||
import { shouldShowComponent } from '../../../../src/customisations/helpers/UIComponents';
|
||||
import { UIComponent } from '../../../../src/settings/UIFeature';
|
||||
import { shouldShowComponent } from "../../../../src/customisations/helpers/UIComponents";
|
||||
import { UIComponent } from "../../../../src/settings/UIFeature";
|
||||
|
||||
jest.mock('../../../../src/customisations/helpers/UIComponents', () => ({
|
||||
jest.mock("../../../../src/customisations/helpers/UIComponents", () => ({
|
||||
shouldShowComponent: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../../../../src/utils/space', () => ({
|
||||
jest.mock("../../../../src/utils/space", () => ({
|
||||
shouldShowSpaceSettings: jest.fn(),
|
||||
showCreateNewRoom: jest.fn(),
|
||||
showCreateNewSubspace: jest.fn(),
|
||||
|
@ -49,172 +49,172 @@ jest.mock('../../../../src/utils/space', () => ({
|
|||
showSpaceSettings: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('../../../../src/utils/leave-behaviour', () => ({
|
||||
jest.mock("../../../../src/utils/leave-behaviour", () => ({
|
||||
leaveSpace: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('<SpaceContextMenu />', () => {
|
||||
const userId = '@test:server';
|
||||
describe("<SpaceContextMenu />", () => {
|
||||
const userId = "@test:server";
|
||||
const mockClient = {
|
||||
getUserId: jest.fn().mockReturnValue(userId),
|
||||
};
|
||||
const makeMockSpace = (props = {}) => ({
|
||||
name: 'test space',
|
||||
getJoinRule: jest.fn(),
|
||||
canInvite: jest.fn(),
|
||||
currentState: {
|
||||
maySendStateEvent: jest.fn(),
|
||||
},
|
||||
client: mockClient,
|
||||
getMyMembership: jest.fn(),
|
||||
...props,
|
||||
}) as unknown as Room;
|
||||
const makeMockSpace = (props = {}) =>
|
||||
({
|
||||
name: "test space",
|
||||
getJoinRule: jest.fn(),
|
||||
canInvite: jest.fn(),
|
||||
currentState: {
|
||||
maySendStateEvent: jest.fn(),
|
||||
},
|
||||
client: mockClient,
|
||||
getMyMembership: jest.fn(),
|
||||
...props,
|
||||
} as unknown as Room);
|
||||
const defaultProps = {
|
||||
space: makeMockSpace(),
|
||||
onFinished: jest.fn(),
|
||||
};
|
||||
const getComponent = (props = {}) =>
|
||||
mount(<SpaceContextMenu {...defaultProps} {...props} />,
|
||||
{
|
||||
wrappingComponent: MatrixClientContext.Provider,
|
||||
wrappingComponentProps: {
|
||||
value: mockClient,
|
||||
},
|
||||
});
|
||||
mount(<SpaceContextMenu {...defaultProps} {...props} />, {
|
||||
wrappingComponent: MatrixClientContext.Provider,
|
||||
wrappingComponentProps: {
|
||||
value: mockClient,
|
||||
},
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
mockClient.getUserId.mockReturnValue(userId);
|
||||
});
|
||||
|
||||
it('renders menu correctly', () => {
|
||||
it("renders menu correctly", () => {
|
||||
const component = getComponent();
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders invite option when space is public', () => {
|
||||
it("renders invite option when space is public", () => {
|
||||
const space = makeMockSpace({
|
||||
getJoinRule: jest.fn().mockReturnValue('public'),
|
||||
getJoinRule: jest.fn().mockReturnValue("public"),
|
||||
});
|
||||
const component = getComponent({ space });
|
||||
expect(findByTestId(component, 'invite-option').length).toBeTruthy();
|
||||
expect(findByTestId(component, "invite-option").length).toBeTruthy();
|
||||
});
|
||||
it('renders invite option when user is has invite rights for space', () => {
|
||||
it("renders invite option when user is has invite rights for space", () => {
|
||||
const space = makeMockSpace({
|
||||
canInvite: jest.fn().mockReturnValue(true),
|
||||
});
|
||||
const component = getComponent({ space });
|
||||
expect(space.canInvite).toHaveBeenCalledWith(userId);
|
||||
expect(findByTestId(component, 'invite-option').length).toBeTruthy();
|
||||
expect(findByTestId(component, "invite-option").length).toBeTruthy();
|
||||
});
|
||||
it('opens invite dialog when invite option is clicked', () => {
|
||||
it("opens invite dialog when invite option is clicked", () => {
|
||||
const space = makeMockSpace({
|
||||
getJoinRule: jest.fn().mockReturnValue('public'),
|
||||
getJoinRule: jest.fn().mockReturnValue("public"),
|
||||
});
|
||||
const onFinished = jest.fn();
|
||||
const component = getComponent({ space, onFinished });
|
||||
|
||||
act(() => {
|
||||
findByTestId(component, 'invite-option').at(0).simulate('click');
|
||||
findByTestId(component, "invite-option").at(0).simulate("click");
|
||||
});
|
||||
|
||||
expect(showSpaceInvite).toHaveBeenCalledWith(space);
|
||||
expect(onFinished).toHaveBeenCalled();
|
||||
});
|
||||
it('renders space settings option when user has rights', () => {
|
||||
it("renders space settings option when user has rights", () => {
|
||||
mocked(shouldShowSpaceSettings).mockReturnValue(true);
|
||||
const component = getComponent();
|
||||
expect(shouldShowSpaceSettings).toHaveBeenCalledWith(defaultProps.space);
|
||||
expect(findByTestId(component, 'settings-option').length).toBeTruthy();
|
||||
expect(findByTestId(component, "settings-option").length).toBeTruthy();
|
||||
});
|
||||
it('opens space settings when space settings option is clicked', () => {
|
||||
it("opens space settings when space settings option is clicked", () => {
|
||||
mocked(shouldShowSpaceSettings).mockReturnValue(true);
|
||||
const onFinished = jest.fn();
|
||||
const component = getComponent({ onFinished });
|
||||
|
||||
act(() => {
|
||||
findByTestId(component, 'settings-option').at(0).simulate('click');
|
||||
findByTestId(component, "settings-option").at(0).simulate("click");
|
||||
});
|
||||
|
||||
expect(showSpaceSettings).toHaveBeenCalledWith(defaultProps.space);
|
||||
expect(onFinished).toHaveBeenCalled();
|
||||
});
|
||||
it('renders leave option when user does not have rights to see space settings', () => {
|
||||
it("renders leave option when user does not have rights to see space settings", () => {
|
||||
const component = getComponent();
|
||||
expect(findByTestId(component, 'leave-option').length).toBeTruthy();
|
||||
expect(findByTestId(component, "leave-option").length).toBeTruthy();
|
||||
});
|
||||
it('leaves space when leave option is clicked', () => {
|
||||
it("leaves space when leave option is clicked", () => {
|
||||
const onFinished = jest.fn();
|
||||
const component = getComponent({ onFinished });
|
||||
act(() => {
|
||||
findByTestId(component, 'leave-option').at(0).simulate('click');
|
||||
findByTestId(component, "leave-option").at(0).simulate("click");
|
||||
});
|
||||
expect(leaveSpace).toHaveBeenCalledWith(defaultProps.space);
|
||||
expect(onFinished).toHaveBeenCalled();
|
||||
});
|
||||
describe('add children section', () => {
|
||||
describe("add children section", () => {
|
||||
const space = makeMockSpace();
|
||||
beforeEach(() => {
|
||||
// set space to allow adding children to space
|
||||
mocked(space.currentState.maySendStateEvent).mockReturnValue(true);
|
||||
mocked(shouldShowComponent).mockReturnValue(true);
|
||||
});
|
||||
it('does not render section when user does not have permission to add children', () => {
|
||||
it("does not render section when user does not have permission to add children", () => {
|
||||
mocked(space.currentState.maySendStateEvent).mockReturnValue(false);
|
||||
const component = getComponent({ space });
|
||||
|
||||
expect(findByTestId(component, 'add-to-space-header').length).toBeFalsy();
|
||||
expect(findByTestId(component, 'new-room-option').length).toBeFalsy();
|
||||
expect(findByTestId(component, 'new-subspace-option').length).toBeFalsy();
|
||||
expect(findByTestId(component, "add-to-space-header").length).toBeFalsy();
|
||||
expect(findByTestId(component, "new-room-option").length).toBeFalsy();
|
||||
expect(findByTestId(component, "new-subspace-option").length).toBeFalsy();
|
||||
});
|
||||
it('does not render section when UIComponent customisations disable room and space creation', () => {
|
||||
it("does not render section when UIComponent customisations disable room and space creation", () => {
|
||||
mocked(shouldShowComponent).mockReturnValue(false);
|
||||
const component = getComponent({ space });
|
||||
|
||||
expect(shouldShowComponent).toHaveBeenCalledWith(UIComponent.CreateRooms);
|
||||
expect(shouldShowComponent).toHaveBeenCalledWith(UIComponent.CreateSpaces);
|
||||
|
||||
expect(findByTestId(component, 'add-to-space-header').length).toBeFalsy();
|
||||
expect(findByTestId(component, 'new-room-option').length).toBeFalsy();
|
||||
expect(findByTestId(component, 'new-subspace-option').length).toBeFalsy();
|
||||
expect(findByTestId(component, "add-to-space-header").length).toBeFalsy();
|
||||
expect(findByTestId(component, "new-room-option").length).toBeFalsy();
|
||||
expect(findByTestId(component, "new-subspace-option").length).toBeFalsy();
|
||||
});
|
||||
|
||||
it('renders section with add room button when UIComponent customisation allows CreateRoom', () => {
|
||||
it("renders section with add room button when UIComponent customisation allows CreateRoom", () => {
|
||||
// only allow CreateRoom
|
||||
mocked(shouldShowComponent).mockImplementation(feature => feature === UIComponent.CreateRooms);
|
||||
mocked(shouldShowComponent).mockImplementation((feature) => feature === UIComponent.CreateRooms);
|
||||
const component = getComponent({ space });
|
||||
|
||||
expect(findByTestId(component, 'add-to-space-header').length).toBeTruthy();
|
||||
expect(findByTestId(component, 'new-room-option').length).toBeTruthy();
|
||||
expect(findByTestId(component, 'new-subspace-option').length).toBeFalsy();
|
||||
expect(findByTestId(component, "add-to-space-header").length).toBeTruthy();
|
||||
expect(findByTestId(component, "new-room-option").length).toBeTruthy();
|
||||
expect(findByTestId(component, "new-subspace-option").length).toBeFalsy();
|
||||
});
|
||||
|
||||
it('renders section with add space button when UIComponent customisation allows CreateSpace', () => {
|
||||
it("renders section with add space button when UIComponent customisation allows CreateSpace", () => {
|
||||
// only allow CreateSpaces
|
||||
mocked(shouldShowComponent).mockImplementation(feature => feature === UIComponent.CreateSpaces);
|
||||
mocked(shouldShowComponent).mockImplementation((feature) => feature === UIComponent.CreateSpaces);
|
||||
const component = getComponent({ space });
|
||||
|
||||
expect(findByTestId(component, 'add-to-space-header').length).toBeTruthy();
|
||||
expect(findByTestId(component, 'new-room-option').length).toBeFalsy();
|
||||
expect(findByTestId(component, 'new-subspace-option').length).toBeTruthy();
|
||||
expect(findByTestId(component, "add-to-space-header").length).toBeTruthy();
|
||||
expect(findByTestId(component, "new-room-option").length).toBeFalsy();
|
||||
expect(findByTestId(component, "new-subspace-option").length).toBeTruthy();
|
||||
});
|
||||
|
||||
it('opens create room dialog on add room button click', () => {
|
||||
it("opens create room dialog on add room button click", () => {
|
||||
const onFinished = jest.fn();
|
||||
const component = getComponent({ space, onFinished });
|
||||
|
||||
act(() => {
|
||||
findByTestId(component, 'new-room-option').at(0).simulate('click');
|
||||
findByTestId(component, "new-room-option").at(0).simulate("click");
|
||||
});
|
||||
expect(showCreateNewRoom).toHaveBeenCalledWith(space);
|
||||
expect(onFinished).toHaveBeenCalled();
|
||||
});
|
||||
it('opens create space dialog on add space button click', () => {
|
||||
it("opens create space dialog on add space button click", () => {
|
||||
const onFinished = jest.fn();
|
||||
const component = getComponent({ space, onFinished });
|
||||
|
||||
act(() => {
|
||||
findByTestId(component, 'new-subspace-option').at(0).simulate('click');
|
||||
findByTestId(component, "new-subspace-option").at(0).simulate("click");
|
||||
});
|
||||
expect(showCreateNewSubspace).toHaveBeenCalledWith(space);
|
||||
expect(onFinished).toHaveBeenCalled();
|
||||
|
|
|
@ -38,10 +38,7 @@ describe("ThreadListContextMenu", () => {
|
|||
let event: MatrixEvent;
|
||||
|
||||
function getComponent(props: Partial<ThreadListContextMenuProps>) {
|
||||
return render(<ThreadListContextMenu
|
||||
mxEvent={event}
|
||||
{...props}
|
||||
/>);
|
||||
return render(<ThreadListContextMenu mxEvent={event} {...props} />);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue