mirror of https://github.com/vector-im/riot-web
Remove reply fallbacks as per merged MSC2781 (#28406)
* Remove reply fallbacks as per merged MSC2781 Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Improve coverage Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>pull/28457/head
parent
73db771ff3
commit
349c9b0c26
|
@ -536,9 +536,7 @@ export default class ContentMessages {
|
||||||
attachMentions(matrixClient.getSafeUserId(), content, null, replyToEvent);
|
attachMentions(matrixClient.getSafeUserId(), content, null, replyToEvent);
|
||||||
attachRelation(content, relation);
|
attachRelation(content, relation);
|
||||||
if (replyToEvent) {
|
if (replyToEvent) {
|
||||||
addReplyToMessageContent(content, replyToEvent, {
|
addReplyToMessageContent(content, replyToEvent);
|
||||||
includeLegacyFallback: false,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SettingsStore.getValue("Performance.addSendMessageTimingMetadata")) {
|
if (SettingsStore.getValue("Performance.addSendMessageTimingMetadata")) {
|
||||||
|
|
|
@ -414,7 +414,7 @@ export class MessageComposer extends React.Component<IProps, IState> {
|
||||||
this.messageComposerInput.current?.sendMessage();
|
this.messageComposerInput.current?.sendMessage();
|
||||||
|
|
||||||
if (this.state.isWysiwygLabEnabled) {
|
if (this.state.isWysiwygLabEnabled) {
|
||||||
const { permalinkCreator, relation, replyToEvent } = this.props;
|
const { relation, replyToEvent } = this.props;
|
||||||
const composerContent = this.state.composerContent;
|
const composerContent = this.state.composerContent;
|
||||||
this.setState({ composerContent: "", initialComposerContent: "" });
|
this.setState({ composerContent: "", initialComposerContent: "" });
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
|
@ -424,7 +424,6 @@ export class MessageComposer extends React.Component<IProps, IState> {
|
||||||
await sendMessage(composerContent, this.state.isRichTextEnabled, {
|
await sendMessage(composerContent, this.state.isRichTextEnabled, {
|
||||||
mxClient: this.props.mxClient,
|
mxClient: this.props.mxClient,
|
||||||
roomContext: this.context,
|
roomContext: this.context,
|
||||||
permalinkCreator,
|
|
||||||
relation,
|
relation,
|
||||||
replyToEvent,
|
replyToEvent,
|
||||||
});
|
});
|
||||||
|
@ -582,7 +581,6 @@ export class MessageComposer extends React.Component<IProps, IState> {
|
||||||
key="controls_input"
|
key="controls_input"
|
||||||
room={this.props.room}
|
room={this.props.room}
|
||||||
placeholder={this.renderPlaceholderText()}
|
placeholder={this.renderPlaceholderText()}
|
||||||
permalinkCreator={this.props.permalinkCreator}
|
|
||||||
relation={this.props.relation}
|
relation={this.props.relation}
|
||||||
replyToEvent={this.props.replyToEvent}
|
replyToEvent={this.props.replyToEvent}
|
||||||
onChange={this.onChange}
|
onChange={this.onChange}
|
||||||
|
@ -597,7 +595,6 @@ export class MessageComposer extends React.Component<IProps, IState> {
|
||||||
key="controls_voice_record"
|
key="controls_voice_record"
|
||||||
ref={this.voiceRecordingButton}
|
ref={this.voiceRecordingButton}
|
||||||
room={this.props.room}
|
room={this.props.room}
|
||||||
permalinkCreator={this.props.permalinkCreator}
|
|
||||||
relation={this.props.relation}
|
relation={this.props.relation}
|
||||||
replyToEvent={this.props.replyToEvent}
|
replyToEvent={this.props.replyToEvent}
|
||||||
/>,
|
/>,
|
||||||
|
@ -642,8 +639,6 @@ export class MessageComposer extends React.Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let recordingTooltip: JSX.Element | undefined;
|
|
||||||
|
|
||||||
const isTooltipOpen = Boolean(this.state.recordingTimeLeftSeconds);
|
const isTooltipOpen = Boolean(this.state.recordingTimeLeftSeconds);
|
||||||
const secondsLeft = this.state.recordingTimeLeftSeconds ? Math.round(this.state.recordingTimeLeftSeconds) : 0;
|
const secondsLeft = this.state.recordingTimeLeftSeconds ? Math.round(this.state.recordingTimeLeftSeconds) : 0;
|
||||||
|
|
||||||
|
@ -673,7 +668,6 @@ export class MessageComposer extends React.Component<IProps, IState> {
|
||||||
return (
|
return (
|
||||||
<Tooltip open={isTooltipOpen} description={formatTimeLeft(secondsLeft)} placement="bottom">
|
<Tooltip open={isTooltipOpen} description={formatTimeLeft(secondsLeft)} placement="bottom">
|
||||||
<div className={classes} ref={this.ref} role="region" aria-label={_t("a11y|message_composer")}>
|
<div className={classes} ref={this.ref} role="region" aria-label={_t("a11y|message_composer")}>
|
||||||
{recordingTooltip}
|
|
||||||
<div className="mx_MessageComposer_wrapper">
|
<div className="mx_MessageComposer_wrapper">
|
||||||
<ReplyPreview
|
<ReplyPreview
|
||||||
replyToEvent={this.props.replyToEvent}
|
replyToEvent={this.props.replyToEvent}
|
||||||
|
|
|
@ -47,7 +47,6 @@ import { CHAT_EFFECTS } from "../../../effects";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
|
||||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||||
import { decorateStartSendingTime, sendRoundTripMetric } from "../../../sendTimePerformanceMetrics";
|
import { decorateStartSendingTime, sendRoundTripMetric } from "../../../sendTimePerformanceMetrics";
|
||||||
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext";
|
||||||
|
@ -177,8 +176,6 @@ export function createMessageContent(
|
||||||
model: EditorModel,
|
model: EditorModel,
|
||||||
replyToEvent: MatrixEvent | undefined,
|
replyToEvent: MatrixEvent | undefined,
|
||||||
relation: IEventRelation | undefined,
|
relation: IEventRelation | undefined,
|
||||||
permalinkCreator?: RoomPermalinkCreator,
|
|
||||||
includeReplyLegacyFallback = true,
|
|
||||||
): RoomMessageEventContent {
|
): RoomMessageEventContent {
|
||||||
const isEmote = containsEmote(model);
|
const isEmote = containsEmote(model);
|
||||||
if (isEmote) {
|
if (isEmote) {
|
||||||
|
@ -209,10 +206,7 @@ export function createMessageContent(
|
||||||
|
|
||||||
attachRelation(content, relation);
|
attachRelation(content, relation);
|
||||||
if (replyToEvent) {
|
if (replyToEvent) {
|
||||||
addReplyToMessageContent(content, replyToEvent, {
|
addReplyToMessageContent(content, replyToEvent);
|
||||||
permalinkCreator,
|
|
||||||
includeLegacyFallback: includeReplyLegacyFallback,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
|
@ -238,12 +232,10 @@ export function isQuickReaction(model: EditorModel): boolean {
|
||||||
interface ISendMessageComposerProps extends MatrixClientProps {
|
interface ISendMessageComposerProps extends MatrixClientProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
|
||||||
relation?: IEventRelation;
|
relation?: IEventRelation;
|
||||||
replyToEvent?: MatrixEvent;
|
replyToEvent?: MatrixEvent;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
onChange?(model: EditorModel): void;
|
onChange?(model: EditorModel): void;
|
||||||
includeReplyLegacyFallback?: boolean;
|
|
||||||
toggleStickerPickerOpen: () => void;
|
toggleStickerPickerOpen: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,10 +250,6 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
||||||
private dispatcherRef?: string;
|
private dispatcherRef?: string;
|
||||||
private sendHistoryManager: SendHistoryManager;
|
private sendHistoryManager: SendHistoryManager;
|
||||||
|
|
||||||
public static defaultProps = {
|
|
||||||
includeReplyLegacyFallback: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
public constructor(props: ISendMessageComposerProps, context: React.ContextType<typeof RoomContext>) {
|
public constructor(props: ISendMessageComposerProps, context: React.ContextType<typeof RoomContext>) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
||||||
|
@ -500,11 +488,7 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
||||||
attachMentions(this.props.mxClient.getSafeUserId(), content, model, replyToEvent);
|
attachMentions(this.props.mxClient.getSafeUserId(), content, model, replyToEvent);
|
||||||
attachRelation(content, this.props.relation);
|
attachRelation(content, this.props.relation);
|
||||||
if (replyToEvent) {
|
if (replyToEvent) {
|
||||||
addReplyToMessageContent(content, replyToEvent, {
|
addReplyToMessageContent(content, replyToEvent);
|
||||||
permalinkCreator: this.props.permalinkCreator,
|
|
||||||
// Exclude the legacy fallback for custom event types such as those used by /fireworks
|
|
||||||
includeLegacyFallback: content.msgtype?.startsWith("m.") ?? true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
shouldSend = false;
|
shouldSend = false;
|
||||||
|
@ -534,8 +518,6 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
|
||||||
model,
|
model,
|
||||||
replyToEvent,
|
replyToEvent,
|
||||||
this.props.relation,
|
this.props.relation,
|
||||||
this.props.permalinkCreator,
|
|
||||||
this.props.includeReplyLegacyFallback,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// don't bother sending an empty message
|
// don't bother sending an empty message
|
||||||
|
|
|
@ -31,7 +31,6 @@ import { doMaybeLocalRoomAction } from "../../../utils/local-room";
|
||||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
import { attachMentions, attachRelation } from "./SendMessageComposer";
|
import { attachMentions, attachRelation } from "./SendMessageComposer";
|
||||||
import { addReplyToMessageContent } from "../../../utils/Reply";
|
import { addReplyToMessageContent } from "../../../utils/Reply";
|
||||||
import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks";
|
|
||||||
import RoomContext from "../../../contexts/RoomContext";
|
import RoomContext from "../../../contexts/RoomContext";
|
||||||
import { IUpload, VoiceMessageRecording } from "../../../audio/VoiceMessageRecording";
|
import { IUpload, VoiceMessageRecording } from "../../../audio/VoiceMessageRecording";
|
||||||
import { createVoiceMessageContent } from "../../../utils/createVoiceMessageContent";
|
import { createVoiceMessageContent } from "../../../utils/createVoiceMessageContent";
|
||||||
|
@ -39,7 +38,6 @@ import AccessibleButton from "../elements/AccessibleButton";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
room: Room;
|
room: Room;
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
|
||||||
relation?: IEventRelation;
|
relation?: IEventRelation;
|
||||||
replyToEvent?: MatrixEvent;
|
replyToEvent?: MatrixEvent;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +91,7 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
|
||||||
throw new Error("No recording started - cannot send anything");
|
throw new Error("No recording started - cannot send anything");
|
||||||
}
|
}
|
||||||
|
|
||||||
const { replyToEvent, relation, permalinkCreator } = this.props;
|
const { replyToEvent, relation } = this.props;
|
||||||
|
|
||||||
await this.state.recorder.stop();
|
await this.state.recorder.stop();
|
||||||
|
|
||||||
|
@ -124,10 +122,7 @@ export default class VoiceRecordComposerTile extends React.PureComponent<IProps,
|
||||||
attachMentions(MatrixClientPeg.safeGet().getSafeUserId(), content, null, replyToEvent);
|
attachMentions(MatrixClientPeg.safeGet().getSafeUserId(), content, null, replyToEvent);
|
||||||
attachRelation(content, relation);
|
attachRelation(content, relation);
|
||||||
if (replyToEvent) {
|
if (replyToEvent) {
|
||||||
addReplyToMessageContent(content, replyToEvent, {
|
addReplyToMessageContent(content, replyToEvent);
|
||||||
permalinkCreator,
|
|
||||||
includeLegacyFallback: true,
|
|
||||||
});
|
|
||||||
// Clear reply_to_event as we put the message into the queue
|
// Clear reply_to_event as we put the message into the queue
|
||||||
// if the send fails, retry will handle resending.
|
// if the send fails, retry will handle resending.
|
||||||
defaultDispatcher.dispatch({
|
defaultDispatcher.dispatch({
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { IContent, IEventRelation, MatrixEvent, MsgType } from "matrix-js-sdk/sr
|
||||||
import { ReplacementEvent, RoomMessageEventContent, RoomMessageTextEventContent } from "matrix-js-sdk/src/types";
|
import { ReplacementEvent, RoomMessageEventContent, RoomMessageTextEventContent } from "matrix-js-sdk/src/types";
|
||||||
|
|
||||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||||
import { parsePermalink, RoomPermalinkCreator } from "../../../../../utils/permalinks/Permalinks";
|
import { parsePermalink } from "../../../../../utils/permalinks/Permalinks";
|
||||||
import { addReplyToMessageContent } from "../../../../../utils/Reply";
|
import { addReplyToMessageContent } from "../../../../../utils/Reply";
|
||||||
import { isNotNull } from "../../../../../Typeguards";
|
import { isNotNull } from "../../../../../Typeguards";
|
||||||
|
|
||||||
|
@ -52,8 +52,6 @@ function getTextReplyFallback(mxEvent: MatrixEvent): string {
|
||||||
interface CreateMessageContentParams {
|
interface CreateMessageContentParams {
|
||||||
relation?: IEventRelation;
|
relation?: IEventRelation;
|
||||||
replyToEvent?: MatrixEvent;
|
replyToEvent?: MatrixEvent;
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
|
||||||
includeReplyLegacyFallback?: boolean;
|
|
||||||
editedEvent?: MatrixEvent;
|
editedEvent?: MatrixEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,13 +60,7 @@ const isMatrixEvent = (e: MatrixEvent | undefined): e is MatrixEvent => e instan
|
||||||
export async function createMessageContent(
|
export async function createMessageContent(
|
||||||
message: string,
|
message: string,
|
||||||
isHTML: boolean,
|
isHTML: boolean,
|
||||||
{
|
{ relation, replyToEvent, editedEvent }: CreateMessageContentParams,
|
||||||
relation,
|
|
||||||
replyToEvent,
|
|
||||||
permalinkCreator,
|
|
||||||
includeReplyLegacyFallback = true,
|
|
||||||
editedEvent,
|
|
||||||
}: CreateMessageContentParams,
|
|
||||||
): Promise<RoomMessageEventContent> {
|
): Promise<RoomMessageEventContent> {
|
||||||
const isEditing = isMatrixEvent(editedEvent);
|
const isEditing = isMatrixEvent(editedEvent);
|
||||||
const isReply = isEditing ? Boolean(editedEvent.replyEventId) : isMatrixEvent(replyToEvent);
|
const isReply = isEditing ? Boolean(editedEvent.replyEventId) : isMatrixEvent(replyToEvent);
|
||||||
|
@ -126,11 +118,8 @@ export async function createMessageContent(
|
||||||
// TODO Handle editing?
|
// TODO Handle editing?
|
||||||
attachRelation(content, newRelation);
|
attachRelation(content, newRelation);
|
||||||
|
|
||||||
if (!isEditing && replyToEvent && permalinkCreator) {
|
if (!isEditing && replyToEvent) {
|
||||||
addReplyToMessageContent(content, replyToEvent, {
|
addReplyToMessageContent(content, replyToEvent);
|
||||||
permalinkCreator,
|
|
||||||
includeLegacyFallback: includeReplyLegacyFallback,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
|
|
|
@ -19,7 +19,6 @@ import { RoomMessageEventContent } from "matrix-js-sdk/src/types";
|
||||||
import { PosthogAnalytics } from "../../../../../PosthogAnalytics";
|
import { PosthogAnalytics } from "../../../../../PosthogAnalytics";
|
||||||
import SettingsStore from "../../../../../settings/SettingsStore";
|
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||||
import { decorateStartSendingTime, sendRoundTripMetric } from "../../../../../sendTimePerformanceMetrics";
|
import { decorateStartSendingTime, sendRoundTripMetric } from "../../../../../sendTimePerformanceMetrics";
|
||||||
import { RoomPermalinkCreator } from "../../../../../utils/permalinks/Permalinks";
|
|
||||||
import { doMaybeLocalRoomAction } from "../../../../../utils/local-room";
|
import { doMaybeLocalRoomAction } from "../../../../../utils/local-room";
|
||||||
import { CHAT_EFFECTS } from "../../../../../effects";
|
import { CHAT_EFFECTS } from "../../../../../effects";
|
||||||
import { containsEmoji } from "../../../../../effects/utils";
|
import { containsEmoji } from "../../../../../effects/utils";
|
||||||
|
@ -41,8 +40,6 @@ export interface SendMessageParams {
|
||||||
relation?: IEventRelation;
|
relation?: IEventRelation;
|
||||||
replyToEvent?: MatrixEvent;
|
replyToEvent?: MatrixEvent;
|
||||||
roomContext: IRoomState;
|
roomContext: IRoomState;
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
|
||||||
includeReplyLegacyFallback?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function sendMessage(
|
export async function sendMessage(
|
||||||
|
@ -50,7 +47,7 @@ export async function sendMessage(
|
||||||
isHTML: boolean,
|
isHTML: boolean,
|
||||||
{ roomContext, mxClient, ...params }: SendMessageParams,
|
{ roomContext, mxClient, ...params }: SendMessageParams,
|
||||||
): Promise<ISendEventResponse | undefined> {
|
): Promise<ISendEventResponse | undefined> {
|
||||||
const { relation, replyToEvent, permalinkCreator } = params;
|
const { relation, replyToEvent } = params;
|
||||||
const { room } = roomContext;
|
const { room } = roomContext;
|
||||||
const roomId = room?.roomId;
|
const roomId = room?.roomId;
|
||||||
|
|
||||||
|
@ -95,11 +92,7 @@ export async function sendMessage(
|
||||||
) {
|
) {
|
||||||
attachRelation(content, relation);
|
attachRelation(content, relation);
|
||||||
if (replyToEvent) {
|
if (replyToEvent) {
|
||||||
addReplyToMessageContent(content, replyToEvent, {
|
addReplyToMessageContent(content, replyToEvent);
|
||||||
permalinkCreator,
|
|
||||||
// Exclude the legacy fallback for custom event types such as those used by /fireworks
|
|
||||||
includeLegacyFallback: content.msgtype?.startsWith("m.") ?? true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// instead of setting shouldSend to false as in SendMessageComposer, just return
|
// instead of setting shouldSend to false as in SendMessageComposer, just return
|
||||||
|
|
|
@ -7,23 +7,10 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { IContent, IEventRelation, MatrixEvent, THREAD_RELATION_TYPE } from "matrix-js-sdk/src/matrix";
|
||||||
IContent,
|
|
||||||
IEventRelation,
|
|
||||||
MatrixEvent,
|
|
||||||
MsgType,
|
|
||||||
THREAD_RELATION_TYPE,
|
|
||||||
M_BEACON_INFO,
|
|
||||||
M_POLL_END,
|
|
||||||
M_POLL_START,
|
|
||||||
} from "matrix-js-sdk/src/matrix";
|
|
||||||
import sanitizeHtml from "sanitize-html";
|
import sanitizeHtml from "sanitize-html";
|
||||||
import escapeHtml from "escape-html";
|
|
||||||
import { PollStartEvent } from "matrix-js-sdk/src/extensible_events_v1/PollStartEvent";
|
|
||||||
|
|
||||||
import { PERMITTED_URL_SCHEMES } from "./UrlUtils";
|
import { PERMITTED_URL_SCHEMES } from "./UrlUtils";
|
||||||
import { makeUserPermalink, RoomPermalinkCreator } from "./permalinks/Permalinks";
|
|
||||||
import { isSelfLocation } from "./location";
|
|
||||||
|
|
||||||
export function getParentEventId(ev?: MatrixEvent): string | undefined {
|
export function getParentEventId(ev?: MatrixEvent): string | undefined {
|
||||||
if (!ev || ev.isRedacted()) return;
|
if (!ev || ev.isRedacted()) return;
|
||||||
|
@ -62,137 +49,6 @@ export function stripHTMLReply(html: string): string {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Part of Replies fallback support
|
|
||||||
export function getNestedReplyText(
|
|
||||||
ev: MatrixEvent,
|
|
||||||
permalinkCreator?: RoomPermalinkCreator,
|
|
||||||
): { body: string; html: string } | null {
|
|
||||||
if (!ev) return null;
|
|
||||||
|
|
||||||
let {
|
|
||||||
body,
|
|
||||||
formatted_body: html,
|
|
||||||
msgtype,
|
|
||||||
} = ev.getContent<{
|
|
||||||
body: string;
|
|
||||||
msgtype?: string;
|
|
||||||
formatted_body?: string;
|
|
||||||
}>();
|
|
||||||
if (getParentEventId(ev)) {
|
|
||||||
if (body) body = stripPlainReply(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!body) body = ""; // Always ensure we have a body, for reasons.
|
|
||||||
|
|
||||||
if (html) {
|
|
||||||
// sanitize the HTML before we put it in an <mx-reply>
|
|
||||||
html = stripHTMLReply(html);
|
|
||||||
} else {
|
|
||||||
// Escape the body to use as HTML below.
|
|
||||||
// We also run a nl2br over the result to fix the fallback representation. We do this
|
|
||||||
// after converting the text to safe HTML to avoid user-provided BR's from being converted.
|
|
||||||
html = escapeHtml(body).replace(/\n/g, "<br/>");
|
|
||||||
}
|
|
||||||
|
|
||||||
// dev note: do not rely on `body` being safe for HTML usage below.
|
|
||||||
|
|
||||||
const evLink = permalinkCreator?.forEvent(ev.getId()!);
|
|
||||||
const userLink = makeUserPermalink(ev.getSender()!);
|
|
||||||
const mxid = ev.getSender();
|
|
||||||
|
|
||||||
if (M_BEACON_INFO.matches(ev.getType())) {
|
|
||||||
const aTheir = isSelfLocation(ev.getContent()) ? "their" : "a";
|
|
||||||
return {
|
|
||||||
html:
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>shared ${aTheir} live location.</blockquote></mx-reply>`,
|
|
||||||
body: `> <${mxid}> shared ${aTheir} live location.\n\n`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (M_POLL_START.matches(ev.getType())) {
|
|
||||||
const extensibleEvent = ev.unstableExtensibleEvent as PollStartEvent;
|
|
||||||
const question = extensibleEvent?.question?.text;
|
|
||||||
return {
|
|
||||||
html:
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>Poll: ${question}</blockquote></mx-reply>`,
|
|
||||||
body: `> <${mxid}> started poll: ${question}\n\n`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (M_POLL_END.matches(ev.getType())) {
|
|
||||||
return {
|
|
||||||
html:
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>Ended poll</blockquote></mx-reply>`,
|
|
||||||
body: `> <${mxid}>Ended poll\n\n`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// This fallback contains text that is explicitly EN.
|
|
||||||
switch (msgtype) {
|
|
||||||
case MsgType.Text:
|
|
||||||
case MsgType.Notice: {
|
|
||||||
html =
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>${html}</blockquote></mx-reply>`;
|
|
||||||
const lines = body.trim().split("\n");
|
|
||||||
if (lines.length > 0) {
|
|
||||||
lines[0] = `<${mxid}> ${lines[0]}`;
|
|
||||||
body = lines.map((line) => `> ${line}`).join("\n") + "\n\n";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MsgType.Image:
|
|
||||||
html =
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>sent an image.</blockquote></mx-reply>`;
|
|
||||||
body = `> <${mxid}> sent an image.\n\n`;
|
|
||||||
break;
|
|
||||||
case MsgType.Video:
|
|
||||||
html =
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>sent a video.</blockquote></mx-reply>`;
|
|
||||||
body = `> <${mxid}> sent a video.\n\n`;
|
|
||||||
break;
|
|
||||||
case MsgType.Audio:
|
|
||||||
html =
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>sent an audio file.</blockquote></mx-reply>`;
|
|
||||||
body = `> <${mxid}> sent an audio file.\n\n`;
|
|
||||||
break;
|
|
||||||
case MsgType.File:
|
|
||||||
html =
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>sent a file.</blockquote></mx-reply>`;
|
|
||||||
body = `> <${mxid}> sent a file.\n\n`;
|
|
||||||
break;
|
|
||||||
case MsgType.Location: {
|
|
||||||
const aTheir = isSelfLocation(ev.getContent()) ? "their" : "a";
|
|
||||||
html =
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>` +
|
|
||||||
`<br>shared ${aTheir} location.</blockquote></mx-reply>`;
|
|
||||||
body = `> <${mxid}> shared ${aTheir} location.\n\n`;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MsgType.Emote: {
|
|
||||||
html =
|
|
||||||
`<mx-reply><blockquote><a href="${evLink}">In reply to</a> * ` +
|
|
||||||
`<a href="${userLink}">${mxid}</a><br>${html}</blockquote></mx-reply>`;
|
|
||||||
const lines = body.trim().split("\n");
|
|
||||||
if (lines.length > 0) {
|
|
||||||
lines[0] = `* <${mxid}> ${lines[0]}`;
|
|
||||||
body = lines.map((line) => `> ${line}`).join("\n") + "\n\n";
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { body, html };
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeReplyMixIn(ev?: MatrixEvent): IEventRelation {
|
export function makeReplyMixIn(ev?: MatrixEvent): IEventRelation {
|
||||||
if (!ev) return {};
|
if (!ev) return {};
|
||||||
|
|
||||||
|
@ -227,34 +83,9 @@ export function shouldDisplayReply(event: MatrixEvent): boolean {
|
||||||
return !!inReplyTo.event_id;
|
return !!inReplyTo.event_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AddReplyOpts {
|
export function addReplyToMessageContent(content: IContent, replyToEvent: MatrixEvent): void {
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
|
||||||
includeLegacyFallback: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IncludeLegacyFeedbackOpts {
|
|
||||||
permalinkCreator?: RoomPermalinkCreator;
|
|
||||||
includeLegacyFallback: true;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function addReplyToMessageContent(
|
|
||||||
content: IContent,
|
|
||||||
replyToEvent: MatrixEvent,
|
|
||||||
opts: AddReplyOpts | IncludeLegacyFeedbackOpts,
|
|
||||||
): void {
|
|
||||||
content["m.relates_to"] = {
|
content["m.relates_to"] = {
|
||||||
...(content["m.relates_to"] || {}),
|
...(content["m.relates_to"] || {}),
|
||||||
...makeReplyMixIn(replyToEvent),
|
...makeReplyMixIn(replyToEvent),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (opts.includeLegacyFallback) {
|
|
||||||
// Part of Replies fallback support - prepend the text we're sending with the text we're replying to
|
|
||||||
const nestedReply = getNestedReplyText(replyToEvent, opts.permalinkCreator);
|
|
||||||
if (nestedReply) {
|
|
||||||
if (content.formatted_body) {
|
|
||||||
content.formatted_body = nestedReply.html + content.formatted_body;
|
|
||||||
}
|
|
||||||
content.body = nestedReply.body + content.body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,7 +351,7 @@ describe("Notifier", () => {
|
||||||
user: mockClient.getSafeUserId(),
|
user: mockClient.getSafeUserId(),
|
||||||
room: testRoom.roomId,
|
room: testRoom.roomId,
|
||||||
});
|
});
|
||||||
addReplyToMessageContent(reply.getContent(), event, { includeLegacyFallback: true });
|
addReplyToMessageContent(reply.getContent(), event);
|
||||||
Notifier.displayPopupNotification(reply, testRoom);
|
Notifier.displayPopupNotification(reply, testRoom);
|
||||||
expect(MockPlatform.displayNotification).toHaveBeenCalledWith(
|
expect(MockPlatform.displayNotification).toHaveBeenCalledWith(
|
||||||
"@bob:example.org (!room1:server)",
|
"@bob:example.org (!room1:server)",
|
||||||
|
|
|
@ -6,42 +6,10 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||||
Please see LICENSE files in the repository root for full details.
|
Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { Room } from "matrix-js-sdk/src/matrix";
|
||||||
IContent,
|
|
||||||
MatrixEvent,
|
|
||||||
MsgType,
|
|
||||||
M_BEACON_INFO,
|
|
||||||
LocationAssetType,
|
|
||||||
M_ASSET,
|
|
||||||
M_POLL_END,
|
|
||||||
Room,
|
|
||||||
} from "matrix-js-sdk/src/matrix";
|
|
||||||
|
|
||||||
import {
|
import { getParentEventId, shouldDisplayReply, stripHTMLReply, stripPlainReply } from "../../src/utils/Reply";
|
||||||
getNestedReplyText,
|
import { mkEvent, stubClient } from "../test-utils";
|
||||||
getParentEventId,
|
|
||||||
shouldDisplayReply,
|
|
||||||
stripHTMLReply,
|
|
||||||
stripPlainReply,
|
|
||||||
} from "../../src/utils/Reply";
|
|
||||||
import { makePollStartEvent, mkEvent, stubClient } from "../test-utils";
|
|
||||||
import { RoomPermalinkCreator } from "../../src/utils/permalinks/Permalinks";
|
|
||||||
|
|
||||||
function makeTestEvent(type: string, content: IContent): MatrixEvent {
|
|
||||||
return mkEvent({
|
|
||||||
event: true,
|
|
||||||
type: type,
|
|
||||||
user: "@user1:server",
|
|
||||||
room: "!room1:server",
|
|
||||||
content,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const mockPermalinkGenerator = {
|
|
||||||
forEvent(eventId: string): string {
|
|
||||||
return "$$permalink$$";
|
|
||||||
},
|
|
||||||
} as RoomPermalinkCreator;
|
|
||||||
|
|
||||||
// don't litter test console with logs
|
// don't litter test console with logs
|
||||||
jest.mock("matrix-js-sdk/src/logger");
|
jest.mock("matrix-js-sdk/src/logger");
|
||||||
|
@ -122,50 +90,6 @@ But this is not
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getNestedReplyText", () => {
|
|
||||||
it("Returns valid reply fallback text for m.text msgtypes", () => {
|
|
||||||
const event = makeTestEvent(MsgType.Text, {
|
|
||||||
body: "body",
|
|
||||||
msgtype: "m.text",
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(getNestedReplyText(event, mockPermalinkGenerator)).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
(
|
|
||||||
[
|
|
||||||
["m.room.message", MsgType.Location, LocationAssetType.Pin],
|
|
||||||
["m.room.message", MsgType.Location, LocationAssetType.Self],
|
|
||||||
[M_BEACON_INFO.name, undefined, LocationAssetType.Pin],
|
|
||||||
[M_BEACON_INFO.name, undefined, LocationAssetType.Self],
|
|
||||||
] as const
|
|
||||||
).forEach(([type, msgType, assetType]) => {
|
|
||||||
it(`should create the expected fallback text for ${assetType} ${type}/${msgType}`, () => {
|
|
||||||
const event = makeTestEvent(type, {
|
|
||||||
body: "body",
|
|
||||||
msgtype: msgType,
|
|
||||||
[M_ASSET.name]: { type: assetType },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(getNestedReplyText(event, mockPermalinkGenerator)).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should create the expected fallback text for poll end events", () => {
|
|
||||||
const event = makeTestEvent(M_POLL_END.name, {
|
|
||||||
body: "body",
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(getNestedReplyText(event, mockPermalinkGenerator)).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("should create the expected fallback text for poll start events", () => {
|
|
||||||
const event = makePollStartEvent("Will this test pass?", "@user:server.org");
|
|
||||||
|
|
||||||
expect(getNestedReplyText(event, mockPermalinkGenerator)).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("shouldDisplayReply", () => {
|
describe("shouldDisplayReply", () => {
|
||||||
it("Returns false for redacted events", () => {
|
it("Returns false for redacted events", () => {
|
||||||
const event = mkEvent({
|
const event = mkEvent({
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Reply getNestedReplyText Returns valid reply fallback text for m.text msgtypes 1`] = `
|
|
||||||
{
|
|
||||||
"body": "> <@user1:server> body
|
|
||||||
|
|
||||||
",
|
|
||||||
"html": "<mx-reply><blockquote><a href="$$permalink$$">In reply to</a> <a href="https://matrix.to/#/@user1:server">@user1:server</a><br>body</blockquote></mx-reply>",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Reply getNestedReplyText should create the expected fallback text for m.pin m.room.message/m.location 1`] = `
|
|
||||||
{
|
|
||||||
"body": "> <@user1:server> shared a location.
|
|
||||||
|
|
||||||
",
|
|
||||||
"html": "<mx-reply><blockquote><a href="$$permalink$$">In reply to</a> <a href="https://matrix.to/#/@user1:server">@user1:server</a><br>shared a location.</blockquote></mx-reply>",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Reply getNestedReplyText should create the expected fallback text for m.pin org.matrix.msc3672.beacon_info/undefined 1`] = `
|
|
||||||
{
|
|
||||||
"body": "> <@user1:server> shared a live location.
|
|
||||||
|
|
||||||
",
|
|
||||||
"html": "<mx-reply><blockquote><a href="$$permalink$$">In reply to</a> <a href="https://matrix.to/#/@user1:server">@user1:server</a><br>shared a live location.</blockquote></mx-reply>",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Reply getNestedReplyText should create the expected fallback text for m.self m.room.message/m.location 1`] = `
|
|
||||||
{
|
|
||||||
"body": "> <@user1:server> shared their location.
|
|
||||||
|
|
||||||
",
|
|
||||||
"html": "<mx-reply><blockquote><a href="$$permalink$$">In reply to</a> <a href="https://matrix.to/#/@user1:server">@user1:server</a><br>shared their location.</blockquote></mx-reply>",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Reply getNestedReplyText should create the expected fallback text for m.self org.matrix.msc3672.beacon_info/undefined 1`] = `
|
|
||||||
{
|
|
||||||
"body": "> <@user1:server> shared their live location.
|
|
||||||
|
|
||||||
",
|
|
||||||
"html": "<mx-reply><blockquote><a href="$$permalink$$">In reply to</a> <a href="https://matrix.to/#/@user1:server">@user1:server</a><br>shared their live location.</blockquote></mx-reply>",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Reply getNestedReplyText should create the expected fallback text for poll end events 1`] = `
|
|
||||||
{
|
|
||||||
"body": "> <@user1:server>Ended poll
|
|
||||||
|
|
||||||
",
|
|
||||||
"html": "<mx-reply><blockquote><a href="$$permalink$$">In reply to</a> <a href="https://matrix.to/#/@user1:server">@user1:server</a><br>Ended poll</blockquote></mx-reply>",
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Reply getNestedReplyText should create the expected fallback text for poll start events 1`] = `
|
|
||||||
{
|
|
||||||
"body": "> <@user:server.org> started poll: Will this test pass?
|
|
||||||
|
|
||||||
",
|
|
||||||
"html": "<mx-reply><blockquote><a href="$$permalink$$">In reply to</a> <a href="https://matrix.to/#/@user:server.org">@user:server.org</a><br>Poll: Will this test pass?</blockquote></mx-reply>",
|
|
||||||
}
|
|
||||||
`;
|
|
|
@ -27,7 +27,6 @@ import defaultDispatcher from "../../../../../src/dispatcher/dispatcher";
|
||||||
import DocumentOffset from "../../../../../src/editor/offset";
|
import DocumentOffset from "../../../../../src/editor/offset";
|
||||||
import { Layout } from "../../../../../src/settings/enums/Layout";
|
import { Layout } from "../../../../../src/settings/enums/Layout";
|
||||||
import { IRoomState, MainSplitContentType } from "../../../../../src/components/structures/RoomView";
|
import { IRoomState, MainSplitContentType } from "../../../../../src/components/structures/RoomView";
|
||||||
import { RoomPermalinkCreator } from "../../../../../src/utils/permalinks/Permalinks";
|
|
||||||
import { mockPlatformPeg } from "../../../../test-utils/platform";
|
import { mockPlatformPeg } from "../../../../test-utils/platform";
|
||||||
import { doMaybeLocalRoomAction } from "../../../../../src/utils/local-room";
|
import { doMaybeLocalRoomAction } from "../../../../../src/utils/local-room";
|
||||||
import { addTextToComposer } from "../../../../test-utils/composer";
|
import { addTextToComposer } from "../../../../test-utils/composer";
|
||||||
|
@ -80,14 +79,12 @@ describe("<SendMessageComposer/>", () => {
|
||||||
viewRoomOpts: { buttons: [] },
|
viewRoomOpts: { buttons: [] },
|
||||||
};
|
};
|
||||||
describe("createMessageContent", () => {
|
describe("createMessageContent", () => {
|
||||||
const permalinkCreator = jest.fn() as any;
|
|
||||||
|
|
||||||
it("sends plaintext messages correctly", () => {
|
it("sends plaintext messages correctly", () => {
|
||||||
const model = new EditorModel([], createPartCreator());
|
const model = new EditorModel([], createPartCreator());
|
||||||
const documentOffset = new DocumentOffset(11, true);
|
const documentOffset = new DocumentOffset(11, true);
|
||||||
model.update("hello world", "insertText", documentOffset);
|
model.update("hello world", "insertText", documentOffset);
|
||||||
|
|
||||||
const content = createMessageContent("@alice:test", model, undefined, undefined, permalinkCreator);
|
const content = createMessageContent("@alice:test", model, undefined, undefined);
|
||||||
|
|
||||||
expect(content).toEqual({
|
expect(content).toEqual({
|
||||||
"body": "hello world",
|
"body": "hello world",
|
||||||
|
@ -101,7 +98,7 @@ describe("<SendMessageComposer/>", () => {
|
||||||
const documentOffset = new DocumentOffset(13, true);
|
const documentOffset = new DocumentOffset(13, true);
|
||||||
model.update("hello *world*", "insertText", documentOffset);
|
model.update("hello *world*", "insertText", documentOffset);
|
||||||
|
|
||||||
const content = createMessageContent("@alice:test", model, undefined, undefined, permalinkCreator);
|
const content = createMessageContent("@alice:test", model, undefined, undefined);
|
||||||
|
|
||||||
expect(content).toEqual({
|
expect(content).toEqual({
|
||||||
"body": "hello *world*",
|
"body": "hello *world*",
|
||||||
|
@ -117,7 +114,7 @@ describe("<SendMessageComposer/>", () => {
|
||||||
const documentOffset = new DocumentOffset(22, true);
|
const documentOffset = new DocumentOffset(22, true);
|
||||||
model.update("/me blinks __quickly__", "insertText", documentOffset);
|
model.update("/me blinks __quickly__", "insertText", documentOffset);
|
||||||
|
|
||||||
const content = createMessageContent("@alice:test", model, undefined, undefined, permalinkCreator);
|
const content = createMessageContent("@alice:test", model, undefined, undefined);
|
||||||
|
|
||||||
expect(content).toEqual({
|
expect(content).toEqual({
|
||||||
"body": "blinks __quickly__",
|
"body": "blinks __quickly__",
|
||||||
|
@ -134,7 +131,7 @@ describe("<SendMessageComposer/>", () => {
|
||||||
model.update("/me ✨sparkles✨", "insertText", documentOffset);
|
model.update("/me ✨sparkles✨", "insertText", documentOffset);
|
||||||
expect(model.parts.length).toEqual(4); // Emoji count as non-text
|
expect(model.parts.length).toEqual(4); // Emoji count as non-text
|
||||||
|
|
||||||
const content = createMessageContent("@alice:test", model, undefined, undefined, permalinkCreator);
|
const content = createMessageContent("@alice:test", model, undefined, undefined);
|
||||||
|
|
||||||
expect(content).toEqual({
|
expect(content).toEqual({
|
||||||
"body": "✨sparkles✨",
|
"body": "✨sparkles✨",
|
||||||
|
@ -149,7 +146,7 @@ describe("<SendMessageComposer/>", () => {
|
||||||
|
|
||||||
model.update("//dev/null is my favourite place", "insertText", documentOffset);
|
model.update("//dev/null is my favourite place", "insertText", documentOffset);
|
||||||
|
|
||||||
const content = createMessageContent("@alice:test", model, undefined, undefined, permalinkCreator);
|
const content = createMessageContent("@alice:test", model, undefined, undefined);
|
||||||
|
|
||||||
expect(content).toEqual({
|
expect(content).toEqual({
|
||||||
"body": "/dev/null is my favourite place",
|
"body": "/dev/null is my favourite place",
|
||||||
|
@ -364,7 +361,6 @@ describe("<SendMessageComposer/>", () => {
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
room: mockRoom,
|
room: mockRoom,
|
||||||
toggleStickerPickerOpen: jest.fn(),
|
toggleStickerPickerOpen: jest.fn(),
|
||||||
permalinkCreator: new RoomPermalinkCreator(mockRoom),
|
|
||||||
};
|
};
|
||||||
const getRawComponent = (props = {}, roomContext = defaultRoomContext, client = mockClient) => (
|
const getRawComponent = (props = {}, roomContext = defaultRoomContext, client = mockClient) => (
|
||||||
<MatrixClientContext.Provider value={client}>
|
<MatrixClientContext.Provider value={client}>
|
||||||
|
@ -482,6 +478,44 @@ describe("<SendMessageComposer/>", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("correctly sends a reply using a slash command", async () => {
|
||||||
|
stubClient();
|
||||||
|
mocked(doMaybeLocalRoomAction).mockImplementation(
|
||||||
|
<T,>(roomId: string, fn: (actualRoomId: string) => Promise<T>, _client?: MatrixClient) => {
|
||||||
|
return fn(roomId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const replyToEvent = mkEvent({
|
||||||
|
type: "m.room.message",
|
||||||
|
user: "@bob:test",
|
||||||
|
room: "!abc:test",
|
||||||
|
content: { "m.mentions": {} },
|
||||||
|
event: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
mockPlatformPeg({ overrideBrowserShortcuts: jest.fn().mockReturnValue(false) });
|
||||||
|
const { container } = getComponent({ replyToEvent });
|
||||||
|
|
||||||
|
addTextToComposer(container, "/tableflip");
|
||||||
|
fireEvent.keyDown(container.querySelector(".mx_SendMessageComposer")!, { key: "Enter" });
|
||||||
|
|
||||||
|
await waitFor(() =>
|
||||||
|
expect(mockClient.sendMessage).toHaveBeenCalledWith("myfakeroom", null, {
|
||||||
|
"body": "(╯°□°)╯︵ ┻━┻",
|
||||||
|
"msgtype": MsgType.Text,
|
||||||
|
"m.mentions": {
|
||||||
|
user_ids: ["@bob:test"],
|
||||||
|
},
|
||||||
|
"m.relates_to": {
|
||||||
|
"m.in_reply_to": {
|
||||||
|
event_id: replyToEvent.getId(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("shows chat effects on message sending", () => {
|
it("shows chat effects on message sending", () => {
|
||||||
mocked(doMaybeLocalRoomAction).mockImplementation(
|
mocked(doMaybeLocalRoomAction).mockImplementation(
|
||||||
<T,>(roomId: string, fn: (actualRoomId: string) => Promise<T>, _client?: MatrixClient) => {
|
<T,>(roomId: string, fn: (actualRoomId: string) => Promise<T>, _client?: MatrixClient) => {
|
||||||
|
|
|
@ -15,7 +15,6 @@ import VoiceRecordComposerTile from "../../../../../src/components/views/rooms/V
|
||||||
import { doMaybeLocalRoomAction } from "../../../../../src/utils/local-room";
|
import { doMaybeLocalRoomAction } from "../../../../../src/utils/local-room";
|
||||||
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
|
||||||
import { IUpload, VoiceMessageRecording } from "../../../../../src/audio/VoiceMessageRecording";
|
import { IUpload, VoiceMessageRecording } from "../../../../../src/audio/VoiceMessageRecording";
|
||||||
import { RoomPermalinkCreator } from "../../../../../src/utils/permalinks/Permalinks";
|
|
||||||
import { VoiceRecordingStore } from "../../../../../src/stores/VoiceRecordingStore";
|
import { VoiceRecordingStore } from "../../../../../src/stores/VoiceRecordingStore";
|
||||||
import { PlaybackClock } from "../../../../../src/audio/PlaybackClock";
|
import { PlaybackClock } from "../../../../../src/audio/PlaybackClock";
|
||||||
import { mkEvent } from "../../../../test-utils";
|
import { mkEvent } from "../../../../test-utils";
|
||||||
|
@ -57,7 +56,6 @@ describe("<VoiceRecordComposerTile/>", () => {
|
||||||
const props = {
|
const props = {
|
||||||
room,
|
room,
|
||||||
ref: voiceRecordComposerTile,
|
ref: voiceRecordComposerTile,
|
||||||
permalinkCreator: new RoomPermalinkCreator(room),
|
|
||||||
};
|
};
|
||||||
mockUpload = {
|
mockUpload = {
|
||||||
mxc: "mxc://example.com/voice",
|
mxc: "mxc://example.com/voice",
|
||||||
|
@ -142,7 +140,6 @@ describe("<VoiceRecordComposerTile/>", () => {
|
||||||
const props = {
|
const props = {
|
||||||
room,
|
room,
|
||||||
ref: voiceRecordComposerTile,
|
ref: voiceRecordComposerTile,
|
||||||
permalinkCreator: new RoomPermalinkCreator(room),
|
|
||||||
replyToEvent,
|
replyToEvent,
|
||||||
};
|
};
|
||||||
render(<VoiceRecordComposerTile {...props} />);
|
render(<VoiceRecordComposerTile {...props} />);
|
||||||
|
|
|
@ -8,26 +8,13 @@ Please see LICENSE files in the repository root for full details.
|
||||||
import { MsgType } from "matrix-js-sdk/src/matrix";
|
import { MsgType } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { filterConsole, mkEvent } from "../../../../../../test-utils";
|
import { filterConsole, mkEvent } from "../../../../../../test-utils";
|
||||||
import { RoomPermalinkCreator } from "../../../../../../../src/utils/permalinks/Permalinks";
|
|
||||||
import {
|
import {
|
||||||
createMessageContent,
|
createMessageContent,
|
||||||
EMOTE_PREFIX,
|
EMOTE_PREFIX,
|
||||||
} from "../../../../../../../src/components/views/rooms/wysiwyg_composer/utils/createMessageContent";
|
} from "../../../../../../../src/components/views/rooms/wysiwyg_composer/utils/createMessageContent";
|
||||||
|
|
||||||
describe("createMessageContent", () => {
|
describe("createMessageContent", () => {
|
||||||
const permalinkCreator = {
|
|
||||||
forEvent(eventId: string): string {
|
|
||||||
return "$$permalink$$";
|
|
||||||
},
|
|
||||||
} as RoomPermalinkCreator;
|
|
||||||
const message = "<em><b>hello</b> world</em>";
|
const message = "<em><b>hello</b> world</em>";
|
||||||
const mockEvent = mkEvent({
|
|
||||||
type: "m.room.message",
|
|
||||||
room: "myfakeroom",
|
|
||||||
user: "myfakeuser",
|
|
||||||
content: { msgtype: "m.text", body: "Replying to this" },
|
|
||||||
event: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.resetAllMocks();
|
jest.resetAllMocks();
|
||||||
|
@ -42,12 +29,12 @@ describe("createMessageContent", () => {
|
||||||
// Warm up by creating the component once, with a long timeout.
|
// Warm up by creating the component once, with a long timeout.
|
||||||
// This prevents tests timing out because of the time spent loading
|
// This prevents tests timing out because of the time spent loading
|
||||||
// the WASM component.
|
// the WASM component.
|
||||||
await createMessageContent(message, true, { permalinkCreator });
|
await createMessageContent(message, true, {});
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
it("Should create html message", async () => {
|
it("Should create html message", async () => {
|
||||||
// When
|
// When
|
||||||
const content = await createMessageContent(message, true, { permalinkCreator });
|
const content = await createMessageContent(message, true, {});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
expect(content).toEqual({
|
expect(content).toEqual({
|
||||||
|
@ -58,34 +45,13 @@ describe("createMessageContent", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add reply to message content", async () => {
|
|
||||||
// When
|
|
||||||
const content = await createMessageContent(message, true, { permalinkCreator, replyToEvent: mockEvent });
|
|
||||||
|
|
||||||
// Then
|
|
||||||
expect(content).toEqual({
|
|
||||||
"body": "> <myfakeuser> Replying to this\n\n*__hello__ world*",
|
|
||||||
"format": "org.matrix.custom.html",
|
|
||||||
"formatted_body":
|
|
||||||
'<mx-reply><blockquote><a href="$$permalink$$">In reply to</a>' +
|
|
||||||
' <a href="https://matrix.to/#/myfakeuser">myfakeuser</a>' +
|
|
||||||
"<br>Replying to this</blockquote></mx-reply><em><b>hello</b> world</em>",
|
|
||||||
"msgtype": "m.text",
|
|
||||||
"m.relates_to": {
|
|
||||||
"m.in_reply_to": {
|
|
||||||
event_id: mockEvent.getId(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should add relation to message", async () => {
|
it("Should add relation to message", async () => {
|
||||||
// When
|
// When
|
||||||
const relation = {
|
const relation = {
|
||||||
rel_type: "m.thread",
|
rel_type: "m.thread",
|
||||||
event_id: "myFakeThreadId",
|
event_id: "myFakeThreadId",
|
||||||
};
|
};
|
||||||
const content = await createMessageContent(message, true, { permalinkCreator, relation });
|
const content = await createMessageContent(message, true, { relation });
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
expect(content).toEqual({
|
expect(content).toEqual({
|
||||||
|
@ -118,7 +84,7 @@ describe("createMessageContent", () => {
|
||||||
},
|
},
|
||||||
event: true,
|
event: true,
|
||||||
});
|
});
|
||||||
const content = await createMessageContent(message, true, { permalinkCreator, editedEvent });
|
const content = await createMessageContent(message, true, { editedEvent });
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
expect(content).toEqual({
|
expect(content).toEqual({
|
||||||
|
@ -141,20 +107,20 @@ describe("createMessageContent", () => {
|
||||||
|
|
||||||
it("Should strip the /me prefix from a message", async () => {
|
it("Should strip the /me prefix from a message", async () => {
|
||||||
const textBody = "some body text";
|
const textBody = "some body text";
|
||||||
const content = await createMessageContent(EMOTE_PREFIX + textBody, true, { permalinkCreator });
|
const content = await createMessageContent(EMOTE_PREFIX + textBody, true, {});
|
||||||
|
|
||||||
expect(content).toMatchObject({ body: textBody, formatted_body: textBody });
|
expect(content).toMatchObject({ body: textBody, formatted_body: textBody });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should strip single / from message prefixed with //", async () => {
|
it("Should strip single / from message prefixed with //", async () => {
|
||||||
const content = await createMessageContent("//twoSlashes", true, { permalinkCreator });
|
const content = await createMessageContent("//twoSlashes", true, {});
|
||||||
|
|
||||||
expect(content).toMatchObject({ body: "/twoSlashes", formatted_body: "/twoSlashes" });
|
expect(content).toMatchObject({ body: "/twoSlashes", formatted_body: "/twoSlashes" });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should set the content type to MsgType.Emote when /me prefix is used", async () => {
|
it("Should set the content type to MsgType.Emote when /me prefix is used", async () => {
|
||||||
const textBody = "some body text";
|
const textBody = "some body text";
|
||||||
const content = await createMessageContent(EMOTE_PREFIX + textBody, true, { permalinkCreator });
|
const content = await createMessageContent(EMOTE_PREFIX + textBody, true, {});
|
||||||
|
|
||||||
expect(content).toMatchObject({ msgtype: MsgType.Emote });
|
expect(content).toMatchObject({ msgtype: MsgType.Emote });
|
||||||
});
|
});
|
||||||
|
@ -164,14 +130,14 @@ describe("createMessageContent", () => {
|
||||||
it("Should replace at-room mentions with `@room` in body", async () => {
|
it("Should replace at-room mentions with `@room` in body", async () => {
|
||||||
const messageComposerState = `<a href="#" contenteditable="false" data-mention-type="at-room" style="some styling">@room</a> `;
|
const messageComposerState = `<a href="#" contenteditable="false" data-mention-type="at-room" style="some styling">@room</a> `;
|
||||||
|
|
||||||
const content = await createMessageContent(messageComposerState, false, { permalinkCreator });
|
const content = await createMessageContent(messageComposerState, false, {});
|
||||||
expect(content).toMatchObject({ body: "@room " });
|
expect(content).toMatchObject({ body: "@room " });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should replace user mentions with user name in body", async () => {
|
it("Should replace user mentions with user name in body", async () => {
|
||||||
const messageComposerState = `<a href="https://matrix.to/#/@test_user:element.io" contenteditable="false" data-mention-type="user" style="some styling">a test user</a> `;
|
const messageComposerState = `<a href="https://matrix.to/#/@test_user:element.io" contenteditable="false" data-mention-type="user" style="some styling">a test user</a> `;
|
||||||
|
|
||||||
const content = await createMessageContent(messageComposerState, false, { permalinkCreator });
|
const content = await createMessageContent(messageComposerState, false, {});
|
||||||
|
|
||||||
expect(content).toMatchObject({ body: "a test user " });
|
expect(content).toMatchObject({ body: "a test user " });
|
||||||
});
|
});
|
||||||
|
@ -179,7 +145,7 @@ describe("createMessageContent", () => {
|
||||||
it("Should replace room mentions with room mxid in body", async () => {
|
it("Should replace room mentions with room mxid in body", async () => {
|
||||||
const messageComposerState = `<a href="https://matrix.to/#/#test_room:element.io" contenteditable="false" data-mention-type="room" style="some styling">a test room</a> `;
|
const messageComposerState = `<a href="https://matrix.to/#/#test_room:element.io" contenteditable="false" data-mention-type="room" style="some styling">a test room</a> `;
|
||||||
|
|
||||||
const content = await createMessageContent(messageComposerState, false, { permalinkCreator });
|
const content = await createMessageContent(messageComposerState, false, {});
|
||||||
|
|
||||||
expect(content).toMatchObject({
|
expect(content).toMatchObject({
|
||||||
body: "#test_room:element.io ",
|
body: "#test_room:element.io ",
|
||||||
|
|
|
@ -17,7 +17,6 @@ import { createTestClient, getRoomContext, mkEvent, mkStubRoom } from "../../../
|
||||||
import defaultDispatcher from "../../../../../../../src/dispatcher/dispatcher";
|
import defaultDispatcher from "../../../../../../../src/dispatcher/dispatcher";
|
||||||
import SettingsStore from "../../../../../../../src/settings/SettingsStore";
|
import SettingsStore from "../../../../../../../src/settings/SettingsStore";
|
||||||
import { SettingLevel } from "../../../../../../../src/settings/SettingLevel";
|
import { SettingLevel } from "../../../../../../../src/settings/SettingLevel";
|
||||||
import { RoomPermalinkCreator } from "../../../../../../../src/utils/permalinks/Permalinks";
|
|
||||||
import EditorStateTransfer from "../../../../../../../src/utils/EditorStateTransfer";
|
import EditorStateTransfer from "../../../../../../../src/utils/EditorStateTransfer";
|
||||||
import * as ConfirmRedactDialog from "../../../../../../../src/components/views/dialogs/ConfirmRedactDialog";
|
import * as ConfirmRedactDialog from "../../../../../../../src/components/views/dialogs/ConfirmRedactDialog";
|
||||||
import * as SlashCommands from "../../../../../../../src/SlashCommands";
|
import * as SlashCommands from "../../../../../../../src/SlashCommands";
|
||||||
|
@ -27,11 +26,6 @@ import { MatrixClientPeg } from "../../../../../../../src/MatrixClientPeg";
|
||||||
import { Action } from "../../../../../../../src/dispatcher/actions";
|
import { Action } from "../../../../../../../src/dispatcher/actions";
|
||||||
|
|
||||||
describe("message", () => {
|
describe("message", () => {
|
||||||
const permalinkCreator = {
|
|
||||||
forEvent(eventId: string): string {
|
|
||||||
return "$$permalink$$";
|
|
||||||
},
|
|
||||||
} as RoomPermalinkCreator;
|
|
||||||
const message = "<i><b>hello</b> world</i>";
|
const message = "<i><b>hello</b> world</i>";
|
||||||
const mockEvent = mkEvent({
|
const mockEvent = mkEvent({
|
||||||
type: "m.room.message",
|
type: "m.room.message",
|
||||||
|
@ -71,7 +65,7 @@ describe("message", () => {
|
||||||
describe("sendMessage", () => {
|
describe("sendMessage", () => {
|
||||||
it("Should not send empty html message", async () => {
|
it("Should not send empty html message", async () => {
|
||||||
// When
|
// When
|
||||||
await sendMessage("", true, { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });
|
await sendMessage("", true, { roomContext: defaultRoomContext, mxClient: mockClient });
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
expect(mockClient.sendMessage).toHaveBeenCalledTimes(0);
|
expect(mockClient.sendMessage).toHaveBeenCalledTimes(0);
|
||||||
|
@ -86,7 +80,6 @@ describe("message", () => {
|
||||||
await sendMessage(message, true, {
|
await sendMessage(message, true, {
|
||||||
roomContext: mockRoomContextWithoutId,
|
roomContext: mockRoomContextWithoutId,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
@ -100,7 +93,6 @@ describe("message", () => {
|
||||||
await sendMessage(message, true, {
|
await sendMessage(message, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
@ -111,7 +103,6 @@ describe("message", () => {
|
||||||
await sendMessage(message, true, {
|
await sendMessage(message, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
relation: {},
|
relation: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -123,7 +114,6 @@ describe("message", () => {
|
||||||
await sendMessage(message, true, {
|
await sendMessage(message, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
relation: {
|
relation: {
|
||||||
event_id: "valid_id",
|
event_id: "valid_id",
|
||||||
rel_type: "m.does_not_match",
|
rel_type: "m.does_not_match",
|
||||||
|
@ -139,7 +129,6 @@ describe("message", () => {
|
||||||
await sendMessage(message, true, {
|
await sendMessage(message, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
relation: {
|
relation: {
|
||||||
event_id: "valid_id",
|
event_id: "valid_id",
|
||||||
rel_type: "m.thread",
|
rel_type: "m.thread",
|
||||||
|
@ -156,7 +145,6 @@ describe("message", () => {
|
||||||
await sendMessage(message, true, {
|
await sendMessage(message, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
@ -183,7 +171,6 @@ describe("message", () => {
|
||||||
await sendMessage(message, true, {
|
await sendMessage(message, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
replyToEvent: mockReplyEvent,
|
replyToEvent: mockReplyEvent,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -195,12 +182,9 @@ describe("message", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const expectedContent = {
|
const expectedContent = {
|
||||||
"body": "> <myfakeuser2> My reply\n\n*__hello__ world*",
|
"body": "*__hello__ world*",
|
||||||
"format": "org.matrix.custom.html",
|
"format": "org.matrix.custom.html",
|
||||||
"formatted_body":
|
"formatted_body": "<i><b>hello</b> world</i>",
|
||||||
'<mx-reply><blockquote><a href="$$permalink$$">In reply to</a>' +
|
|
||||||
' <a href="https://matrix.to/#/myfakeuser2">myfakeuser2</a>' +
|
|
||||||
"<br>My reply</blockquote></mx-reply><i><b>hello</b> world</i>",
|
|
||||||
"msgtype": "m.text",
|
"msgtype": "m.text",
|
||||||
"m.relates_to": {
|
"m.relates_to": {
|
||||||
"m.in_reply_to": {
|
"m.in_reply_to": {
|
||||||
|
@ -217,7 +201,6 @@ describe("message", () => {
|
||||||
await sendMessage(message, true, {
|
await sendMessage(message, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
@ -229,7 +212,7 @@ describe("message", () => {
|
||||||
|
|
||||||
it("Should handle emojis", async () => {
|
it("Should handle emojis", async () => {
|
||||||
// When
|
// When
|
||||||
await sendMessage("🎉", false, { roomContext: defaultRoomContext, mxClient: mockClient, permalinkCreator });
|
await sendMessage("🎉", false, { roomContext: defaultRoomContext, mxClient: mockClient });
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
expect(spyDispatcher).toHaveBeenCalledWith({ action: "effects.confetti" });
|
expect(spyDispatcher).toHaveBeenCalledWith({ action: "effects.confetti" });
|
||||||
|
@ -244,7 +227,6 @@ describe("message", () => {
|
||||||
await sendMessage(validCommand, true, {
|
await sendMessage(validCommand, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
@ -257,7 +239,6 @@ describe("message", () => {
|
||||||
await sendMessage(invalidPrefixCommand, true, {
|
await sendMessage(invalidPrefixCommand, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
@ -275,7 +256,6 @@ describe("message", () => {
|
||||||
const result = await sendMessage(validCommand, true, {
|
const result = await sendMessage(validCommand, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Then
|
// Then
|
||||||
|
@ -290,7 +270,6 @@ describe("message", () => {
|
||||||
await sendMessage(inputText, true, {
|
await sendMessage(inputText, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
expect(mockClient.sendMessage).toHaveBeenCalledWith(
|
expect(mockClient.sendMessage).toHaveBeenCalledWith(
|
||||||
"myfakeroom",
|
"myfakeroom",
|
||||||
|
@ -309,7 +288,6 @@ describe("message", () => {
|
||||||
await sendMessage(inputText, true, {
|
await sendMessage(inputText, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
relation: mockRelation,
|
relation: mockRelation,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -326,7 +304,6 @@ describe("message", () => {
|
||||||
await sendMessage("input", true, {
|
await sendMessage("input", true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
replyToEvent: mockEvent,
|
replyToEvent: mockEvent,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -341,7 +318,6 @@ describe("message", () => {
|
||||||
const result = await sendMessage(input, true, {
|
const result = await sendMessage(input, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
replyToEvent: mockEvent,
|
replyToEvent: mockEvent,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -357,7 +333,6 @@ describe("message", () => {
|
||||||
await sendMessage(invalidCommandInput, true, {
|
await sendMessage(invalidCommandInput, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// we expect the message to have been sent
|
// we expect the message to have been sent
|
||||||
|
@ -378,7 +353,6 @@ describe("message", () => {
|
||||||
const result = await sendMessage(invalidCommandInput, true, {
|
const result = await sendMessage(invalidCommandInput, true, {
|
||||||
roomContext: defaultRoomContext,
|
roomContext: defaultRoomContext,
|
||||||
mxClient: mockClient,
|
mxClient: mockClient,
|
||||||
permalinkCreator,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(result).toBeUndefined();
|
expect(result).toBeUndefined();
|
||||||
|
|
Loading…
Reference in New Issue