@@ -10,12 +10,17 @@ import (
1010 "fmt"
1111 "net/url"
1212 "testing"
13+ "time"
14+
15+ "github.com/matrix-org/gomatrixserverlib"
16+
17+ "github.com/tidwall/gjson"
1318
1419 "github.com/matrix-org/complement/internal/b"
1520 "github.com/matrix-org/complement/internal/client"
21+ "github.com/matrix-org/complement/internal/federation"
1622 "github.com/matrix-org/complement/internal/match"
1723 "github.com/matrix-org/complement/internal/must"
18- "github.com/tidwall/gjson"
1924)
2025
2126// A reason to include in the request body when testing knock reason parameters
@@ -40,6 +45,20 @@ func TestKnocking(t *testing.T) {
4045 charlieUserID := "@charlie:hs2"
4146 charlie := deployment .Client (t , "hs2" , charlieUserID )
4247
48+ // Create a server to observe
49+ inviteWaiter := NewWaiter ()
50+ srv := federation .NewServer (t , deployment ,
51+ federation .HandleKeyRequests (),
52+ federation .HandleInviteRequests (func (ev * gomatrixserverlib.Event ) {
53+ inviteWaiter .Finish ()
54+ }),
55+ federation .HandleTransactionRequests (nil , nil ),
56+ )
57+ cancel := srv .Listen ()
58+ defer cancel ()
59+ srv .UnexpectedRequestsAreErrors = false
60+ david := srv .UserID ("david" )
61+
4362 // Create a room for alice and bob to test knocking with
4463 roomIDOne := alice .CreateRoom (t , struct {
4564 Preset string `json:"preset"`
@@ -48,9 +67,12 @@ func TestKnocking(t *testing.T) {
4867 "private_chat" , // Set to private in order to get an invite-only room
4968 "7" , // Room version required for knocking.
5069 })
70+ alice .InviteRoom (t , roomIDOne , david )
71+ inviteWaiter .Wait (t , 5 * time .Second )
72+ serverRoomOne := srv .MustJoinRoom (t , deployment , "hs1" , roomIDOne , david )
5173
5274 // Test knocking between two users on the same homeserver
53- knockingBetweenTwoUsersTest (t , roomIDOne , alice , bob , false )
75+ knockingBetweenTwoUsersTest (t , roomIDOne , alice , bob , serverRoomOne , false )
5476
5577 // Create a room for alice and charlie to test knocking with
5678 roomIDTwo := alice .CreateRoom (t , struct {
@@ -60,12 +82,16 @@ func TestKnocking(t *testing.T) {
6082 "private_chat" , // Set to private in order to get an invite-only room
6183 "7" , // Room version required for knocking.
6284 })
85+ inviteWaiter = NewWaiter ()
86+ alice .InviteRoom (t , roomIDTwo , david )
87+ inviteWaiter .Wait (t , 5 * time .Second )
88+ serverRoomTwo := srv .MustJoinRoom (t , deployment , "hs1" , roomIDTwo , david )
6389
6490 // Test knocking between two users, each on a separate homeserver
65- knockingBetweenTwoUsersTest (t , roomIDTwo , alice , charlie , true )
91+ knockingBetweenTwoUsersTest (t , roomIDTwo , alice , charlie , serverRoomTwo , true )
6692}
6793
68- func knockingBetweenTwoUsersTest (t * testing.T , roomID string , inRoomUser , knockingUser * client.CSAPI , federation bool ) {
94+ func knockingBetweenTwoUsersTest (t * testing.T , roomID string , inRoomUser , knockingUser * client.CSAPI , serverRoom * federation. ServerRoom , testFederation bool ) {
6995 t .Run ("Knocking on a room with a join rule other than 'knock' should fail" , func (t * testing.T ) {
7096 knockOnRoomWithStatus (t , knockingUser , roomID , "Can I knock anyways?" , []string {"hs1" }, 403 )
7197 })
@@ -109,6 +135,19 @@ func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knocki
109135 })
110136
111137 t .Run ("Users in the room see a user's membership update when they knock" , func (t * testing.T ) {
138+ // check the membership seen over the federation
139+ knockerState := serverRoom .CurrentState ("m.room.member" , knockingUser .UserID )
140+ if knockerState == nil {
141+ t .Errorf ("Did not get membership state for knocking user" )
142+ } else {
143+ m , err := knockerState .Membership ()
144+ if err != nil {
145+ t .Errorf ("Unable to unpack membership state for knocking user: %v" , err )
146+ } else if m != "knock" {
147+ t .Errorf ("membership for knocking user: got %#v, want \" knock\" " , m )
148+ }
149+ }
150+
112151 inRoomUser .SyncUntilTimelineHas (t , roomID , func (ev gjson.Result ) bool {
113152 if ev .Get ("type" ).Str != "m.room.member" || ev .Get ("sender" ).Str != knockingUser .UserID {
114153 return false
@@ -119,7 +158,7 @@ func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knocki
119158 })
120159 })
121160
122- if ! federation {
161+ if ! testFederation {
123162 // Rescinding a knock over federation is currently not specced
124163 t .Run ("A user that has knocked on a local room can rescind their knock and then knock again" , func (t * testing.T ) {
125164 // We need to carry out an incremental sync after knocking in order to get leave information
0 commit comments