Skip to content

Commit

Permalink
Test the updated MSC2946 room hierarchy endpoint. (#187)
Browse files Browse the repository at this point in the history
  • Loading branch information
clokep authored Aug 10, 2021
1 parent 5ae7105 commit 2574030
Showing 1 changed file with 209 additions and 2 deletions.
211 changes: 209 additions & 2 deletions tests/msc2946_test.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
// +build msc2946

// This file includes tests for MSC2946, the spaces summary API.
//
// There are currently tests for two unstable versions of it for backwards
// compatibility:
//
// * The /spaces endpoint, which was the original version.
// * The /hierarchy endpoint, which is an updated version.
//
// Both endpoints return data from the same set of rooms / spaces, but have
// different API shapes.
//
// TODO When support for this is stable, the tests for /spaces should be removed.

package tests

import (
Expand Down Expand Up @@ -42,6 +55,7 @@ func eventKey(srcRoomID, dstRoomID, evType string) string {
// - the user is joined to all rooms except R4.
// - R2 <---> Root is a two-way link.
// - The remaining links are just children links.
// - R1 and R2 are suggested rooms.
//
// Tests that:
// - Querying the root returns the entire graph
Expand Down Expand Up @@ -125,7 +139,8 @@ func TestClientSpacesSummary(t *testing.T) {
Type: spaceChildEventType,
StateKey: &r1,
Content: map[string]interface{}{
"via": []string{"hs1"},
"via": []string{"hs1"},
"suggested": true,
},
})
rootToSS1 := eventKey(root, ss1, spaceChildEventType)
Expand All @@ -141,7 +156,8 @@ func TestClientSpacesSummary(t *testing.T) {
Type: spaceChildEventType,
StateKey: &r2,
Content: map[string]interface{}{
"via": []string{"hs1"},
"via": []string{"hs1"},
"suggested": true,
},
})
// Note that this link gets ignored since R2 is not a space.
Expand Down Expand Up @@ -220,6 +236,39 @@ func TestClientSpacesSummary(t *testing.T) {
}, nil),
},
})

res = alice.MustDo(t, "GET", []string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"}, nil)
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
root, r1, r2, r3, r4, ss1, ss2,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, func(roomInt interface{}, data gjson.Result) error {
roomID := roomInt.(string)
// check fields
if name, ok := roomNames[roomID]; ok {
if data.Get("name").Str != name {
return fmt.Errorf("room %s got name %s want %s", roomID, data.Get("name").Str, name)
}
}
if roomID == ss1 {
wantType := "m.space"
if data.Get("room_type").Str != wantType {
return fmt.Errorf("room %s got type %s want %s", roomID, data.Get("room_type").Str, wantType)
}
}
return nil
}),
// Check that the links from Root down to other rooms and spaces exist.
match.JSONCheckOff("rooms.#.children_state|@flatten", []interface{}{
rootToR1, rootToR2, rootToSS1,
ss1ToSS2, ss2ToR3, ss2ToR4,
}, func(r gjson.Result) interface{} {
return eventKey(r.Get("room_id").Str, r.Get("state_key").Str, r.Get("type").Str)
}, nil),
},
})
})

// - Setting max_rooms_per_space works correctly
Expand Down Expand Up @@ -251,6 +300,103 @@ func TestClientSpacesSummary(t *testing.T) {
}
})

// - Setting max_depth works correctly
t.Run("max_depth", func(t *testing.T) {
// Should only include R1, SS1, and R2.
query := make(url.Values, 1)
query.Set("max_depth", "1")
res := alice.MustDoFunc(
t,
"GET",
[]string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"},
client.WithQueries(query),
)
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
root, r1, r2, ss1,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
// All of the links are still there.
match.JSONCheckOff("rooms.#.children_state|@flatten", []interface{}{
rootToR1, rootToR2, rootToSS1, ss1ToSS2,
}, func(r gjson.Result) interface{} {
return eventKey(r.Get("room_id").Str, r.Get("state_key").Str, r.Get("type").Str)
}, nil),
},
})
})

// - Setting suggested_only works correctly
t.Run("suggested_only", func(t *testing.T) {
// Should only include R1, SS1, and R2.
query := make(url.Values, 1)
query.Set("suggested_only", "true")
res := alice.MustDoFunc(
t,
"GET",
[]string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"},
client.WithQueries(query),
)
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
root, r1, r2,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
// All of the links are still there.
match.JSONCheckOff("rooms.#.children_state|@flatten", []interface{}{
rootToR1, rootToR2,
}, func(r gjson.Result) interface{} {
return eventKey(r.Get("room_id").Str, r.Get("state_key").Str, r.Get("type").Str)
}, nil),
},
})
})

// - Setting max_depth works correctly
t.Run("pagination", func(t *testing.T) {
// The initial page should only include Root, R1, SS1, and SS2.
query := make(url.Values, 1)
query.Set("limit", "4")
res := alice.MustDoFunc(
t,
"GET",
[]string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"},
client.WithQueries(query),
)
body := must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
root, r1, ss1, ss2,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
},
})

// The following page should include R3, R4, and R2.
query = make(url.Values, 1)
query.Set("from", client.GetJSONFieldStr(t, body, "next_token"))
res = alice.MustDoFunc(
t,
"GET",
[]string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"},
client.WithQueries(query),
)
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
r3, r4, r2,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
},
})
})

t.Run("redact link", func(t *testing.T) {
// Remove the root -> SS1 link
alice.SendEventSynced(t, root, b.Event{
Expand All @@ -273,6 +419,22 @@ func TestClientSpacesSummary(t *testing.T) {
}, nil),
},
})

res = alice.MustDo(t, "GET", []string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"}, nil)
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
root, r1, r2,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
match.JSONCheckOff("rooms.#.children_state|@flatten", []interface{}{
rootToR1, rootToR2,
}, func(r gjson.Result) interface{} {
return eventKey(r.Get("room_id").Str, r.Get("state_key").Str, r.Get("type").Str)
}, nil),
},
})
})
}

Expand Down Expand Up @@ -387,6 +549,21 @@ func TestClientSpacesSummaryJoinRules(t *testing.T) {
}, nil),
},
})
res = bob.MustDo(t, "GET", []string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"}, nil)
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
root,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
match.JSONCheckOff("rooms.#.children_state|@flatten", []interface{}{
rootToR1, rootToSS1,
}, func(r gjson.Result) interface{} {
return eventKey(r.Get("room_id").Str, r.Get("state_key").Str, r.Get("type").Str)
}, nil),
},
})

// Invite to R1 and R3, querying again should only show R1 (since SS1 is not visible).
alice.InviteRoom(t, r1, bob.UserID)
Expand All @@ -407,6 +584,21 @@ func TestClientSpacesSummaryJoinRules(t *testing.T) {
}, nil),
},
})
res = bob.MustDo(t, "GET", []string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"}, nil)
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
root, r1,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
match.JSONCheckOff("rooms.#.children_state|@flatten", []interface{}{
rootToR1, rootToSS1,
}, func(r gjson.Result) interface{} {
return eventKey(r.Get("room_id").Str, r.Get("state_key").Str, r.Get("type").Str)
}, nil),
},
})

// Invite to SS1 and it now appears, as well as the rooms under it.
alice.InviteRoom(t, ss1, bob.UserID)
Expand All @@ -426,6 +618,21 @@ func TestClientSpacesSummaryJoinRules(t *testing.T) {
}, nil),
},
})
res = bob.MustDo(t, "GET", []string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", root, "hierarchy"}, nil)
must.MatchResponse(t, res, match.HTTPResponse{
JSON: []match.JSON{
match.JSONCheckOff("rooms", []interface{}{
root, r1, ss1, r2, r3,
}, func(r gjson.Result) interface{} {
return r.Get("room_id").Str
}, nil),
match.JSONCheckOff("rooms.#.children_state|@flatten", []interface{}{
rootToR1, rootToSS1, ss1ToR2, ss1ToR3,
}, func(r gjson.Result) interface{} {
return eventKey(r.Get("room_id").Str, r.Get("state_key").Str, r.Get("type").Str)
}, nil),
},
})
}

// Tests that MSC2946 works over federation. Creates a space directory like:
Expand Down

0 comments on commit 2574030

Please sign in to comment.