Phase 2 : Refactor TextualBody to MVVM and remove legacy component (#33165)

* Refactor TextualBody to MVVM and remove legacy component

* Update snapshot + fix eslint warning

* update css to fix playwright tests failure

* return i18n into the MVVM

* Update snapshots

* Update tests to reflect the css changes

* Update snapshot

* Update css to correct letter-spacing

* Update css to fix playwright issues.

* Preserve inline emote sender rendering in TextualBodyView

* Update snapshot to reflect html change

* Update back to span instead of button, the default button css fails tests

* Extract TextualBodyFactory from MBodyFactory

* Update snapshot

* Update HTML snapshot to pass tests

* Update Snapshots

* Added several tests for coverage

* Remove double checks, merge function already checks.

* Remove unessecery comment

* revert to button

* Update snapshots because of the revert

* added Math.min() to simplify ternary expressions.

* Update playwright screenshots for accessibility

* Update playwright screenshots

* Update css to fix playwright fail

* Update screenshot + snapshots

* Add comments to props
This commit is contained in:
Zack
2026-04-28 07:07:19 +00:00
committed by GitHub
parent 7766ae92d7
commit 4e9655dc6b
42 changed files with 1061 additions and 555 deletions
@@ -38,6 +38,11 @@ jest.mock("../../../../../src/components/views/messages/MBodyFactory", () => ({
renderMBody: () => <div data-testid="file-body" />,
}));
jest.mock("../../../../../src/components/views/messages/TextualBodyFactory", () => ({
__esModule: true,
TextualBodyFactory: () => <div data-testid="textual-body" />,
}));
jest.mock("../../../../../src/components/views/messages/MImageReplyBody", () => ({
__esModule: true,
default: () => <div data-testid="image-reply-body" />,
@@ -53,11 +58,6 @@ jest.mock("../../../../../src/components/views/messages/MStickerBody", () => ({
default: () => <div data-testid="sticker-body" />,
}));
jest.mock("../../../../../src/components/views/messages/TextualBody.tsx", () => ({
__esModule: true,
default: () => <div data-testid="textual-body" />,
}));
describe("MessageEvent", () => {
let room: Room;
let client: MatrixClient;
@@ -21,13 +21,18 @@ import {
} from "../../../../test-utils";
import * as languageHandler from "../../../../../src/languageHandler";
import DMRoomMap from "../../../../../src/utils/DMRoomMap";
import TextualBody from "../../../../../src/components/views/messages/TextualBody";
import { TextualBodyFactory as TextualBody } from "../../../../../src/components/views/messages/TextualBodyFactory";
import MatrixClientContext from "../../../../../src/contexts/MatrixClientContext";
import RoomContext from "../../../../../src/contexts/RoomContext";
import { RoomPermalinkCreator } from "../../../../../src/utils/permalinks/Permalinks";
import { type MediaEventHelper } from "../../../../../src/utils/MediaEventHelper";
import { getRoomContext } from "../../../../test-utils/room";
jest.mock("../../../../../src/hooks/useMediaVisible", () => ({
__esModule: true,
useMediaVisible: () => [true, jest.fn()],
}));
const room1Id = "!room1:example.com";
const room2Id = "!room2:example.com";
const room2Name = "Room 2";
@@ -104,7 +109,6 @@ describe("<TextualBody />", () => {
defaultMatrixClient.pushProcessor = new PushProcessor(defaultMatrixClient);
defaultRoom = mkStubRoom(room1Id, "test room", defaultMatrixClient);
defaultProps.permalinkCreator = new RoomPermalinkCreator(defaultRoom);
otherRoom = mkStubRoom(room2Id, room2Name, defaultMatrixClient);
mocked(defaultRoom).findEventById.mockImplementation((eventId: string) => {
@@ -117,10 +121,14 @@ describe("<TextualBody />", () => {
const getComponent = (props = {}, matrixClient: MatrixClient = defaultMatrixClient, renderingFn?: any) => {
const mergedProps = { ...defaultProps, ...props };
const room = matrixClient.getRoom(mergedProps.mxEvent.getRoomId()) ?? defaultRoom;
const finalProps = {
...mergedProps,
permalinkCreator: mergedProps.permalinkCreator ?? new RoomPermalinkCreator(room),
};
return (renderingFn ?? render)(
<MatrixClientContext.Provider value={matrixClient}>
<RoomContext.Provider value={getRoomContext(room, {})}>
<TextualBody {...mergedProps} />
<TextualBody {...finalProps} />
</RoomContext.Provider>
</MatrixClientContext.Provider>,
);
@@ -163,9 +171,7 @@ describe("<TextualBody />", () => {
const { container } = getComponent({ mxEvent: ev, replacingEventId: ev.getId() });
const annotated = container.querySelector(".mx_MEmoteBody > .mx_EventTile_annotatedInline");
expect(annotated).not.toBeNull();
expect(annotated?.tagName).toBe("DIV");
expect(container).toHaveTextContent("* sender winks(edited)");
});
it("renders m.notice correctly", () => {
@@ -130,7 +130,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for an
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"
class="mx_MTextBody mx_EventTile_content _root_1hgc7_8 _text_1hgc7_13"
>
<div
class="mx_EventTile_body markdown-body translate"
@@ -177,7 +177,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for eve
exports[`<TextualBody /> renders formatted m.text correctly pills appear for room links with vias 1`] = `
<DocumentFragment>
<div
class="mx_MTextBody mx_EventTile_content"
class="mx_MTextBody mx_EventTile_content _root_1hgc7_8 _text_1hgc7_13"
>
<div
class="mx_EventTile_body markdown-body translate"
@@ -225,7 +225,7 @@ exports[`<TextualBody /> renders formatted m.text correctly pills appear for roo
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"
class="mx_MTextBody mx_EventTile_content _root_1hgc7_8 _text_1hgc7_13"
>
<div
class="mx_EventTile_body markdown-body translate"