diff --git a/tests/knocking_test.go b/tests/knocking_test.go index 8fead174..4192d5f3 100644 --- a/tests/knocking_test.go +++ b/tests/knocking_test.go @@ -117,11 +117,11 @@ func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knocki }) t.Run("Knocking on a room with join rule 'knock' should succeed", func(t *testing.T) { - knockOnRoomSynced(t, knockingUser, roomID, testKnockReason, []string{"hs1"}) + mustKnockOnRoomSynced(t, knockingUser, roomID, testKnockReason, []string{"hs1"}) }) t.Run("A user that has already knocked is allowed to knock again on the same room", func(t *testing.T) { - knockOnRoomSynced(t, knockingUser, roomID, "I really like knock knock jokes", []string{"hs1"}) + mustKnockOnRoomSynced(t, knockingUser, roomID, "I really like knock knock jokes", []string{"hs1"}) }) t.Run("Users in the room see a user's membership update when they knock", func(t *testing.T) { @@ -183,7 +183,7 @@ func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knocki }) // Knock again to return us to the knocked state - knockOnRoomSynced(t, knockingUser, roomID, "Let me in... again?", []string{"hs1"}) + mustKnockOnRoomSynced(t, knockingUser, roomID, "Let me in... again?", []string{"hs1"}) }) } @@ -211,7 +211,7 @@ func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knocki })) // Knock again - knockOnRoomSynced(t, knockingUser, roomID, "Pleeease let me in?", []string{"hs1"}) + mustKnockOnRoomSynced(t, knockingUser, roomID, "Pleeease let me in?", []string{"hs1"}) }) t.Run("A user can knock on a room without a reason", func(t *testing.T) { @@ -227,7 +227,7 @@ func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knocki ) // Knock again, this time without a reason - knockOnRoomSynced(t, knockingUser, roomID, "", []string{"hs1"}) + mustKnockOnRoomSynced(t, knockingUser, roomID, "", []string{"hs1"}) }) t.Run("A user in the room can accept a knock", func(t *testing.T) { @@ -279,22 +279,36 @@ func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knocki }) } -// knockOnRoomSynced will knock on a given room on the behalf of a user, and block until the knock has persisted. +func syncKnockedOn(userID, roomID string) client.SyncCheckOpt { + return func(clientUserID string, topLevelSyncJSON gjson.Result) error { + // two forms which depend on what the client user is: + // - passively viewing a membership for a room you're joined in + // - actively leaving the room + if clientUserID == userID { + events := topLevelSyncJSON.Get("rooms.knock." + client.GjsonEscape(roomID) + ".knock_state.events") + if events.Exists() && events.IsArray() { + // We don't currently define any required state event types to be sent. + // If we've reached this point, then an entry for this room was found + return nil + } + return fmt.Errorf("no knock section for room %s", roomID) + } + + // passive + return client.SyncTimelineHas(roomID, func(ev gjson.Result) bool { + return ev.Get("type").Str == "m.room.member" && ev.Get("state_key").Str == userID && ev.Get("content.membership").Str == "knock" + })(clientUserID, topLevelSyncJSON) + } +} + +// mustKnockOnRoomSynced will knock on a given room on the behalf of a user, and block until the knock has persisted. // serverNames should be populated if knocking on a room that the user's homeserver isn't currently a part of. // Fails the test if the knock response does not return a 200 status code. -func knockOnRoomSynced(t *testing.T, c *client.CSAPI, roomID, reason string, serverNames []string) { +func mustKnockOnRoomSynced(t *testing.T, c *client.CSAPI, roomID, reason string, serverNames []string) { knockOnRoomWithStatus(t, c, roomID, reason, serverNames, 200) // The knock should have succeeded. Block until we see the knock appear down sync - c.MustSyncUntil(t, client.SyncReq{}, func(clientUserID string, topLevelSyncJSON gjson.Result) error { - events := topLevelSyncJSON.Get("rooms.knock." + client.GjsonEscape(roomID) + ".knock_state.events") - if events.Exists() && events.IsArray() { - // We don't currently define any required state event types to be sent. - // If we've reached this point, then an entry for this room was found - return nil - } - return fmt.Errorf("no knock section for room %s", roomID) - }) + c.MustSyncUntil(t, client.SyncReq{}, syncKnockedOn(c.UserID, roomID)) } // knockOnRoomWithStatus will knock on a given room on the behalf of a user.