Skip to content

Commit 8c9e20c

Browse files
authored
Add tests for MSC3083 - joining a restricted room. (#98)
These are disabled by default must be opted into with the build tag `msc3083`.
1 parent 8863736 commit 8c9e20c

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed

dockerfiles/synapse/homeserver.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,5 @@ AS_REGISTRATION_FILES
105105
experimental_features:
106106
# Enable knocking support
107107
msc2403_enabled: true
108+
# Enable spaces support
109+
spaces_enabled: true

internal/client/client.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,23 @@ func (c *CSAPI) JoinRoom(t *testing.T, roomIDOrAlias string, serverNames []strin
8484
return GetJSONFieldStr(t, body, "room_id")
8585
}
8686

87+
// LeaveRoom joins the room ID, else fails the test.
88+
func (c *CSAPI) LeaveRoom(t *testing.T, roomID string) {
89+
t.Helper()
90+
// leave the room
91+
c.MustDoRaw(t, "POST", []string{"_matrix", "client", "r0", "rooms", roomID, "leave"}, nil, "application/json", nil)
92+
}
93+
94+
// InviteRoom invites userID to the room ID, else fails the test.
95+
func (c *CSAPI) InviteRoom(t *testing.T, roomID string, userID string) {
96+
t.Helper()
97+
// Invite the user to the room
98+
body := map[string]interface{}{
99+
"user_id": userID,
100+
}
101+
c.MustDo(t, "POST", []string{"_matrix", "client", "r0", "rooms", roomID, "invite"}, body)
102+
}
103+
87104
// SendEventSynced sends `e` into the room and waits for its event ID to come down /sync.
88105
// Returns the event ID of the sent event.
89106
func (c *CSAPI) SendEventSynced(t *testing.T, roomID string, e b.Event) string {

tests/msc3083_test.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
// +build msc3083
2+
3+
// Tests MSC3083, an experimental feature for joining restricted rooms based on
4+
// membership in a space.
5+
6+
package tests
7+
8+
import (
9+
"net/url"
10+
"testing"
11+
12+
"github.com/matrix-org/complement/internal/b"
13+
"github.com/matrix-org/complement/internal/client"
14+
)
15+
16+
var (
17+
spaceChildEventType = "org.matrix.msc1772.space.child"
18+
spaceParentEventType = "org.matrix.msc1772.space.parent"
19+
)
20+
21+
func FailJoinRoom(c *client.CSAPI, t *testing.T, roomIDOrAlias string, serverName string) {
22+
// This is copied from Client.JoinRoom to test a join failure.
23+
query := make(url.Values, 1)
24+
query.Set("server_name", serverName)
25+
c.MustDoWithStatusRaw(
26+
t,
27+
"POST",
28+
[]string{"_matrix", "client", "r0", "join", roomIDOrAlias},
29+
nil,
30+
"application/json",
31+
query,
32+
403,
33+
)
34+
}
35+
36+
// Test joining a room with join rules restricted to membership in a space.
37+
func TestRestrictedRoomsLocalJoin(t *testing.T) {
38+
deployment := Deploy(t, "msc3083", b.BlueprintOneToOneRoom)
39+
defer deployment.Destroy(t)
40+
41+
// Create the space and put a room in it.
42+
alice := deployment.Client(t, "hs1", "@alice:hs1")
43+
space := alice.CreateRoom(t, map[string]interface{}{
44+
"preset": "public_chat",
45+
"name": "Space",
46+
})
47+
// The room is an unstable room version which supports the restricted join_rule.
48+
room := alice.CreateRoom(t, map[string]interface{}{
49+
"preset": "public_chat",
50+
"name": "Room",
51+
"room_version": "org.matrix.msc3083",
52+
"initial_state": []map[string]interface{}{
53+
{
54+
"type": "m.room.join_rules",
55+
"state_key": "",
56+
"content": map[string]interface{}{
57+
"join_rule": "restricted",
58+
"allow": []map[string]interface{}{
59+
{
60+
"space": &space,
61+
"via": []string{"hs1"},
62+
},
63+
},
64+
},
65+
},
66+
},
67+
})
68+
alice.SendEventSynced(t, space, b.Event{
69+
Type: spaceChildEventType,
70+
StateKey: &room,
71+
Content: map[string]interface{}{
72+
"via": []string{"hs1"},
73+
},
74+
})
75+
76+
// Create a second user and attempt to join the room, it should fail.
77+
bob := deployment.Client(t, "hs1", "@bob:hs1")
78+
FailJoinRoom(bob, t, room, "hs1")
79+
80+
// Join the space, attempt to join the room again, which now should succeed.
81+
bob.JoinRoom(t, space, []string{"hs1"})
82+
bob.JoinRoom(t, room, []string{"hs1"})
83+
84+
// Leaving the room works and the user is unable to re-join.
85+
bob.LeaveRoom(t, room)
86+
bob.LeaveRoom(t, space)
87+
FailJoinRoom(bob, t, room, "hs1")
88+
89+
// Invite the user and joining should work.
90+
alice.InviteRoom(t, room, "@bob:hs1")
91+
bob.JoinRoom(t, room, []string{"hs1"})
92+
93+
// Leave the room again, and join the space.
94+
bob.LeaveRoom(t, room)
95+
bob.JoinRoom(t, space, []string{"hs1"})
96+
97+
// Update the room to have bad values in the "allow" field, which should stop
98+
// joining from working properly.
99+
emptyStateKey := ""
100+
alice.SendEventSynced(
101+
t,
102+
room,
103+
b.Event{
104+
Type: "m.room.join_rules",
105+
Sender: alice.UserID,
106+
StateKey: &emptyStateKey,
107+
Content: map[string]interface{}{
108+
"join_rule": "restricted",
109+
"allow": []string{"invalid"},
110+
},
111+
},
112+
)
113+
// Fails since invalid values get filtered out of allow.
114+
FailJoinRoom(bob, t, room, "hs1")
115+
116+
alice.SendEventSynced(
117+
t,
118+
room,
119+
b.Event{
120+
Type: "m.room.join_rules",
121+
Sender: alice.UserID,
122+
StateKey: &emptyStateKey,
123+
Content: map[string]interface{}{
124+
"join_rule": "restricted",
125+
"allow": "invalid",
126+
},
127+
},
128+
)
129+
// Fails since a fully invalid allow key rquires an invite.
130+
FailJoinRoom(bob, t, room, "hs1")
131+
}

0 commit comments

Comments
 (0)