refactor: Rename `huddle` to `direct_message_group` in non API.

This commit performs a sweep on the first batch of non API
files to rename "huddle" to "direct_message_group`.

It also renames variables and methods of type -
"huddle_message" to "group_direct_message".

This is a part of #28640
This commit is contained in:
roanster007 2024-07-04 17:35:48 +05:30 committed by Tim Abbott
parent fa2f86ff80
commit 52692a6448
50 changed files with 647 additions and 548 deletions

View File

@ -10,7 +10,7 @@ from django.utils.translation import override as override_language
from confirmation import settings as confirmation_settings
from zerver.actions.message_send import (
internal_send_huddle_message,
internal_send_group_direct_message,
internal_send_private_message,
internal_send_stream_message,
)
@ -87,7 +87,7 @@ def send_message_to_signup_notification_stream(
def send_group_direct_message_to_admins(sender: UserProfile, realm: Realm, content: str) -> None:
administrators = list(realm.get_human_admin_users())
internal_send_huddle_message(
internal_send_group_direct_message(
realm,
sender,
content,

View File

@ -105,7 +105,7 @@ from zerver.models import (
from zerver.models.clients import get_client
from zerver.models.groups import SystemGroups
from zerver.models.realms import PrivateMessagePolicyEnum
from zerver.models.recipients import get_huddle_user_ids
from zerver.models.recipients import get_direct_message_group_user_ids
from zerver.models.scheduled_jobs import NotificationTriggers
from zerver.models.streams import get_stream, get_stream_by_id_in_realm
from zerver.models.users import get_system_bot, get_user_by_delivery_email, is_cross_realm_bot_email
@ -374,7 +374,7 @@ def get_recipient_info(
)
elif recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
message_to_user_id_set = set(get_huddle_user_ids(recipient))
message_to_user_id_set = set(get_direct_message_group_user_ids(recipient))
else:
raise ValueError("Bad recipient type")
@ -547,7 +547,7 @@ def get_service_bot_events(
# Mention triggers, for stream messages
if is_stream and user_profile_id in mentioned_user_ids:
trigger = "mention"
# Direct message triggers for personal and huddle messages
# Direct message triggers for personal and group direct messages
elif not is_stream and user_profile_id in active_user_ids:
trigger = NotificationTriggers.DIRECT_MESSAGE
else:
@ -1222,9 +1222,9 @@ def do_send_messages(
def already_sent_mirrored_message_id(message: Message) -> Optional[int]:
if message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
# For huddle messages, we use a 10-second window because the
# timestamps aren't guaranteed to actually match between two
# copies of the same message.
# For group direct messages, we use a 10-second window because
# the timestamps aren't guaranteed to actually match between
# two copies of the same message.
time_window = timedelta(seconds=10)
else:
time_window = timedelta(seconds=0)
@ -1989,7 +1989,7 @@ def internal_send_stream_message_by_name(
return sent_message_result.message_id
def internal_prep_huddle_message(
def internal_prep_group_direct_message(
realm: Realm,
sender: UserProfile,
content: str,
@ -2011,7 +2011,7 @@ def internal_prep_huddle_message(
)
def internal_send_huddle_message(
def internal_send_group_direct_message(
realm: Realm,
sender: UserProfile,
content: str,
@ -2019,7 +2019,7 @@ def internal_send_huddle_message(
emails: Optional[List[str]] = None,
recipient_users: Optional[List[UserProfile]] = None,
) -> Optional[int]:
message = internal_prep_huddle_message(
message = internal_prep_group_direct_message(
realm, sender, content, emails=emails, recipient_users=recipient_users
)

View File

@ -47,15 +47,15 @@ def check_send_typing_notification(sender: UserProfile, user_ids: List[int], ope
# If any of the user_ids being sent in are invalid, we will
# just reject the whole request, since a partial list of user_ids
# can create confusion related to huddles. Plus it's a good
# sign that a client is confused (or possibly even malicious) if
# we get bad user_ids.
# can create confusion related to direct message groups. Plus it's
# a good sign that a client is confused (or possibly even malicious)
# if we get bad user_ids.
user_profiles = []
for user_id in user_ids:
try:
# We include cross-bot realms as possible recipients,
# so that clients can know which huddle conversation
# is relevant here.
# so that clients can know which direct message group
# conversation is relevant here.
user_profile = get_user_by_id_in_realm_including_cross_realm(user_id, sender.realm)
except UserProfile.DoesNotExist:
raise JsonableError(_("Invalid user ID {user_id}").format(user_id=user_id))

View File

@ -50,30 +50,30 @@ ZerverFieldsT: TypeAlias = Dict[str, Any]
class SubscriberHandler:
def __init__(self) -> None:
self.stream_info: Dict[int, Set[int]] = {}
self.huddle_info: Dict[int, Set[int]] = {}
self.direct_message_group_info: Dict[int, Set[int]] = {}
def set_info(
self,
users: Set[int],
stream_id: Optional[int] = None,
huddle_id: Optional[int] = None,
direct_message_group_id: Optional[int] = None,
) -> None:
if stream_id is not None:
self.stream_info[stream_id] = users
elif huddle_id is not None:
self.huddle_info[huddle_id] = users
elif direct_message_group_id is not None:
self.direct_message_group_info[direct_message_group_id] = users
else:
raise AssertionError("stream_id or huddle_id is required")
raise AssertionError("stream_id or direct_message_group_id is required")
def get_users(
self, stream_id: Optional[int] = None, huddle_id: Optional[int] = None
self, stream_id: Optional[int] = None, direct_message_group_id: Optional[int] = None
) -> Set[int]:
if stream_id is not None:
return self.stream_info[stream_id]
elif huddle_id is not None:
return self.huddle_info[huddle_id]
elif direct_message_group_id is not None:
return self.direct_message_group_info[direct_message_group_id]
else:
raise AssertionError("stream_id or huddle_id is required")
raise AssertionError("stream_id or direct_message_group_id is required")
def build_zerver_realm(
@ -214,7 +214,7 @@ def build_subscription(recipient_id: int, user_id: int, subscription_id: int) ->
class GetUsers(Protocol):
def __call__(self, stream_id: int = ..., huddle_id: int = ...) -> Set[int]: ...
def __call__(self, stream_id: int = ..., direct_message_group_id: int = ...) -> Set[int]: ...
def build_stream_subscriptions(
@ -245,24 +245,26 @@ def build_stream_subscriptions(
return subscriptions
def build_huddle_subscriptions(
def build_direct_message_group_subscriptions(
get_users: GetUsers,
zerver_recipient: List[ZerverFieldsT],
zerver_huddle: List[ZerverFieldsT],
zerver_direct_message_group: List[ZerverFieldsT],
) -> List[ZerverFieldsT]:
subscriptions: List[ZerverFieldsT] = []
huddle_ids = {huddle["id"] for huddle in zerver_huddle}
direct_message_group_ids = {
direct_message_group["id"] for direct_message_group in zerver_direct_message_group
}
recipient_map = {
recipient["id"]: recipient["type_id"] # recipient_id -> stream_id
for recipient in zerver_recipient
if recipient["type"] == Recipient.DIRECT_MESSAGE_GROUP
and recipient["type_id"] in huddle_ids
and recipient["type_id"] in direct_message_group_ids
}
for recipient_id, huddle_id in recipient_map.items():
user_ids = get_users(huddle_id=huddle_id)
for recipient_id, direct_message_group_id in recipient_map.items():
user_ids = get_users(direct_message_group_id=direct_message_group_id)
for user_id in user_ids:
subscription = build_subscription(
recipient_id=recipient_id,
@ -307,7 +309,7 @@ def build_recipient(type_id: int, recipient_id: int, type: int) -> ZerverFieldsT
def build_recipients(
zerver_userprofile: Iterable[ZerverFieldsT],
zerver_stream: Iterable[ZerverFieldsT],
zerver_huddle: Iterable[ZerverFieldsT] = [],
zerver_direct_message_group: Iterable[ZerverFieldsT] = [],
) -> List[ZerverFieldsT]:
"""
This function was only used HipChat import, this function may be
@ -339,8 +341,8 @@ def build_recipients(
recipient_dict = model_to_dict(recipient)
recipients.append(recipient_dict)
for huddle in zerver_huddle:
type_id = huddle["id"]
for direct_message_group in zerver_direct_message_group:
type_id = direct_message_group["id"]
type = Recipient.DIRECT_MESSAGE_GROUP
recipient = Recipient(
type_id=type_id,
@ -482,11 +484,11 @@ def build_stream(
return stream_dict
def build_huddle(huddle_id: int) -> ZerverFieldsT:
huddle = Huddle(
id=huddle_id,
def build_direct_message_group(direct_message_group_id: int) -> ZerverFieldsT:
direct_message_group = Huddle(
id=direct_message_group_id,
)
return model_to_dict(huddle)
return model_to_dict(direct_message_group)
def build_message(

View File

@ -21,8 +21,8 @@ from zerver.data_import.import_util import (
SubscriberHandler,
ZerverFieldsT,
build_attachment,
build_huddle,
build_huddle_subscriptions,
build_direct_message_group,
build_direct_message_group_subscriptions,
build_message,
build_personal_subscriptions,
build_realm,
@ -232,17 +232,18 @@ def convert_channel_data(
return streams
def generate_huddle_name(huddle_members: List[str]) -> str:
def generate_direct_message_group_name(direct_message_group_members: List[str]) -> str:
# Simple hash function to generate a unique hash key for the
# members of a huddle. Needs to be consistent only within the
# lifetime of export tool run, as it doesn't appear in the output.
# members of a direct_message_group. Needs to be consistent
# only within the lifetime of export tool run, as it doesn't
# appear in the output.
import hashlib
return hashlib.md5("".join(sorted(huddle_members)).encode()).hexdigest()
return hashlib.md5("".join(sorted(direct_message_group_members)).encode()).hexdigest()
def convert_huddle_data(
huddle_data: List[ZerverFieldsT],
def convert_direct_message_group_data(
direct_message_group_data: List[ZerverFieldsT],
user_data_map: Dict[str, Dict[str, Any]],
subscriber_handler: SubscriberHandler,
huddle_id_mapper: IdMapper,
@ -250,21 +251,23 @@ def convert_huddle_data(
realm_id: int,
team_name: str,
) -> List[ZerverFieldsT]:
zerver_huddle = []
for huddle in huddle_data:
if len(huddle["members"]) > 2:
huddle_name = generate_huddle_name(huddle["members"])
huddle_id = huddle_id_mapper.get(huddle_name)
huddle_dict = build_huddle(huddle_id)
huddle_user_ids = set()
for username in huddle["members"]:
huddle_user_ids.add(user_id_mapper.get(username))
subscriber_handler.set_info(
users=huddle_user_ids,
huddle_id=huddle_id,
zerver_direct_message_group = []
for direct_message_group in direct_message_group_data:
if len(direct_message_group["members"]) > 2:
direct_message_group_name = generate_direct_message_group_name(
direct_message_group["members"]
)
zerver_huddle.append(huddle_dict)
return zerver_huddle
direct_message_group_id = huddle_id_mapper.get(direct_message_group_name)
direct_message_group_dict = build_direct_message_group(direct_message_group_id)
direct_message_group_user_ids = set()
for username in direct_message_group["members"]:
direct_message_group_user_ids.add(user_id_mapper.get(username))
subscriber_handler.set_info(
users=direct_message_group_user_ids,
direct_message_group_id=direct_message_group_id,
)
zerver_direct_message_group.append(direct_message_group_dict)
return zerver_direct_message_group
def build_reactions(
@ -591,12 +594,12 @@ def process_posts(
if "channel" in post_dict:
message_dict["channel_name"] = post_dict["channel"]
elif "channel_members" in post_dict:
# This case is for handling posts from direct messages and huddles,
# not channels. Direct messages and huddles are known as direct_channels
# in Slack and hence the name channel_members.
# This case is for handling posts from direct messages and direct message,
# groups not channels. Direct messages and direct message groups are known
# as direct_channels in Slack and hence the name channel_members.
channel_members = post_dict["channel_members"]
if len(channel_members) > 2:
message_dict["huddle_name"] = generate_huddle_name(channel_members)
message_dict["huddle_name"] = generate_direct_message_group_name(channel_members)
elif len(channel_members) == 2:
message_dict["pm_members"] = channel_members
else:
@ -697,7 +700,7 @@ def write_message_data(
else:
post_types = ["channel_post"]
logging.warning(
"Skipping importing huddles and DMs since there are multiple teams in the export"
"Skipping importing direct message groups and DMs since there are multiple teams in the export"
)
for post_type in post_types:
@ -924,10 +927,10 @@ def do_convert_data(mattermost_data_dir: str, output_dir: str, masking_content:
)
realm["zerver_stream"] = zerver_stream
zerver_huddle: List[ZerverFieldsT] = []
zerver_direct_message_group: List[ZerverFieldsT] = []
if len(mattermost_data["team"]) == 1:
zerver_huddle = convert_huddle_data(
huddle_data=mattermost_data["direct_channel"],
zerver_direct_message_group = convert_direct_message_group_data(
direct_message_group_data=mattermost_data["direct_channel"],
user_data_map=username_to_user,
subscriber_handler=subscriber_handler,
huddle_id_mapper=huddle_id_mapper,
@ -935,14 +938,14 @@ def do_convert_data(mattermost_data_dir: str, output_dir: str, masking_content:
realm_id=realm_id,
team_name=team_name,
)
realm["zerver_huddle"] = zerver_huddle
realm["zerver_huddle"] = zerver_direct_message_group
all_users = user_handler.get_all_users()
zerver_recipient = build_recipients(
zerver_userprofile=all_users,
zerver_stream=zerver_stream,
zerver_huddle=zerver_huddle,
zerver_direct_message_group=zerver_direct_message_group,
)
realm["zerver_recipient"] = zerver_recipient
@ -952,10 +955,10 @@ def do_convert_data(mattermost_data_dir: str, output_dir: str, masking_content:
zerver_stream=zerver_stream,
)
huddle_subscriptions = build_huddle_subscriptions(
direct_message_group_subscriptions = build_direct_message_group_subscriptions(
get_users=subscriber_handler.get_users,
zerver_recipient=zerver_recipient,
zerver_huddle=zerver_huddle,
zerver_direct_message_group=zerver_direct_message_group,
)
personal_subscriptions = build_personal_subscriptions(
@ -963,8 +966,10 @@ def do_convert_data(mattermost_data_dir: str, output_dir: str, masking_content:
)
# Mattermost currently supports only exporting messages from channels.
# Personal messages and huddles are not exported.
zerver_subscription = personal_subscriptions + stream_subscriptions + huddle_subscriptions
# Personal and Group Direct messages are not exported.
zerver_subscription = (
personal_subscriptions + stream_subscriptions + direct_message_group_subscriptions
)
realm["zerver_subscription"] = zerver_subscription
zerver_realmemoji = write_emoticon_data(

View File

@ -14,8 +14,8 @@ from zerver.data_import.import_util import (
SubscriberHandler,
ZerverFieldsT,
build_attachment,
build_huddle,
build_huddle_subscriptions,
build_direct_message_group,
build_direct_message_group_subscriptions,
build_message,
build_personal_subscriptions,
build_realm,
@ -238,29 +238,29 @@ def convert_stream_subscription_data(
subscriber_handler.set_info(users=users, stream_id=stream["id"])
def convert_huddle_data(
def convert_direct_message_group_data(
huddle_id_to_huddle_map: Dict[str, Dict[str, Any]],
huddle_id_mapper: IdMapper,
user_id_mapper: IdMapper,
subscriber_handler: SubscriberHandler,
) -> List[ZerverFieldsT]:
zerver_huddle: List[ZerverFieldsT] = []
zerver_direct_message_group: List[ZerverFieldsT] = []
for rc_huddle_id in huddle_id_to_huddle_map:
huddle_id = huddle_id_mapper.get(rc_huddle_id)
huddle = build_huddle(huddle_id)
zerver_huddle.append(huddle)
direct_message_group_id = huddle_id_mapper.get(rc_huddle_id)
direct_message_group = build_direct_message_group(direct_message_group_id)
zerver_direct_message_group.append(direct_message_group)
huddle_dict = huddle_id_to_huddle_map[rc_huddle_id]
huddle_user_ids = set()
for rc_user_id in huddle_dict["uids"]:
huddle_user_ids.add(user_id_mapper.get(rc_user_id))
direct_message_group_dict = huddle_id_to_huddle_map[rc_huddle_id]
direct_message_group_user_ids = set()
for rc_user_id in direct_message_group_dict["uids"]:
direct_message_group_user_ids.add(user_id_mapper.get(rc_user_id))
subscriber_handler.set_info(
users=huddle_user_ids,
huddle_id=huddle_id,
users=direct_message_group_user_ids,
direct_message_group_id=direct_message_group_id,
)
return zerver_huddle
return zerver_direct_message_group
def build_custom_emoji(
@ -679,8 +679,8 @@ def process_messages(
# Message is in a 1:1 or group direct message.
rc_channel_id = message["rid"]
if rc_channel_id in huddle_id_to_huddle_map:
huddle_id = huddle_id_mapper.get(rc_channel_id)
message_dict["recipient_id"] = huddle_id_to_recipient_id[huddle_id]
direct_message_group_id = huddle_id_mapper.get(rc_channel_id)
message_dict["recipient_id"] = huddle_id_to_recipient_id[direct_message_group_id]
else:
rc_member_ids = direct_id_to_direct_map[rc_channel_id]["uids"]
@ -876,7 +876,7 @@ def map_receiver_id_to_recipient_id(
huddle_id_to_recipient_id: Dict[int, int],
user_id_to_recipient_id: Dict[int, int],
) -> None:
# receiver_id represents stream_id/huddle_id/user_id
# receiver_id represents stream_id/direct_message_group_id/user_id
for recipient in zerver_recipient:
if recipient["type"] == Recipient.STREAM:
stream_id_to_recipient_id[recipient["type_id"]] = recipient["id"]
@ -886,16 +886,18 @@ def map_receiver_id_to_recipient_id(
user_id_to_recipient_id[recipient["type_id"]] = recipient["id"]
# This is inspired by get_huddle_hash from zerver/models/recipients.py. It
# expects strings identifying Rocket.Chat users, like
# `LdBZ7kPxtKESyHPEe`, not integer IDs.
# This is inspired by get_direct_message_group_hash
# from zerver/models/recipients.py. It expects strings
# identifying Rocket.Chat users, like `LdBZ7kPxtKESyHPEe`,
# not integer IDs.
#
# Its purpose is to be a stable map usable for deduplication/merging
# of Rocket.Chat threads involving the same set of people. Thus, its
# only important property is that if two sets of users S and T are
# equal and thus will have the same actual huddle hash once imported,
# that get_string_huddle_hash(S) = get_string_huddle_hash(T).
def get_string_huddle_hash(id_list: List[str]) -> str:
# equal and thus will have the same actual direct message group hash
# once imported, that get_string_direct_message_group_hash(S) =
# get_string_direct_message_group_hash(T).
def get_string_direct_message_group_hash(id_list: List[str]) -> str:
id_list = sorted(set(id_list))
hash_key = ",".join(str(x) for x in id_list)
return hashlib.sha1(hash_key.encode()).hexdigest()
@ -910,15 +912,17 @@ def categorize_channels_and_map_with_id(
huddle_id_to_huddle_map: Dict[str, Dict[str, Any]],
livechat_id_to_livechat_map: Dict[str, Dict[str, Any]],
) -> None:
huddle_hashed_channels: Dict[str, Any] = {}
direct_message_group_hashed_channels: Dict[str, Any] = {}
for channel in channel_data:
if channel.get("prid"):
dsc_id_to_dsc_map[channel["_id"]] = channel
elif channel["t"] == "d":
if len(channel["uids"]) > 2:
huddle_hash = get_string_huddle_hash(channel["uids"])
direct_message_group_hash = get_string_direct_message_group_hash(channel["uids"])
logging.info(
"Huddle channel found. UIDs: %s -> hash %s", channel["uids"], huddle_hash
"Huddle channel found. UIDs: %s -> hash %s",
channel["uids"],
direct_message_group_hash,
)
if channel["msgs"] == 0: # nocoverage
@ -926,25 +930,29 @@ def categorize_channels_and_map_with_id(
# contain duplicates of real huddles, with no
# messages in the duplicate. We ignore these
# minor database corruptions in the Rocket.Chat
# export. Doing so is safe, because a huddle with no
# message history has no value in Zulip's data
# model.
logging.debug("Skipping huddle with 0 messages: %s", channel)
elif huddle_hash in huddle_hashed_channels: # nocoverage
# export. Doing so is safe, because a direct
# message group with no message history has no
# value in Zulip's data model.
logging.debug("Skipping direct message group with 0 messages: %s", channel)
elif (
direct_message_group_hash in direct_message_group_hashed_channels
): # nocoverage
logging.info(
"Mapping huddle hash %s to existing channel: %s",
huddle_hash,
huddle_hashed_channels[huddle_hash],
"Mapping direct message group hash %s to existing channel: %s",
direct_message_group_hash,
direct_message_group_hashed_channels[direct_message_group_hash],
)
huddle_id_to_huddle_map[channel["_id"]] = huddle_hashed_channels[huddle_hash]
huddle_id_to_huddle_map[channel["_id"]] = direct_message_group_hashed_channels[
direct_message_group_hash
]
# Ideally, we'd merge the duplicate huddles. Doing
# so correctly requires special handling in
# convert_huddle_data() and on the message import
# side as well, since those appear to be mapped
# via rocketchat channel IDs and not all of that
# information is resolved via the
# huddle_id_to_huddle_map.
# Ideally, we'd merge the duplicate direct message
# groups. Doing so correctly requires special
# handling in convert_direct_message_group_data()
# and on the message import side as well, since
# those appear to be mapped via rocketchat channel
# IDs and not all of that information is resolved
# via the huddle_id_to_huddle_map.
#
# For now, just throw an exception here rather
# than during the import process.
@ -953,7 +961,7 @@ def categorize_channels_and_map_with_id(
)
else:
huddle_id_to_huddle_map[channel["_id"]] = channel
huddle_hashed_channels[huddle_hash] = channel
direct_message_group_hashed_channels[direct_message_group_hash] = channel
else:
direct_id_to_direct_map[channel["_id"]] = channel
elif channel["t"] == "l":
@ -1114,20 +1122,20 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
subscriber_handler=subscriber_handler,
)
zerver_huddle = convert_huddle_data(
zerver_direct_message_group = convert_direct_message_group_data(
huddle_id_to_huddle_map=huddle_id_to_huddle_map,
huddle_id_mapper=huddle_id_mapper,
user_id_mapper=user_id_mapper,
subscriber_handler=subscriber_handler,
)
realm["zerver_huddle"] = zerver_huddle
realm["zerver_huddle"] = zerver_direct_message_group
all_users = user_handler.get_all_users()
zerver_recipient = build_recipients(
zerver_userprofile=all_users,
zerver_stream=zerver_stream,
zerver_huddle=zerver_huddle,
zerver_direct_message_group=zerver_direct_message_group,
)
realm["zerver_recipient"] = zerver_recipient
@ -1137,17 +1145,19 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
zerver_stream=zerver_stream,
)
huddle_subscriptions = build_huddle_subscriptions(
direct_message_group_subscriptions = build_direct_message_group_subscriptions(
get_users=subscriber_handler.get_users,
zerver_recipient=zerver_recipient,
zerver_huddle=zerver_huddle,
zerver_direct_message_group=zerver_direct_message_group,
)
personal_subscriptions = build_personal_subscriptions(
zerver_recipient=zerver_recipient,
)
zerver_subscription = personal_subscriptions + stream_subscriptions + huddle_subscriptions
zerver_subscription = (
personal_subscriptions + stream_subscriptions + direct_message_group_subscriptions
)
realm["zerver_subscription"] = zerver_subscription
zerver_realmemoji = build_custom_emoji(

View File

@ -24,7 +24,7 @@ from zerver.data_import.import_util import (
build_attachment,
build_avatar,
build_defaultstream,
build_huddle,
build_direct_message_group,
build_message,
build_realm,
build_recipient,
@ -160,7 +160,7 @@ def slack_workspace_to_realm(
3. slack_recipient_name_to_zulip_recipient_id, which is a dictionary to map from Slack recipient
name(channel names, mpim names, usernames, etc) to Zulip recipient id
4. added_channels, which is a dictionary to map from channel name to channel id, Zulip stream_id
5. added_mpims, which is a dictionary to map from MPIM name to MPIM id, Zulip huddle_id
5. added_mpims, which is a dictionary to map from MPIM name to MPIM id, Zulip direct_message_group_id
6. dm_members, which is a dictionary to map from DM id to tuple of DM participants.
7. avatars, which is list to map avatars to Zulip avatar records.json
8. emoji_url_map, which is maps emoji name to its Slack URL
@ -507,7 +507,8 @@ def channels_to_zerver_stream(
Returns:
1. realm, converted realm data
2. added_channels, which is a dictionary to map from channel name to channel id, Zulip stream_id
3. added_mpims, which is a dictionary to map from MPIM(multiparty IM) name to MPIM id, Zulip huddle_id
3. added_mpims, which is a dictionary to map from MPIM(multiparty IM) name to MPIM id, Zulip
direct_message_group_id
4. dm_members, which is a dictionary to map from DM id to tuple of DM participants.
5. slack_recipient_name_to_zulip_recipient_id, which is a dictionary to map from Slack recipient
name(channel names, mpim names, usernames etc) to Zulip recipient_id
@ -527,7 +528,7 @@ def channels_to_zerver_stream(
subscription_id_count = recipient_id_count = 0
stream_id_count = defaultstream_id = 0
huddle_id_count = 0
direct_message_group_id_count = 0
def process_channels(channels: List[Dict[str, Any]], invite_only: bool = False) -> None:
nonlocal stream_id_count
@ -600,20 +601,20 @@ def channels_to_zerver_stream(
private_channels = []
process_channels(private_channels, True)
# mpim is the Slack equivalent of huddle.
# mpim is the Slack equivalent of direct message group.
def process_mpims(mpims: List[Dict[str, Any]]) -> None:
nonlocal huddle_id_count
nonlocal direct_message_group_id_count
nonlocal recipient_id_count
nonlocal subscription_id_count
for mpim in mpims:
huddle = build_huddle(huddle_id_count)
realm["zerver_huddle"].append(huddle)
direct_message_group = build_direct_message_group(direct_message_group_id_count)
realm["zerver_huddle"].append(direct_message_group)
added_mpims[mpim["name"]] = (mpim["id"], huddle_id_count)
added_mpims[mpim["name"]] = (mpim["id"], direct_message_group_id_count)
recipient = build_recipient(
huddle_id_count, recipient_id_count, Recipient.DIRECT_MESSAGE_GROUP
direct_message_group_id_count, recipient_id_count, Recipient.DIRECT_MESSAGE_GROUP
)
realm["zerver_recipient"].append(recipient)
slack_recipient_name_to_zulip_recipient_id[mpim["name"]] = recipient_id_count
@ -626,7 +627,7 @@ def channels_to_zerver_stream(
subscription_id_count,
)
huddle_id_count += 1
direct_message_group_id_count += 1
recipient_id_count += 1
logging.info("%s -> created", mpim["name"])
@ -1267,10 +1268,10 @@ def fetch_shared_channel_users(
except FileNotFoundError:
private_channels = []
try:
huddles = get_data_file(slack_data_dir + "/mpims.json")
direct_message_groups = get_data_file(slack_data_dir + "/mpims.json")
except FileNotFoundError:
huddles = []
for channel in public_channels + private_channels + huddles:
direct_message_groups = []
for channel in public_channels + private_channels + direct_message_groups:
added_channels[channel["name"]] = True
for user_id in channel["members"]:
if user_id not in normal_user_ids:

View File

@ -7,7 +7,7 @@ from django.utils.translation import gettext as _
from zulip_bots.lib import BotIdentity, RateLimit
from zerver.actions.message_send import (
internal_send_huddle_message,
internal_send_group_direct_message,
internal_send_private_message,
internal_send_stream_message_by_name,
)
@ -109,7 +109,7 @@ class EmbeddedBotHandler:
self.user_profile, recipient_user, message["content"]
)
else:
message_id = internal_send_huddle_message(
message_id = internal_send_group_direct_message(
self.user_profile.realm, self.user_profile, message["content"], emails=recipients
)
return {"id": message_id}

View File

@ -135,7 +135,7 @@ def bulk_fetch_user_display_recipients(
"""
from zerver.models import Recipient
from zerver.models.recipients import bulk_get_huddle_user_ids
from zerver.models.recipients import bulk_get_direct_message_group_user_ids
if len(recipient_tuples) == 0:
return {}
@ -144,12 +144,16 @@ def bulk_fetch_user_display_recipients(
get_type = lambda tup: tup[1]
personal_tuples = [tup for tup in recipient_tuples if get_type(tup) == Recipient.PERSONAL]
huddle_tuples = [
direct_message_group_tuples = [
tup for tup in recipient_tuples if get_type(tup) == Recipient.DIRECT_MESSAGE_GROUP
]
huddle_recipient_ids = [get_recipient_id(tup) for tup in huddle_tuples]
huddle_recipient_id_to_user_ids = bulk_get_huddle_user_ids(huddle_recipient_ids)
direct_message_group_recipient_ids = [
get_recipient_id(tup) for tup in direct_message_group_tuples
]
huddle_recipient_id_to_user_ids = bulk_get_direct_message_group_user_ids(
direct_message_group_recipient_ids
)
# Find all user ids whose UserProfiles we will need to fetch:
user_ids_to_fetch: Set[int] = set()
@ -157,9 +161,9 @@ def bulk_fetch_user_display_recipients(
for ignore_recipient_id, ignore_recipient_type, user_id in personal_tuples:
user_ids_to_fetch.add(user_id)
for recipient_id in huddle_recipient_ids:
huddle_user_ids = huddle_recipient_id_to_user_ids[recipient_id]
user_ids_to_fetch |= huddle_user_ids
for recipient_id in direct_message_group_recipient_ids:
direct_message_group_user_ids = huddle_recipient_id_to_user_ids[recipient_id]
user_ids_to_fetch |= direct_message_group_user_ids
# Fetch the needed user dictionaries.
user_display_recipients = bulk_fetch_single_user_display_recipients(list(user_ids_to_fetch))
@ -170,7 +174,7 @@ def bulk_fetch_user_display_recipients(
display_recipients = [user_display_recipients[user_id]]
result[recipient_id] = display_recipients
for recipient_id in huddle_recipient_ids:
for recipient_id in direct_message_group_recipient_ids:
user_ids = sorted(huddle_recipient_id_to_user_ids[recipient_id])
display_recipients = [user_display_recipients[user_id] for user_id in user_ids]
result[recipient_id] = display_recipients
@ -191,15 +195,15 @@ def bulk_fetch_display_recipients(
stream_recipients = {
recipient for recipient in recipient_tuples if recipient[1] == Recipient.STREAM
}
personal_and_huddle_recipients = recipient_tuples - stream_recipients
direct_message_recipients = recipient_tuples - stream_recipients
stream_display_recipients = bulk_fetch_stream_names(stream_recipients)
personal_and_huddle_display_recipients = bulk_fetch_user_display_recipients(
personal_and_huddle_recipients
direct_message_display_recipients = bulk_fetch_user_display_recipients(
direct_message_recipients
)
# Glue the dicts together and return:
return {**stream_display_recipients, **personal_and_huddle_display_recipients}
return {**stream_display_recipients, **direct_message_display_recipients}
@return_same_value_during_entire_request

View File

@ -11,7 +11,7 @@ from typing_extensions import override
from zerver.actions.message_send import (
check_send_message,
internal_send_huddle_message,
internal_send_group_direct_message,
internal_send_private_message,
internal_send_stream_message,
)
@ -458,7 +458,7 @@ def process_missed_message(to: str, message: EmailMessage) -> None:
display_recipient = get_display_recipient(recipient)
emails = [user_dict["email"] for user_dict in display_recipient]
recipient_str = ", ".join(emails)
internal_send_huddle_message(user_profile.realm, user_profile, body, emails=emails)
internal_send_group_direct_message(user_profile.realm, user_profile, body, emails=emails)
else:
raise AssertionError("Invalid recipient type!")

View File

@ -33,7 +33,7 @@ from zerver.lib.tex import change_katex_to_raw_latex
from zerver.lib.timezone import canonicalize_timezone
from zerver.lib.topic import get_topic_resolution_and_bare_name
from zerver.lib.url_encoding import (
huddle_narrow_url,
direct_message_group_narrow_url,
personal_narrow_url,
stream_narrow_url,
topic_narrow_url,
@ -262,7 +262,7 @@ def build_message_list(
elif message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
grouping = {"huddle": message.recipient_id}
display_recipient = get_display_recipient(message.recipient)
narrow_link = huddle_narrow_url(
narrow_link = direct_message_group_narrow_url(
user=user,
display_recipient=display_recipient,
)
@ -385,8 +385,8 @@ def do_send_missedmessage_events_reply_in_zulip(
The email will have its reply to address set to a limited used email
address that will send a Zulip message to the correct recipient. This
allows the user to respond to missed direct messages, huddles, and
@-mentions directly from the email.
allows the user to respond to missed direct messages, direct message
groups, and @-mentions directly from the email.
`user_profile` is the user to send the reminder to
`missed_messages` is a list of dictionaries to Message objects and other data
@ -474,7 +474,7 @@ def do_send_missedmessage_events_reply_in_zulip(
senders = list({m["message"].sender for m in missed_messages})
if missed_messages[0]["message"].recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
display_recipient = get_display_recipient(missed_messages[0]["message"].recipient)
narrow_url = huddle_narrow_url(
narrow_url = direct_message_group_narrow_url(
user=user_profile,
display_recipient=display_recipient,
)
@ -482,18 +482,18 @@ def do_send_missedmessage_events_reply_in_zulip(
other_recipients = [r["full_name"] for r in display_recipient if r["id"] != user_profile.id]
context.update(group_pm=True)
if len(other_recipients) == 2:
huddle_display_name = " and ".join(other_recipients)
context.update(huddle_display_name=huddle_display_name)
direct_message_group_display_name = " and ".join(other_recipients)
context.update(huddle_display_name=direct_message_group_display_name)
elif len(other_recipients) == 3:
huddle_display_name = (
direct_message_group_display_name = (
f"{other_recipients[0]}, {other_recipients[1]}, and {other_recipients[2]}"
)
context.update(huddle_display_name=huddle_display_name)
context.update(huddle_display_name=direct_message_group_display_name)
else:
huddle_display_name = "{}, and {} others".format(
direct_message_group_display_name = "{}, and {} others".format(
", ".join(other_recipients[:2]), len(other_recipients) - 2
)
context.update(huddle_display_name=huddle_display_name)
context.update(huddle_display_name=direct_message_group_display_name)
elif missed_messages[0]["message"].recipient.type == Recipient.PERSONAL:
narrow_url = personal_narrow_url(
realm=user_profile.realm,

View File

@ -886,7 +886,7 @@ def get_realm_config() -> Config:
"zerver_huddle",
],
virtual_parent=user_profile_config,
custom_fetch=custom_fetch_huddle_objects,
custom_fetch=custom_fetch_direct_message_groups,
)
# Now build permanent tables from our temp tables.
@ -1118,7 +1118,7 @@ def fetch_reaction_data(response: TableData, message_ids: Set[int]) -> None:
response["zerver_reaction"] = make_raw(list(query))
def custom_fetch_huddle_objects(response: TableData, context: Context) -> None:
def custom_fetch_direct_message_groups(response: TableData, context: Context) -> None:
realm = context["realm"]
user_profile_ids = {
r["id"] for r in response["zerver_userprofile"] + response["zerver_userprofile_mirrordummy"]

View File

@ -83,7 +83,7 @@ from zerver.models import (
from zerver.models.groups import SystemGroups
from zerver.models.presence import PresenceSequence
from zerver.models.realms import get_realm
from zerver.models.recipients import get_huddle_hash
from zerver.models.recipients import get_direct_message_group_hash
from zerver.models.users import get_system_bot, get_user_profile_by_id
from zproject.backends import AUTH_BACKEND_NAME_MAP
@ -277,19 +277,21 @@ def fix_service_tokens(data: TableData, table: TableName) -> None:
item["token"] = generate_api_key()
def process_huddle_hash(data: TableData, table: TableName) -> None:
def process_direct_message_group_hash(data: TableData, table: TableName) -> None:
"""
Build new huddle hashes with the updated ids of the users
Build new direct message group hashes with the updated ids of the users
"""
for huddle in data[table]:
user_id_list = id_map_to_list["huddle_to_user_list"][huddle["id"]]
huddle["huddle_hash"] = get_huddle_hash(user_id_list)
for direct_message_group in data[table]:
user_id_list = id_map_to_list["huddle_to_user_list"][direct_message_group["id"]]
direct_message_group["huddle_hash"] = get_direct_message_group_hash(user_id_list)
def get_huddles_from_subscription(data: TableData, table: TableName) -> None:
def get_direct_message_groups_from_subscription(data: TableData, table: TableName) -> None:
"""
Extract the IDs of the user_profiles involved in a huddle from the subscription object
This helps to generate a unique huddle hash from the updated user_profile ids
Extract the IDs of the user_profiles involved in a direct message group from
the subscription object
This helps to generate a unique direct message group hash from the updated
user_profile ids
"""
id_map_to_list["huddle_to_user_list"] = {
value: [] for value in ID_MAP["recipient_to_huddle_map"].values()
@ -297,8 +299,10 @@ def get_huddles_from_subscription(data: TableData, table: TableName) -> None:
for subscription in data[table]:
if subscription["recipient"] in ID_MAP["recipient_to_huddle_map"]:
huddle_id = ID_MAP["recipient_to_huddle_map"][subscription["recipient"]]
id_map_to_list["huddle_to_user_list"][huddle_id].append(subscription["user_profile_id"])
direct_message_group_id = ID_MAP["recipient_to_huddle_map"][subscription["recipient"]]
id_map_to_list["huddle_to_user_list"][direct_message_group_id].append(
subscription["user_profile_id"]
)
def fix_customprofilefield(data: TableData) -> None:
@ -550,10 +554,10 @@ def re_map_foreign_keys_internal(
elif related_table == "user_profile" and item["type"] == 1:
pass
elif related_table == "huddle" and item["type"] == 3:
# save the recipient id with the huddle id, so that we can extract
# the user_profile ids involved in a huddle with the help of the
# subscription object
# check function 'get_huddles_from_subscription'
# save the recipient id with the direct message group id, so that
# we can extract the user_profile ids involved in a direct message
# group with the help of the subscription object
# check function 'get_direct_message_groups_from_subscription'
ID_MAP["recipient_to_huddle_map"][item["id"]] = lookup_table[old_id]
else:
continue
@ -672,9 +676,9 @@ def remove_denormalized_recipient_column_from_data(data: TableData) -> None:
if "recipient" in user_profile_dict:
del user_profile_dict["recipient"]
for huddle_dict in data["zerver_huddle"]:
if "recipient" in huddle_dict:
del huddle_dict["recipient"]
for direct_message_group_dict in data["zerver_huddle"]:
if "recipient" in direct_message_group_dict:
del direct_message_group_dict["recipient"]
def get_db_table(model_class: Any) -> str:
@ -1226,10 +1230,11 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea
if "zerver_huddle" in data:
update_model_ids(Huddle, data, "huddle")
# We don't import Huddle yet, since we don't have the data to
# compute huddle hashes until we've imported some of the
# tables below.
# We can't get huddle hashes without processing subscriptions
# first, during which get_huddles_from_subscription is called.
# compute direct message group hashes until we've imported some
# of the tables below.
# We can't get direct message group hashes without processing
# subscriptions first, during which
# get_direct_message_groups_from_subscription is called.
re_map_foreign_keys(
data,
@ -1261,7 +1266,7 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea
bulk_set_users_or_streams_recipient_fields(UserProfile, UserProfile.objects.filter(realm=realm))
re_map_foreign_keys(data, "zerver_subscription", "user_profile", related_table="user_profile")
get_huddles_from_subscription(data, "zerver_subscription")
get_direct_message_groups_from_subscription(data, "zerver_subscription")
re_map_foreign_keys(data, "zerver_subscription", "recipient", related_table="recipient")
update_model_ids(Subscription, data, "subscription")
fix_subscriptions_is_user_active_column(data, user_profiles, crossrealm_user_ids)
@ -1307,14 +1312,14 @@ def do_import_realm(import_dir: Path, subdomain: str, processes: int = 1) -> Rea
)
if "zerver_huddle" in data:
process_huddle_hash(data, "zerver_huddle")
process_direct_message_group_hash(data, "zerver_huddle")
bulk_import_model(data, Huddle)
for huddle in Huddle.objects.filter(recipient=None):
for direct_message_group in Huddle.objects.filter(recipient=None):
recipient = Recipient.objects.get(
type=Recipient.DIRECT_MESSAGE_GROUP, type_id=huddle.id
type=Recipient.DIRECT_MESSAGE_GROUP, type_id=direct_message_group.id
)
huddle.recipient = recipient
huddle.save(update_fields=["recipient"])
direct_message_group.recipient = recipient
direct_message_group.save(update_fields=["recipient"])
if "zerver_alertword" in data:
re_map_foreign_keys(data, "zerver_alertword", "user_profile", related_table="user_profile")

View File

@ -81,14 +81,14 @@ class RawUnreadDirectMessageDict(TypedDict):
other_user_id: int
class RawUnreadHuddleDict(TypedDict):
class RawUnreadDirectMessageGroupDict(TypedDict):
user_ids_string: str
class RawUnreadMessagesResult(TypedDict):
pm_dict: Dict[int, RawUnreadDirectMessageDict]
stream_dict: Dict[int, RawUnreadStreamDict]
huddle_dict: Dict[int, RawUnreadHuddleDict]
huddle_dict: Dict[int, RawUnreadDirectMessageGroupDict]
mentions: Set[int]
muted_stream_ids: Set[int]
unmuted_stream_msgs: Set[int]
@ -108,7 +108,7 @@ class UnreadDirectMessageInfo(TypedDict):
unread_message_ids: List[int]
class UnreadHuddleInfo(TypedDict):
class UnreadDirectMessageGroupInfo(TypedDict):
user_ids_string: str
unread_message_ids: List[int]
@ -116,7 +116,7 @@ class UnreadHuddleInfo(TypedDict):
class UnreadMessagesResult(TypedDict):
pms: List[UnreadDirectMessageInfo]
streams: List[UnreadStreamInfo]
huddles: List[UnreadHuddleInfo]
huddles: List[UnreadDirectMessageGroupInfo]
mentions: List[int]
count: int
old_unreads_missing: bool
@ -519,7 +519,7 @@ def get_messages_with_usermessage_rows_for_user(
).values_list("message_id", flat=True)
def huddle_users(recipient_id: int) -> str:
def direct_message_group_users(recipient_id: int) -> str:
display_recipient: List[UserDisplayRecipient] = get_display_recipient_by_id(
recipient_id,
Recipient.DIRECT_MESSAGE_GROUP,
@ -624,7 +624,7 @@ def extract_unread_data_from_um_rows(
stream_dict: Dict[int, RawUnreadStreamDict] = {}
muted_stream_ids: Set[int] = set()
unmuted_stream_msgs: Set[int] = set()
huddle_dict: Dict[int, RawUnreadHuddleDict] = {}
direct_message_group_dict: Dict[int, RawUnreadDirectMessageGroupDict] = {}
mentions: Set[int] = set()
total_unreads = 0
@ -633,7 +633,7 @@ def extract_unread_data_from_um_rows(
stream_dict=stream_dict,
muted_stream_ids=muted_stream_ids,
unmuted_stream_msgs=unmuted_stream_msgs,
huddle_dict=huddle_dict,
huddle_dict=direct_message_group_dict,
mentions=mentions,
old_unreads_missing=False,
)
@ -668,14 +668,14 @@ def extract_unread_data_from_um_rows(
return False
huddle_cache: Dict[int, str] = {}
direct_message_group_cache: Dict[int, str] = {}
def get_huddle_users(recipient_id: int) -> str:
if recipient_id in huddle_cache:
return huddle_cache[recipient_id]
def get_direct_message_group_users(recipient_id: int) -> str:
if recipient_id in direct_message_group_cache:
return direct_message_group_cache[recipient_id]
user_ids_string = huddle_users(recipient_id)
huddle_cache[recipient_id] = user_ids_string
user_ids_string = direct_message_group_users(recipient_id)
direct_message_group_cache[recipient_id] = user_ids_string
return user_ids_string
for row in rows:
@ -706,8 +706,8 @@ def extract_unread_data_from_um_rows(
)
elif msg_type == Recipient.DIRECT_MESSAGE_GROUP:
user_ids_string = get_huddle_users(recipient_id)
huddle_dict[message_id] = dict(
user_ids_string = get_direct_message_group_users(recipient_id)
direct_message_group_dict[message_id] = dict(
user_ids_string=user_ids_string,
)
@ -791,12 +791,14 @@ def aggregate_pms(
return [lookup_dict[k] for k in sorted_keys]
def aggregate_huddles(*, input_dict: Dict[int, RawUnreadHuddleDict]) -> List[UnreadHuddleInfo]:
lookup_dict: Dict[str, UnreadHuddleInfo] = {}
def aggregate_direct_message_groups(
*, input_dict: Dict[int, RawUnreadDirectMessageGroupDict]
) -> List[UnreadDirectMessageGroupInfo]:
lookup_dict: Dict[str, UnreadDirectMessageGroupInfo] = {}
for message_id, attribute_dict in input_dict.items():
user_ids_string = attribute_dict["user_ids_string"]
if user_ids_string not in lookup_dict:
obj = UnreadHuddleInfo(
obj = UnreadDirectMessageGroupInfo(
user_ids_string=user_ids_string,
unread_message_ids=[],
)
@ -817,19 +819,19 @@ def aggregate_unread_data(raw_data: RawUnreadMessagesResult) -> UnreadMessagesRe
pm_dict = raw_data["pm_dict"]
stream_dict = raw_data["stream_dict"]
unmuted_stream_msgs = raw_data["unmuted_stream_msgs"]
huddle_dict = raw_data["huddle_dict"]
direct_message_group_dict = raw_data["huddle_dict"]
mentions = list(raw_data["mentions"])
count = len(pm_dict) + len(unmuted_stream_msgs) + len(huddle_dict)
count = len(pm_dict) + len(unmuted_stream_msgs) + len(direct_message_group_dict)
pm_objects = aggregate_pms(input_dict=pm_dict)
stream_objects = aggregate_streams(input_dict=stream_dict)
huddle_objects = aggregate_huddles(input_dict=huddle_dict)
direct_message_groups = aggregate_direct_message_groups(input_dict=direct_message_group_dict)
result: UnreadMessagesResult = dict(
pms=pm_objects,
streams=stream_objects,
huddles=huddle_objects,
huddles=direct_message_groups,
mentions=mentions,
count=count,
old_unreads_missing=raw_data["old_unreads_missing"],
@ -892,7 +894,7 @@ def apply_unread_message_event(
user_ids = sorted(user_ids)
user_ids_string = ",".join(str(uid) for uid in user_ids)
state["huddle_dict"][message_id] = RawUnreadHuddleDict(
state["huddle_dict"][message_id] = RawUnreadDirectMessageGroupDict(
user_ids_string=user_ids_string,
)
@ -993,7 +995,7 @@ def add_message_to_unread_msgs(
else:
user_ids.append(my_user_id)
user_ids_string = ",".join(str(user_id) for user_id in sorted(user_ids))
state["huddle_dict"][message_id] = RawUnreadHuddleDict(
state["huddle_dict"][message_id] = RawUnreadDirectMessageGroupDict(
user_ids_string=user_ids_string,
)
elif message_details["type"] == "stream":

View File

@ -648,7 +648,7 @@ class NarrowBuilder:
)
return query.where(maybe_negate(cond))
def _get_huddle_recipients(self, other_user: UserProfile) -> Set[int]:
def _get_direct_message_group_recipients(self, other_user: UserProfile) -> Set[int]:
self_recipient_ids = [
recipient_tuple["recipient_id"]
for recipient_tuple in Subscription.objects.filter(
@ -693,7 +693,9 @@ class NarrowBuilder:
return query.where(maybe_negate(cond))
# all direct messages including another person (group and 1:1)
huddle_recipient_ids = self._get_huddle_recipients(narrow_user_profile)
direct_message_group_recipient_ids = self._get_direct_message_group_recipients(
narrow_user_profile
)
self_recipient_id = self.user_profile.recipient_id
# See note above in `by_dm` about needing bidirectional messages
@ -711,7 +713,7 @@ class NarrowBuilder:
column("recipient_id", Integer) == narrow_user_profile.recipient_id,
),
and_(
column("recipient_id", Integer).in_(huddle_recipient_ids),
column("recipient_id", Integer).in_(direct_message_group_recipient_ids),
),
),
)
@ -734,7 +736,7 @@ class NarrowBuilder:
except UserProfile.DoesNotExist:
raise BadNarrowOperatorError("unknown user " + str(operand))
recipient_ids = self._get_huddle_recipients(narrow_profile)
recipient_ids = self._get_direct_message_group_recipients(narrow_profile)
cond = and_(
column("flags", Integer).op("&")(UserMessage.flags.is_private.mask) != 0,
column("realm_id", Integer) == self.realm.id,

View File

@ -47,7 +47,7 @@ from zerver.lib.avatar import absolute_avatar_url, get_avatar_for_inaccessible_u
from zerver.lib.display_recipient import get_display_recipient
from zerver.lib.emoji_utils import hex_codepoint_to_emoji
from zerver.lib.exceptions import ErrorCode, JsonableError
from zerver.lib.message import access_message_and_usermessage, huddle_users
from zerver.lib.message import access_message_and_usermessage, direct_message_group_users
from zerver.lib.notification_data import get_mentioned_user_group
from zerver.lib.remote_server import (
record_push_notifications_recently_working,
@ -1006,7 +1006,7 @@ def get_message_payload(
data["topic"] = message.topic_name()
elif message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
data["recipient_type"] = "private"
data["pm_users"] = huddle_users(message.recipient.id)
data["pm_users"] = direct_message_group_users(message.recipient.id)
else: # Recipient.PERSONAL
data["recipient_type"] = "private"

View File

@ -4,7 +4,10 @@ from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
from zerver.models import Huddle, Recipient, UserProfile
from zerver.models.recipients import get_huddle_hash, get_or_create_huddle
from zerver.models.recipients import (
get_direct_message_group_hash,
get_or_create_direct_message_group,
)
from zerver.models.users import is_cross_realm_bot_email
@ -45,21 +48,24 @@ def get_recipient_from_user_profiles(
type_id=user_profile.id,
)
# Otherwise, we need a huddle. Make sure the sender is included in huddle messages
# Otherwise, we need a direct message group. Make sure the sender
# is included in the group direct messages
recipient_profiles_map[sender.id] = sender
user_ids = list(recipient_profiles_map)
if create:
huddle = get_or_create_huddle(user_ids)
direct_message_group = get_or_create_direct_message_group(user_ids)
else:
# We intentionally let the Huddle.DoesNotExist escape, in the
# case that there is no such huddle, and the user passed
# create=False
huddle = Huddle.objects.get(huddle_hash=get_huddle_hash(user_ids))
# case that there is no such direct message group, and the user
# passed create=False
direct_message_group = Huddle.objects.get(
huddle_hash=get_direct_message_group_hash(user_ids)
)
return Recipient(
id=huddle.recipient_id,
id=direct_message_group.recipient_id,
type=Recipient.DIRECT_MESSAGE_GROUP,
type_id=huddle.id,
type_id=direct_message_group.id,
)

View File

@ -216,7 +216,7 @@ def move_expired_messages_to_archive_by_recipient(
)
def move_expired_personal_and_huddle_messages_to_archive(
def move_expired_direct_messages_to_archive(
realm: Realm,
chunk_size: int = MESSAGE_BATCH_SIZE,
) -> int:
@ -226,7 +226,7 @@ def move_expired_personal_and_huddle_messages_to_archive(
recipient_types = (Recipient.PERSONAL, Recipient.DIRECT_MESSAGE_GROUP)
# Archive expired personal and huddle Messages in the realm, including cross-realm messages.
# Archive expired direct Messages in the realm, including cross-realm messages.
# Uses index: zerver_message_realm_recipient_date_sent
query = SQL(
"""
@ -356,11 +356,9 @@ def archive_messages_by_recipient(
)
def archive_personal_and_huddle_messages(
realm: Realm, chunk_size: int = MESSAGE_BATCH_SIZE
) -> None:
logger.info("Archiving personal and huddle messages for realm %s", realm.string_id)
message_count = move_expired_personal_and_huddle_messages_to_archive(realm, chunk_size)
def archive_direct_messages(realm: Realm, chunk_size: int = MESSAGE_BATCH_SIZE) -> None:
logger.info("Archiving personal and group direct messages for realm %s", realm.string_id)
message_count = move_expired_direct_messages_to_archive(realm, chunk_size)
logger.info("Done. Archived %s messages", message_count)
@ -400,7 +398,7 @@ def archive_messages(chunk_size: int = MESSAGE_BATCH_SIZE) -> None:
for realm, streams in get_realms_and_streams_for_archiving():
archive_stream_messages(realm, streams, chunk_size=STREAM_MESSAGE_BATCH_SIZE)
if realm.message_retention_days != -1:
archive_personal_and_huddle_messages(realm, chunk_size)
archive_direct_messages(realm, chunk_size)
# Messages have been archived for the realm, now we can clean up attachments:
delete_expired_attachments(realm)

View File

@ -1095,7 +1095,7 @@ Output:
)
return sent_message_result.message_id
def send_huddle_message(
def send_group_direct_message(
self,
from_user: UserProfile,
to_users: List[UserProfile],
@ -1980,7 +1980,7 @@ Output:
self.send_personal_message(polonius, prospero)
self.send_personal_message(shiva, polonius)
self.send_huddle_message(aaron, [polonius, zoe])
self.send_group_direct_message(aaron, [polonius, zoe])
members_group = NamedUserGroup.objects.get(name="role:members", realm=realm)
do_change_realm_permission_group_setting(
@ -2069,7 +2069,7 @@ class ZulipTestCase(ZulipTestCaseMixin, TestCase):
return message_id
@override
def send_huddle_message(
def send_group_direct_message(
self,
from_user: UserProfile,
to_users: List[UserProfile],
@ -2078,7 +2078,7 @@ class ZulipTestCase(ZulipTestCaseMixin, TestCase):
read_by_sender: bool = True,
skip_capture_on_commit_callbacks: bool = False,
) -> int:
"""This function is a wrapper on 'send_huddle_message',
"""This function is a wrapper on 'send_group_direct_message',
defined in 'ZulipTestCaseMixin' with an extra parameter
'skip_capture_on_commit_callbacks'.
@ -2087,12 +2087,12 @@ class ZulipTestCase(ZulipTestCaseMixin, TestCase):
because they already have 'self.captureOnCommitCallbacks'
(See the comment in 'capture_send_event_calls').
For all other cases, we should call 'send_huddle_message' with
For all other cases, we should call 'send_group_direct_message' with
'self.captureOnCommitCallbacks' for 'send_event_on_commit' or/and
'queue_event_on_commit' to work.
"""
if skip_capture_on_commit_callbacks:
message_id = super().send_huddle_message(
message_id = super().send_group_direct_message(
from_user,
to_users,
content,
@ -2100,7 +2100,7 @@ class ZulipTestCase(ZulipTestCaseMixin, TestCase):
)
else:
with self.captureOnCommitCallbacks(execute=True):
message_id = super().send_huddle_message(
message_id = super().send_group_direct_message(
from_user,
to_users,
content,

View File

@ -28,7 +28,9 @@ def personal_narrow_url(*, realm: Realm, sender: UserProfile) -> str:
return base_url + pm_slug
def huddle_narrow_url(*, user: UserProfile, display_recipient: List[UserDisplayRecipient]) -> str:
def direct_message_group_narrow_url(
*, user: UserProfile, display_recipient: List[UserDisplayRecipient]
) -> str:
realm = user.realm
other_user_ids = [r["id"] for r in display_recipient if r["id"] != user.id]
pm_slug = ",".join(str(user_id) for user_id in sorted(other_user_ids)) + "-group"

View File

@ -706,15 +706,13 @@ def get_user_ids_who_can_access_user(target_user: UserProfile) -> List[int]:
active_non_guest_user_ids_in_realm = active_non_guest_user_ids(realm.id)
users_in_subscribed_streams_or_huddles_dict = get_subscribers_of_target_user_subscriptions(
[target_user]
)
users_sharing_any_subscription = get_subscribers_of_target_user_subscriptions([target_user])
users_involved_in_dms_dict = get_users_involved_in_dms_with_target_users([target_user], realm)
user_ids_who_can_access_target_user = (
{target_user.id}
| set(active_non_guest_user_ids_in_realm)
| users_in_subscribed_streams_or_huddles_dict[target_user.id]
| users_sharing_any_subscription[target_user.id]
| users_involved_in_dms_dict[target_user.id]
)
return list(user_ids_who_can_access_target_user)

View File

@ -11,7 +11,7 @@ from django.utils.translation import override as override_language
from zerver.actions.message_send import (
do_send_messages,
internal_prep_huddle_message,
internal_prep_group_direct_message,
internal_prep_stream_message,
)
from zerver.lib.message import SendMessageRequest, remove_single_newlines
@ -174,7 +174,7 @@ configuration change), or [turn this feature off]({organization_settings_url}) a
organization_settings_url="/#organization/organization-settings",
move_content_another_stream_help_url="/help/move-content-to-another-channel",
)
return internal_prep_huddle_message(
return internal_prep_group_direct_message(
realm, sender, remove_single_newlines(content), recipient_users=administrators
)

View File

@ -17,7 +17,7 @@ from zerver.lib.management import ZulipBaseCommand
from zerver.lib.soft_deactivation import reactivate_user_if_soft_deactivated
from zerver.lib.upload import save_attachment_contents
from zerver.models import AbstractUserMessage, Attachment, Message, Recipient, Stream, UserProfile
from zerver.models.recipients import get_or_create_huddle
from zerver.models.recipients import get_or_create_direct_message_group
from zerver.models.users import get_user_by_delivery_email
@ -176,8 +176,10 @@ This is most often used for legal compliance.
recipient=user_b.recipient, sender=user_a
)
else:
huddle = get_or_create_huddle([user.id for user in user_profiles])
limits &= Q(recipient=huddle.recipient)
direct_message_group = get_or_create_direct_message_group(
[user.id for user in user_profiles]
)
limits &= Q(recipient=direct_message_group.recipient)
attachments_written: Set[str] = set()
messages_query = Message.objects.filter(limits, realm=realm).order_by("date_sent")

View File

@ -73,7 +73,7 @@ class Recipient(models.Model):
return self._type_names[self.type]
def get_huddle_user_ids(recipient: Recipient) -> ValuesQuerySet["Subscription", int]:
def get_direct_message_group_user_ids(recipient: Recipient) -> ValuesQuerySet["Subscription", int]:
from zerver.models import Subscription
assert recipient.type == Recipient.DIRECT_MESSAGE_GROUP
@ -87,7 +87,7 @@ def get_huddle_user_ids(recipient: Recipient) -> ValuesQuerySet["Subscription",
)
def bulk_get_huddle_user_ids(recipient_ids: List[int]) -> Dict[int, Set[int]]:
def bulk_get_direct_message_group_user_ids(recipient_ids: List[int]) -> Dict[int, Set[int]]:
"""
Takes a list of huddle-type recipient_ids, returns a dict
mapping recipient id to list of user ids in the huddle.
@ -133,13 +133,13 @@ class Huddle(models.Model):
recipient = models.ForeignKey(Recipient, null=True, on_delete=models.SET_NULL)
def get_huddle_hash(id_list: List[int]) -> str:
def get_direct_message_group_hash(id_list: List[int]) -> str:
id_list = sorted(set(id_list))
hash_key = ",".join(str(x) for x in id_list)
return hashlib.sha1(hash_key.encode()).hexdigest()
def get_or_create_huddle(id_list: List[int]) -> Huddle:
def get_or_create_direct_message_group(id_list: List[int]) -> Huddle:
"""
Takes a list of user IDs and returns the Huddle object for the
group consisting of these users. If the Huddle object does not
@ -147,15 +147,17 @@ def get_or_create_huddle(id_list: List[int]) -> Huddle:
"""
from zerver.models import Subscription, UserProfile
huddle_hash = get_huddle_hash(id_list)
direct_message_group_hash = get_direct_message_group_hash(id_list)
with transaction.atomic():
(huddle, created) = Huddle.objects.get_or_create(huddle_hash=huddle_hash)
(direct_message_group, created) = Huddle.objects.get_or_create(
huddle_hash=direct_message_group_hash
)
if created:
recipient = Recipient.objects.create(
type_id=huddle.id, type=Recipient.DIRECT_MESSAGE_GROUP
type_id=direct_message_group.id, type=Recipient.DIRECT_MESSAGE_GROUP
)
huddle.recipient = recipient
huddle.save(update_fields=["recipient"])
direct_message_group.recipient = recipient
direct_message_group.save(update_fields=["recipient"])
subs_to_create = [
Subscription(
recipient=recipient,
@ -167,4 +169,4 @@ def get_or_create_huddle(id_list: List[int]) -> Huddle:
.values_list("id", "is_active")
]
Subscription.objects.bulk_create(subs_to_create)
return huddle
return direct_message_group

View File

@ -1039,7 +1039,7 @@ class TestMissedMessageEmailMessages(ZulipTestCase):
self.assertEqual(message.recipient.type_id, user_profile.id)
self.assertEqual(message.recipient.type, Recipient.PERSONAL)
def test_receive_missed_huddle_message_email_messages(self) -> None:
def test_receive_missed_group_direct_message_email_messages(self) -> None:
# Build dummy messages for message notification email reply.
# Have Othello send Iago and Cordelia a group direct message.
# Cordelia will reply via email Iago and Othello will receive
@ -1065,9 +1065,9 @@ class TestMissedMessageEmailMessages(ZulipTestCase):
mm_address = create_missed_message_address(user_profile, usermessage.message)
incoming_valid_message = EmailMessage()
incoming_valid_message.set_content("TestMissedHuddleMessageEmailMessages body")
incoming_valid_message.set_content("TestMissedGroupDirectMessageEmailMessages body")
incoming_valid_message["Subject"] = "TestMissedHuddleMessageEmailMessages subject"
incoming_valid_message["Subject"] = "TestMissedGroupDirectMessageEmailMessages subject"
incoming_valid_message["From"] = self.example_email("cordelia")
incoming_valid_message["To"] = mm_address
incoming_valid_message["Reply-to"] = self.example_email("cordelia")
@ -1079,7 +1079,7 @@ class TestMissedMessageEmailMessages(ZulipTestCase):
user_profile = self.example_user("iago")
message = most_recent_message(user_profile)
self.assertEqual(message.content, "TestMissedHuddleMessageEmailMessages body")
self.assertEqual(message.content, "TestMissedGroupDirectMessageEmailMessages body")
self.assertEqual(message.sender, self.example_user("cordelia"))
self.assertEqual(message.recipient.type, Recipient.DIRECT_MESSAGE_GROUP)
@ -1087,7 +1087,7 @@ class TestMissedMessageEmailMessages(ZulipTestCase):
user_profile = self.example_user("othello")
message = most_recent_message(user_profile)
self.assertEqual(message.content, "TestMissedHuddleMessageEmailMessages body")
self.assertEqual(message.content, "TestMissedGroupDirectMessageEmailMessages body")
self.assertEqual(message.sender, self.example_user("cordelia"))
self.assertEqual(message.recipient.type, Recipient.DIRECT_MESSAGE_GROUP)

View File

@ -598,14 +598,17 @@ class NormalActionsTest(BaseAction):
is_embedded_update_only=False,
)
def test_huddle_send_message_events(self) -> None:
huddle = [
def test_direct_message_group_send_message_events(self) -> None:
direct_message_group = [
self.example_user("hamlet"),
self.example_user("othello"),
]
with self.verify_action():
self.send_huddle_message(
self.example_user("cordelia"), huddle, "hola", skip_capture_on_commit_callbacks=True
self.send_group_direct_message(
self.example_user("cordelia"),
direct_message_group,
"hola",
skip_capture_on_commit_callbacks=True,
)
def test_user_creation_events_on_sending_messages(self) -> None:
@ -634,7 +637,7 @@ class NormalActionsTest(BaseAction):
desdemona = self.example_user("desdemona")
with self.verify_action(num_events=3) as events:
self.send_huddle_message(
self.send_group_direct_message(
othello, [polonius, desdemona, bot], "hola", skip_capture_on_commit_callbacks=True
)
check_realm_user_add("events[0]", events[0])
@ -1068,17 +1071,17 @@ class NormalActionsTest(BaseAction):
do_update_message_flags(user_profile, "remove", "read", [personal_message])
check_update_message_flags_remove("events[0]", events[0])
huddle_message = self.send_huddle_message(
group_direct_message = self.send_group_direct_message(
from_user=self.example_user("cordelia"),
to_users=[user_profile, self.example_user("othello")],
content=content,
)
with self.verify_action(state_change_expected=True):
do_update_message_flags(user_profile, "add", "read", [huddle_message])
do_update_message_flags(user_profile, "add", "read", [group_direct_message])
with self.verify_action(state_change_expected=True) as events:
do_update_message_flags(user_profile, "remove", "read", [huddle_message])
do_update_message_flags(user_profile, "remove", "read", [group_direct_message])
check_update_message_flags_remove("events[0]", events[0])
def test_send_message_to_existing_recipient(self) -> None:

View File

@ -90,7 +90,7 @@ from zerver.models.clients import get_client
from zerver.models.groups import SystemGroups
from zerver.models.presence import PresenceSequence
from zerver.models.realms import get_realm
from zerver.models.recipients import get_huddle_hash
from zerver.models.recipients import get_direct_message_group_hash
from zerver.models.streams import get_active_streams, get_stream
from zerver.models.users import get_system_bot, get_user_by_delivery_email
@ -127,7 +127,7 @@ def get_user_id(r: Realm, full_name: str) -> int:
return UserProfile.objects.get(realm=r, full_name=full_name).id
def get_huddle_hashes(r: Realm) -> str:
def get_direct_message_group_hashes(r: Realm) -> str:
cordelia_full_name = "Cordelia, Lear's daughter"
hamlet_full_name = "King Hamlet"
othello_full_name = "Othello, the Moor of Venice"
@ -138,8 +138,8 @@ def get_huddle_hashes(r: Realm) -> str:
get_user_id(r, othello_full_name),
]
huddle_hash = get_huddle_hash(user_id_list)
return huddle_hash
direct_message_group_hash = get_direct_message_group_hash(user_id_list)
return direct_message_group_hash
class ExportFile(ZulipTestCase):
@ -584,18 +584,18 @@ class RealmImportExportTest(ExportFile):
self.subscribe(self.example_user("hamlet"), "Private D")
self.send_stream_message(self.example_user("prospero"), "Private D", "Hello again stream D")
# Create huddles
self.send_huddle_message(
# Create direct message groups
self.send_group_direct_message(
self.example_user("iago"), [self.example_user("cordelia"), self.example_user("AARON")]
)
huddle_a = Huddle.objects.last()
self.send_huddle_message(
direct_message_group_a = Huddle.objects.last()
self.send_group_direct_message(
self.example_user("ZOE"),
[self.example_user("hamlet"), self.example_user("AARON"), self.example_user("othello")],
)
huddle_b = Huddle.objects.last()
direct_message_group_b = Huddle.objects.last()
huddle_c_message_id = self.send_huddle_message(
direct_message_group_c_message_id = self.send_group_direct_message(
self.example_user("AARON"),
[self.example_user("cordelia"), self.example_user("ZOE"), self.example_user("othello")],
)
@ -720,13 +720,17 @@ class RealmImportExportTest(ExportFile):
.values_list("id", flat=True)
)
# Third huddle is not exported since none of the members gave consent
assert huddle_a is not None and huddle_b is not None
huddle_recipients = Recipient.objects.filter(
type_id__in=[huddle_a.id, huddle_b.id], type=Recipient.DIRECT_MESSAGE_GROUP
# Third direct message group is not exported since none of
# the members gave consent
assert direct_message_group_a is not None and direct_message_group_b is not None
direct_message_group_recipients = Recipient.objects.filter(
type_id__in=[direct_message_group_a.id, direct_message_group_b.id],
type=Recipient.DIRECT_MESSAGE_GROUP,
)
pm_query = Q(recipient__in=huddle_recipients) | Q(sender__in=consented_user_ids)
exported_huddle_ids = (
pm_query = Q(recipient__in=direct_message_group_recipients) | Q(
sender__in=consented_user_ids
)
exported_direct_message_group_ids = (
Message.objects.filter(pm_query, realm=realm.id)
.values_list("id", flat=True)
.values_list("id", flat=True)
@ -737,14 +741,14 @@ class RealmImportExportTest(ExportFile):
*private_stream_message_ids,
stream_b_second_message_id,
*exported_pm_ids,
*exported_huddle_ids,
*exported_direct_message_group_ids,
}
self.assertEqual(self.get_set(data["zerver_message"], "id"), exported_msg_ids)
self.assertNotIn(stream_b_first_message_id, exported_msg_ids)
self.assertNotIn(stream_c_message_id, exported_msg_ids)
self.assertNotIn(huddle_c_message_id, exported_msg_ids)
self.assertNotIn(direct_message_group_c_message_id, exported_msg_ids)
self.assertNotIn(pm_a_msg_id, exported_msg_ids)
self.assertIn(pm_b_msg_id, exported_msg_ids)
@ -801,15 +805,15 @@ class RealmImportExportTest(ExportFile):
modified_user=hamlet, event_type=RealmAuditLog.USER_CREATED
).update(acting_user_id=cross_realm_bot.id)
# data to test import of huddles
huddle = [
# data to test import of direct message groups
direct_message_group = [
self.example_user("hamlet"),
self.example_user("othello"),
]
self.send_huddle_message(
self.send_group_direct_message(
self.example_user("cordelia"),
huddle,
"test huddle message",
direct_message_group,
"test group direct message",
)
user_mention_message = "@**King Hamlet** Hello"
@ -991,8 +995,12 @@ class RealmImportExportTest(ExportFile):
self.verify_emoji_code_foreign_keys()
# Our huddle hashes change, because hashes use ids that change.
self.assertNotEqual(get_huddle_hashes(original_realm), get_huddle_hashes(imported_realm))
# Our direct message group hashes change, because hashes
# use ids that change.
self.assertNotEqual(
get_direct_message_group_hashes(original_realm),
get_direct_message_group_hashes(imported_realm),
)
# test to highlight that bs4 which we use to do data-**id
# replacements modifies the HTML sometimes. eg replacing <br>
@ -1039,13 +1047,11 @@ class RealmImportExportTest(ExportFile):
Recipient.objects.get(type=Recipient.STREAM, type_id=stream.id).id,
)
for huddle_object in Huddle.objects.all():
for dm_group in Huddle.objects.all():
# Huddles don't have a realm column, so we just test all Huddles for simplicity.
self.assertEqual(
huddle_object.recipient_id,
Recipient.objects.get(
type=Recipient.DIRECT_MESSAGE_GROUP, type_id=huddle_object.id
).id,
dm_group.recipient_id,
Recipient.objects.get(type=Recipient.DIRECT_MESSAGE_GROUP, type_id=dm_group.id).id,
)
self.assertEqual(ScheduledMessage.objects.filter(realm=imported_realm).count(), 1)
@ -1268,13 +1274,15 @@ class RealmImportExportTest(ExportFile):
return realmauditlog_event_type
@getter
def get_huddle_message(r: Realm) -> str:
huddle_hash = get_huddle_hashes(r)
huddle_id = Huddle.objects.get(huddle_hash=huddle_hash).id
huddle_recipient = Recipient.objects.get(type_id=huddle_id, type=3)
huddle_message = Message.objects.get(recipient=huddle_recipient)
self.assertEqual(huddle_message.content, "test huddle message")
return huddle_message.content
def get_group_direct_message(r: Realm) -> str:
direct_message_group_hash = get_direct_message_group_hashes(r)
direct_message_group_id = Huddle.objects.get(huddle_hash=direct_message_group_hash).id
direct_message_group_recipient = Recipient.objects.get(
type_id=direct_message_group_id, type=3
)
group_direct_message = Message.objects.get(recipient=direct_message_group_recipient)
self.assertEqual(group_direct_message.content, "test group direct message")
return group_direct_message.content
@getter
def get_alertwords(r: Realm) -> Set[str]:
@ -1883,12 +1891,16 @@ class SingleUserExportTest(ExportFile):
# Try to fool the export again
self.send_personal_message(othello, hamlet)
self.send_huddle_message(othello, [hamlet, polonius])
self.send_group_direct_message(othello, [hamlet, polonius])
hi_hamlet_message_id = self.send_personal_message(cordelia, hamlet, "hi hamlet")
hi_peeps_message_id = self.send_huddle_message(cordelia, [hamlet, othello], "hi peeps")
bye_peeps_message_id = self.send_huddle_message(othello, [cordelia, hamlet], "bye peeps")
hi_peeps_message_id = self.send_group_direct_message(
cordelia, [hamlet, othello], "hi peeps"
)
bye_peeps_message_id = self.send_group_direct_message(
othello, [cordelia, hamlet], "bye peeps"
)
bye_hamlet_message_id = self.send_personal_message(cordelia, hamlet, "bye hamlet")
@ -1903,7 +1915,9 @@ class SingleUserExportTest(ExportFile):
messages = read_json("messages-000001.json")
huddle_name = "Cordelia, Lear's daughter, King Hamlet, Othello, the Moor of Venice"
direct_message_group_name = (
"Cordelia, Lear's daughter, King Hamlet, Othello, the Moor of Venice"
)
excerpt = [
(rec["id"], rec["content"], rec["recipient_name"])
@ -1915,8 +1929,8 @@ class SingleUserExportTest(ExportFile):
(smile_message_id, "SMILE!", "Denmark"),
(hi_stream_message_id, "hi stream", "Denmark"),
(hi_hamlet_message_id, "hi hamlet", hamlet.full_name),
(hi_peeps_message_id, "hi peeps", huddle_name),
(bye_peeps_message_id, "bye peeps", huddle_name),
(hi_peeps_message_id, "hi peeps", direct_message_group_name),
(bye_peeps_message_id, "bye peeps", direct_message_group_name),
(bye_hamlet_message_id, "bye hamlet", hamlet.full_name),
(hi_myself_message_id, "hi myself", cordelia.full_name),
(bye_stream_message_id, "bye stream", "Denmark"),

View File

@ -10,11 +10,11 @@ from zerver.data_import.mattermost import (
build_reactions,
check_user_in_team,
convert_channel_data,
convert_huddle_data,
convert_direct_message_group_data,
convert_user_data,
create_username_to_user_mapping,
do_convert_data,
generate_huddle_name,
generate_direct_message_group_name,
get_mentioned_user_ids,
label_mirror_dummy_users,
mattermost_data_file_to_dict,
@ -336,7 +336,7 @@ class MatterMostImporter(ZulipTestCase):
{malfoy_id, pansy_id},
)
def test_convert_huddle_data(self) -> None:
def test_convert_direct_message_group_data(self) -> None:
fixture_file_name = self.fixture_file_name(
"export.json", "mattermost_fixtures/direct_channel"
)
@ -358,8 +358,8 @@ class MatterMostImporter(ZulipTestCase):
team_name=team_name,
)
zerver_huddle = convert_huddle_data(
huddle_data=mattermost_data["direct_channel"],
zerver_huddle = convert_direct_message_group_data(
direct_message_group_data=mattermost_data["direct_channel"],
user_data_map=username_to_user,
subscriber_handler=subscriber_handler,
huddle_id_mapper=huddle_id_mapper,
@ -369,12 +369,15 @@ class MatterMostImporter(ZulipTestCase):
)
self.assert_length(zerver_huddle, 1)
huddle_members = mattermost_data["direct_channel"][1]["members"]
huddle_name = generate_huddle_name(huddle_members)
direct_message_group_members = mattermost_data["direct_channel"][1]["members"]
direct_message_group_name = generate_direct_message_group_name(direct_message_group_members)
self.assertTrue(huddle_id_mapper.has(huddle_name))
self.assertTrue(huddle_id_mapper.has(direct_message_group_name))
self.assertEqual(
subscriber_handler.get_users(huddle_id=huddle_id_mapper.get(huddle_name)), {1, 2, 3}
subscriber_handler.get_users(
direct_message_group_id=huddle_id_mapper.get(direct_message_group_name)
),
{1, 2, 3},
)
def test_write_emoticon_data(self) -> None:
@ -669,8 +672,8 @@ class MatterMostImporter(ZulipTestCase):
self.assertEqual(
warn_log.output,
[
"WARNING:root:Skipping importing huddles and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing huddles and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing direct message groups and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing direct message groups and DMs since there are multiple teams in the export",
],
)
@ -871,14 +874,16 @@ class MatterMostImporter(ZulipTestCase):
self.assertFalse(stream_messages[3].has_image)
self.assertTrue(stream_messages[3].has_link)
huddle_messages = messages.filter(recipient__type=Recipient.DIRECT_MESSAGE_GROUP).order_by(
"date_sent"
group_direct_messages = messages.filter(
recipient__type=Recipient.DIRECT_MESSAGE_GROUP
).order_by("date_sent")
direct_message_group_recipients = group_direct_messages.values_list("recipient", flat=True)
self.assert_length(group_direct_messages, 3)
self.assert_length(set(direct_message_group_recipients), 1)
self.assertEqual(group_direct_messages[0].sender.email, "ginny@zulip.com")
self.assertEqual(
group_direct_messages[0].content, "Who is going to Hogsmeade this weekend?\n\n"
)
huddle_recipients = huddle_messages.values_list("recipient", flat=True)
self.assert_length(huddle_messages, 3)
self.assert_length(set(huddle_recipients), 1)
self.assertEqual(huddle_messages[0].sender.email, "ginny@zulip.com")
self.assertEqual(huddle_messages[0].content, "Who is going to Hogsmeade this weekend?\n\n")
personal_messages = messages.filter(recipient__type=Recipient.PERSONAL).order_by(
"date_sent"
@ -909,8 +914,8 @@ class MatterMostImporter(ZulipTestCase):
self.assertEqual(
warn_log.output,
[
"WARNING:root:Skipping importing huddles and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing huddles and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing direct message groups and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing direct message groups and DMs since there are multiple teams in the export",
],
)
@ -936,8 +941,8 @@ class MatterMostImporter(ZulipTestCase):
self.assertEqual(
warn_log.output,
[
"WARNING:root:Skipping importing huddles and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing huddles and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing direct message groups and DMs since there are multiple teams in the export",
"WARNING:root:Skipping importing direct message groups and DMs since there are multiple teams in the export",
],
)

View File

@ -581,14 +581,14 @@ class TestMessageForIdsDisplayRecipientFetching(ZulipTestCase):
self.assertEqual(messages[0]["display_recipient"], "Verona")
self.assertEqual(messages[1]["display_recipient"], "Denmark")
def test_display_recipient_huddle(self) -> None:
def test_display_recipient_direct_message_group(self) -> None:
hamlet = self.example_user("hamlet")
cordelia = self.example_user("cordelia")
othello = self.example_user("othello")
iago = self.example_user("iago")
message_ids = [
self.send_huddle_message(hamlet, [cordelia, othello], "test"),
self.send_huddle_message(cordelia, [hamlet, othello, iago], "test"),
self.send_group_direct_message(hamlet, [cordelia, othello], "test"),
self.send_group_direct_message(cordelia, [hamlet, othello, iago], "test"),
]
messages = messages_for_ids(
@ -619,11 +619,11 @@ class TestMessageForIdsDisplayRecipientFetching(ZulipTestCase):
self.subscribe(hamlet, "Scotland")
message_ids = [
self.send_huddle_message(hamlet, [cordelia, othello], "test"),
self.send_group_direct_message(hamlet, [cordelia, othello], "test"),
self.send_stream_message(cordelia, "Verona", content="test"),
self.send_personal_message(hamlet, cordelia, "test"),
self.send_stream_message(cordelia, "Denmark", content="test"),
self.send_huddle_message(cordelia, [hamlet, othello, iago], "test"),
self.send_group_direct_message(cordelia, [hamlet, othello, iago], "test"),
self.send_personal_message(cordelia, othello, "test"),
]

View File

@ -63,7 +63,7 @@ from zerver.models import (
UserTopic,
)
from zerver.models.realms import get_realm
from zerver.models.recipients import get_or_create_huddle
from zerver.models.recipients import get_or_create_direct_message_group
from zerver.models.streams import get_stream
from zerver.views.message_fetch import get_messages_backend
@ -385,15 +385,17 @@ class NarrowBuilderTest(ZulipTestCase):
"WHERE (flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s OR sender_id = %(sender_id_2)s AND recipient_id = %(recipient_id_2)s)",
)
def test_add_term_using_dm_operator_more_than_one_user_as_operand_no_huddle(self) -> None:
def test_add_term_using_dm_operator_more_than_one_user_as_operand_no_direct_message_group(
self,
) -> None:
# If the group doesn't exist, it's a flat false
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
term = NarrowParameter(operator="dm", operand=two_others)
self._do_add_term_test(term, "WHERE false")
def test_add_term_using_dm_operator_more_than_one_user_as_operand(self) -> None:
# Make the huddle first
get_or_create_huddle(
# Make the direct message group first
get_or_create_direct_message_group(
[
self.example_user("hamlet").id,
self.example_user("cordelia").id,
@ -416,7 +418,7 @@ class NarrowBuilderTest(ZulipTestCase):
"WHERE NOT ((flags & %(flags_1)s) != %(param_1)s AND realm_id = %(realm_id_1)s AND (sender_id = %(sender_id_1)s AND recipient_id = %(recipient_id_1)s OR sender_id = %(sender_id_2)s AND recipient_id = %(recipient_id_2)s))",
)
def test_add_term_using_dm_operator_more_than_one_user_as_operand_no_huddle_and_negated(
def test_add_term_using_dm_operator_more_than_one_user_as_operand_no_direct_message_group_and_negated(
self,
) -> None: # NEGATED
# If the group doesn't exist, it's a flat true
@ -427,8 +429,8 @@ class NarrowBuilderTest(ZulipTestCase):
def test_add_term_using_dm_operator_more_than_one_user_as_operand_and_negated(
self,
) -> None: # NEGATED
# Make the huddle first
get_or_create_huddle(
# Make the direct message group first
get_or_create_direct_message_group(
[
self.example_user("hamlet").id,
self.example_user("cordelia").id,
@ -464,7 +466,7 @@ class NarrowBuilderTest(ZulipTestCase):
)
# Test with at least one such group direct messages existing
self.send_huddle_message(
self.send_group_direct_message(
self.user_profile, [self.example_user("othello"), self.example_user("cordelia")]
)
@ -2218,7 +2220,7 @@ class GetOldMessagesTest(ZulipTestCase):
self.send_personal_message(me, self.example_user("iago"))
self.send_huddle_message(
self.send_group_direct_message(
me,
[self.example_user("iago"), self.example_user("cordelia")],
)
@ -2227,7 +2229,7 @@ class GetOldMessagesTest(ZulipTestCase):
# Then deactivate Aaron to test "dm" narrow includes messages
# from deactivated users also.
self.send_personal_message(me, self.example_user("aaron"))
self.send_huddle_message(
self.send_group_direct_message(
me,
[self.example_user("iago"), self.example_user("aaron")],
)
@ -2257,18 +2259,20 @@ class GetOldMessagesTest(ZulipTestCase):
def test_get_messages_with_nonexistent_group_dm(self) -> None:
me = self.example_user("hamlet")
# Huddle which doesn't match anything gets no results
non_existent_huddle = [
# Direct message group which doesn't match anything gets no results
non_existent_direct_message_group = [
me.id,
self.example_user("iago").id,
self.example_user("othello").id,
]
self.login_user(me)
narrow: List[Dict[str, Any]] = [dict(operator="dm", operand=non_existent_huddle)]
narrow: List[Dict[str, Any]] = [
dict(operator="dm", operand=non_existent_direct_message_group)
]
result = self.get_and_check_messages(dict(narrow=orjson.dumps(narrow).decode()))
self.assertEqual(result["messages"], [])
narrow = [dict(operator="dm", operand=non_existent_huddle, negated=True)]
narrow = [dict(operator="dm", operand=non_existent_direct_message_group, negated=True)]
result = self.get_and_check_messages(dict(narrow=orjson.dumps(narrow).decode()))
self.assertEqual([m["id"] for m in result["messages"]], [1, 3])
@ -2295,17 +2299,17 @@ class GetOldMessagesTest(ZulipTestCase):
matching_message_ids = [
# group direct message, sent by current user
self.send_huddle_message(
self.send_group_direct_message(
me,
[iago, cordelia, othello],
),
# group direct message, sent by searched user
self.send_huddle_message(
self.send_group_direct_message(
cordelia,
[me, othello],
),
# group direct message, sent by another user
self.send_huddle_message(
self.send_group_direct_message(
othello,
[me, cordelia],
),
@ -2323,12 +2327,12 @@ class GetOldMessagesTest(ZulipTestCase):
# direct 1:1 message, current user to self
self.send_personal_message(me, me),
# group direct message, sent by current user
self.send_huddle_message(
self.send_group_direct_message(
me,
[iago, othello],
),
# group direct message, sent by searched user
self.send_huddle_message(
self.send_group_direct_message(
cordelia,
[iago, othello],
),
@ -2352,17 +2356,17 @@ class GetOldMessagesTest(ZulipTestCase):
othello = self.example_user("othello")
message_ids = [
self.send_huddle_message(
self.send_group_direct_message(
me,
[iago, cordelia, othello],
),
self.send_personal_message(me, cordelia),
self.send_huddle_message(
self.send_group_direct_message(
cordelia,
[me, othello],
),
self.send_personal_message(cordelia, me),
self.send_huddle_message(
self.send_group_direct_message(
iago,
[cordelia, me],
),
@ -2383,11 +2387,11 @@ class GetOldMessagesTest(ZulipTestCase):
othello = self.example_user("othello")
matching_message_ids = [
self.send_huddle_message(
self.send_group_direct_message(
me,
[iago, cordelia, othello],
),
self.send_huddle_message(
self.send_group_direct_message(
me,
[cordelia, othello],
),
@ -2395,11 +2399,11 @@ class GetOldMessagesTest(ZulipTestCase):
non_matching_message_ids = [
self.send_personal_message(me, cordelia),
self.send_huddle_message(
self.send_group_direct_message(
me,
[iago, othello],
),
self.send_huddle_message(
self.send_group_direct_message(
self.example_user("cordelia"),
[iago, othello],
),
@ -2423,15 +2427,15 @@ class GetOldMessagesTest(ZulipTestCase):
othello = self.example_user("othello")
message_ids = [
self.send_huddle_message(
self.send_group_direct_message(
me,
[iago, cordelia, othello],
),
self.send_huddle_message(
self.send_group_direct_message(
me,
[cordelia, othello],
),
self.send_huddle_message(
self.send_group_direct_message(
me,
[cordelia, iago],
),

View File

@ -1010,22 +1010,22 @@ class GetUnreadMsgsTest(ZulipTestCase):
),
)
def test_raw_unread_huddle(self) -> None:
def test_raw_unread_direct_message_group(self) -> None:
cordelia = self.example_user("cordelia")
othello = self.example_user("othello")
hamlet = self.example_user("hamlet")
prospero = self.example_user("prospero")
huddle1_message_ids = [
self.send_huddle_message(
direct_message_group1_message_ids = [
self.send_group_direct_message(
cordelia,
[hamlet, othello],
)
for i in range(3)
]
huddle2_message_ids = [
self.send_huddle_message(
direct_message_group2_message_ids = [
self.send_group_direct_message(
cordelia,
[hamlet, prospero],
)
@ -1036,18 +1036,20 @@ class GetUnreadMsgsTest(ZulipTestCase):
user_profile=hamlet,
)
huddle_dict = raw_unread_data["huddle_dict"]
direct_message_group_dict = raw_unread_data["huddle_dict"]
self.assertEqual(
set(huddle_dict.keys()),
set(huddle1_message_ids) | set(huddle2_message_ids),
set(direct_message_group_dict.keys()),
set(direct_message_group1_message_ids) | set(direct_message_group2_message_ids),
)
huddle_string = ",".join(str(uid) for uid in sorted([cordelia.id, hamlet.id, othello.id]))
direct_message_group_string = ",".join(
str(uid) for uid in sorted([cordelia.id, hamlet.id, othello.id])
)
self.assertEqual(
huddle_dict[huddle1_message_ids[0]],
dict(user_ids_string=huddle_string),
direct_message_group_dict[direct_message_group1_message_ids[0]],
dict(user_ids_string=direct_message_group_string),
)
def test_raw_unread_personal(self) -> None:
@ -1205,7 +1207,7 @@ class GetUnreadMsgsTest(ZulipTestCase):
content="hello",
)
huddle_message_id = self.send_huddle_message(
group_direct_message_id = self.send_group_direct_message(
sender,
[user_profile, othello],
"hello3",
@ -1260,13 +1262,17 @@ class GetUnreadMsgsTest(ZulipTestCase):
unread_stream["unread_message_ids"], [unmuted_topic_muted_stream_message_id]
)
huddle_string = ",".join(
direct_message_group_string = ",".join(
str(uid) for uid in sorted([sender_id, user_profile.id, othello.id])
)
unread_huddle = result["huddles"][0]
self.assertEqual(unread_huddle["user_ids_string"], huddle_string)
self.assertEqual(unread_huddle["unread_message_ids"], [huddle_message_id])
unread_direct_message_group = result["huddles"][0]
self.assertEqual(
unread_direct_message_group["user_ids_string"], direct_message_group_string
)
self.assertEqual(
unread_direct_message_group["unread_message_ids"], [group_direct_message_id]
)
self.assertEqual(result["mentions"], [])
@ -2497,13 +2503,13 @@ class MarkUnreadTest(ZulipTestCase):
)
self.assertTrue(um.flags.read)
def test_huddle_messages_unread(self) -> None:
def test_group_direct_messages_unread(self) -> None:
sender = self.example_user("cordelia")
receiver = self.example_user("hamlet")
user1 = self.example_user("othello")
message_ids = [
# self.send_huddle_message(sender, receiver, content="Hello") for i in range(4)
self.send_huddle_message(sender, [receiver, user1])
# self.send_group_direct_message(sender, receiver, content="Hello") for i in range(4)
self.send_group_direct_message(sender, [receiver, user1])
for i in range(4)
]
self.login("hamlet")
@ -2558,13 +2564,13 @@ class MarkUnreadTest(ZulipTestCase):
)
self.assertTrue(um.flags.read)
def test_huddle_messages_unread_mention(self) -> None:
def test_group_direct_messages_unread_mention(self) -> None:
sender = self.example_user("cordelia")
receiver = self.example_user("hamlet")
user1 = self.example_user("othello")
message_ids = [
# self.send_huddle_message(sender, receiver, content="Hello") for i in range(4)
self.send_huddle_message(
# self.send_group_direct_message(sender, receiver, content="Hello") for i in range(4)
self.send_group_direct_message(
from_user=sender, to_users=[receiver, user1], content="@**King Hamlet**"
)
for i in range(4)

View File

@ -544,10 +544,10 @@ class TestMessageNotificationEmails(ZulipTestCase):
email_subject = "DMs with Othello, the Moor of Venice"
self._test_cases(msg_id, verify_body_include, email_subject)
def _extra_context_in_missed_huddle_messages_two_others(
def _extra_context_in_missed_group_direct_messages_two_others(
self, show_message_content: bool = True
) -> None:
msg_id = self.send_huddle_message(
msg_id = self.send_group_direct_message(
self.example_user("othello"),
[
self.example_user("hamlet"),
@ -585,8 +585,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
verify_body_does_not_include=verify_body_does_not_include,
)
def _extra_context_in_missed_huddle_messages_three_others(self) -> None:
msg_id = self.send_huddle_message(
def _extra_context_in_missed_group_direct_messages_three_others(self) -> None:
msg_id = self.send_group_direct_message(
self.example_user("othello"),
[
self.example_user("hamlet"),
@ -602,8 +602,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
)
self._test_cases(msg_id, verify_body_include, email_subject)
def _extra_context_in_missed_huddle_messages_many_others(self) -> None:
msg_id = self.send_huddle_message(
def _extra_context_in_missed_group_direct_messages_many_others(self) -> None:
msg_id = self.send_group_direct_message(
self.example_user("othello"),
[
self.example_user("hamlet"),
@ -648,8 +648,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
)
self.assert_length(mail.outbox, 0)
def _deleted_message_in_missed_huddle_messages(self) -> None:
msg_id = self.send_huddle_message(
def _deleted_message_in_missed_group_direct_messages(self) -> None:
msg_id = self.send_group_direct_message(
self.example_user("othello"),
[
self.example_user("hamlet"),
@ -1042,7 +1042,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
show_message_content=False, message_content_disabled_by_user=True
)
mail.outbox = []
self._extra_context_in_missed_huddle_messages_two_others(show_message_content=False)
self._extra_context_in_missed_group_direct_messages_two_others(show_message_content=False)
def test_extra_context_in_missed_stream_messages(self) -> None:
self._extra_context_in_missed_stream_messages_mention()
@ -1100,14 +1100,14 @@ class TestMessageNotificationEmails(ZulipTestCase):
def test_extra_context_in_missed_personal_messages(self) -> None:
self._extra_context_in_missed_personal_messages()
def test_extra_context_in_missed_huddle_messages_two_others(self) -> None:
self._extra_context_in_missed_huddle_messages_two_others()
def test_extra_context_in_missed_group_direct_messages_two_others(self) -> None:
self._extra_context_in_missed_group_direct_messages_two_others()
def test_extra_context_in_missed_huddle_messages_three_others(self) -> None:
self._extra_context_in_missed_huddle_messages_three_others()
def test_extra_context_in_missed_group_direct_messages_three_others(self) -> None:
self._extra_context_in_missed_group_direct_messages_three_others()
def test_extra_context_in_missed_huddle_messages_many_others(self) -> None:
self._extra_context_in_missed_huddle_messages_many_others()
def test_extra_context_in_missed_group_direct_messages_many_others(self) -> None:
self._extra_context_in_missed_group_direct_messages_many_others()
def test_deleted_message_in_missed_stream_messages(self) -> None:
self._deleted_message_in_missed_stream_messages()
@ -1115,8 +1115,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
def test_deleted_message_in_missed_personal_messages(self) -> None:
self._deleted_message_in_missed_personal_messages()
def test_deleted_message_in_missed_huddle_messages(self) -> None:
self._deleted_message_in_missed_huddle_messages()
def test_deleted_message_in_missed_group_direct_messages(self) -> None:
self._deleted_message_in_missed_group_direct_messages()
def test_realm_message_content_allowed_in_email_notifications(self) -> None:
user = self.example_user("hamlet")

View File

@ -20,7 +20,7 @@ from zerver.actions.message_send import (
extract_stream_indicator,
internal_prep_private_message,
internal_prep_stream_message_by_name,
internal_send_huddle_message,
internal_send_group_direct_message,
internal_send_private_message,
internal_send_stream_message,
internal_send_stream_message_by_name,
@ -61,7 +61,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 PrivateMessagePolicyEnum, WildcardMentionPolicyEnum, get_realm
from zerver.models.recipients import get_or_create_huddle
from zerver.models.recipients import 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
@ -713,14 +713,14 @@ class MessagePOSTTest(ZulipTestCase):
msg = self.get_last_message()
self.assertEqual("Test message", msg.content)
huddle = get_or_create_huddle(
direct_message_group = get_or_create_direct_message_group(
[
self.example_user("hamlet").id,
self.example_user("othello").id,
self.example_user("cordelia").id,
]
)
self.assertEqual(msg.recipient_id, huddle.recipient_id)
self.assertEqual(msg.recipient_id, direct_message_group.recipient_id)
def test_personal_message_copying_self(self) -> None:
"""
@ -967,9 +967,9 @@ class MessagePOSTTest(ZulipTestCase):
)
self.assert_json_error(result, "Message must have recipients")
def test_mirrored_huddle(self) -> None:
def test_mirrored_direct_message_group(self) -> None:
"""
Sending a mirrored huddle message works
Sending a mirrored group direct message works
"""
result = self.api_post(
self.mit_user("starnine"),
@ -1042,9 +1042,9 @@ class MessagePOSTTest(ZulipTestCase):
)
self.assert_json_error(result, "User not authorized for this query")
def test_duplicated_mirrored_huddle(self) -> None:
def test_duplicated_mirrored_direct_message_group(self) -> None:
"""
Sending two mirrored huddles in the row return the same ID
Sending two mirrored direct message groups in the row return the same ID
"""
msg = {
"type": "direct",
@ -2325,7 +2325,7 @@ class StreamMessagesTest(ZulipTestCase):
self.assert_stream_message(non_ascii_stream_name, topic_name="hümbüǵ", content="hümbüǵ")
def test_get_raw_unread_data_for_huddle_messages(self) -> None:
def test_get_raw_unread_data_for_group_direct_messages(self) -> None:
users = [
self.example_user("hamlet"),
self.example_user("cordelia"),
@ -2334,8 +2334,8 @@ class StreamMessagesTest(ZulipTestCase):
self.example_user("othello"),
]
message1_id = self.send_huddle_message(users[0], users, "test content 1")
message2_id = self.send_huddle_message(users[0], users, "test content 2")
message1_id = self.send_group_direct_message(users[0], users, "test content 1")
message2_id = self.send_group_direct_message(users[0], users, "test content 2")
msg_data = get_raw_unread_data(users[1])
@ -2580,7 +2580,7 @@ class InternalPrepTest(ZulipTestCase):
)
with self.assertLogs(level="ERROR") as m:
internal_send_huddle_message(
internal_send_group_direct_message(
realm=realm,
sender=cordelia,
emails=[hamlet.email, othello.email],
@ -2840,23 +2840,24 @@ class TestCrossRealmPMs(ZulipTestCase):
# (We don't particularly need this feature, but since users can
# already individually send direct messages to cross-realm bots,
# we shouldn't prevent them from sending multiple bots at once.
# We may revisit this if it's a nuisance for huddles.)
self.send_huddle_message(user1, [notification_bot, support_bot])
# We may revisit this if it's a nuisance for direct message
# groups.)
self.send_group_direct_message(user1, [notification_bot, support_bot])
assert_message_received(notification_bot, user1)
assert_message_received(support_bot, user1)
# Prevent old loophole where I could send direct messages to other
# users as long as I copied a cross-realm bot from the same realm.
with assert_invalid_user():
self.send_huddle_message(user1, [user3, support_bot])
self.send_group_direct_message(user1, [user3, support_bot])
# Users on three different realms can't send direct messages to
# each other, even if one of the users is a cross-realm bot.
with assert_invalid_user():
self.send_huddle_message(user1, [user2, notification_bot])
self.send_group_direct_message(user1, [user2, notification_bot])
with assert_invalid_user():
self.send_huddle_message(notification_bot, [user1, user2])
self.send_group_direct_message(notification_bot, [user1, user2])
# Users on the different realms cannot send direct messages to
# each other.
@ -2871,7 +2872,7 @@ class TestCrossRealmPMs(ZulipTestCase):
# Users on three different realms cannot send direct messages
# to each other.
with assert_invalid_user():
self.send_huddle_message(user1, [user2, user3])
self.send_group_direct_message(user1, [user2, user3])
class TestAddressee(ZulipTestCase):

View File

@ -6,7 +6,10 @@ from django.utils.timezone import now as timezone_now
from zerver.actions.message_send import get_active_presence_idle_user_ids
from zerver.lib.test_classes import ZulipTestCase
from zerver.models import Message, UserPresence, UserProfile
from zerver.models.recipients import bulk_get_huddle_user_ids, get_huddle_user_ids
from zerver.models.recipients import (
bulk_get_direct_message_group_user_ids,
get_direct_message_group_user_ids,
)
class MissedMessageTest(ZulipTestCase):
@ -64,36 +67,46 @@ class MissedMessageTest(ZulipTestCase):
set_presence(hamlet, "website", ago=15)
assert_active_presence_idle_user_ids([])
# Hamlet is active now, so only Othello should be in the list for a huddle
# message.
# Hamlet is active now, so only Othello should be in the list for a group
# direct message.
hamlet_notifications_data.stream_email_notify = False
hamlet_notifications_data.dm_push_notify = False
othello_notifications_data.dm_push_notify = True
assert_active_presence_idle_user_ids([othello.id])
class TestBulkGetHuddleUserIds(ZulipTestCase):
def test_bulk_get_huddle_user_ids(self) -> None:
class TestBulkGetDirectMessageGroupUserIds(ZulipTestCase):
def test_bulk_get_direct_message_group_user_ids(self) -> None:
hamlet = self.example_user("hamlet")
cordelia = self.example_user("cordelia")
othello = self.example_user("othello")
iago = self.example_user("iago")
message_ids = [
self.send_huddle_message(hamlet, [cordelia, othello], "test"),
self.send_huddle_message(cordelia, [hamlet, othello, iago], "test"),
self.send_group_direct_message(hamlet, [cordelia, othello], "test"),
self.send_group_direct_message(cordelia, [hamlet, othello, iago], "test"),
]
messages = Message.objects.filter(id__in=message_ids).order_by("id")
first_huddle_recipient = messages[0].recipient
first_huddle_user_ids = set(get_huddle_user_ids(first_huddle_recipient))
second_huddle_recipient = messages[1].recipient
second_huddle_user_ids = set(get_huddle_user_ids(second_huddle_recipient))
huddle_user_ids = bulk_get_huddle_user_ids(
[first_huddle_recipient.id, second_huddle_recipient.id]
first_direct_message_group_recipient = messages[0].recipient
first_direct_message_group_user_ids = set(
get_direct_message_group_user_ids(first_direct_message_group_recipient)
)
second_direct_message_group_recipient = messages[1].recipient
second_direct_message_group_user_ids = set(
get_direct_message_group_user_ids(second_direct_message_group_recipient)
)
self.assertEqual(huddle_user_ids[first_huddle_recipient.id], first_huddle_user_ids)
self.assertEqual(huddle_user_ids[second_huddle_recipient.id], second_huddle_user_ids)
def test_bulk_get_huddle_user_ids_empty_list(self) -> None:
self.assertEqual(bulk_get_huddle_user_ids([]), {})
direct_message_group_user_ids = bulk_get_direct_message_group_user_ids(
[first_direct_message_group_recipient.id, second_direct_message_group_recipient.id]
)
self.assertEqual(
direct_message_group_user_ids[first_direct_message_group_recipient.id],
first_direct_message_group_user_ids,
)
self.assertEqual(
direct_message_group_user_ids[second_direct_message_group_recipient.id],
second_direct_message_group_user_ids,
)
def test_bulk_get_direct_message_group_user_ids_empty_list(self) -> None:
self.assertEqual(bulk_get_direct_message_group_user_ids([]), {})

View File

@ -231,18 +231,20 @@ class MutedUsersTests(ZulipTestCase):
# Have Cordelia send messages to Hamlet and Othello.
stream_message = self.send_stream_message(cordelia, "general", "Spam in stream")
huddle_message = self.send_huddle_message(cordelia, [hamlet, othello], "Spam in huddle")
group_direct_message = self.send_group_direct_message(
cordelia, [hamlet, othello], "Spam in direct message group"
)
pm_to_hamlet = self.send_personal_message(cordelia, hamlet, "Spam in direct message")
pm_to_othello = self.send_personal_message(cordelia, othello, "Spam in direct message")
# These should be marked as read for Hamlet, since he has muted Cordelia.
self.assert_usermessage_read_flag(hamlet, stream_message, True)
self.assert_usermessage_read_flag(hamlet, huddle_message, True)
self.assert_usermessage_read_flag(hamlet, group_direct_message, True)
self.assert_usermessage_read_flag(hamlet, pm_to_hamlet, True)
# These messages should be unreads for Othello, since he hasn't muted Cordelia.
self.assert_usermessage_read_flag(othello, stream_message, False)
self.assert_usermessage_read_flag(othello, huddle_message, False)
self.assert_usermessage_read_flag(othello, group_direct_message, False)
self.assert_usermessage_read_flag(othello, pm_to_othello, False)
def test_existing_messages_from_muted_user_marked_as_read(self) -> None:
@ -258,17 +260,19 @@ class MutedUsersTests(ZulipTestCase):
# Have Cordelia send messages to Hamlet and Othello.
stream_message = self.send_stream_message(cordelia, "general", "Spam in stream")
huddle_message = self.send_huddle_message(cordelia, [hamlet, othello], "Spam in huddle")
group_direct_message = self.send_group_direct_message(
cordelia, [hamlet, othello], "Spam in direct message group"
)
pm_to_hamlet = self.send_personal_message(cordelia, hamlet, "Spam in direct message")
pm_to_othello = self.send_personal_message(cordelia, othello, "Spam in direct message")
# These messages are unreads for both Hamlet and Othello right now.
self.assert_usermessage_read_flag(hamlet, stream_message, False)
self.assert_usermessage_read_flag(hamlet, huddle_message, False)
self.assert_usermessage_read_flag(hamlet, group_direct_message, False)
self.assert_usermessage_read_flag(hamlet, pm_to_hamlet, False)
self.assert_usermessage_read_flag(othello, stream_message, False)
self.assert_usermessage_read_flag(othello, huddle_message, False)
self.assert_usermessage_read_flag(othello, group_direct_message, False)
self.assert_usermessage_read_flag(othello, pm_to_othello, False)
# Hamlet mutes Cordelia.
@ -278,12 +282,12 @@ class MutedUsersTests(ZulipTestCase):
# The messages sent earlier should be marked as read for Hamlet.
self.assert_usermessage_read_flag(hamlet, stream_message, True)
self.assert_usermessage_read_flag(hamlet, huddle_message, True)
self.assert_usermessage_read_flag(hamlet, group_direct_message, True)
self.assert_usermessage_read_flag(hamlet, pm_to_hamlet, True)
# These messages are still unreads for Othello, since he did not mute Cordelia.
self.assert_usermessage_read_flag(othello, stream_message, False)
self.assert_usermessage_read_flag(othello, huddle_message, False)
self.assert_usermessage_read_flag(othello, group_direct_message, False)
self.assert_usermessage_read_flag(othello, pm_to_othello, False)
def test_muted_message_send_notifications_not_enqueued(self) -> None:

View File

@ -16,7 +16,7 @@ from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.timezone import canonicalize_timezone
from zerver.models import Message, Recipient, Stream, UserProfile
from zerver.models.realms import get_realm
from zerver.models.recipients import get_huddle_user_ids
from zerver.models.recipients import get_direct_message_group_user_ids
from zerver.models.streams import get_stream
from zerver.models.users import get_system_bot
from zerver.signals import JUST_CREATED_THRESHOLD, get_device_browser, get_device_os
@ -342,7 +342,7 @@ class TestNotifyNewUser(ZulipTestCase):
)
# Group DM
self.assertEqual(
set(get_huddle_user_ids(message.recipient)),
set(get_direct_message_group_user_ids(message.recipient)),
expected_group_direct_message_user_ids,
)
self.assertIn(

View File

@ -4005,11 +4005,11 @@ class TestGetAPNsPayload(PushNotificationTest):
self.assertDictEqual(payload, expected)
@mock.patch("zerver.lib.push_notifications.push_notifications_configured", return_value=True)
def test_get_message_payload_apns_huddle_message(
def test_get_message_payload_apns_group_direct_message(
self, mock_push_notifications: mock.MagicMock
) -> None:
user_profile = self.example_user("othello")
message_id = self.send_huddle_message(
message_id = self.send_group_direct_message(
self.sender, [self.example_user("othello"), self.example_user("cordelia")]
)
message = Message.objects.get(id=message_id)
@ -4225,7 +4225,7 @@ class TestGetAPNsPayload(PushNotificationTest):
@override_settings(PUSH_NOTIFICATION_REDACT_CONTENT=True)
def test_get_message_payload_apns_redacted_content(self) -> None:
user_profile = self.example_user("othello")
message_id = self.send_huddle_message(
message_id = self.send_group_direct_message(
self.sender, [self.example_user("othello"), self.example_user("cordelia")]
)
message = Message.objects.get(id=message_id)

View File

@ -616,14 +616,14 @@ class ReactionEventTest(ZulipTestCase):
self.assertEqual(event_user_ids, {iago.id, hamlet.id})
# Group direct message; event should go to all participants.
huddle_message_id = self.send_huddle_message(
group_direct_message_id = self.send_group_direct_message(
hamlet,
[polonius, iago],
"hello message to multiple receiver",
)
with self.capture_send_event_calls(expected_num_events=1) as events:
result = self.api_post(
polonius, f"/api/v1/messages/{huddle_message_id}/reactions", reaction_info
polonius, f"/api/v1/messages/{group_direct_message_id}/reactions", reaction_info
)
self.assert_json_success(result)
event = events[0]["event"]

View File

@ -55,12 +55,12 @@ class TestReadReceipts(ZulipTestCase):
self.assertTrue(hamlet.id in result.json()["user_ids"])
self.assertTrue(sender.id not in result.json()["user_ids"])
def test_huddle_message(self) -> None:
def test_group_direct_message(self) -> None:
hamlet = self.example_user("hamlet")
sender = self.example_user("othello")
cordelia = self.example_user("cordelia")
message_id = self.send_huddle_message(sender, [hamlet, cordelia])
message_id = self.send_group_direct_message(sender, [hamlet, cordelia])
self.login("hamlet")
result = self.client_get(f"/json/messages/{message_id}/read_receipts")

View File

@ -18,7 +18,7 @@ from confirmation.models import Confirmation, create_confirmation_link
from zerver.actions.create_realm import do_change_realm_subdomain, do_create_realm
from zerver.actions.create_user import do_create_user
from zerver.actions.message_send import (
internal_send_huddle_message,
internal_send_group_direct_message,
internal_send_private_message,
internal_send_stream_message,
)
@ -2220,7 +2220,7 @@ class ScrubRealmTest(ZulipTestCase):
notification_bot, get_stream("Scotland", zulip), "test", "test"
)
internal_send_private_message(notification_bot, othello, "test")
internal_send_huddle_message(
internal_send_group_direct_message(
zulip, notification_bot, "test", emails=[othello.email, iago.email]
)
@ -2228,7 +2228,7 @@ class ScrubRealmTest(ZulipTestCase):
notification_bot, get_stream("Shakespeare", lear), "test", "test"
)
internal_send_private_message(notification_bot, king, "test")
internal_send_huddle_message(
internal_send_group_direct_message(
lear, notification_bot, "test", emails=[cordelia.email, king.email]
)

View File

@ -10,7 +10,7 @@ from zerver.data_import.rocketchat import (
build_reactions,
categorize_channels_and_map_with_id,
convert_channel_data,
convert_huddle_data,
convert_direct_message_group_data,
convert_stream_subscription_data,
do_convert_data,
map_receiver_id_to_recipient_id,
@ -227,9 +227,11 @@ class RocketChatImporter(ZulipTestCase):
self.assertIn(direct_id, direct_id_to_direct_map)
self.assertEqual(direct_id_to_direct_map[direct_id], rocketchat_data["room"][4])
huddle_id = rocketchat_data["room"][12]["_id"]
self.assertIn(huddle_id, huddle_id_to_huddle_map)
self.assertEqual(huddle_id_to_huddle_map[huddle_id], rocketchat_data["room"][12])
direct_message_group_id = rocketchat_data["room"][12]["_id"]
self.assertIn(direct_message_group_id, huddle_id_to_huddle_map)
self.assertEqual(
huddle_id_to_huddle_map[direct_message_group_id], rocketchat_data["room"][12]
)
livechat_id = rocketchat_data["room"][14]["_id"]
self.assertIn(livechat_id, livechat_id_to_livechat_map)
@ -412,7 +414,7 @@ class RocketChatImporter(ZulipTestCase):
self.assert_length(subscriber_handler.get_users(stream_id=zerver_stream[6]["id"]), 0)
self.assertTrue(zerver_stream[6]["deactivated"])
def test_convert_huddle_data(self) -> None:
def test_convert_direct_message_group_data(self) -> None:
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
rocketchat_data = rocketchat_data_to_dict(fixture_dir_name)
@ -452,20 +454,22 @@ class RocketChatImporter(ZulipTestCase):
livechat_id_to_livechat_map=livechat_id_to_livechat_map,
)
zerver_huddle = convert_huddle_data(
zerver_direct_message_group = convert_direct_message_group_data(
huddle_id_to_huddle_map=huddle_id_to_huddle_map,
huddle_id_mapper=huddle_id_mapper,
user_id_mapper=user_id_mapper,
subscriber_handler=subscriber_handler,
)
self.assert_length(zerver_huddle, 1)
self.assert_length(zerver_direct_message_group, 1)
rc_huddle_id = rocketchat_data["room"][12]["_id"]
self.assertTrue(huddle_id_mapper.has(rc_huddle_id))
huddle_id = huddle_id_mapper.get(rc_huddle_id)
self.assertEqual(subscriber_handler.get_users(huddle_id=huddle_id), {3, 4, 5})
direct_message_group_id = huddle_id_mapper.get(rc_huddle_id)
self.assertEqual(
subscriber_handler.get_users(direct_message_group_id=direct_message_group_id), {3, 4, 5}
)
def test_write_emoticon_data(self) -> None:
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
@ -560,7 +564,7 @@ class RocketChatImporter(ZulipTestCase):
realm_id=realm_id,
)
zerver_huddle = convert_huddle_data(
zerver_direct_message_group = convert_direct_message_group_data(
huddle_id_to_huddle_map=huddle_id_to_huddle_map,
huddle_id_mapper=huddle_id_mapper,
user_id_mapper=user_id_mapper,
@ -572,7 +576,7 @@ class RocketChatImporter(ZulipTestCase):
zerver_recipient = build_recipients(
zerver_userprofile=all_users,
zerver_stream=zerver_stream,
zerver_huddle=zerver_huddle,
zerver_direct_message_group=zerver_direct_message_group,
)
stream_id_to_recipient_id: Dict[int, int] = {}
@ -659,7 +663,7 @@ class RocketChatImporter(ZulipTestCase):
self.assertIn(rocketchat_data["message"][11], private_messages)
self.assertIn(rocketchat_data["message"][12], private_messages)
self.assertIn(rocketchat_data["message"][50], private_messages) # Huddle message
self.assertIn(rocketchat_data["message"][50], private_messages) # Group direct message
self.assertIn(rocketchat_data["message"][79], livechat_messages)
self.assertIn(rocketchat_data["message"][83], livechat_messages)
@ -1021,23 +1025,23 @@ class RocketChatImporter(ZulipTestCase):
self.assertTrue(stream_messages[23].has_image)
self.assertTrue(stream_messages[23].has_link)
huddle_messages = messages.filter(recipient__type=Recipient.DIRECT_MESSAGE_GROUP).order_by(
"date_sent"
)
huddle_recipients = huddle_messages.values_list("recipient", flat=True)
self.assert_length(huddle_messages, 5)
self.assert_length(set(huddle_recipients), 2)
self.assertEqual(huddle_messages[0].sender.email, "hermionegranger@email.com")
self.assertEqual(huddle_messages[0].content, "Hey people!")
group_direct_messages = messages.filter(
recipient__type=Recipient.DIRECT_MESSAGE_GROUP
).order_by("date_sent")
direct_message_group_recipients = group_direct_messages.values_list("recipient", flat=True)
self.assert_length(group_direct_messages, 5)
self.assert_length(set(direct_message_group_recipients), 2)
self.assertEqual(group_direct_messages[0].sender.email, "hermionegranger@email.com")
self.assertEqual(group_direct_messages[0].content, "Hey people!")
self.assertEqual(huddle_messages[2].sender.email, "harrypotter@email.com")
self.assertEqual(group_direct_messages[2].sender.email, "harrypotter@email.com")
self.assertRegex(
huddle_messages[2].content,
group_direct_messages[2].content,
"This year's curriculum is out.\n\n\\[Hogwarts Curriculum.pdf\\]\\(.*\\)",
)
self.assertTrue(huddle_messages[2].has_attachment)
self.assertFalse(huddle_messages[2].has_image)
self.assertTrue(huddle_messages[2].has_link)
self.assertTrue(group_direct_messages[2].has_attachment)
self.assertFalse(group_direct_messages[2].has_image)
self.assertTrue(group_direct_messages[2].has_link)
personal_messages = messages.filter(recipient__type=Recipient.PERSONAL).order_by(
"date_sent"

View File

@ -566,7 +566,7 @@ class TestServiceBotEventTriggers(ZulipTestCase):
@for_all_bot_types
@patch_queue_publish("zerver.actions.message_send.queue_event_on_commit")
def test_trigger_on_huddle_message_from_user(
def test_trigger_on_group_direct_message_from_user(
self, mock_queue_event_on_commit: mock.Mock
) -> None:
self.second_bot_profile.bot_type = self.bot_profile.bot_type
@ -591,15 +591,15 @@ class TestServiceBotEventTriggers(ZulipTestCase):
mock_queue_event_on_commit.side_effect = check_values_passed
self.send_huddle_message(sender, recipients, "test")
self.send_group_direct_message(sender, recipients, "test")
self.assertEqual(mock_queue_event_on_commit.call_count, 2)
@for_all_bot_types
@patch_queue_publish("zerver.actions.message_send.queue_event_on_commit")
def test_no_trigger_on_huddle_message_from_bot(
def test_no_trigger_on_group_direct_message_from_bot(
self, mock_queue_event_on_commit: mock.Mock
) -> None:
sender = self.second_bot_profile
recipients = [self.user_profile, self.bot_profile]
self.send_huddle_message(sender, recipients)
self.send_group_direct_message(sender, recipients)
self.assertFalse(mock_queue_event_on_commit.called)

View File

@ -78,7 +78,7 @@ from zerver.models import (
UserProfile,
)
from zerver.models.realms import get_realm
from zerver.models.recipients import get_huddle_user_ids
from zerver.models.recipients import get_direct_message_group_user_ids
from zerver.models.streams import get_stream
from zerver.models.users import get_system_bot, get_user, get_user_by_delivery_email
from zerver.views.auth import redirect_and_log_into_subdomain, start_two_factor_auth
@ -2899,7 +2899,7 @@ class UserSignUpTest(ZulipTestCase):
last_message.content,
)
self.assertEqual(
set(get_huddle_user_ids(last_message.recipient)),
set(get_direct_message_group_user_ids(last_message.recipient)),
expected_group_direct_message_user_ids,
)

View File

@ -314,7 +314,7 @@ class SlackImporter(ZulipTestCase):
[ # Private channels ("groups")
{"name": "private", "members": ["U061A1R2R", "U11111111"]},
],
[ # Huddles ("mpims")
[ # Direct message groups ("mpims")
{
"name": "mpdm-foo--bar--baz-1",
"members": ["U061A1R2R", "U061A5N1G", "U22222222"],

View File

@ -58,7 +58,7 @@ class UserSoftDeactivationTests(ZulipTestCase):
# We are sending this message to ensure that users have at least
# one UserMessage row.
self.send_huddle_message(users[0], users)
self.send_group_direct_message(users[0], users)
with self.assertLogs(logger_string, level="INFO") as m:
do_soft_deactivate_users(users)
@ -112,7 +112,7 @@ class UserSoftDeactivationTests(ZulipTestCase):
self.example_user("iago"),
self.example_user("cordelia"),
]
self.send_huddle_message(users[0], users)
self.send_group_direct_message(users[0], users)
with self.assertLogs(logger_string, level="INFO") as m:
do_soft_deactivate_users(users)

View File

@ -179,7 +179,7 @@ class TutorialTests(ZulipTestCase):
bot = get_system_bot(settings.WELCOME_BOT, user1.realm_id)
content = "whatever"
self.login_user(user1)
self.send_huddle_message(user1, [bot, user2], content)
self.send_group_direct_message(user1, [bot, user2], content)
user1_messages = message_stream_count(user1)
self.assertEqual(most_recent_message(user1).content, content)
# Welcome bot should still respond to initial direct message

View File

@ -2,7 +2,7 @@ import orjson
from zerver.lib.test_classes import ZulipTestCase
from zerver.models import Huddle
from zerver.models.recipients import get_huddle_hash
from zerver.models.recipients import get_direct_message_group_hash
class TypingValidateOperatorTest(ZulipTestCase):
@ -202,8 +202,8 @@ class TypingHappyPathTestDirectMessages(ZulipTestCase):
expected_recipient_emails = {user.email for user in expected_recipients}
expected_recipient_ids = {user.id for user in expected_recipients}
huddle_hash = get_huddle_hash(list(expected_recipient_ids))
self.assertFalse(Huddle.objects.filter(huddle_hash=huddle_hash).exists())
direct_message_group_hash = get_direct_message_group_hash(list(expected_recipient_ids))
self.assertFalse(Huddle.objects.filter(huddle_hash=direct_message_group_hash).exists())
params = dict(
to=orjson.dumps([user.id for user in recipient_users]).decode(),
@ -216,10 +216,10 @@ class TypingHappyPathTestDirectMessages(ZulipTestCase):
self.assert_json_success(result)
self.assert_length(events, 1)
# We should not be adding new Huddles just because
# a user started typing in the compose box. Let's
# wait till they send an actual message.
self.assertFalse(Huddle.objects.filter(huddle_hash=huddle_hash).exists())
# We should not be adding new Direct Message groups
# just because a user started typing in the compose
# box. Let's wait till they send an actual message.
self.assertFalse(Huddle.objects.filter(huddle_hash=direct_message_group_hash).exists())
event = events[0]["event"]
event_recipient_emails = {user["email"] for user in event["recipients"]}

View File

@ -2782,19 +2782,19 @@ class DeleteUserTest(ZulipTestCase):
self.assertGreater(len(personal_message_ids_to_hamlet), 0)
self.assertTrue(Message.objects.filter(realm_id=realm.id, sender=hamlet).exists())
huddle_message_ids_from_cordelia = [
self.send_huddle_message(cordelia, [hamlet, othello]) for i in range(3)
group_direct_message_ids_from_cordelia = [
self.send_group_direct_message(cordelia, [hamlet, othello]) for i in range(3)
]
huddle_message_ids_from_hamlet = [
self.send_huddle_message(hamlet, [cordelia, othello]) for i in range(3)
group_direct_message_ids_from_hamlet = [
self.send_group_direct_message(hamlet, [cordelia, othello]) for i in range(3)
]
huddle_with_hamlet_recipient_ids = list(
direct_message_group_with_hamlet_recipient_ids = list(
Subscription.objects.filter(
user_profile=hamlet, recipient__type=Recipient.DIRECT_MESSAGE_GROUP
).values_list("recipient_id", flat=True)
)
self.assertGreater(len(huddle_with_hamlet_recipient_ids), 0)
self.assertGreater(len(direct_message_group_with_hamlet_recipient_ids), 0)
do_delete_user(hamlet, acting_user=None)
@ -2808,18 +2808,22 @@ class DeleteUserTest(ZulipTestCase):
self.assertEqual(replacement_dummy_user.date_joined, hamlet_date_joined)
self.assertEqual(Message.objects.filter(id__in=personal_message_ids_to_hamlet).count(), 0)
# Huddle messages from hamlet should have been deleted, but messages of other participants should
# be kept.
self.assertEqual(Message.objects.filter(id__in=huddle_message_ids_from_hamlet).count(), 0)
self.assertEqual(Message.objects.filter(id__in=huddle_message_ids_from_cordelia).count(), 3)
# Group direct messages from hamlet should have been deleted, but messages of other
# participants should be kept.
self.assertEqual(
Message.objects.filter(id__in=group_direct_message_ids_from_hamlet).count(), 0
)
self.assertEqual(
Message.objects.filter(id__in=group_direct_message_ids_from_cordelia).count(), 3
)
self.assertEqual(
Message.objects.filter(realm_id=realm.id, sender_id=hamlet_user_id).count(), 0
)
# Verify that the dummy user is subscribed to the deleted user's huddles, to keep huddle data
# in a correct state.
for recipient_id in huddle_with_hamlet_recipient_ids:
# Verify that the dummy user is subscribed to the deleted user's direct message groups,
# to keep direct message group's data in a correct state.
for recipient_id in direct_message_group_with_hamlet_recipient_ids:
self.assertTrue(
Subscription.objects.filter(
user_profile=replacement_dummy_user, recipient_id=recipient_id
@ -2849,19 +2853,19 @@ class DeleteUserTest(ZulipTestCase):
self.assertGreater(len(personal_message_ids_to_hamlet), 0)
self.assertTrue(Message.objects.filter(realm_id=realm.id, sender=hamlet).exists())
huddle_message_ids_from_cordelia = [
self.send_huddle_message(cordelia, [hamlet, othello]) for i in range(3)
group_direct_message_ids_from_cordelia = [
self.send_group_direct_message(cordelia, [hamlet, othello]) for i in range(3)
]
huddle_message_ids_from_hamlet = [
self.send_huddle_message(hamlet, [cordelia, othello]) for i in range(3)
group_direct_message_ids_from_hamlet = [
self.send_group_direct_message(hamlet, [cordelia, othello]) for i in range(3)
]
huddle_with_hamlet_recipient_ids = list(
direct_message_group_with_hamlet_recipient_ids = list(
Subscription.objects.filter(
user_profile=hamlet, recipient__type=Recipient.DIRECT_MESSAGE_GROUP
).values_list("recipient_id", flat=True)
)
self.assertGreater(len(huddle_with_hamlet_recipient_ids), 0)
self.assertGreater(len(direct_message_group_with_hamlet_recipient_ids), 0)
original_messages_from_hamlet_count = Message.objects.filter(
realm_id=realm.id, sender_id=hamlet_user_id
@ -2885,12 +2889,12 @@ class DeleteUserTest(ZulipTestCase):
len(personal_message_ids_to_hamlet),
)
self.assertEqual(
Message.objects.filter(id__in=huddle_message_ids_from_hamlet).count(),
len(huddle_message_ids_from_hamlet),
Message.objects.filter(id__in=group_direct_message_ids_from_hamlet).count(),
len(group_direct_message_ids_from_hamlet),
)
self.assertEqual(
Message.objects.filter(id__in=huddle_message_ids_from_cordelia).count(),
len(huddle_message_ids_from_cordelia),
Message.objects.filter(id__in=group_direct_message_ids_from_cordelia).count(),
len(group_direct_message_ids_from_cordelia),
)
self.assertEqual(
@ -2898,9 +2902,9 @@ class DeleteUserTest(ZulipTestCase):
original_messages_from_hamlet_count,
)
# Verify that the dummy user is subscribed to the deleted user's huddles, to keep huddle data
# in a correct state.
for recipient_id in huddle_with_hamlet_recipient_ids:
# Verify that the dummy user is subscribed to the deleted user's direct message groups,
# to keep direct message group's data in a correct state.
for recipient_id in direct_message_group_with_hamlet_recipient_ids:
self.assertTrue(
Subscription.objects.filter(
user_profile=replacement_dummy_user, recipient_id=recipient_id

View File

@ -19,7 +19,7 @@ from zerver.lib.zulip_update_announcements import (
)
from zerver.models.messages import Message
from zerver.models.realms import get_realm
from zerver.models.recipients import Recipient, get_huddle_user_ids
from zerver.models.recipients import Recipient, get_direct_message_group_user_ids
from zerver.models.streams import get_stream
from zerver.models.users import get_system_bot
@ -77,7 +77,7 @@ class ZulipUpdateAnnouncementsTest(ZulipTestCase):
self.assertEqual(group_direct_message.sender, notification_bot)
self.assertEqual(group_direct_message.date_sent, now)
self.assertEqual(
set(get_huddle_user_ids(group_direct_message.recipient)),
set(get_direct_message_group_user_ids(group_direct_message.recipient)),
expected_group_direct_message_user_ids,
)
self.assertEqual(realm.zulip_update_announcements_level, 0)
@ -270,7 +270,7 @@ class ZulipUpdateAnnouncementsTest(ZulipTestCase):
self.assertEqual(group_direct_message.sender, notification_bot)
self.assertEqual(group_direct_message.date_sent, now)
self.assertEqual(
set(get_huddle_user_ids(group_direct_message.recipient)),
set(get_direct_message_group_user_ids(group_direct_message.recipient)),
expected_group_direct_message_user_ids,
)
self.assertEqual(realm.zulip_update_announcements_level, 0)

View File

@ -70,7 +70,7 @@ from zerver.models import (
from zerver.models.alert_words import flush_alert_word
from zerver.models.clients import get_client
from zerver.models.realms import WildcardMentionPolicyEnum, get_realm
from zerver.models.recipients import get_or_create_huddle
from zerver.models.recipients import get_or_create_direct_message_group
from zerver.models.streams import get_stream
from zerver.models.users import get_user, get_user_by_delivery_email, get_user_profile_by_id
from zilencer.models import RemoteRealm, RemoteZulipServer, RemoteZulipServerAuditLog
@ -929,7 +929,9 @@ class Command(ZulipBaseCommand):
# Create several initial huddles
for i in range(options["num_huddles"]):
get_or_create_huddle(random.sample(user_profiles_ids, random.randint(3, 4)))
get_or_create_direct_message_group(
random.sample(user_profiles_ids, random.randint(3, 4))
)
# Create several initial pairs for personals
personals_pairs = [