Add tests for cases where we got a reaction from someone else.

This commit is contained in:
Half-Shot 2024-10-31 16:39:53 +00:00
parent 21380c7791
commit a9e6aa3d54
2 changed files with 43 additions and 17 deletions

View File

@ -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(
<TestComponentWrapper rtcSession={rtcSession} />,
);
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(
<TestComponentWrapper rtcSession={rtcSession} />,
);
await act(() => room.testSendReaction(memberEventAlice, memberUserIdBob));
expect(queryByRole("list")?.children).to.have.lengthOf(0);
});
});

View File

@ -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(() => {