Pillify event permalinks (#10392)

This commit is contained in:
Michael Weimann 2023-03-21 10:23:20 +01:00 committed by GitHub
parent d8acdd1750
commit 96d1b74ffc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 742 additions and 144 deletions

View file

@ -18,13 +18,14 @@ import React from "react";
import { act, render, RenderResult, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { mocked, Mocked } from "jest-mock";
import { MatrixClient, Room } from "matrix-js-sdk/src/matrix";
import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import dis from "../../../../src/dispatcher/dispatcher";
import { Pill, PillProps, PillType } from "../../../../src/components/views/elements/Pill";
import {
filterConsole,
flushPromises,
mkMessage,
mkRoomCanonicalAliasEvent,
mkRoomMemberJoinEvent,
stubClient,
@ -39,6 +40,9 @@ describe("<Pill>", () => {
const room1Alias = "#room1:example.com";
const room1Id = "!room1:example.com";
let room1: Room;
let room1Message: MatrixEvent;
const room2Id = "!room2:example.com";
let room2: Room;
const space1Id = "!space1:example.com";
let space1: Room;
const user1Id = "@user1:example.com";
@ -63,21 +67,33 @@ describe("<Pill>", () => {
filterConsole(
"Failed to parse permalink Error: Unknown entity type in permalink",
"Room !room1:example.com does not have an m.room.create event",
"Room !space1:example.com does not have an m.room.create event",
);
beforeEach(() => {
client = mocked(stubClient());
DMRoomMap.makeShared();
room1 = new Room(room1Id, client, client.getSafeUserId());
room1 = new Room(room1Id, client, user1Id);
room1.name = "Room 1";
const user1JoinRoom1Event = mkRoomMemberJoinEvent(user1Id, room1Id, {
displayname: "User 1",
});
room1.currentState.setStateEvents([
mkRoomCanonicalAliasEvent(client.getSafeUserId(), room1Id, room1Alias),
mkRoomCanonicalAliasEvent(user1Id, room1Id, room1Alias),
user1JoinRoom1Event,
]);
room1.getMember(user1Id)!.setMembershipEvent(user1JoinRoom1Event);
room1Message = mkMessage({
id: "$123-456",
event: true,
user: user1Id,
room: room1Id,
msg: "Room 1 Message",
});
room1.addLiveEvents([room1Message]);
room2 = new Room(room2Id, client, user1Id);
room2.name = "Room 2";
space1 = new Room(space1Id, client, client.getSafeUserId());
space1.name = "Space 1";
@ -85,6 +101,7 @@ describe("<Pill>", () => {
client.getRooms.mockReturnValue([room1, space1]);
client.getRoom.mockImplementation((roomId: string) => {
if (roomId === room1.roomId) return room1;
if (roomId === room2.roomId) return room2;
if (roomId === space1.roomId) return space1;
return null;
});
@ -220,4 +237,29 @@ describe("<Pill>", () => {
});
expect(renderResult.asFragment()).toMatchSnapshot();
});
it("should render the expected pill for a message in the same room", () => {
renderPill({
room: room1,
url: `${permalinkPrefix}${room1Id}/${room1Message.getId()}`,
});
expect(renderResult.asFragment()).toMatchSnapshot();
});
it("should render the expected pill for a message in another room", () => {
renderPill({
room: room2,
url: `${permalinkPrefix}${room1Id}/${room1Message.getId()}`,
});
expect(renderResult.asFragment()).toMatchSnapshot();
});
it("should not render a pill with an unknown type", () => {
// @ts-ignore
renderPill({ type: "unknown" });
expect(renderResult.asFragment()).toMatchInlineSnapshot(`
<DocumentFragment>
<div />
</DocumentFragment>
`);
});
});

View file

@ -14,7 +14,7 @@ exports[`<Pill> should not render an avatar or link when called with inMessage =
class="mx_Pill mx_RoomPill"
>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
Room 1
</span>
@ -53,7 +53,7 @@ exports[`<Pill> should render the expected pill for @room 1`] = `
/>
</span>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
@room
</span>
@ -63,6 +63,88 @@ exports[`<Pill> should render the expected pill for @room 1`] = `
</DocumentFragment>
`;
exports[`<Pill> should render the expected pill for a message in another room 1`] = `
<DocumentFragment>
<div>
<bdi>
<a
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!room1:example.com/$123-456"
>
Message in
<span
aria-hidden="true"
class="mx_BaseAvatar"
role="presentation"
>
<span
aria-hidden="true"
class="mx_BaseAvatar_initial"
style="font-size: 10.4px; width: 16px; line-height: 16px;"
>
R
</span>
<img
alt=""
aria-hidden="true"
class="mx_BaseAvatar_image"
data-testid="avatar-img"
src="data:image/png;base64,00"
style="width: 16px; height: 16px;"
/>
</span>
<span
class="mx_Pill_text"
>
Room 1
</span>
</a>
</bdi>
</div>
</DocumentFragment>
`;
exports[`<Pill> should render the expected pill for a message in the same room 1`] = `
<DocumentFragment>
<div>
<bdi>
<a
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!room1:example.com/$123-456"
>
Message from
<span
aria-hidden="true"
class="mx_BaseAvatar"
role="presentation"
>
<span
aria-hidden="true"
class="mx_BaseAvatar_initial"
style="font-size: 10.4px; width: 16px; line-height: 16px;"
>
U
</span>
<img
alt=""
aria-hidden="true"
class="mx_BaseAvatar_image"
data-testid="avatar-img"
src="data:image/png;base64,00"
style="width: 16px; height: 16px;"
/>
</span>
<span
class="mx_Pill_text"
>
User 1
</span>
</a>
</bdi>
</div>
</DocumentFragment>
`;
exports[`<Pill> should render the expected pill for a room alias 1`] = `
<DocumentFragment>
<div>
@ -93,7 +175,7 @@ exports[`<Pill> should render the expected pill for a room alias 1`] = `
/>
</span>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
Room 1
</span>
@ -133,7 +215,7 @@ exports[`<Pill> should render the expected pill for a space 1`] = `
/>
</span>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
Space 1
</span>
@ -173,7 +255,7 @@ exports[`<Pill> should render the expected pill for a user not in the room 1`] =
/>
</span>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
User 2
</span>
@ -213,7 +295,7 @@ exports[`<Pill> when rendering a pill for a room should render the expected pill
/>
</span>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
Room 1
</span>
@ -253,7 +335,7 @@ exports[`<Pill> when rendering a pill for a user in the room should render as ex
/>
</span>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
User 1
</span>

View file

@ -63,6 +63,9 @@ describe("<TextualBody />", () => {
isGuest: () => false,
mxcUrlToHttp: (s: string) => s,
getUserId: () => "@user:example.com",
fetchRoomEvent: () => {
throw new Error("MockClient event not found");
},
});
});
@ -172,7 +175,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"Chat with <span><bdi><a class="mx_Pill mx_UserPill mx_UserPill_me" href="https://matrix.to/#/@user:example.com"><img class="mx_BaseAvatar mx_BaseAvatar_image" src="mxc://avatar.url/image.png" style="width: 16px; height: 16px;" alt="" data-testid="avatar-img" aria-hidden="true"><span class="mx_Pill_linkText">Member</span></a></bdi></span>"`,
`"Chat with <span><bdi><a class="mx_Pill mx_UserPill mx_UserPill_me" href="https://matrix.to/#/@user:example.com"><img class="mx_BaseAvatar mx_BaseAvatar_image" src="mxc://avatar.url/image.png" style="width: 16px; height: 16px;" alt="" data-testid="avatar-img" aria-hidden="true"><span class="mx_Pill_text">Member</span></a></bdi></span>"`,
);
});
@ -190,7 +193,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev });
const content = container.querySelector(".mx_EventTile_body");
expect(content.innerHTML).toMatchInlineSnapshot(
`"Visit <span><bdi><a class="mx_Pill mx_RoomPill" href="https://matrix.to/#/#room:example.com"><span class="mx_Pill_linkText">#room:example.com</span></a></bdi></span>"`,
`"Visit <span><bdi><a class="mx_Pill mx_RoomPill" href="https://matrix.to/#/#room:example.com"><div class="mx_Pill_LinkIcon mx_BaseAvatar mx_BaseAvatar_image"></div><span class="mx_Pill_text">#room:example.com</span></a></bdi></span>"`,
);
});
});
@ -275,23 +278,26 @@ describe("<TextualBody />", () => {
expect(content).toMatchSnapshot();
});
it("pills do not appear for event permalinks", () => {
it("pills do not appear for event permalinks with a custom label", () => {
const ev = mkFormattedMessage(
"An [event link](https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/" +
"$16085560162aNpaH:example.com?via=example.com) with text",
'An <a href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/' +
'$16085560162aNpaH:example.com?via=example.com">event link</a> with text',
);
const { container } = getComponent({ mxEvent: ev }, matrixClient);
const { asFragment, container } = getComponent({ mxEvent: ev }, matrixClient);
expect(container).toHaveTextContent("An event link with text");
const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML(
'<span class="mx_EventTile_body markdown-body" dir="auto">' +
'An <a href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/' +
'$16085560162aNpaH:example.com?via=example.com" ' +
'rel="noreferrer noopener">event link</a> with text</span>',
expect(asFragment()).toMatchSnapshot();
});
it("pills appear for event permalinks without a custom label", () => {
const ev = mkFormattedMessage(
"See this message https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/$16085560162aNpaH:example.com?via=example.com",
'See this message <a href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/$16085560162aNpaH:example.com?via=example.com">' +
"https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/$16085560162aNpaH:example.com?via=example.com</a>",
);
const { asFragment } = getComponent({ mxEvent: ev }, matrixClient);
expect(asFragment()).toMatchSnapshot();
});
it("pills appear for room links with vias", () => {
@ -301,19 +307,9 @@ describe("<TextualBody />", () => {
'A <a href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com' +
'?via=example.com&amp;via=bob.com">room link</a> with vias',
);
const { container } = getComponent({ mxEvent: ev }, matrixClient);
const { asFragment, container } = getComponent({ mxEvent: ev }, matrixClient);
expect(container).toHaveTextContent("A room name with vias");
const content = container.querySelector(".mx_EventTile_body");
expect(content).toContainHTML(
'<span class="mx_EventTile_body markdown-body" dir="auto">' +
'A <span><bdi><a class="mx_Pill mx_RoomPill" ' +
'href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com' +
'?via=example.com&amp;via=bob.com"' +
'><img class="mx_BaseAvatar mx_BaseAvatar_image" ' +
'src="mxc://avatar.url/room.png" ' +
'style="width: 16px; height: 16px;" alt="" data-testid="avatar-img" aria-hidden="true">' +
'<span class="mx_Pill_linkText">room name</span></a></bdi></span> with vias</span>',
);
expect(asFragment()).toMatchSnapshot();
});
it("pills appear for an MXID permalink", () => {

View file

@ -62,7 +62,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for an
style="width: 16px; height: 16px;"
/>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
Member
</span>
@ -72,6 +72,104 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for an
</span>
`;
exports[`<TextualBody /> renders formatted m.text correctly pills appear for event permalinks without a custom label 1`] = `
<DocumentFragment>
<div
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body markdown-body"
dir="auto"
>
See this message
<span>
<bdi>
<a
class="mx_Pill mx_EventPill"
href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/$16085560162aNpaH:example.com?via=example.com"
>
Message in
<img
alt=""
aria-hidden="true"
class="mx_BaseAvatar mx_BaseAvatar_image"
data-testid="avatar-img"
src="mxc://avatar.url/room.png"
style="width: 16px; height: 16px;"
/>
<span
class="mx_Pill_text"
>
room name
</span>
</a>
</bdi>
</span>
</span>
</div>
</DocumentFragment>
`;
exports[`<TextualBody /> renders formatted m.text correctly pills appear for room links with vias 1`] = `
<DocumentFragment>
<div
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body markdown-body"
dir="auto"
>
A
<span>
<bdi>
<a
class="mx_Pill mx_RoomPill"
href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com?via=example.com&via=bob.com"
>
<img
alt=""
aria-hidden="true"
class="mx_BaseAvatar mx_BaseAvatar_image"
data-testid="avatar-img"
src="mxc://avatar.url/room.png"
style="width: 16px; height: 16px;"
/>
<span
class="mx_Pill_text"
>
room name
</span>
</a>
</bdi>
</span>
with vias
</span>
</div>
</DocumentFragment>
`;
exports[`<TextualBody /> renders formatted m.text correctly pills do not appear for event permalinks with a custom label 1`] = `
<DocumentFragment>
<div
class="mx_MTextBody mx_EventTile_content"
>
<span
class="mx_EventTile_body markdown-body"
dir="auto"
>
An
<a
href="https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/$16085560162aNpaH:example.com?via=example.com"
rel="noreferrer noopener"
>
event link
</a>
with text
</span>
</div>
</DocumentFragment>
`;
exports[`<TextualBody /> renders formatted m.text correctly pills do not appear in code blocks 1`] = `
<span
class="mx_EventTile_body markdown-body"
@ -133,7 +231,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills get injected c
style="width: 16px; height: 16px;"
/>
<span
class="mx_Pill_linkText"
class="mx_Pill_text"
>
Member
</span>