From 0f482b4c6b4994d5524c3c351ff315864ee4c221 Mon Sep 17 00:00:00 2001 From: kegsay <7190048+kegsay@users.noreply.github.com> Date: Tue, 20 Feb 2024 15:06:12 +0000 Subject: [PATCH] Add tests for MSC4102 (#709) * Add failing test for https://github.com/matrix-org/matrix-spec/issues/1727 * Logs are fun * Update with semantics of MSC4102 * Also test over federation --- tests/csapi/thread_notifications_test.go | 51 ++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/tests/csapi/thread_notifications_test.go b/tests/csapi/thread_notifications_test.go index de440d49..3acfa462 100644 --- a/tests/csapi/thread_notifications_test.go +++ b/tests/csapi/thread_notifications_test.go @@ -301,3 +301,54 @@ func TestThreadedReceipts(t *testing.T) { }), ) } + +// Regression test for https://github.com/matrix-org/matrix-spec/issues/1727 +// Servers should always prefer the unthreaded receipt when there is a clash of receipts +func TestThreadReceiptsInSyncMSC4102(t *testing.T) { + runtime.SkipIf(t, runtime.Dendrite) // not supported + deployment := complement.Deploy(t, 2) + defer deployment.Destroy(t) + + // Create a room with alice and bob. + alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{}) + bob := deployment.Register(t, "hs2", helpers.RegistrationOpts{}) + roomID := alice.MustCreateRoom(t, map[string]interface{}{"preset": "public_chat"}) + bob.MustJoinRoom(t, roomID, []string{"hs1"}) + eventA := alice.SendEventSynced(t, roomID, b.Event{ + Type: "m.room.message", + Content: map[string]interface{}{ + "msgtype": "m.text", + "body": "Hello world!", + }, + }) + eventB := alice.SendEventSynced(t, roomID, b.Event{ + Type: "m.room.message", + Content: map[string]interface{}{ + "msgtype": "m.text", + "body": "Start thread!", + "m.relates_to": map[string]interface{}{ + "event_id": eventA, + "rel_type": "m.thread", + }, + }, + }) + // now send an unthreaded RR for event B and a threaded RR for event B and ensure we see the unthreaded RR + // down /sync. Non-compliant servers will typically send the last one only. + alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "receipt", "m.read", eventB}, client.WithJSONBody(t, struct{}{})) + alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "rooms", roomID, "receipt", "m.read", eventB}, client.WithJSONBody(t, map[string]interface{}{"thread_id": eventA})) + + alice.MustSyncUntil( + t, + client.SyncReq{}, + syncHasUnthreadedReadReceipt(roomID, alice.UserID, eventB), + ) + + // bob over federation must also see the same result, to show that the receipt EDUs over + // federation are bundled correctly, or are sent as separate EDUs. + bob.MustSyncUntil( + t, + client.SyncReq{}, + syncHasUnthreadedReadReceipt(roomID, alice.UserID, eventB), + ) + +}