messages: Add unread 1:1/self DMs to pm_dict if DM group exists.

In get_raw_unread_data, 1:1 or self messages are added to pm_dict.
However, if a DirectMessageGroup is the recipient, the message is
added to huddle_dict by default.

To keep API compatibility, we override this behavior to populate
pm_dict for 1:1 and self DMs when a DirectMessageGroup exists.
This ensures clients relying on pm_dict continue to work during
and after the migration.

This PR fixes part of issue #25713.
This commit is contained in:
Mohammad Reza Kianifar
2025-06-01 23:12:49 +00:00
committed by Tim Abbott
parent 30d2d82d02
commit df00b68529
2 changed files with 85 additions and 3 deletions

View File

@@ -1007,9 +1007,26 @@ def extract_unread_data_from_um_rows(
elif msg_type == Recipient.DIRECT_MESSAGE_GROUP:
user_ids_string = get_direct_message_group_users(recipient_id)
direct_message_group_dict[message_id] = dict(
user_ids_string=user_ids_string,
)
user_ids = [int(uid) for uid in user_ids_string.split(",")]
# For API compatibility, we populate pm_dict for 1:1 and self DMs
# so clients relying on pm_dict continue to work during the migration.
# We populate direct_message_group_dict for group size > 2.
if len(user_ids) <= 2:
if len(user_ids) == 1:
# For self-DM, other_user_id is the user's own id
other_user_id = user_ids[0]
else:
# For 1:1 DM, other_user_id is the other participant
other_user_id = user_ids[1] if user_ids[0] == user_profile.id else user_ids[0]
pm_dict[message_id] = dict(
other_user_id=other_user_id,
)
else:
direct_message_group_dict[message_id] = dict(
user_ids_string=user_ids_string,
)
# TODO: Add support for alert words here as well.
is_mentioned = (row["flags"] & UserMessage.flags.mentioned) != 0

View File

@@ -38,6 +38,7 @@ from zerver.models import (
)
from zerver.models.groups import NamedUserGroup
from zerver.models.realms import get_realm
from zerver.models.recipients import get_or_create_direct_message_group
from zerver.models.streams import get_stream
if TYPE_CHECKING:
@@ -1143,6 +1144,37 @@ class GetUnreadMsgsTest(ZulipTestCase):
dict(other_user_id=cordelia.id),
)
def test_raw_unread_personal_using_direct_group_message(self) -> None:
cordelia = self.example_user("cordelia")
othello = self.example_user("othello")
hamlet = self.example_user("hamlet")
# creating direct message group for 1:1 messages
get_or_create_direct_message_group(id_list=[cordelia.id, hamlet.id])
get_or_create_direct_message_group(id_list=[othello.id, hamlet.id])
cordelia_pm_message_ids = [self.send_personal_message(cordelia, hamlet) for i in range(3)]
othello_pm_message_ids = [self.send_personal_message(othello, hamlet) for i in range(3)]
raw_unread_data = get_raw_unread_data(
user_profile=hamlet,
)
pm_dict = raw_unread_data["pm_dict"]
self.assertEqual(
set(pm_dict.keys()),
set(cordelia_pm_message_ids) | set(othello_pm_message_ids),
)
self.assertEqual(
pm_dict[cordelia_pm_message_ids[0]],
dict(other_user_id=cordelia.id),
)
self.assertEqual(
pm_dict[othello_pm_message_ids[0]],
dict(other_user_id=othello.id),
)
def test_raw_unread_personal_from_self(self) -> None:
hamlet = self.example_user("hamlet")
@@ -1237,6 +1269,39 @@ class GetUnreadMsgsTest(ZulipTestCase):
dict(other_user_id=hamlet.id),
)
def test_raw_unread_personal_from_self_using_direct_message_group(self) -> None:
hamlet = self.example_user("hamlet")
# creating direct message group for self messages
get_or_create_direct_message_group(id_list=[hamlet.id])
# Send a message to ourself.
message_id = self.send_personal_message(
from_user=hamlet,
to_user=hamlet,
read_by_sender=False,
)
um = UserMessage.objects.get(
user_profile_id=hamlet.id,
message_id=message_id,
)
self.assertFalse(um.flags.read)
raw_unread_data = get_raw_unread_data(
user_profile=hamlet,
)
pm_dict = raw_unread_data["pm_dict"]
self.assertEqual(
set(pm_dict.keys()),
{message_id},
)
self.assertEqual(
pm_dict[message_id],
dict(other_user_id=hamlet.id),
)
def test_unread_msgs(self) -> None:
sender = self.example_user("cordelia")
sender_id = sender.id