2022-01-28 15:44:03 +00:00
|
|
|
/*
|
|
|
|
Copyright 2022 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";
|
2022-08-02 13:10:43 +00:00
|
|
|
// eslint-disable-next-line deprecate/import
|
2022-01-28 15:44:03 +00:00
|
|
|
import { mount, ReactWrapper } from "enzyme";
|
|
|
|
import { Room } from "matrix-js-sdk/src/models/room";
|
|
|
|
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
|
|
|
|
|
|
|
|
import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
|
|
|
|
import { Layout } from "../../../../src/settings/enums/Layout";
|
|
|
|
import RoomContext, { TimelineRenderingType } from "../../../../src/contexts/RoomContext";
|
|
|
|
import { createTestClient } from "../../../test-utils";
|
|
|
|
import { IRoomState } from "../../../../src/components/structures/RoomView";
|
|
|
|
import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
2022-03-02 21:09:24 +00:00
|
|
|
import MessageComposerButtons from "../../../../src/components/views/rooms/MessageComposerButtons";
|
2022-01-28 15:44:03 +00:00
|
|
|
|
2022-03-25 02:11:56 +00:00
|
|
|
// @ts-ignore - we're deliberately not implementing the whole interface here, but
|
|
|
|
// can't use Partial<> for types because it'll annoy TS more than it helps.
|
|
|
|
const mockProps: React.ComponentProps<typeof MessageComposerButtons> = {
|
|
|
|
addEmoji: () => false,
|
|
|
|
haveRecording: false,
|
|
|
|
isStickerPickerOpen: false,
|
2022-09-16 09:10:33 +00:00
|
|
|
menuPosition: undefined,
|
2022-03-25 02:11:56 +00:00
|
|
|
onRecordStartEndClick: () => {},
|
|
|
|
setStickerPickerOpen: () => {},
|
|
|
|
toggleButtonMenu: () => {},
|
|
|
|
};
|
|
|
|
|
2022-01-28 15:44:03 +00:00
|
|
|
describe("MessageComposerButtons", () => {
|
2022-02-02 09:30:53 +00:00
|
|
|
it("Renders emoji and upload buttons in wide mode", () => {
|
2022-01-28 15:44:03 +00:00
|
|
|
const buttons = wrapAndRender(
|
|
|
|
<MessageComposerButtons
|
2022-09-16 09:10:33 +00:00
|
|
|
{...mockProps}
|
2022-01-28 15:44:03 +00:00
|
|
|
isMenuOpen={false}
|
|
|
|
showLocationButton={true}
|
2022-03-04 18:04:30 +00:00
|
|
|
showPollsButton={true}
|
2022-01-28 15:44:03 +00:00
|
|
|
showStickersButton={true}
|
2022-02-02 09:30:53 +00:00
|
|
|
/>,
|
2022-02-23 14:03:46 +00:00
|
|
|
false,
|
2022-02-02 09:30:53 +00:00
|
|
|
);
|
|
|
|
|
2022-12-12 11:24:14 +00:00
|
|
|
expect(buttonLabels(buttons)).toEqual(["Emoji", "Attachment", "More options"]);
|
2022-02-02 09:30:53 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it("Renders other buttons in menu in wide mode", () => {
|
|
|
|
const buttons = wrapAndRender(
|
|
|
|
<MessageComposerButtons
|
2022-09-16 09:10:33 +00:00
|
|
|
{...mockProps}
|
2022-02-02 09:30:53 +00:00
|
|
|
isMenuOpen={true}
|
|
|
|
showLocationButton={true}
|
2022-03-04 18:04:30 +00:00
|
|
|
showPollsButton={true}
|
2022-02-02 09:30:53 +00:00
|
|
|
showStickersButton={true}
|
2022-01-28 15:44:03 +00:00
|
|
|
/>,
|
2022-02-23 14:03:46 +00:00
|
|
|
false,
|
2022-01-28 15:44:03 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
expect(buttonLabels(buttons)).toEqual([
|
2022-02-02 09:30:53 +00:00
|
|
|
"Emoji",
|
|
|
|
"Attachment",
|
|
|
|
"More options",
|
2022-12-12 11:24:14 +00:00
|
|
|
["Sticker", "Voice Message", "Poll", "Location"],
|
2022-01-28 15:44:03 +00:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("Renders only some buttons in narrow mode", () => {
|
|
|
|
const buttons = wrapAndRender(
|
|
|
|
<MessageComposerButtons
|
2022-09-16 09:10:33 +00:00
|
|
|
{...mockProps}
|
2022-01-28 15:44:03 +00:00
|
|
|
isMenuOpen={false}
|
|
|
|
showLocationButton={true}
|
2022-03-04 18:04:30 +00:00
|
|
|
showPollsButton={true}
|
2022-01-28 15:44:03 +00:00
|
|
|
showStickersButton={true}
|
|
|
|
/>,
|
2022-02-23 14:03:46 +00:00
|
|
|
true,
|
2022-01-28 15:44:03 +00:00
|
|
|
);
|
|
|
|
|
2022-12-12 11:24:14 +00:00
|
|
|
expect(buttonLabels(buttons)).toEqual(["Emoji", "More options"]);
|
2022-01-28 15:44:03 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
it("Renders other buttons in menu (except voice messages) in narrow mode", () => {
|
|
|
|
const buttons = wrapAndRender(
|
|
|
|
<MessageComposerButtons
|
2022-09-16 09:10:33 +00:00
|
|
|
{...mockProps}
|
2022-01-28 15:44:03 +00:00
|
|
|
isMenuOpen={true}
|
|
|
|
showLocationButton={true}
|
2022-03-04 18:04:30 +00:00
|
|
|
showPollsButton={true}
|
2022-01-28 15:44:03 +00:00
|
|
|
showStickersButton={true}
|
|
|
|
/>,
|
2022-02-23 14:03:46 +00:00
|
|
|
true,
|
2022-01-28 15:44:03 +00:00
|
|
|
);
|
|
|
|
|
2022-12-12 11:24:14 +00:00
|
|
|
expect(buttonLabels(buttons)).toEqual(["Emoji", "More options", ["Attachment", "Sticker", "Poll", "Location"]]);
|
2022-01-28 15:44:03 +00:00
|
|
|
});
|
2022-03-04 18:04:30 +00:00
|
|
|
|
2022-12-12 11:24:14 +00:00
|
|
|
describe("polls button", () => {
|
|
|
|
it("should render when asked to", () => {
|
2022-03-04 18:04:30 +00:00
|
|
|
const buttons = wrapAndRender(
|
|
|
|
<MessageComposerButtons
|
2022-09-16 09:10:33 +00:00
|
|
|
{...mockProps}
|
2022-03-04 18:04:30 +00:00
|
|
|
isMenuOpen={true}
|
|
|
|
showLocationButton={true}
|
|
|
|
showPollsButton={true}
|
|
|
|
showStickersButton={true}
|
|
|
|
/>,
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(buttonLabels(buttons)).toEqual([
|
|
|
|
"Emoji",
|
|
|
|
"More options",
|
2022-12-12 11:24:14 +00:00
|
|
|
["Attachment", "Sticker", "Poll", "Location"],
|
2022-03-04 18:04:30 +00:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
2022-12-12 11:24:14 +00:00
|
|
|
it("should not render when asked not to", () => {
|
2022-03-04 18:04:30 +00:00
|
|
|
const buttons = wrapAndRender(
|
|
|
|
<MessageComposerButtons
|
2022-09-16 09:10:33 +00:00
|
|
|
{...mockProps}
|
2022-03-04 18:04:30 +00:00
|
|
|
isMenuOpen={true}
|
|
|
|
showLocationButton={true}
|
|
|
|
showPollsButton={false} // !! the change from the alternate test
|
|
|
|
showStickersButton={true}
|
|
|
|
/>,
|
|
|
|
true,
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(buttonLabels(buttons)).toEqual([
|
|
|
|
"Emoji",
|
|
|
|
"More options",
|
|
|
|
[
|
|
|
|
"Attachment",
|
|
|
|
"Sticker",
|
|
|
|
// "Poll", // should be hidden
|
|
|
|
"Location",
|
|
|
|
],
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
});
|
2022-09-16 09:10:33 +00:00
|
|
|
|
|
|
|
describe("with showVoiceBroadcastButton = true", () => {
|
|
|
|
it("should render the »Voice broadcast« button", () => {
|
|
|
|
const buttons = wrapAndRender(
|
|
|
|
<MessageComposerButtons
|
|
|
|
{...mockProps}
|
|
|
|
isMenuOpen={true}
|
|
|
|
showLocationButton={true}
|
|
|
|
showPollsButton={true}
|
|
|
|
showStickersButton={true}
|
|
|
|
showVoiceBroadcastButton={true}
|
|
|
|
/>,
|
|
|
|
false,
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(buttonLabels(buttons)).toEqual([
|
|
|
|
"Emoji",
|
|
|
|
"Attachment",
|
|
|
|
"More options",
|
2022-12-12 11:24:14 +00:00
|
|
|
["Sticker", "Voice Message", "Voice broadcast", "Poll", "Location"],
|
2022-09-16 09:10:33 +00:00
|
|
|
]);
|
|
|
|
});
|
|
|
|
});
|
2022-01-28 15:44:03 +00:00
|
|
|
});
|
|
|
|
|
2022-02-23 14:03:46 +00:00
|
|
|
function wrapAndRender(component: React.ReactElement, narrow: boolean): ReactWrapper {
|
2022-03-21 09:03:03 +00:00
|
|
|
const mockClient = createTestClient();
|
2022-12-12 11:24:14 +00:00
|
|
|
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(mockClient);
|
2022-01-28 15:44:03 +00:00
|
|
|
const roomId = "myroomid";
|
|
|
|
const mockRoom: any = {
|
|
|
|
currentState: undefined,
|
|
|
|
roomId,
|
|
|
|
client: mockClient,
|
2022-12-12 11:24:14 +00:00
|
|
|
getMember: function (userId: string): RoomMember {
|
2022-01-28 15:44:03 +00:00
|
|
|
return new RoomMember(roomId, userId);
|
|
|
|
},
|
|
|
|
};
|
2022-02-23 14:03:46 +00:00
|
|
|
const roomState = createRoomState(mockRoom, narrow);
|
2022-01-28 15:44:03 +00:00
|
|
|
|
|
|
|
return mount(
|
|
|
|
<MatrixClientContext.Provider value={mockClient}>
|
2022-12-12 11:24:14 +00:00
|
|
|
<RoomContext.Provider value={roomState}>{component}</RoomContext.Provider>
|
2022-01-28 15:44:03 +00:00
|
|
|
</MatrixClientContext.Provider>,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-02-23 14:03:46 +00:00
|
|
|
function createRoomState(room: Room, narrow: boolean): IRoomState {
|
2022-01-28 15:44:03 +00:00
|
|
|
return {
|
|
|
|
room: room,
|
|
|
|
roomId: room.roomId,
|
|
|
|
roomLoading: true,
|
|
|
|
peekLoading: false,
|
|
|
|
shouldPeek: true,
|
|
|
|
membersLoaded: false,
|
|
|
|
numUnreadMessages: 0,
|
2022-06-10 18:41:05 +00:00
|
|
|
canSelfRedact: false,
|
2022-01-28 15:44:03 +00:00
|
|
|
canPeek: false,
|
|
|
|
showApps: false,
|
|
|
|
isPeeking: false,
|
|
|
|
showRightPanel: true,
|
|
|
|
joining: false,
|
|
|
|
atEndOfLiveTimeline: true,
|
|
|
|
showTopUnreadMessagesBar: false,
|
|
|
|
statusBarVisible: false,
|
|
|
|
canReact: false,
|
2022-03-04 15:53:22 +00:00
|
|
|
canSendMessages: false,
|
2022-01-28 15:44:03 +00:00
|
|
|
layout: Layout.Group,
|
|
|
|
lowBandwidth: false,
|
|
|
|
alwaysShowTimestamps: false,
|
|
|
|
showTwelveHourTimestamps: false,
|
|
|
|
readMarkerInViewThresholdMs: 3000,
|
|
|
|
readMarkerOutOfViewThresholdMs: 30000,
|
2022-04-14 23:23:22 +00:00
|
|
|
showHiddenEvents: false,
|
2022-01-28 15:44:03 +00:00
|
|
|
showReadReceipts: true,
|
|
|
|
showRedactions: true,
|
|
|
|
showJoinLeaves: true,
|
|
|
|
showAvatarChanges: true,
|
|
|
|
showDisplaynameChanges: true,
|
|
|
|
matrixClientIsReady: false,
|
|
|
|
timelineRenderingType: TimelineRenderingType.Room,
|
|
|
|
liveTimeline: undefined,
|
2022-03-22 22:40:09 +00:00
|
|
|
resizing: false,
|
2022-02-23 14:03:46 +00:00
|
|
|
narrow,
|
2022-10-07 02:27:28 +00:00
|
|
|
activeCall: null,
|
2022-01-28 15:44:03 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function buttonLabels(buttons: ReactWrapper): any[] {
|
|
|
|
// Note: Depends on the fact that the mini buttons use aria-label
|
2022-01-31 16:05:05 +00:00
|
|
|
// and the labels under More options use textContent
|
2022-12-12 11:24:14 +00:00
|
|
|
const mainButtons = buttons
|
|
|
|
.find("div.mx_MessageComposer_button[aria-label]")
|
|
|
|
.map((button: ReactWrapper) => button.prop("aria-label") as string)
|
|
|
|
.filter((x) => x);
|
2022-01-28 15:44:03 +00:00
|
|
|
|
2022-12-12 11:24:14 +00:00
|
|
|
const extraButtons = buttons
|
|
|
|
.find('.mx_MessageComposer_Menu div.mx_AccessibleButton[role="menuitem"]')
|
|
|
|
.map((button: ReactWrapper) => button.text())
|
|
|
|
.filter((x) => x);
|
2022-01-28 15:44:03 +00:00
|
|
|
|
2022-12-12 11:24:14 +00:00
|
|
|
const list: any[] = [...mainButtons];
|
2022-01-31 16:05:05 +00:00
|
|
|
|
|
|
|
if (extraButtons.length > 0) {
|
|
|
|
list.push(extraButtons);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
2022-01-28 15:44:03 +00:00
|
|
|
}
|