Skip to content

Commit

Permalink
Add a test for restricted rooms appearing in the spaces summary (MSC3083
Browse files Browse the repository at this point in the history
). (#109)
  • Loading branch information
clokep authored Jun 2, 2021
1 parent 3ddda9b commit 726472e
Showing 1 changed file with 168 additions and 1 deletion.
169 changes: 168 additions & 1 deletion tests/msc3083_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build msc3083
// +build msc2946,msc3083

// Tests MSC3083, an experimental feature for joining restricted rooms based on
// membership in a space.
Expand All @@ -14,6 +14,7 @@ import (
"github.com/matrix-org/complement/internal/docker"
"github.com/matrix-org/complement/internal/match"
"github.com/matrix-org/complement/internal/must"
"github.com/tidwall/gjson"
)

func failJoinRoom(t *testing.T, c *client.CSAPI, roomIDOrAlias string, serverName string) {
Expand Down Expand Up @@ -163,3 +164,169 @@ func TestRestrictedRoomsRemoteJoin(t *testing.T) {
// Execute the checks.
checkRestrictedRoom(t, alice, bob, space, room)
}

// 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()

res := user.MustDo(t, "POST", []string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", space, "spaces"}, map[string]interface{}{})
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", expected_rooms, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
},
})
}

// Tests that MSC2946 works for a restricted room.
//
// Create a space with a room in it that has join rules restricted to membership
// in that space.
//
// The user should be unable to see the room in the spaces summary unless they
// are a member of the space.
func TestRestrictedRoomsSpacesSummary(t *testing.T) {
deployment := Deploy(t, b.BlueprintOneToOneRoom)
defer deployment.Destroy(t)

// Create the rooms
alice := deployment.Client(t, "hs1", "@alice:hs1")
space := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Space",
// World readable to allow peeking without joining.
"initial_state": []map[string]interface{}{
{
"type": "m.room.history_visibility",
"state_key": "",
"content": map[string]interface{}{
"history_visibility": "world_readable",
},
},
},
})
// The room is an unstable room version which supports the restricted join_rule.
room := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
"state_key": "",
"content": map[string]interface{}{
"join_rule": "restricted",
"allow": []map[string]interface{}{
{
"space": &space,
"via": []string{"hs1"},
},
},
},
},
},
})
alice.SendEventSynced(t, space, b.Event{
Type: "org.matrix.msc1772.space.child",
StateKey: &room,
Content: map[string]interface{}{
"via": []string{"hs1"},
},
})

t.Logf("Space: %s", space)
t.Logf("Room: %s", room)

// Create a second user on the same homeserver.
bob := deployment.Client(t, "hs1", "@bob:hs1")

// Querying the space returns only the space, as the room is restricted.
requestAndAssertSummary(t, bob, space, []interface{}{space})

// Join the space, and now the restricted room should appear.
bob.JoinRoom(t, space, []string{"hs1"})
requestAndAssertSummary(t, bob, space, []interface{}{space, room})
}

// Tests that MSC2946 works over federation for a restricted room.
//
// Create a space with a room in it that has join rules restricted to membership
// in that space. The space and room are on different homeservers. While generating
// the summary of space hs1 needs to ask hs2 to generate the summary for room since
// it is not participating in the room.
//
// The user should be unable to see the room in the spaces summary unless they
// are a member of the space.
//
// This tests the interactions over federation where the space and room are on
// different homeservers, and one might not have the proper information needed to
// decide if a user is in a room.
func TestRestrictedRoomsSpacesSummaryFederation(t *testing.T) {
deployment := Deploy(t, b.BlueprintFederationTwoLocalOneRemote)
defer deployment.Destroy(t)

// Create the rooms
alice := deployment.Client(t, "hs1", "@alice:hs1")
bob := deployment.Client(t, "hs1", "@bob:hs1")
space := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Space",
"initial_state": []map[string]interface{}{
{
"type": "m.room.history_visibility",
"state_key": "",
"content": map[string]string{
"history_visibility": "world_readable",
},
},
},
})

// The room is an unstable room version which supports the restricted join_rule
// and is created on hs2.
charlie := deployment.Client(t, "hs2", "@charlie:hs2")
room := charlie.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
"state_key": "",
"content": map[string]interface{}{
"join_rule": "restricted",
"allow": []map[string]interface{}{
{
"space": &space,
"via": []string{"hs1"},
},
},
},
},
},
})

// create the link (this doesn't really make sense since how would alice know
// about the room? but it works for testing)
alice.SendEventSynced(t, space, b.Event{
Type: spaceChildEventType,
StateKey: &room,
Content: map[string]interface{}{
"via": []string{"hs2"},
},
})

// The room appears for neither alice or bob initially. Although alice is in
// the space and should be able to access the room, hs2 doesn't know this!
requestAndAssertSummary(t, alice, space, []interface{}{space})
requestAndAssertSummary(t, bob, space, []interface{}{space})

// charlie joins the space and now hs2 knows that alice is in the space (and
// can join the room).
charlie.JoinRoom(t, space, []string{"hs1"})

// The restricted room should appear for alice (who is in the space).
requestAndAssertSummary(t, alice, space, []interface{}{space, room})
requestAndAssertSummary(t, bob, space, []interface{}{space})
}

0 comments on commit 726472e

Please sign in to comment.