diff --git a/src/Membership/StandardRoomMembershipRevision.test.ts b/src/Membership/StandardRoomMembershipRevision.test.ts new file mode 100644 index 0000000..c11504f --- /dev/null +++ b/src/Membership/StandardRoomMembershipRevision.test.ts @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 2024 Gnuxie +// +// SPDX-License-Identifier: AFL-3.0 + +import { describeRoomMember } from '../StateTracking/DeclareRoomState'; +import { randomRoomID, randomUserID } from '../TestUtilities/EventGeneration'; +import { Membership } from './MembershipChange'; +import { StandardRoomMembershipRevision } from './StandardRoomMembershipRevision'; + +test('Membership events are unintenrned', function () { + const joinLeaveUser = randomUserID(); + const room = randomRoomID([]); + const joinEvent = describeRoomMember({ + sender: joinLeaveUser, + room_id: room.toRoomIDOrAlias(), + }); + const leaveEvent = describeRoomMember({ + sender: joinLeaveUser, + room_id: room.toRoomIDOrAlias(), + membership: Membership.Leave, + }); + const revision = StandardRoomMembershipRevision.blankRevision(room) + .reviseFromMembership([joinEvent]) + .reviseFromMembership([leaveEvent]); + expect([...revision.members()].length).toBe(1); +}); diff --git a/src/Membership/StandardRoomMembershipRevision.ts b/src/Membership/StandardRoomMembershipRevision.ts index 3510e86..23172c2 100644 --- a/src/Membership/StandardRoomMembershipRevision.ts +++ b/src/Membership/StandardRoomMembershipRevision.ts @@ -126,6 +126,12 @@ export class StandardRoomMembershipRevision implements RoomMembershipRevision { change.userID, change ); + const existingMembership = this.membershipForUser(change.userID); + if (existingMembership !== undefined) { + nextMembershipByEventID = nextMembershipByEventID.delete( + existingMembership.eventID + ); + } nextMembershipByEventID = nextMembershipByEventID.set( change.eventID, change diff --git a/src/TestUtilities/EventGeneration.ts b/src/TestUtilities/EventGeneration.ts index 3e9a9d2..d05dffa 100644 --- a/src/TestUtilities/EventGeneration.ts +++ b/src/TestUtilities/EventGeneration.ts @@ -12,8 +12,10 @@ import { MatrixRoomReference, } from '../MatrixTypes/MatrixRoomReference'; import { + StringEventID, StringRoomID, StringUserID, + isStringEventID, isStringRoomID, isStringUserID, } from '../MatrixTypes/StringlyTypedMatrix'; @@ -66,7 +68,7 @@ export function makePolicyRuleUserEvent({ }); const rawEventJSON = { room_id, - event_id: `$${randomUUID()}:example.com`, + event_id: randomEventID(), origin_server_ts: Date.now(), state_key: description.state_key, type: description.type, @@ -109,3 +111,11 @@ export function randomUserID(): StringUserID { } return userID; } + +export function randomEventID(): StringEventID { + const eventID = `$${randomUUID()}:example.com`; + if (!isStringEventID(eventID)) { + throw new TypeError(`EventID generator is wrong`); + } + return eventID; +}