Skip to content

Commit 1c13fff

Browse files
add 40presence tests (#555)
Sytest: Add `40presence` tests
1 parent d2a7c49 commit 1c13fff

File tree

4 files changed

+138
-24
lines changed

4 files changed

+138
-24
lines changed

internal/client/client.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,43 @@ func SyncEphemeralHas(roomID string, check func(gjson.Result) bool) SyncCheckOpt
706706
}
707707
}
708708

709+
// Check that the sync contains presence from a user, optionally with an expected presence (set to nil to not check),
710+
// and optionally with extra checks.
711+
func SyncPresenceHas(fromUser string, expectedPresence *string, checks ...func(gjson.Result) bool) SyncCheckOpt {
712+
return func(clientUserID string, topLevelSyncJSON gjson.Result) error {
713+
presenceEvents := topLevelSyncJSON.Get("presence.events")
714+
if !presenceEvents.Exists() {
715+
return fmt.Errorf("presence.events does not exist")
716+
}
717+
for _, x := range presenceEvents.Array() {
718+
if !(x.Get("type").Exists() &&
719+
x.Get("sender").Exists() &&
720+
x.Get("content").Exists() &&
721+
x.Get("content.presence").Exists()) {
722+
return fmt.Errorf(
723+
"malformatted presence event, expected the following fields: [sender, type, content, content.presence]: %s",
724+
x.Raw,
725+
)
726+
} else if x.Get("sender").Str != fromUser {
727+
continue
728+
} else if expectedPresence != nil && x.Get("content.presence").Str != *expectedPresence {
729+
return fmt.Errorf(
730+
"found presence for user %s, but not expected presence: got %s, want %s",
731+
fromUser, x.Get("content.presence").Str, *expectedPresence,
732+
)
733+
} else {
734+
for i, check := range checks {
735+
if !check(x) {
736+
return fmt.Errorf("matched presence event to user %s, but check %d did not pass", fromUser, i)
737+
}
738+
}
739+
return nil
740+
}
741+
}
742+
return fmt.Errorf("did not find %s in presence events", fromUser)
743+
}
744+
}
745+
709746
// Checks that `userID` gets invited to `roomID`.
710747
//
711748
// This checks different parts of the /sync response depending on the client making the request.

tests/csapi/apidoc_presence_test.go

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,24 @@ package csapi_tests
77
import (
88
"testing"
99

10+
"github.com/tidwall/gjson"
11+
1012
"github.com/matrix-org/complement/internal/b"
1113
"github.com/matrix-org/complement/internal/client"
1214
"github.com/matrix-org/complement/internal/match"
1315
"github.com/matrix-org/complement/internal/must"
1416
)
1517

1618
func TestPresence(t *testing.T) {
17-
deployment := Deploy(t, b.BlueprintAlice)
19+
deployment := Deploy(t, b.BlueprintOneToOneRoom)
1820
defer deployment.Destroy(t)
1921

20-
authedClient := deployment.Client(t, "hs1", "@alice:hs1")
22+
alice := deployment.Client(t, "hs1", "@alice:hs1")
23+
bob := deployment.Client(t, "hs1", "@bob:hs1")
24+
2125
// sytest: GET /presence/:user_id/status fetches initial status
2226
t.Run("GET /presence/:user_id/status fetches initial status", func(t *testing.T) {
23-
res := authedClient.DoFunc(t, "GET", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"})
27+
res := alice.DoFunc(t, "GET", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"})
2428
must.MatchResponse(t, res, match.HTTPResponse{
2529
JSON: []match.JSON{
2630
match.JSONKeyPresent("presence"),
@@ -34,16 +38,56 @@ func TestPresence(t *testing.T) {
3438
"status_msg": statusMsg,
3539
"presence": "online",
3640
})
37-
res := authedClient.DoFunc(t, "PUT", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"}, reqBody)
41+
res := alice.DoFunc(t, "PUT", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"}, reqBody)
3842
must.MatchResponse(t, res, match.HTTPResponse{
3943
StatusCode: 200,
4044
})
41-
res = authedClient.DoFunc(t, "GET", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"})
45+
res = alice.DoFunc(t, "GET", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"})
4246
must.MatchResponse(t, res, match.HTTPResponse{
4347
JSON: []match.JSON{
4448
match.JSONKeyPresent("presence"),
4549
match.JSONKeyEqual("status_msg", statusMsg),
4650
},
4751
})
4852
})
53+
// sytest: Presence can be set from sync
54+
t.Run("Presence can be set from sync", func(t *testing.T) {
55+
_, bobSinceToken := bob.MustSync(t, client.SyncReq{TimeoutMillis: "0"})
56+
57+
alice.MustSync(t, client.SyncReq{TimeoutMillis: "0", SetPresence: "unavailable"})
58+
59+
bob.MustSyncUntil(t, client.SyncReq{Since: bobSinceToken}, client.SyncPresenceHas(alice.UserID, b.Ptr("unavailable")))
60+
})
61+
// sytest: Presence changes are reported to local room members
62+
t.Run("Presence changes are reported to local room members", func(t *testing.T) {
63+
_, bobSinceToken := bob.MustSync(t, client.SyncReq{TimeoutMillis: "0"})
64+
65+
statusMsg := "Update for room members"
66+
alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"},
67+
client.WithJSONBody(t, map[string]interface{}{
68+
"status_msg": statusMsg,
69+
"presence": "online",
70+
}),
71+
)
72+
73+
bob.MustSyncUntil(t, client.SyncReq{Since: bobSinceToken},
74+
client.SyncPresenceHas(alice.UserID, b.Ptr("online"), func(ev gjson.Result) bool {
75+
return ev.Get("content.status_msg").Str == statusMsg
76+
}),
77+
)
78+
})
79+
// sytest: Presence changes to UNAVAILABLE are reported to local room members
80+
t.Run("Presence changes to UNAVAILABLE are reported to local room members", func(t *testing.T) {
81+
_, bobSinceToken := bob.MustSync(t, client.SyncReq{TimeoutMillis: "0"})
82+
83+
alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"},
84+
client.WithJSONBody(t, map[string]interface{}{
85+
"presence": "unavailable",
86+
}),
87+
)
88+
89+
bob.MustSyncUntil(t, client.SyncReq{Since: bobSinceToken},
90+
client.SyncPresenceHas(alice.UserID, b.Ptr("unavailable")),
91+
)
92+
})
4993
}

tests/csapi/rooms_members_local_test.go

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
package csapi_tests
22

33
import (
4-
"fmt"
54
"testing"
65

7-
"github.com/tidwall/gjson"
8-
96
"github.com/matrix-org/complement/internal/b"
107
"github.com/matrix-org/complement/internal/client"
118
"github.com/matrix-org/complement/runtime"
@@ -41,22 +38,7 @@ func TestMembersLocal(t *testing.T) {
4138
t.Parallel()
4239
alice.MustSyncUntil(t, client.SyncReq{},
4340
client.SyncJoinedTo(bob.UserID, roomID),
44-
func(clientUserID string, topLevelSyncJSON gjson.Result) error {
45-
presenceEvents := topLevelSyncJSON.Get("presence.events")
46-
if !presenceEvents.Exists() {
47-
return fmt.Errorf("presence.events does not exist")
48-
}
49-
for _, x := range presenceEvents.Array() {
50-
fieldsExists := x.Get("type").Exists() && x.Get("content").Exists() && x.Get("sender").Exists()
51-
if !fieldsExists {
52-
return fmt.Errorf("expected fields type, content and sender")
53-
}
54-
if x.Get("sender").Str == bob.UserID {
55-
return nil
56-
}
57-
}
58-
return fmt.Errorf("did not find %s in presence events", bob.UserID)
59-
},
41+
client.SyncPresenceHas(bob.UserID, nil),
6042
)
6143
})
6244
})

tests/federation_presence_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package tests
2+
3+
import (
4+
"testing"
5+
6+
"github.com/tidwall/gjson"
7+
8+
"github.com/matrix-org/complement/internal/b"
9+
"github.com/matrix-org/complement/internal/client"
10+
)
11+
12+
func TestRemotePresence(t *testing.T) {
13+
deployment := Deploy(t, b.BlueprintFederationOneToOneRoom)
14+
defer deployment.Destroy(t)
15+
16+
alice := deployment.Client(t, "hs1", "@alice:hs1")
17+
bob := deployment.Client(t, "hs2", "@bob:hs2")
18+
19+
// sytest: Presence changes are also reported to remote room members
20+
t.Run("Presence changes are also reported to remote room members", func(t *testing.T) {
21+
_, bobSinceToken := bob.MustSync(t, client.SyncReq{TimeoutMillis: "0"})
22+
23+
statusMsg := "Update for room members"
24+
alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"},
25+
client.WithJSONBody(t, map[string]interface{}{
26+
"status_msg": statusMsg,
27+
"presence": "online",
28+
}),
29+
)
30+
31+
bob.MustSyncUntil(t, client.SyncReq{Since: bobSinceToken},
32+
client.SyncPresenceHas(alice.UserID, b.Ptr("online"), func(ev gjson.Result) bool {
33+
return ev.Get("content.status_msg").Str == statusMsg
34+
}),
35+
)
36+
})
37+
// sytest: Presence changes to UNAVAILABLE are reported to remote room members
38+
t.Run("Presence changes to UNAVAILABLE are reported to remote room members", func(t *testing.T) {
39+
_, bobSinceToken := bob.MustSync(t, client.SyncReq{TimeoutMillis: "0"})
40+
41+
alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "v3", "presence", "@alice:hs1", "status"},
42+
client.WithJSONBody(t, map[string]interface{}{
43+
"presence": "unavailable",
44+
}),
45+
)
46+
47+
bob.MustSyncUntil(t, client.SyncReq{Since: bobSinceToken},
48+
client.SyncPresenceHas(alice.UserID, b.Ptr("unavailable")),
49+
)
50+
})
51+
}

0 commit comments

Comments
 (0)