From 48ae16b5a55091ee71645fc2def6dc179e28af79 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 9 Aug 2022 15:37:13 +0100 Subject: [PATCH] Fix pillification sometimes doubling up (#9152) * Fix pillification sometimes doubling up * Remove redundant assignment * Add unit tests around pillification * Kill ts-ignore --- src/utils/pillify.tsx | 4 +- test/utils/pillify-test.tsx | 93 +++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 test/utils/pillify-test.tsx diff --git a/src/utils/pillify.tsx b/src/utils/pillify.tsx index 87b95007e32..b7a1b4e5583 100644 --- a/src/utils/pillify.tsx +++ b/src/utils/pillify.tsx @@ -44,8 +44,8 @@ export function pillifyLinks(nodes: ArrayLike, mxEvent: MatrixEvent, pi while (node) { let pillified = false; - if (node.tagName === "PRE" || node.tagName === "CODE") { - // Skip code blocks + if (node.tagName === "PRE" || node.tagName === "CODE" || pills.includes(node)) { + // Skip code blocks and existing pills node = node.nextSibling as Element; continue; } else if (node.tagName === "A" && node.getAttribute("href")) { diff --git a/test/utils/pillify-test.tsx b/test/utils/pillify-test.tsx new file mode 100644 index 00000000000..1ceff1cb848 --- /dev/null +++ b/test/utils/pillify-test.tsx @@ -0,0 +1,93 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from "react"; +import { render } from "@testing-library/react"; +import { MatrixEvent } from "matrix-js-sdk/src/models/event"; +import { ConditionKind, EventType, PushRuleActionName, Room, TweakName } from "matrix-js-sdk/src/matrix"; + +import { pillifyLinks } from "../../src/utils/pillify"; +import { stubClient } from "../test-utils"; +import { MatrixClientPeg } from "../../src/MatrixClientPeg"; +import DMRoomMap from "../../src/utils/DMRoomMap"; + +describe("pillify", () => { + const roomId = "!room:id"; + const event = new MatrixEvent({ + room_id: roomId, + type: EventType.RoomMessage, + content: { + body: "@room", + }, + }); + + beforeEach(() => { + stubClient(); + const cli = MatrixClientPeg.get(); + (cli.getRoom as jest.Mock).mockReturnValue(new Room(roomId, cli, cli.getUserId())); + cli.pushRules.global = { + override: [ + { + rule_id: ".m.rule.roomnotif", + default: true, + enabled: true, + conditions: [{ + kind: ConditionKind.EventMatch, + key: "content.body", + pattern: "@room", + }], + actions: [ + PushRuleActionName.Notify, + { + set_tweak: TweakName.Highlight, + value: true, + }, + ], + }, + ], + }; + + DMRoomMap.makeShared(); + }); + + it("should do nothing for empty element", () => { + const { container } = render(
); + const originalHtml = container.outerHTML; + const containers: Element[] = []; + pillifyLinks([container], event, containers); + expect(containers).toHaveLength(0); + expect(container.outerHTML).toEqual(originalHtml); + }); + + it("should pillify @room", () => { + const { container } = render(
@room
); + const containers: Element[] = []; + pillifyLinks([container], event, containers); + expect(containers).toHaveLength(1); + expect(container.querySelector(".mx_Pill.mx_AtRoomPill").textContent).toBe("!@room"); + }); + + it("should not double up pillification on repeated calls", () => { + const { container } = render(
@room
); + const containers: Element[] = []; + pillifyLinks([container], event, containers); + pillifyLinks([container], event, containers); + pillifyLinks([container], event, containers); + pillifyLinks([container], event, containers); + expect(containers).toHaveLength(1); + expect(container.querySelector(".mx_Pill.mx_AtRoomPill").textContent).toBe("!@room"); + }); +});