Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to tests for restricted rooms based on changes to MSC3083. #145

Merged
merged 8 commits into from
Jul 26, 2021
133 changes: 130 additions & 3 deletions tests/msc3083_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func setupRestrictedRoom(t *testing.T, deployment *docker.Deployment) (*client.C
room := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"room_version": "org.matrix.msc3083.v2",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
Expand Down Expand Up @@ -90,6 +90,9 @@ func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, s
bob.JoinRoom(t, space, []string{"hs1"})
bob.JoinRoom(t, room, []string{"hs1"})

// Joining the same room again should work fine (e.g. to change your display name).
bob.JoinRoom(t, room, []string{"hs1"})

// Leaving the room works and the user is unable to re-join.
bob.LeaveRoom(t, room)
bob.LeaveRoom(t, space)
Expand Down Expand Up @@ -181,6 +184,130 @@ func TestRestrictedRoomsRemoteJoin(t *testing.T) {
checkRestrictedRoom(t, alice, bob, space, room)
}

// Not all servers can issue join events for a restricted room. Ensure a join
// completes successfully when a server is in a room, but unable to issue joins
// for it.
func TestRestrictedRoomsLimitedJoin(t *testing.T) {
deployment := Deploy(t, b.BlueprintFederationTwoLocalOneRemote)
defer deployment.Destroy(t)

// Charlie sets up the space so it is on the other server.
charlie := deployment.Client(t, "hs2", "@charlie:hs2")
space := charlie.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Space",
"creation_content": map[string]interface{}{
"type": "m.space",
},
})
// The room is an unstable room version which supports the restricted join_rule.
room := charlie.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083.v2",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
"state_key": "",
"content": map[string]interface{}{
"join_rule": "restricted",
"allow": []map[string]interface{}{
{
"type": "m.room_membership",
"room_id": &space,
"via": []string{"hs2"},
},
},
},
},
},
})
charlie.SendEventSynced(t, space, b.Event{
Type: "m.space.child",
StateKey: &room,
Content: map[string]interface{}{
"via": []string{"hs2"},
},
})

// Invite alice manually and accept it.
alice := deployment.Client(t, "hs1", "@alice:hs1")
charlie.InviteRoom(t, room, alice.UserID)
alice.JoinRoom(t, room, []string{"hs2"})

// Alice should not be able to issue invites.
clokep marked this conversation as resolved.
Show resolved Hide resolved
bob := deployment.Client(t, "hs1", "@bob:hs1")
body := map[string]interface{}{
"user_id": bob.UserID,
}
res := alice.DoFunc(
t,
"POST",
[]string{"_matrix", "client", "r0", "rooms", room, "invite"},
client.WithJSONBody(t, body),
)
must.MatchResponse(t, res, match.HTTPResponse{
StatusCode: 403,
})

// Bob cannot join the room.
failJoinRoom(t, bob, room, "hs1")

// Join the space, joining the room should work, but will bounce through hs2.
clokep marked this conversation as resolved.
Show resolved Hide resolved
bob.JoinRoom(t, space, []string{"hs2"})
bob.JoinRoom(t, room, []string{"hs1"})

// Ensure that the join comes down sync on hs2. Note that we want to ensure hs2
// accepted the event.
charlie.SyncUntilTimelineHas(
t,
room,
func(ev gjson.Result) bool {
if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != bob.UserID {
return false
}
must.EqualStr(t, ev.Get("sender").Str, bob.UserID, "Bob should have joined by himself")
must.EqualStr(t, ev.Get("content").Get("membership").Str, "join", "Bob failed to join the room")

return true
},
)

// Raise the power level so that users on hs1 can invite people and then leave
// the room.
state_key := ""
charlie.SendEventSynced(t, room, b.Event{
Type: "m.room.power_levels",
StateKey: &state_key,
Content: map[string]interface{}{
"invite": 0,
"users": map[string]interface{}{
charlie.UserID: 100,
},
},
})
charlie.LeaveRoom(t, room)

// Ensure the events have synced to hs1.
alice.SyncUntilTimelineHas(
t,
room,
func(ev gjson.Result) bool {
if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != charlie.UserID {
return false
}
must.EqualStr(t, ev.Get("content").Get("membership").Str, "leave", "Charlie failed to leave the room")

return true
},
)

// Have bob leave and rejoin. This should still work even though hs2 isn't in
// the room anymore!
bob.LeaveRoom(t, room)
bob.JoinRoom(t, room, []string{"hs1"})
}

// Request the room summary and ensure the expected rooms are in the response.
func requestAndAssertSummary(t *testing.T, user *client.CSAPI, space string, expected_rooms []interface{}) {
t.Helper()
Expand Down Expand Up @@ -229,7 +356,7 @@ func TestRestrictedRoomsSpacesSummary(t *testing.T) {
room := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"room_version": "org.matrix.msc3083.v2",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
Expand Down Expand Up @@ -312,7 +439,7 @@ func TestRestrictedRoomsSpacesSummaryFederation(t *testing.T) {
room := charlie.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"room_version": "org.matrix.msc3083.v2",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
Expand Down