diff --git a/ee/packages/federation-matrix/tests/end-to-end/room.spec.ts b/ee/packages/federation-matrix/tests/end-to-end/room.spec.ts index ecbd82b2bae4f..8a76d7ef1a4e4 100644 --- a/ee/packages/federation-matrix/tests/end-to-end/room.spec.ts +++ b/ee/packages/federation-matrix/tests/end-to-end/room.spec.ts @@ -1647,18 +1647,62 @@ import { SynapseClient } from '../helper/synapse-client'; rid = pendingInvitation?.rid!; }, 15000); - it('It should allow RC user to reject the invite', async () => { + it('should allow RC user to reject the invite and remove the subscription', async () => { const rejectResponse = await rejectRoomInvite(rid, rc1AdminRequestConfig); expect(rejectResponse.success).toBe(true); - }); - it('It should remove the subscription after rejection', async () => { const subscriptions = await getSubscriptions(rc1AdminRequestConfig); - const invitedSub = subscriptions.update.find((sub) => sub.fname?.includes(channelName)); - expect(invitedSub).toBeFalsy(); }); }); + + describe('Revoked invitation flow from Synapse', () => { + describe('Synapse revokes an invitation before the RC user responds', () => { + let matrixRoomId: string; + let channelName: string; + let rid: string; + + beforeAll(async () => { + channelName = `federated-channel-revoked-${Date.now()}`; + matrixRoomId = await hs1AdminApp.createRoom(channelName); + + // hs1 invites RC user + await hs1AdminApp.matrixClient.invite(matrixRoomId, federationConfig.rc1.adminMatrixUserId); + const subscriptions = await getSubscriptions(rc1AdminRequestConfig); + + const pendingInvitation = subscriptions.update.find( + (subscription) => subscription.status === 'INVITED' && subscription.fname?.includes(channelName), + ); + + expect(pendingInvitation).not.toBeUndefined(); + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + rid = pendingInvitation?.rid!; + + // hs1 revokes the invitation by kicking the invited user + await hs1AdminApp.matrixClient.kick(matrixRoomId, federationConfig.rc1.adminMatrixUserId, 'Invitation revoked'); + }, 15000); + + it('should fail when RC user tries to accept the revoked invitation', async () => { + const acceptResponse = await acceptRoomInvite(rid, rc1AdminRequestConfig); + expect(acceptResponse.success).toBe(false); + }); + + it('should allow RC user to reject the revoked invitation and remove the subscription', async () => { + const rejectResponse = await rejectRoomInvite(rid, rc1AdminRequestConfig); + expect(rejectResponse.success).toBe(true); + + const subscriptions = await getSubscriptions(rc1AdminRequestConfig); + const invitedSub = subscriptions.update.find((sub) => sub.fname?.includes(channelName)); + expect(invitedSub).toBeFalsy(); + }); + + it('should have the RC user with leave membership on Synapse side after revoked invitation', async () => { + const member = await hs1AdminApp.findRoomMember(channelName, federationConfig.rc1.adminMatrixUserId); + expect(member?.membership).toBe('leave'); + }); + }); + }); }); });