direct_messages: Use DM groups for 1:1 or self DMs if present.

This is a preparatory refactor for migrating the internal structure of
Recipient objects for group DMs to use the DirectMessageGroup type,
not the legacy PERSONAL type. This step has the message-sending code
path check if a DirectMessageGroupe exists and prefer it if available.

It should have no effect in production other than doing a useless
database query for each outgoing DM, since we do not at present ever
create such DirectMessageGroup objects. (It will not add a marginal
database query once the migration is complete, just during this
transition).
This commit is contained in:
Mohammad Reza Kianifar
2025-05-15 03:02:11 +00:00
committed by Tim Abbott
parent e5db9614eb
commit a0488715f3
10 changed files with 151 additions and 28 deletions

View File

@@ -75,7 +75,7 @@ from zerver.models import (
from zerver.models.constants import MAX_TOPIC_NAME_LENGTH
from zerver.models.groups import SystemGroups
from zerver.models.realms import get_realm
from zerver.models.recipients import get_or_create_direct_message_group
from zerver.models.recipients import get_direct_message_group, get_or_create_direct_message_group
from zerver.models.streams import get_stream
from zerver.models.users import get_system_bot, get_user
from zerver.views.message_send import InvalidMirrorInputError
@@ -2554,6 +2554,27 @@ class PersonalMessageSendTest(ZulipTestCase):
recipient = Recipient.objects.get(type_id=user_profile.id, type=Recipient.PERSONAL)
self.assertEqual(most_recent_message(user_profile).recipient, recipient)
def test_personal_to_self_using_direct_message_group(self) -> None:
"""
If you send a personal to yourself using direct_message_group, only you see it.
"""
user_profile = self.example_user("hamlet")
direct_message_group = get_or_create_direct_message_group([user_profile.id])
other_user_profiles = UserProfile.objects.filter(~Q(id=user_profile.id))
old_messages = list(map(message_stream_count, other_user_profiles))
self.login("hamlet")
self.send_personal_message(user_profile, user_profile)
new_messages = list(map(message_stream_count, other_user_profiles))
self.assertEqual(old_messages, new_messages)
self.assertEqual(
most_recent_message(user_profile).recipient, direct_message_group.recipient
)
def assert_personal(
self, sender: UserProfile, receiver: UserProfile, content: str = "testcontent"
) -> None:
@@ -2577,7 +2598,14 @@ class PersonalMessageSendTest(ZulipTestCase):
self.assertEqual(message_stream_count(sender), sender_messages + 1)
self.assertEqual(message_stream_count(receiver), receiver_messages + 1)
recipient = Recipient.objects.get(type_id=receiver.id, type=Recipient.PERSONAL)
direct_message_group = get_direct_message_group([sender.id, receiver.id])
if direct_message_group:
recipient = Recipient.objects.get(
type_id=direct_message_group.id, type=Recipient.DIRECT_MESSAGE_GROUP
)
else:
recipient = Recipient.objects.get(type_id=receiver.id, type=Recipient.PERSONAL)
self.assertEqual(most_recent_message(sender).recipient, recipient)
self.assertEqual(most_recent_message(receiver).recipient, recipient)
@@ -2591,6 +2619,21 @@ class PersonalMessageSendTest(ZulipTestCase):
receiver=self.example_user("othello"),
)
def test_personal_using_direct_message_group(self) -> None:
"""
If you send a personal using direct_message_group, only you and the recipient see it.
"""
sender = self.example_user("hamlet")
receiver = self.example_user("othello")
get_or_create_direct_message_group([sender.id, receiver.id])
self.login("hamlet")
self.assert_personal(
sender=sender,
receiver=receiver,
)
def test_direct_message_initiator_group_setting(self) -> None:
"""
Tests that direct_message_initiator_group_setting works correctly.
@@ -2631,7 +2674,7 @@ class PersonalMessageSendTest(ZulipTestCase):
# Have the administrator send a message, and verify that allows the user to reply.
self.send_personal_message(admin, user_profile)
with self.assert_database_query_count(16):
with self.assert_database_query_count(17):
self.send_personal_message(user_profile, admin)
# Tests that user cannot initiate direct message thread in groups.
@@ -2667,7 +2710,7 @@ class PersonalMessageSendTest(ZulipTestCase):
user_group,
acting_user=None,
)
with self.assert_database_query_count(16):
with self.assert_database_query_count(17):
self.send_personal_message(user_profile, cordelia)
# Test that query count decreases if setting is set to a system group.
@@ -2681,7 +2724,7 @@ class PersonalMessageSendTest(ZulipTestCase):
acting_user=None,
)
othello = self.example_user("othello")
with self.assert_database_query_count(15):
with self.assert_database_query_count(16):
self.send_personal_message(user_profile, othello)
def test_direct_message_permission_group_setting(self) -> None:
@@ -2709,7 +2752,7 @@ class PersonalMessageSendTest(ZulipTestCase):
acting_user=None,
)
# Tests if the user is allowed to send to administrators.
with self.assert_database_query_count(16):
with self.assert_database_query_count(17):
self.send_personal_message(user_profile, admin)
self.send_personal_message(admin, user_profile)
# Tests if we can send messages to self irrespective of the value of the setting.
@@ -2759,7 +2802,7 @@ class PersonalMessageSendTest(ZulipTestCase):
with self.assertRaises(DirectMessagePermissionError):
self.send_personal_message(cordelia, polonius)
with self.assert_database_query_count(16):
with self.assert_database_query_count(17):
self.send_personal_message(user_profile, cordelia)
# Test that query count decreases if setting is set to a system group.
@@ -2772,7 +2815,7 @@ class PersonalMessageSendTest(ZulipTestCase):
members_group,
acting_user=None,
)
with self.assert_database_query_count(15):
with self.assert_database_query_count(16):
self.send_personal_message(user_profile, cordelia)
do_change_realm_permission_group_setting(