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;