From f9ad2a5151eb5a9ba5ed607842767d62750d5d8b Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 3 Mar 2022 07:54:44 -0500 Subject: [PATCH] Hide unpinnable pinned messages in more cases (#7921) * Hide unpinnable pinned messages in more cases Signed-off-by: Robin Townsend * Fix typo Signed-off-by: Robin Townsend * Test that unpinnable pinned messages get hidden Signed-off-by: Robin Townsend * Fix cli.relations error in test Signed-off-by: Robin Townsend * Use event: true shortcut when calling mkEvent Signed-off-by: Robin Townsend * Use mockResolvedValue instead of mockReturnValue for async mock Signed-off-by: Robin Townsend * Actually mock redacted messages correctly Signed-off-by: Robin Townsend * Ensure that panel is updated before assertions are made Signed-off-by: Robin Townsend * Move calls to update out of act They don't need to be there. Signed-off-by: Robin Townsend --- .../views/right_panel/PinnedMessagesCard.tsx | 2 +- .../right_panel/PinnedMessagesCard-test.tsx | 100 ++++++++++++++++++ test/test-utils/test-utils.ts | 1 + 3 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 test/components/views/right_panel/PinnedMessagesCard-test.tsx diff --git a/src/components/views/right_panel/PinnedMessagesCard.tsx b/src/components/views/right_panel/PinnedMessagesCard.tsx index d6a5139b5e..1b110a76c3 100644 --- a/src/components/views/right_panel/PinnedMessagesCard.tsx +++ b/src/components/views/right_panel/PinnedMessagesCard.tsx @@ -99,7 +99,7 @@ const PinnedMessagesCard = ({ room, onClose }: IProps) => { const promises = pinnedEventIds.map(async eventId => { const timelineSet = room.getUnfilteredTimelineSet(); const localEvent = timelineSet?.getTimelineForEvent(eventId)?.getEvents().find(e => e.getId() === eventId); - if (localEvent) return localEvent; + if (localEvent) return PinningUtils.isPinnable(localEvent) ? localEvent : null; try { // Fetch the event and latest edit in parallel diff --git a/test/components/views/right_panel/PinnedMessagesCard-test.tsx b/test/components/views/right_panel/PinnedMessagesCard-test.tsx new file mode 100644 index 0000000000..3c0fb73aa1 --- /dev/null +++ b/test/components/views/right_panel/PinnedMessagesCard-test.tsx @@ -0,0 +1,100 @@ +/* +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 { mount } from "enzyme"; +import { act } from "react-dom/test-utils"; +import { MatrixEvent } from "matrix-js-sdk/src/models/event"; +import { EventType } from "matrix-js-sdk/src/@types/event"; + +import "../../../skinned-sdk"; +import { stubClient, wrapInMatrixClientContext, mkStubRoom, mkEvent } from "../../../test-utils"; +import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; +import _PinnedMessagesCard from "../../../../src/components/views/right_panel/PinnedMessagesCard"; +import PinnedEventTile from "../../../../src/components/views/rooms/PinnedEventTile"; + +describe("", () => { + stubClient(); + const cli = MatrixClientPeg.get(); + cli.setRoomAccountData = () => {}; + cli.relations = jest.fn().mockResolvedValue({ events: [] }); + const PinnedMessagesCard = wrapInMatrixClientContext(_PinnedMessagesCard); + + const mkRoom = (localPins: MatrixEvent[], nonLocalPins: MatrixEvent[]) => { + const pins = [...localPins, ...nonLocalPins]; + const room = mkStubRoom(); + + // Insert pin IDs into room state + const pinState = mkEvent({ + event: true, + type: EventType.RoomPinnedEvents, + content: { + pinned: pins.map(e => e.getId()), + }, + }); + room.currentState.getStateEvents.mockReturnValue(pinState); + + // Insert local pins into local timeline set + room.getUnfilteredTimelineSet = () => ({ + getTimelineForEvent: () => ({ + getEvents: () => localPins, + }), + }); + + // Return all pins over fetchRoomEvent + cli.fetchRoomEvent = (roomId, eventId) => pins.find(e => e.getId() === eventId)?.event; + + return room; + }; + + it("hides unpinnable events found in local timeline", async () => { + // Redacted messages are unpinnable + const pin = mkEvent({ + event: true, + type: EventType.RoomMessage, + content: {}, + unsigned: { redacted_because: {} }, + }); + + let pins; + await act(async () => { + pins = mount( {}} />); + // Wait a tick for state updates + await new Promise(resolve => setImmediate(resolve)); + }); + pins.update(); + expect(pins.find(PinnedEventTile).length).toBe(0); + }); + + it("hides unpinnable events not found in local timeline", async () => { + // Redacted messages are unpinnable + const pin = mkEvent({ + event: true, + type: EventType.RoomMessage, + content: {}, + unsigned: { redacted_because: {} }, + }); + + let pins; + await act(async () => { + pins = mount( {}} />); + // Wait a tick for state updates + await new Promise(resolve => setImmediate(resolve)); + }); + pins.update(); + expect(pins.find(PinnedEventTile).length).toBe(0); + }); +}); diff --git a/test/test-utils/test-utils.ts b/test/test-utils/test-utils.ts index a894faf550..747aa9ab1b 100644 --- a/test/test-utils/test-utils.ts +++ b/test/test-utils/test-utils.ts @@ -172,6 +172,7 @@ export function mkEvent(opts: MakeEventProps): MatrixEvent { prev_content: opts.prev_content, event_id: "$" + Math.random() + "-" + Math.random(), origin_server_ts: opts.ts, + unsigned: opts.unsigned, }; if (opts.skey) { event.state_key = opts.skey;