From a9e6aa3d544047ce0fd7f0b5b0b0422e157a151c Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Thu, 31 Oct 2024 16:39:53 +0000 Subject: [PATCH] Add tests for cases where we got a reaction from someone else. --- src/useReactions.test.tsx | 39 +++++++++++++++++++++++++++++++++------ src/useReactions.tsx | 21 ++++++++++----------- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/useReactions.test.tsx b/src/useReactions.test.tsx index 99db2619..79caeb0a 100644 --- a/src/useReactions.test.tsx +++ b/src/useReactions.test.tsx @@ -99,9 +99,12 @@ export class MockRTCSession extends EventEmitter { } } -function createReaction(parentMemberEvent: string): MatrixEvent { +function createReaction( + parentMemberEvent: string, + overridenSender?: string, +): MatrixEvent { return new MatrixEvent({ - sender: membership[parentMemberEvent], + sender: overridenSender ?? membership[parentMemberEvent], type: EventType.Reaction, origin_server_ts: new Date().getTime(), content: { @@ -140,15 +143,20 @@ export class MockRoom extends EventEmitter { return { getChildEventsForEvent: (membershipEventId: string) => ({ getRelations: (): MatrixEvent[] => { - const sender = membership[membershipEventId]; - return this.existingRelations.filter((r) => r.getSender() === sender); + return this.existingRelations.filter( + (r) => + r.getContent()["m.relates_to"]?.event_id === membershipEventId, + ); }, }), } as unknown as Room["relations"]; } - public testSendReaction(parentMemberEvent: string): string { - const evt = createReaction(parentMemberEvent); + public testSendReaction( + parentMemberEvent: string, + overridenSender?: string, + ): string { + const evt = createReaction(parentMemberEvent, overridenSender); this.emit(RoomEvent.Timeline, evt, this, undefined, false, { timeline: new EventTimeline(new EventTimelineSet(undefined)), }); @@ -238,4 +246,23 @@ describe("useReactions", () => { }); expect(queryByRole("list")?.children).to.have.lengthOf(0); }); + test("ignores invalid sender for historic event", () => { + const room = new MockRoom([ + createReaction(memberEventAlice, memberUserIdBob), + ]); + const rtcSession = new MockRTCSession(room); + const { queryByRole } = render( + , + ); + expect(queryByRole("list")?.children).to.have.lengthOf(0); + }); + test("ignores invalid sender for new event", async () => { + const room = new MockRoom([]); + const rtcSession = new MockRTCSession(room); + const { queryByRole } = render( + , + ); + await act(() => room.testSendReaction(memberEventAlice, memberUserIdBob)); + expect(queryByRole("list")?.children).to.have.lengthOf(0); + }); }); diff --git a/src/useReactions.tsx b/src/useReactions.tsx index 6aac4043..342c43e1 100644 --- a/src/useReactions.tsx +++ b/src/useReactions.tsx @@ -113,14 +113,17 @@ export const ReactionsProvider = ({ useEffect(() => { // Fetches the first reaction for a given event. We assume no more than // one reaction on an event here. - const getLastReactionEvent = (eventId: string): MatrixEvent | undefined => { + const getLastReactionEvent = ( + eventId: string, + expectedSender: string, + ): MatrixEvent | undefined => { const relations = room.relations.getChildEventsForEvent( eventId, RelationType.Annotation, EventType.Reaction, ); const allEvents = relations?.getRelations() ?? []; - return allEvents.find((u) => u.sender === myUserId); + return allEvents.find((u) => u.event.sender === expectedSender); }; // Remove any raised hands for users no longer joined to the call. @@ -144,7 +147,7 @@ export const ReactionsProvider = ({ // was raised, reset. removeRaisedHand(m.sender); } - const reaction = getLastReactionEvent(m.eventId); + const reaction = getLastReactionEvent(m.eventId, m.sender); const eventId = reaction?.getId(); if (!eventId) { continue; @@ -160,14 +163,10 @@ export const ReactionsProvider = ({ } } } - }, [ - room, - memberships, - myUserId, - raisedHands, - addRaisedHand, - removeRaisedHand, - ]); + // Ignoring raisedHands here because we don't want to trigger each time the raised + // hands set is updated. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [room, memberships, myUserId, addRaisedHand, removeRaisedHand]); // This effect handles any *live* reaction/redactions in the room. useEffect(() => {