Fix "[object Promise]" appearing in HTML exports (#9975)
Fixes https://github.com/vector-im/element-web/issues/24272
This commit is contained in:
parent
3e2bf5640e
commit
4c1e4f5127
13 changed files with 895 additions and 84 deletions
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
import { render, RenderResult } from "@testing-library/react";
|
||||
import { EventType, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import type { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { flushPromises, mkMessage, stubClient } from "../../../test-utils";
|
||||
import MessageEditHistoryDialog from "../../../../src/components/views/dialogs/MessageEditHistoryDialog";
|
||||
|
||||
describe("<MessageEditHistory />", () => {
|
||||
const roomId = "!aroom:example.com";
|
||||
let client: jest.Mocked<MatrixClient>;
|
||||
let event: MatrixEvent;
|
||||
|
||||
beforeEach(() => {
|
||||
client = stubClient() as jest.Mocked<MatrixClient>;
|
||||
event = mkMessage({
|
||||
event: true,
|
||||
user: "@user:example.com",
|
||||
room: "!room:example.com",
|
||||
msg: "My Great Message",
|
||||
});
|
||||
});
|
||||
|
||||
async function renderComponent(): Promise<RenderResult> {
|
||||
const result = render(<MessageEditHistoryDialog mxEvent={event} onFinished={jest.fn()} />);
|
||||
await flushPromises();
|
||||
return result;
|
||||
}
|
||||
|
||||
function mockEdits(...edits: { msg: string; ts: number | undefined }[]) {
|
||||
client.relations.mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
events: edits.map(
|
||||
(e) =>
|
||||
new MatrixEvent({
|
||||
type: EventType.RoomMessage,
|
||||
room_id: roomId,
|
||||
origin_server_ts: e.ts,
|
||||
content: {
|
||||
body: e.msg,
|
||||
},
|
||||
}),
|
||||
),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
it("should match the snapshot", async () => {
|
||||
mockEdits({ msg: "My Great Massage", ts: 1234 });
|
||||
|
||||
const { container } = await renderComponent();
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should support events with ", async () => {
|
||||
mockEdits(
|
||||
{ msg: "My Great Massage", ts: undefined },
|
||||
{ msg: "My Great Massage?", ts: undefined },
|
||||
{ msg: "My Great Missage", ts: undefined },
|
||||
);
|
||||
|
||||
const { container } = await renderComponent();
|
||||
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,322 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<MessageEditHistory /> should match the snapshot 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-labelledby="mx_BaseDialog_title"
|
||||
class="mx_MessageEditHistoryDialog mx_Dialog_fixedWidth"
|
||||
data-focus-lock-disabled="false"
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="mx_Dialog_header mx_Dialog_headerWithCancel"
|
||||
>
|
||||
<h2
|
||||
class="mx_Heading_h2 mx_Dialog_title"
|
||||
id="mx_BaseDialog_title"
|
||||
>
|
||||
Message edits
|
||||
</h2>
|
||||
<div
|
||||
aria-label="Close dialog"
|
||||
class="mx_AccessibleButton mx_Dialog_cancelButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mx_AutoHideScrollbar mx_ScrollPanel mx_MessageEditHistoryDialog_scrollPanel"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="mx_RoomView_messageListWrapper"
|
||||
>
|
||||
<ol
|
||||
aria-live="polite"
|
||||
class="mx_RoomView_MessageList"
|
||||
>
|
||||
<ul
|
||||
class="mx_MessageEditHistoryDialog_edits"
|
||||
>
|
||||
<li>
|
||||
<div
|
||||
aria-label="Thu, Jan 1 1970"
|
||||
class="mx_DateSeparator"
|
||||
role="separator"
|
||||
tabindex="-1"
|
||||
>
|
||||
<hr
|
||||
role="none"
|
||||
/>
|
||||
<h2
|
||||
aria-hidden="true"
|
||||
>
|
||||
Thu, Jan 1 1970
|
||||
</h2>
|
||||
<hr
|
||||
role="none"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
class="mx_EventTile"
|
||||
>
|
||||
<div
|
||||
class="mx_EventTile_line"
|
||||
>
|
||||
<span
|
||||
class="mx_MessageTimestamp"
|
||||
>
|
||||
00:00
|
||||
</span>
|
||||
<div
|
||||
class="mx_EventTile_content"
|
||||
>
|
||||
<span
|
||||
class="mx_EventTile_body"
|
||||
dir="auto"
|
||||
>
|
||||
My Great Massage
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MessageActionBar"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Remove
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`<MessageEditHistory /> should support events with 1`] = `
|
||||
<div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
<div
|
||||
aria-labelledby="mx_BaseDialog_title"
|
||||
class="mx_MessageEditHistoryDialog mx_Dialog_fixedWidth"
|
||||
data-focus-lock-disabled="false"
|
||||
role="dialog"
|
||||
>
|
||||
<div
|
||||
class="mx_Dialog_header mx_Dialog_headerWithCancel"
|
||||
>
|
||||
<h2
|
||||
class="mx_Heading_h2 mx_Dialog_title"
|
||||
id="mx_BaseDialog_title"
|
||||
>
|
||||
Message edits
|
||||
</h2>
|
||||
<div
|
||||
aria-label="Close dialog"
|
||||
class="mx_AccessibleButton mx_Dialog_cancelButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="mx_AutoHideScrollbar mx_ScrollPanel mx_MessageEditHistoryDialog_scrollPanel"
|
||||
tabindex="-1"
|
||||
>
|
||||
<div
|
||||
class="mx_RoomView_messageListWrapper"
|
||||
>
|
||||
<ol
|
||||
aria-live="polite"
|
||||
class="mx_RoomView_MessageList"
|
||||
>
|
||||
<ul
|
||||
class="mx_MessageEditHistoryDialog_edits"
|
||||
>
|
||||
<li>
|
||||
<div
|
||||
aria-label=", NaN NaN"
|
||||
class="mx_DateSeparator"
|
||||
role="separator"
|
||||
tabindex="-1"
|
||||
>
|
||||
<hr
|
||||
role="none"
|
||||
/>
|
||||
<h2
|
||||
aria-hidden="true"
|
||||
>
|
||||
, NaN NaN
|
||||
</h2>
|
||||
<hr
|
||||
role="none"
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
class="mx_EventTile"
|
||||
>
|
||||
<div
|
||||
class="mx_EventTile_line"
|
||||
>
|
||||
<span
|
||||
class="mx_MessageTimestamp"
|
||||
>
|
||||
NaN:NaN
|
||||
</span>
|
||||
<div
|
||||
class="mx_EventTile_content"
|
||||
>
|
||||
<span
|
||||
class="mx_EventTile_body markdown-body"
|
||||
dir="auto"
|
||||
>
|
||||
<span>
|
||||
My Great Massage
|
||||
<span
|
||||
class="mx_EditHistoryMessage_deletion"
|
||||
>
|
||||
?
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MessageActionBar"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Remove
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
class="mx_EventTile"
|
||||
>
|
||||
<div
|
||||
class="mx_EventTile_line"
|
||||
>
|
||||
<span
|
||||
class="mx_MessageTimestamp"
|
||||
>
|
||||
NaN:NaN
|
||||
</span>
|
||||
<div
|
||||
class="mx_EventTile_content"
|
||||
>
|
||||
<span
|
||||
class="mx_EventTile_body markdown-body"
|
||||
dir="auto"
|
||||
>
|
||||
<span>
|
||||
My Great M
|
||||
<span
|
||||
class="mx_EditHistoryMessage_deletion"
|
||||
>
|
||||
i
|
||||
</span>
|
||||
<span
|
||||
class="mx_EditHistoryMessage_insertion"
|
||||
>
|
||||
a
|
||||
</span>
|
||||
ssage
|
||||
<span
|
||||
class="mx_EditHistoryMessage_insertion"
|
||||
>
|
||||
?
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MessageActionBar"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Remove
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
class="mx_EventTile"
|
||||
>
|
||||
<div
|
||||
class="mx_EventTile_line"
|
||||
>
|
||||
<span
|
||||
class="mx_MessageTimestamp"
|
||||
>
|
||||
NaN:NaN
|
||||
</span>
|
||||
<div
|
||||
class="mx_EventTile_content"
|
||||
>
|
||||
<span
|
||||
class="mx_EventTile_body"
|
||||
dir="auto"
|
||||
>
|
||||
My Great Missage
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="mx_MessageActionBar"
|
||||
>
|
||||
<div
|
||||
class="mx_AccessibleButton"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
Remove
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
data-focus-guard="true"
|
||||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
|
||||
tabindex="0"
|
||||
/>
|
||||
</div>
|
||||
`;
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2022 - 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||
import * as React from "react";
|
||||
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
|
||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
||||
import { render } from "@testing-library/react";
|
||||
import { render, type RenderResult } from "@testing-library/react";
|
||||
import { Room } from "matrix-js-sdk/src/models/room";
|
||||
|
||||
import { stubClient } from "../../../test-utils";
|
||||
|
@ -26,6 +26,8 @@ import { MatrixClientPeg } from "../../../../src/MatrixClientPeg";
|
|||
|
||||
const ROOM_ID = "!qPewotXpIctQySfjSy:localhost";
|
||||
|
||||
type Props = React.ComponentPropsWithoutRef<typeof SearchResultTile>;
|
||||
|
||||
describe("SearchResultTile", () => {
|
||||
beforeAll(() => {
|
||||
stubClient();
|
||||
|
@ -35,50 +37,72 @@ describe("SearchResultTile", () => {
|
|||
jest.spyOn(cli, "getRoom").mockReturnValue(room);
|
||||
});
|
||||
|
||||
function renderComponent(props: Partial<Props>): RenderResult {
|
||||
return render(<SearchResultTile timeline={[]} ourEventsIndexes={[1]} {...props} />);
|
||||
}
|
||||
|
||||
it("Sets up appropriate callEventGrouper for m.call. events", () => {
|
||||
const { container } = render(
|
||||
<SearchResultTile
|
||||
timeline={[
|
||||
new MatrixEvent({
|
||||
type: EventType.CallInvite,
|
||||
sender: "@user1:server",
|
||||
room_id: ROOM_ID,
|
||||
origin_server_ts: 1432735824652,
|
||||
content: { call_id: "call.1" },
|
||||
event_id: "$1:server",
|
||||
}),
|
||||
new MatrixEvent({
|
||||
content: {
|
||||
body: "This is an example text message",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "<b>This is an example text message</b>",
|
||||
msgtype: "m.text",
|
||||
},
|
||||
event_id: "$144429830826TWwbB:localhost",
|
||||
origin_server_ts: 1432735824653,
|
||||
room_id: ROOM_ID,
|
||||
sender: "@example:example.org",
|
||||
type: "m.room.message",
|
||||
unsigned: {
|
||||
age: 1234,
|
||||
},
|
||||
}),
|
||||
new MatrixEvent({
|
||||
type: EventType.CallAnswer,
|
||||
sender: "@user2:server",
|
||||
room_id: ROOM_ID,
|
||||
origin_server_ts: 1432735824654,
|
||||
content: { call_id: "call.1" },
|
||||
event_id: "$2:server",
|
||||
}),
|
||||
]}
|
||||
ourEventsIndexes={[1]}
|
||||
/>,
|
||||
);
|
||||
const { container } = renderComponent({
|
||||
timeline: [
|
||||
new MatrixEvent({
|
||||
type: EventType.CallInvite,
|
||||
sender: "@user1:server",
|
||||
room_id: ROOM_ID,
|
||||
origin_server_ts: 1432735824652,
|
||||
content: { call_id: "call.1" },
|
||||
event_id: "$1:server",
|
||||
}),
|
||||
new MatrixEvent({
|
||||
content: {
|
||||
body: "This is an example text message",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: "<b>This is an example text message</b>",
|
||||
msgtype: "m.text",
|
||||
},
|
||||
event_id: "$144429830826TWwbB:localhost",
|
||||
origin_server_ts: 1432735824653,
|
||||
room_id: ROOM_ID,
|
||||
sender: "@example:example.org",
|
||||
type: "m.room.message",
|
||||
unsigned: {
|
||||
age: 1234,
|
||||
},
|
||||
}),
|
||||
new MatrixEvent({
|
||||
type: EventType.CallAnswer,
|
||||
sender: "@user2:server",
|
||||
room_id: ROOM_ID,
|
||||
origin_server_ts: 1432735824654,
|
||||
content: { call_id: "call.1" },
|
||||
event_id: "$2:server",
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const tiles = container.querySelectorAll<HTMLElement>(".mx_EventTile");
|
||||
expect(tiles.length).toEqual(2);
|
||||
expect(tiles[0].dataset.eventId).toBe("$1:server");
|
||||
expect(tiles[1].dataset.eventId).toBe("$144429830826TWwbB:localhost");
|
||||
expect(tiles[0]!.dataset.eventId).toBe("$1:server");
|
||||
expect(tiles[1]!.dataset.eventId).toBe("$144429830826TWwbB:localhost");
|
||||
});
|
||||
|
||||
it("supports events with missing timestamps", () => {
|
||||
const { container } = renderComponent({
|
||||
timeline: [...Array(20)].map(
|
||||
(_, i) =>
|
||||
new MatrixEvent({
|
||||
type: EventType.RoomMessage,
|
||||
sender: "@user1:server",
|
||||
room_id: ROOM_ID,
|
||||
content: { body: `Message #${i}` },
|
||||
event_id: `$${i}:server`,
|
||||
origin_server_ts: undefined,
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const separators = container.querySelectorAll(".mx_DateSeparator");
|
||||
// One separator is always rendered at the top, we don't want any
|
||||
// between messages.
|
||||
expect(separators.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue