Skip to content

Commit de7469f

Browse files
committed
Start of test with engineered conditions to always reproduce tricky invite scenario
Regression tests for element-hq/synapse#18075
1 parent 8f0c763 commit de7469f

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

federation/server.go

+51
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,57 @@ func (s *Server) MustCreateEvent(t ct.TestLike, room *ServerRoom, ev Event) goma
357357
return signedEvent
358358
}
359359

360+
// Invite someone a room.
361+
func (s *Server) MustInviteRoom(
362+
t ct.TestLike,
363+
deployment FederationDeployment,
364+
remoteServer spec.ServerName,
365+
roomID string,
366+
inviterUserID string,
367+
inviteeUserID string,
368+
) {
369+
t.Helper()
370+
fedClient := s.FederationClient(deployment)
371+
372+
room := s.rooms[roomID]
373+
if room == nil {
374+
ct.Fatalf(t, "MustInviteRoom: room %s not found", roomID)
375+
}
376+
roomVersionImplementation, err := gomatrixserverlib.GetRoomVersion(room.Version)
377+
378+
rawInviteEvent := s.MustCreateEvent(t, room, Event{
379+
Type: "m.room.member",
380+
StateKey: &inviterUserID,
381+
Sender: inviteeUserID,
382+
Content: map[string]interface{}{
383+
"membership": "invite",
384+
},
385+
})
386+
inviteReq, err := fclient.NewInviteV2Request(rawInviteEvent, []gomatrixserverlib.InviteStrippedState{})
387+
if err != nil {
388+
t.Fatalf("failed to make invite request: %s", err)
389+
}
390+
sendInviteResp, err := fedClient.SendInviteV2(
391+
context.Background(),
392+
spec.ServerName(s.ServerName()),
393+
remoteServer,
394+
inviteReq,
395+
)
396+
if err != nil {
397+
t.Fatalf("MustInviteRoom: failed to send invite v2: %s", err)
398+
}
399+
400+
inviteEvent, err := roomVersionImplementation.NewEventFromUntrustedJSON(sendInviteResp.Event)
401+
if err != nil {
402+
t.Fatalf("MustInviteRoom: failed to decode event response: %w", err)
403+
}
404+
405+
room.AddEvent(inviteEvent)
406+
s.rooms[roomID] = room
407+
408+
t.Logf("Server.MustInviteRoom %s invited %s to room ID %s", inviterUserID, inviteeUserID, roomID)
409+
}
410+
360411
// MustJoinRoom will make the server send a make_join and a send_join to join a room
361412
// It returns the resultant room.
362413
func (s *Server) MustJoinRoom(t ct.TestLike, deployment FederationDeployment, remoteServer spec.ServerName, roomID string, userID string, partialState ...bool) *ServerRoom {

tests/federation_rooms_invite_test.go

+41-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/tidwall/gjson"
1414

1515
"github.com/matrix-org/complement/client"
16+
"github.com/matrix-org/complement/federation"
1617
"github.com/matrix-org/complement/helpers"
1718
"github.com/matrix-org/complement/match"
1819
"github.com/matrix-org/complement/must"
@@ -99,7 +100,7 @@ func TestFederationRoomsInvite(t *testing.T) {
99100
verifyState(t, res, wantFields, wantValues, roomID, alice)
100101
})
101102

102-
t.Run("Remote invited user can join the room when homeserver is already participating in the room", func(t *testing.T) {
103+
t.Run("Remote invited user can join the room when homeserver is already participating in the room (e2e)", func(t *testing.T) {
103104
t.Parallel()
104105
roomID := alice.MustCreateRoom(t, map[string]interface{}{
105106
"preset": "private_chat",
@@ -121,7 +122,7 @@ func TestFederationRoomsInvite(t *testing.T) {
121122
alice.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(bob2.UserID, roomID))
122123
})
123124

124-
t.Run("Remote invited user can reject invite when homeserver is already participating in the room", func(t *testing.T) {
125+
t.Run("Remote invited user can reject invite when homeserver is already participating in the room (e2e)", func(t *testing.T) {
125126
t.Parallel()
126127
roomID := alice.MustCreateRoom(t, map[string]interface{}{
127128
"preset": "private_chat",
@@ -143,6 +144,44 @@ func TestFederationRoomsInvite(t *testing.T) {
143144
alice.MustSyncUntil(t, client.SyncReq{Filter: includeLeaveSyncFilter}, client.SyncLeftFrom(bob2.UserID, roomID))
144145
})
145146

147+
// Engineered condition where we only send `/invite` requests over federation and do
148+
// not send the event in a `/send` transaction. Regression tests for
149+
// https://github.com/element-hq/synapse/pull/18075
150+
t.Run("Remote invited user can join the room when homeserver is already participating in the room (engineered)", func(t *testing.T) {
151+
t.Parallel()
152+
153+
srv := federation.NewServer(t, deployment,
154+
federation.HandleKeyRequests(),
155+
// bob1 will use this to join the remote room
156+
federation.HandleMakeSendJoinRequests(),
157+
)
158+
cancel := srv.Listen()
159+
defer cancel()
160+
161+
engineeredAliceUserId := srv.UserID("alice")
162+
163+
roomVersion := alice.GetDefaultRoomVersion(t)
164+
initalEvents := federation.InitialRoomEvents(roomVersion, engineeredAliceUserId)
165+
serverRoom := srv.MustMakeRoom(t, roomVersion, initalEvents)
166+
roomID := serverRoom.RoomID
167+
168+
// bob1 is invited and can join the room (hs2 is now participating of the room)
169+
//
170+
// alice.MustInviteRoom(t, roomID, bob.UserID)
171+
srv.MustInviteRoom(t, deployment, "hs1", roomID, engineeredAliceUserId, bob.UserID)
172+
bob.MustSyncUntil(t, client.SyncReq{}, client.SyncInvitedTo(bob.UserID, roomID))
173+
bob.MustJoinRoom(t, roomID, []string{srv.ServerName()})
174+
// Make sure alice can see bob in the room
175+
// alice.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(bob.UserID, roomID))
176+
177+
// bob2 is invited and can also join the room
178+
// alice.MustInviteRoom(t, roomID, bob2.UserID)
179+
// bob2.MustSyncUntil(t, client.SyncReq{}, client.SyncInvitedTo(bob2.UserID, roomID))
180+
// bob2.MustJoinRoom(t, roomID, []string{srv.ServerName()})
181+
// // Make sure alice can see bob2 in the room
182+
// alice.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(bob2.UserID, roomID))
183+
})
184+
146185
t.Run("Invited user has 'is_direct' flag in prev_content after joining", func(t *testing.T) {
147186
roomID := alice.MustCreateRoom(t, map[string]interface{}{
148187
"preset": "private_chat",

0 commit comments

Comments
 (0)