Skip to content

Commit 80330aa

Browse files
MSC4308: Thread Subscriptions extension to Sliding Sync tests (#802)
* MSC4306: Thread Subscriptions Tests * Enable MSC4306 tests in CI for Synapse * GetPushRule -> MustGetPushRule * Add non-failing GetPushRule * Disable MSC4306 push rules in non-MSC4306 test * MSC4308: Thread Subscriptions extension to Sliding Sync tests * Update tests/msc4306/thread_subscriptions_sliding_sync_test.go Co-authored-by: Eric Eastwood <[email protected]> * Make it obvious it's MSC4308 --------- Co-authored-by: Eric Eastwood <[email protected]>
1 parent 6c854fc commit 80330aa

File tree

2 files changed

+113
-0
lines changed

2 files changed

+113
-0
lines changed

client/client.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/json"
99
"fmt"
1010
"io"
11+
"log"
1112
"math/rand"
1213
"net/http"
1314
"net/http/httputil"
@@ -752,6 +753,19 @@ func (t *loggedRoundTripper) RoundTrip(req *http.Request) (*http.Response, error
752753
return res, err
753754
}
754755

756+
// Extracts a JSON object given a search key
757+
// Caller must check `result.Exists()` to see whether the object actually exists.
758+
func GetOptionalJSONFieldObject(t ct.TestLike, body []byte, wantKey string) gjson.Result {
759+
t.Helper()
760+
res := gjson.GetBytes(body, wantKey)
761+
if !res.Exists() {
762+
log.Printf("OptionalJSONFieldObject: key '%s' absent from %s", wantKey, string(body))
763+
} else if !res.IsObject() {
764+
ct.Fatalf(t, "OptionalJSONFieldObject: key '%s' is not an object, body: %s", wantKey, string(body))
765+
}
766+
return res
767+
}
768+
755769
// GetJSONFieldStr extracts a value from a byte-encoded JSON body given a search key
756770
func GetJSONFieldStr(t ct.TestLike, body []byte, wantKey string) string {
757771
t.Helper()
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package tests
2+
3+
import (
4+
"testing"
5+
6+
"github.com/matrix-org/complement"
7+
"github.com/matrix-org/complement/b"
8+
"github.com/matrix-org/complement/client"
9+
"github.com/matrix-org/complement/helpers"
10+
"github.com/matrix-org/complement/match"
11+
"github.com/matrix-org/complement/must"
12+
"github.com/tidwall/gjson"
13+
)
14+
15+
func MustDoSlidingSync(t *testing.T, user *client.CSAPI, pos string, thread_subs_ext map[string]interface{}) (string, gjson.Result) {
16+
body := map[string]interface{}{
17+
"extensions": map[string]interface{}{
18+
"io.element.msc4308.thread_subscriptions": thread_subs_ext,
19+
},
20+
}
21+
if pos != "" {
22+
body["pos"] = pos
23+
}
24+
resp := user.MustDo(t, "POST", []string{"_matrix", "client", "unstable", "org.matrix.simplified_msc3575", "sync"}, client.WithJSONBody(t, body))
25+
respBody := client.ParseJSON(t, resp)
26+
27+
newPos := client.GetJSONFieldStr(t, respBody, "pos")
28+
extension := client.GetOptionalJSONFieldObject(t, respBody, "extensions.io\\.element\\.msc4308\\.thread_subscriptions")
29+
if !extension.Exists() {
30+
// Missing extension is semantically the same as an empty one
31+
// So eliminate the nil for simplicity
32+
extension = gjson.Parse("{}")
33+
}
34+
return newPos, extension
35+
}
36+
37+
// Tests the thread subscriptions extension to sliding sync, introduced in MSC4308
38+
// but treated as the same unit as MSC4306.
39+
func TestMSC4308ThreadSubscriptionsSlidingSync(t *testing.T) {
40+
deployment := complement.Deploy(t, 1)
41+
defer deployment.Destroy(t)
42+
43+
t.Run("Receives thread subscriptions over initial sliding sync", func(t *testing.T) {
44+
alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{})
45+
roomID := alice.MustCreateRoom(t, map[string]interface{}{})
46+
threadRootID := alice.SendEventSynced(t, roomID, b.Event{
47+
Type: "m.room.message",
48+
Content: map[string]interface{}{
49+
"msgtype": "m.text",
50+
"body": "what do you think? reply in a thread!",
51+
},
52+
})
53+
54+
// Subscribe to the thread manually
55+
alice.MustDo(t, "PUT", []string{"_matrix", "client", "unstable", "io.element.msc4306", "rooms", roomID, "thread", threadRootID, "subscription"}, client.WithJSONBody(t, map[string]interface{}{}))
56+
57+
_, thread_subscription_ext := MustDoSlidingSync(t, alice, "", map[string]interface{}{
58+
"enabled": true,
59+
"limit": 2,
60+
})
61+
62+
must.MatchGJSON(t, thread_subscription_ext,
63+
match.JSONKeyTypeEqual("subscribed."+gjson.Escape(roomID)+"."+gjson.Escape(threadRootID)+".bump_stamp", gjson.Number),
64+
match.JSONKeyEqual("subscribed."+gjson.Escape(roomID)+"."+gjson.Escape(threadRootID)+".automatic", false),
65+
)
66+
})
67+
68+
t.Run("Receives thread subscriptions over incremental sliding sync", func(t *testing.T) {
69+
alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{})
70+
roomID := alice.MustCreateRoom(t, map[string]interface{}{})
71+
threadRootID := alice.SendEventSynced(t, roomID, b.Event{
72+
Type: "m.room.message",
73+
Content: map[string]interface{}{
74+
"msgtype": "m.text",
75+
"body": "what do you think? reply in a thread!",
76+
},
77+
})
78+
79+
newPos, ext := MustDoSlidingSync(t, alice, "", map[string]interface{}{
80+
"enabled": true,
81+
"limit": 2,
82+
})
83+
must.MatchGJSON(t, ext,
84+
match.JSONKeyMissing("subscribed"))
85+
86+
// Subscribe to the thread manually
87+
alice.MustDo(t, "PUT", []string{"_matrix", "client", "unstable", "io.element.msc4306", "rooms", roomID, "thread", threadRootID, "subscription"}, client.WithJSONBody(t, map[string]interface{}{}))
88+
89+
_, ext = MustDoSlidingSync(t, alice, newPos, map[string]interface{}{
90+
"enabled": true,
91+
"limit": 2,
92+
})
93+
94+
must.MatchGJSON(t, ext,
95+
match.JSONKeyTypeEqual("subscribed."+gjson.Escape(roomID)+"."+gjson.Escape(threadRootID)+".bump_stamp", gjson.Number),
96+
match.JSONKeyEqual("subscribed."+gjson.Escape(roomID)+"."+gjson.Escape(threadRootID)+".automatic", false),
97+
)
98+
})
99+
}

0 commit comments

Comments
 (0)