diff --git a/tests/csapi/apidoc_room_receipts_test.go b/tests/csapi/apidoc_room_receipts_test.go index 30e7fa84..32758020 100644 --- a/tests/csapi/apidoc_room_receipts_test.go +++ b/tests/csapi/apidoc_room_receipts_test.go @@ -17,15 +17,19 @@ func createRoomForReadReceipts(t *testing.T, c *client.CSAPI) (string, string) { c.MustSyncUntil(t, client.SyncReq{}, client.SyncJoinedTo(c.UserID, roomID)) - eventID := c.SendEventSynced(t, roomID, b.Event{ + eventID := sendMessageIntoRoom(t, c, roomID) + + return roomID, eventID +} + +func sendMessageIntoRoom(t *testing.T, c *client.CSAPI, roomID string) string { + return c.SendEventSynced(t, roomID, b.Event{ Type: "m.room.message", Content: map[string]interface{}{ "msgtype": "m.text", "body": "Hello world!", }, }) - - return roomID, eventID } func syncHasReadReceipt(roomID, userID, eventID string) client.SyncCheckOpt { @@ -45,7 +49,41 @@ func TestRoomReceipts(t *testing.T) { alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "receipt", "m.read", eventID}, client.WithJSONBody(t, struct{}{})) // Make sure the read receipt shows up in sync. - alice.MustSyncUntil(t, client.SyncReq{}, syncHasReadReceipt(roomID, alice.UserID, eventID)) + sinceToken := alice.MustSyncUntil(t, client.SyncReq{}, syncHasReadReceipt(roomID, alice.UserID, eventID)) + + // Receipt events include a `room_id` field over federation, but they should + // not do so down `/sync` to clients. Ensure homeservers strip that field out. + t.Run("Receipts DO NOT include a `room_id` field", func(t *testing.T) { + // Send another event to read. + eventID2 := sendMessageIntoRoom(t, alice, roomID) + + // Send a read receipt for the event. + alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "receipt", "m.read", eventID2}, client.WithJSONBody(t, struct{}{})) + + alice.MustSyncUntil( + t, + client.SyncReq{Since: sinceToken}, + client.SyncEphemeralHas(roomID, func(r gjson.Result) bool { + // Check that this is a m.receipt ephemeral event. + if r.Get("type").Str != "m.receipt" { + return false + } + + // Check that the receipt type is "m.read". + if !r.Get(`content.*.m\.read`).Exists() { + t.Fatalf("Receipt was not of type 'm.read'") + } + + // Ensure that the `room_id` field does NOT exist. + if r.Get("room_id").Exists() { + t.Fatalf("Read receipt should not contain 'room_id' field when syncing but saw: %s", r.Raw) + } + + // Exit the /sync loop. + return true; + }), + ) + }) } // sytest: POST /rooms/:room_id/read_markers can create read marker diff --git a/tests/csapi/room_typing_test.go b/tests/csapi/room_typing_test.go index 84253cca..7769dd06 100644 --- a/tests/csapi/room_typing_test.go +++ b/tests/csapi/room_typing_test.go @@ -6,6 +6,7 @@ import ( "github.com/matrix-org/complement" "github.com/matrix-org/complement/client" "github.com/matrix-org/complement/helpers" + "github.com/tidwall/gjson" ) // sytest: PUT /rooms/:room_id/typing/:user_id sets typing notification @@ -33,6 +34,30 @@ func TestTyping(t *testing.T) { alice.SendTyping(t, roomID, false, 0) bob.MustSyncUntil(t, client.SyncReq{Since: token}, client.SyncUsersTyping(roomID, []string{})) }) + + // Typing events include a `room_id` field over federation, but they should + // not do so down `/sync` to clients. Ensure homeservers strip that field out. + t.Run("Typing events DO NOT include a `room_id` field", func(t *testing.T) { + alice.SendTyping(t, roomID, true, 0) + + bob.MustSyncUntil( + t, + client.SyncReq{Since: token}, + client.SyncEphemeralHas(roomID, func(r gjson.Result) bool { + if r.Get("type").Str != "m.typing" { + return false + } + + // Ensure that the `room_id` field does NOT exist. + if r.Get("room_id").Exists() { + t.Fatalf("Typing event should not contain `room_id` field when syncing but saw: %s", r.Raw) + } + + // Exit the /sync loop. + return true; + }), + ) + }) } // sytest: Typing notifications don't leak