mirror of https://github.com/zulip/zulip.git
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:
parent
fa2f86ff80
commit
52692a6448
|
@ -10,7 +10,7 @@ from django.utils.translation import override as override_language
|
||||||
|
|
||||||
from confirmation import settings as confirmation_settings
|
from confirmation import settings as confirmation_settings
|
||||||
from zerver.actions.message_send import (
|
from zerver.actions.message_send import (
|
||||||
internal_send_huddle_message,
|
internal_send_group_direct_message,
|
||||||
internal_send_private_message,
|
internal_send_private_message,
|
||||||
internal_send_stream_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:
|
def send_group_direct_message_to_admins(sender: UserProfile, realm: Realm, content: str) -> None:
|
||||||
administrators = list(realm.get_human_admin_users())
|
administrators = list(realm.get_human_admin_users())
|
||||||
internal_send_huddle_message(
|
internal_send_group_direct_message(
|
||||||
realm,
|
realm,
|
||||||
sender,
|
sender,
|
||||||
content,
|
content,
|
||||||
|
|
|
@ -105,7 +105,7 @@ from zerver.models import (
|
||||||
from zerver.models.clients import get_client
|
from zerver.models.clients import get_client
|
||||||
from zerver.models.groups import SystemGroups
|
from zerver.models.groups import SystemGroups
|
||||||
from zerver.models.realms import PrivateMessagePolicyEnum
|
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.scheduled_jobs import NotificationTriggers
|
||||||
from zerver.models.streams import get_stream, get_stream_by_id_in_realm
|
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
|
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:
|
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:
|
else:
|
||||||
raise ValueError("Bad recipient type")
|
raise ValueError("Bad recipient type")
|
||||||
|
@ -547,7 +547,7 @@ def get_service_bot_events(
|
||||||
# Mention triggers, for stream messages
|
# Mention triggers, for stream messages
|
||||||
if is_stream and user_profile_id in mentioned_user_ids:
|
if is_stream and user_profile_id in mentioned_user_ids:
|
||||||
trigger = "mention"
|
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:
|
elif not is_stream and user_profile_id in active_user_ids:
|
||||||
trigger = NotificationTriggers.DIRECT_MESSAGE
|
trigger = NotificationTriggers.DIRECT_MESSAGE
|
||||||
else:
|
else:
|
||||||
|
@ -1222,9 +1222,9 @@ def do_send_messages(
|
||||||
|
|
||||||
def already_sent_mirrored_message_id(message: Message) -> Optional[int]:
|
def already_sent_mirrored_message_id(message: Message) -> Optional[int]:
|
||||||
if message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
|
if message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
|
||||||
# For huddle messages, we use a 10-second window because the
|
# For group direct messages, we use a 10-second window because
|
||||||
# timestamps aren't guaranteed to actually match between two
|
# the timestamps aren't guaranteed to actually match between
|
||||||
# copies of the same message.
|
# two copies of the same message.
|
||||||
time_window = timedelta(seconds=10)
|
time_window = timedelta(seconds=10)
|
||||||
else:
|
else:
|
||||||
time_window = timedelta(seconds=0)
|
time_window = timedelta(seconds=0)
|
||||||
|
@ -1989,7 +1989,7 @@ def internal_send_stream_message_by_name(
|
||||||
return sent_message_result.message_id
|
return sent_message_result.message_id
|
||||||
|
|
||||||
|
|
||||||
def internal_prep_huddle_message(
|
def internal_prep_group_direct_message(
|
||||||
realm: Realm,
|
realm: Realm,
|
||||||
sender: UserProfile,
|
sender: UserProfile,
|
||||||
content: str,
|
content: str,
|
||||||
|
@ -2011,7 +2011,7 @@ def internal_prep_huddle_message(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def internal_send_huddle_message(
|
def internal_send_group_direct_message(
|
||||||
realm: Realm,
|
realm: Realm,
|
||||||
sender: UserProfile,
|
sender: UserProfile,
|
||||||
content: str,
|
content: str,
|
||||||
|
@ -2019,7 +2019,7 @@ def internal_send_huddle_message(
|
||||||
emails: Optional[List[str]] = None,
|
emails: Optional[List[str]] = None,
|
||||||
recipient_users: Optional[List[UserProfile]] = None,
|
recipient_users: Optional[List[UserProfile]] = None,
|
||||||
) -> Optional[int]:
|
) -> Optional[int]:
|
||||||
message = internal_prep_huddle_message(
|
message = internal_prep_group_direct_message(
|
||||||
realm, sender, content, emails=emails, recipient_users=recipient_users
|
realm, sender, content, emails=emails, recipient_users=recipient_users
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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
|
# 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
|
# just reject the whole request, since a partial list of user_ids
|
||||||
# can create confusion related to huddles. Plus it's a good
|
# can create confusion related to direct message groups. Plus it's
|
||||||
# sign that a client is confused (or possibly even malicious) if
|
# a good sign that a client is confused (or possibly even malicious)
|
||||||
# we get bad user_ids.
|
# if we get bad user_ids.
|
||||||
user_profiles = []
|
user_profiles = []
|
||||||
for user_id in user_ids:
|
for user_id in user_ids:
|
||||||
try:
|
try:
|
||||||
# We include cross-bot realms as possible recipients,
|
# We include cross-bot realms as possible recipients,
|
||||||
# so that clients can know which huddle conversation
|
# so that clients can know which direct message group
|
||||||
# is relevant here.
|
# conversation is relevant here.
|
||||||
user_profile = get_user_by_id_in_realm_including_cross_realm(user_id, sender.realm)
|
user_profile = get_user_by_id_in_realm_including_cross_realm(user_id, sender.realm)
|
||||||
except UserProfile.DoesNotExist:
|
except UserProfile.DoesNotExist:
|
||||||
raise JsonableError(_("Invalid user ID {user_id}").format(user_id=user_id))
|
raise JsonableError(_("Invalid user ID {user_id}").format(user_id=user_id))
|
||||||
|
|
|
@ -50,30 +50,30 @@ ZerverFieldsT: TypeAlias = Dict[str, Any]
|
||||||
class SubscriberHandler:
|
class SubscriberHandler:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.stream_info: Dict[int, Set[int]] = {}
|
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(
|
def set_info(
|
||||||
self,
|
self,
|
||||||
users: Set[int],
|
users: Set[int],
|
||||||
stream_id: Optional[int] = None,
|
stream_id: Optional[int] = None,
|
||||||
huddle_id: Optional[int] = None,
|
direct_message_group_id: Optional[int] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
if stream_id is not None:
|
if stream_id is not None:
|
||||||
self.stream_info[stream_id] = users
|
self.stream_info[stream_id] = users
|
||||||
elif huddle_id is not None:
|
elif direct_message_group_id is not None:
|
||||||
self.huddle_info[huddle_id] = users
|
self.direct_message_group_info[direct_message_group_id] = users
|
||||||
else:
|
else:
|
||||||
raise AssertionError("stream_id or huddle_id is required")
|
raise AssertionError("stream_id or direct_message_group_id is required")
|
||||||
|
|
||||||
def get_users(
|
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]:
|
) -> Set[int]:
|
||||||
if stream_id is not None:
|
if stream_id is not None:
|
||||||
return self.stream_info[stream_id]
|
return self.stream_info[stream_id]
|
||||||
elif huddle_id is not None:
|
elif direct_message_group_id is not None:
|
||||||
return self.huddle_info[huddle_id]
|
return self.direct_message_group_info[direct_message_group_id]
|
||||||
else:
|
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(
|
def build_zerver_realm(
|
||||||
|
@ -214,7 +214,7 @@ def build_subscription(recipient_id: int, user_id: int, subscription_id: int) ->
|
||||||
|
|
||||||
|
|
||||||
class GetUsers(Protocol):
|
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(
|
def build_stream_subscriptions(
|
||||||
|
@ -245,24 +245,26 @@ def build_stream_subscriptions(
|
||||||
return subscriptions
|
return subscriptions
|
||||||
|
|
||||||
|
|
||||||
def build_huddle_subscriptions(
|
def build_direct_message_group_subscriptions(
|
||||||
get_users: GetUsers,
|
get_users: GetUsers,
|
||||||
zerver_recipient: List[ZerverFieldsT],
|
zerver_recipient: List[ZerverFieldsT],
|
||||||
zerver_huddle: List[ZerverFieldsT],
|
zerver_direct_message_group: List[ZerverFieldsT],
|
||||||
) -> List[ZerverFieldsT]:
|
) -> List[ZerverFieldsT]:
|
||||||
subscriptions: 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_map = {
|
||||||
recipient["id"]: recipient["type_id"] # recipient_id -> stream_id
|
recipient["id"]: recipient["type_id"] # recipient_id -> stream_id
|
||||||
for recipient in zerver_recipient
|
for recipient in zerver_recipient
|
||||||
if recipient["type"] == Recipient.DIRECT_MESSAGE_GROUP
|
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():
|
for recipient_id, direct_message_group_id in recipient_map.items():
|
||||||
user_ids = get_users(huddle_id=huddle_id)
|
user_ids = get_users(direct_message_group_id=direct_message_group_id)
|
||||||
for user_id in user_ids:
|
for user_id in user_ids:
|
||||||
subscription = build_subscription(
|
subscription = build_subscription(
|
||||||
recipient_id=recipient_id,
|
recipient_id=recipient_id,
|
||||||
|
@ -307,7 +309,7 @@ def build_recipient(type_id: int, recipient_id: int, type: int) -> ZerverFieldsT
|
||||||
def build_recipients(
|
def build_recipients(
|
||||||
zerver_userprofile: Iterable[ZerverFieldsT],
|
zerver_userprofile: Iterable[ZerverFieldsT],
|
||||||
zerver_stream: Iterable[ZerverFieldsT],
|
zerver_stream: Iterable[ZerverFieldsT],
|
||||||
zerver_huddle: Iterable[ZerverFieldsT] = [],
|
zerver_direct_message_group: Iterable[ZerverFieldsT] = [],
|
||||||
) -> List[ZerverFieldsT]:
|
) -> List[ZerverFieldsT]:
|
||||||
"""
|
"""
|
||||||
This function was only used HipChat import, this function may be
|
This function was only used HipChat import, this function may be
|
||||||
|
@ -339,8 +341,8 @@ def build_recipients(
|
||||||
recipient_dict = model_to_dict(recipient)
|
recipient_dict = model_to_dict(recipient)
|
||||||
recipients.append(recipient_dict)
|
recipients.append(recipient_dict)
|
||||||
|
|
||||||
for huddle in zerver_huddle:
|
for direct_message_group in zerver_direct_message_group:
|
||||||
type_id = huddle["id"]
|
type_id = direct_message_group["id"]
|
||||||
type = Recipient.DIRECT_MESSAGE_GROUP
|
type = Recipient.DIRECT_MESSAGE_GROUP
|
||||||
recipient = Recipient(
|
recipient = Recipient(
|
||||||
type_id=type_id,
|
type_id=type_id,
|
||||||
|
@ -482,11 +484,11 @@ def build_stream(
|
||||||
return stream_dict
|
return stream_dict
|
||||||
|
|
||||||
|
|
||||||
def build_huddle(huddle_id: int) -> ZerverFieldsT:
|
def build_direct_message_group(direct_message_group_id: int) -> ZerverFieldsT:
|
||||||
huddle = Huddle(
|
direct_message_group = Huddle(
|
||||||
id=huddle_id,
|
id=direct_message_group_id,
|
||||||
)
|
)
|
||||||
return model_to_dict(huddle)
|
return model_to_dict(direct_message_group)
|
||||||
|
|
||||||
|
|
||||||
def build_message(
|
def build_message(
|
||||||
|
|
|
@ -21,8 +21,8 @@ from zerver.data_import.import_util import (
|
||||||
SubscriberHandler,
|
SubscriberHandler,
|
||||||
ZerverFieldsT,
|
ZerverFieldsT,
|
||||||
build_attachment,
|
build_attachment,
|
||||||
build_huddle,
|
build_direct_message_group,
|
||||||
build_huddle_subscriptions,
|
build_direct_message_group_subscriptions,
|
||||||
build_message,
|
build_message,
|
||||||
build_personal_subscriptions,
|
build_personal_subscriptions,
|
||||||
build_realm,
|
build_realm,
|
||||||
|
@ -232,17 +232,18 @@ def convert_channel_data(
|
||||||
return streams
|
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
|
# Simple hash function to generate a unique hash key for the
|
||||||
# members of a huddle. Needs to be consistent only within the
|
# members of a direct_message_group. Needs to be consistent
|
||||||
# lifetime of export tool run, as it doesn't appear in the output.
|
# only within the lifetime of export tool run, as it doesn't
|
||||||
|
# appear in the output.
|
||||||
import hashlib
|
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(
|
def convert_direct_message_group_data(
|
||||||
huddle_data: List[ZerverFieldsT],
|
direct_message_group_data: List[ZerverFieldsT],
|
||||||
user_data_map: Dict[str, Dict[str, Any]],
|
user_data_map: Dict[str, Dict[str, Any]],
|
||||||
subscriber_handler: SubscriberHandler,
|
subscriber_handler: SubscriberHandler,
|
||||||
huddle_id_mapper: IdMapper,
|
huddle_id_mapper: IdMapper,
|
||||||
|
@ -250,21 +251,23 @@ def convert_huddle_data(
|
||||||
realm_id: int,
|
realm_id: int,
|
||||||
team_name: str,
|
team_name: str,
|
||||||
) -> List[ZerverFieldsT]:
|
) -> List[ZerverFieldsT]:
|
||||||
zerver_huddle = []
|
zerver_direct_message_group = []
|
||||||
for huddle in huddle_data:
|
for direct_message_group in direct_message_group_data:
|
||||||
if len(huddle["members"]) > 2:
|
if len(direct_message_group["members"]) > 2:
|
||||||
huddle_name = generate_huddle_name(huddle["members"])
|
direct_message_group_name = generate_direct_message_group_name(
|
||||||
huddle_id = huddle_id_mapper.get(huddle_name)
|
direct_message_group["members"]
|
||||||
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_huddle.append(huddle_dict)
|
direct_message_group_id = huddle_id_mapper.get(direct_message_group_name)
|
||||||
return zerver_huddle
|
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(
|
def build_reactions(
|
||||||
|
@ -591,12 +594,12 @@ def process_posts(
|
||||||
if "channel" in post_dict:
|
if "channel" in post_dict:
|
||||||
message_dict["channel_name"] = post_dict["channel"]
|
message_dict["channel_name"] = post_dict["channel"]
|
||||||
elif "channel_members" in post_dict:
|
elif "channel_members" in post_dict:
|
||||||
# This case is for handling posts from direct messages and huddles,
|
# This case is for handling posts from direct messages and direct message,
|
||||||
# not channels. Direct messages and huddles are known as direct_channels
|
# groups not channels. Direct messages and direct message groups are known
|
||||||
# in Slack and hence the name channel_members.
|
# as direct_channels in Slack and hence the name channel_members.
|
||||||
channel_members = post_dict["channel_members"]
|
channel_members = post_dict["channel_members"]
|
||||||
if len(channel_members) > 2:
|
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:
|
elif len(channel_members) == 2:
|
||||||
message_dict["pm_members"] = channel_members
|
message_dict["pm_members"] = channel_members
|
||||||
else:
|
else:
|
||||||
|
@ -697,7 +700,7 @@ def write_message_data(
|
||||||
else:
|
else:
|
||||||
post_types = ["channel_post"]
|
post_types = ["channel_post"]
|
||||||
logging.warning(
|
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:
|
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
|
realm["zerver_stream"] = zerver_stream
|
||||||
|
|
||||||
zerver_huddle: List[ZerverFieldsT] = []
|
zerver_direct_message_group: List[ZerverFieldsT] = []
|
||||||
if len(mattermost_data["team"]) == 1:
|
if len(mattermost_data["team"]) == 1:
|
||||||
zerver_huddle = convert_huddle_data(
|
zerver_direct_message_group = convert_direct_message_group_data(
|
||||||
huddle_data=mattermost_data["direct_channel"],
|
direct_message_group_data=mattermost_data["direct_channel"],
|
||||||
user_data_map=username_to_user,
|
user_data_map=username_to_user,
|
||||||
subscriber_handler=subscriber_handler,
|
subscriber_handler=subscriber_handler,
|
||||||
huddle_id_mapper=huddle_id_mapper,
|
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,
|
realm_id=realm_id,
|
||||||
team_name=team_name,
|
team_name=team_name,
|
||||||
)
|
)
|
||||||
realm["zerver_huddle"] = zerver_huddle
|
realm["zerver_huddle"] = zerver_direct_message_group
|
||||||
|
|
||||||
all_users = user_handler.get_all_users()
|
all_users = user_handler.get_all_users()
|
||||||
|
|
||||||
zerver_recipient = build_recipients(
|
zerver_recipient = build_recipients(
|
||||||
zerver_userprofile=all_users,
|
zerver_userprofile=all_users,
|
||||||
zerver_stream=zerver_stream,
|
zerver_stream=zerver_stream,
|
||||||
zerver_huddle=zerver_huddle,
|
zerver_direct_message_group=zerver_direct_message_group,
|
||||||
)
|
)
|
||||||
realm["zerver_recipient"] = zerver_recipient
|
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,
|
zerver_stream=zerver_stream,
|
||||||
)
|
)
|
||||||
|
|
||||||
huddle_subscriptions = build_huddle_subscriptions(
|
direct_message_group_subscriptions = build_direct_message_group_subscriptions(
|
||||||
get_users=subscriber_handler.get_users,
|
get_users=subscriber_handler.get_users,
|
||||||
zerver_recipient=zerver_recipient,
|
zerver_recipient=zerver_recipient,
|
||||||
zerver_huddle=zerver_huddle,
|
zerver_direct_message_group=zerver_direct_message_group,
|
||||||
)
|
)
|
||||||
|
|
||||||
personal_subscriptions = build_personal_subscriptions(
|
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.
|
# Mattermost currently supports only exporting messages from channels.
|
||||||
# Personal messages and huddles are not exported.
|
# Personal and Group Direct messages are not exported.
|
||||||
zerver_subscription = personal_subscriptions + stream_subscriptions + huddle_subscriptions
|
zerver_subscription = (
|
||||||
|
personal_subscriptions + stream_subscriptions + direct_message_group_subscriptions
|
||||||
|
)
|
||||||
realm["zerver_subscription"] = zerver_subscription
|
realm["zerver_subscription"] = zerver_subscription
|
||||||
|
|
||||||
zerver_realmemoji = write_emoticon_data(
|
zerver_realmemoji = write_emoticon_data(
|
||||||
|
|
|
@ -14,8 +14,8 @@ from zerver.data_import.import_util import (
|
||||||
SubscriberHandler,
|
SubscriberHandler,
|
||||||
ZerverFieldsT,
|
ZerverFieldsT,
|
||||||
build_attachment,
|
build_attachment,
|
||||||
build_huddle,
|
build_direct_message_group,
|
||||||
build_huddle_subscriptions,
|
build_direct_message_group_subscriptions,
|
||||||
build_message,
|
build_message,
|
||||||
build_personal_subscriptions,
|
build_personal_subscriptions,
|
||||||
build_realm,
|
build_realm,
|
||||||
|
@ -238,29 +238,29 @@ def convert_stream_subscription_data(
|
||||||
subscriber_handler.set_info(users=users, stream_id=stream["id"])
|
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_to_huddle_map: Dict[str, Dict[str, Any]],
|
||||||
huddle_id_mapper: IdMapper,
|
huddle_id_mapper: IdMapper,
|
||||||
user_id_mapper: IdMapper,
|
user_id_mapper: IdMapper,
|
||||||
subscriber_handler: SubscriberHandler,
|
subscriber_handler: SubscriberHandler,
|
||||||
) -> List[ZerverFieldsT]:
|
) -> List[ZerverFieldsT]:
|
||||||
zerver_huddle: List[ZerverFieldsT] = []
|
zerver_direct_message_group: List[ZerverFieldsT] = []
|
||||||
|
|
||||||
for rc_huddle_id in huddle_id_to_huddle_map:
|
for rc_huddle_id in huddle_id_to_huddle_map:
|
||||||
huddle_id = huddle_id_mapper.get(rc_huddle_id)
|
direct_message_group_id = huddle_id_mapper.get(rc_huddle_id)
|
||||||
huddle = build_huddle(huddle_id)
|
direct_message_group = build_direct_message_group(direct_message_group_id)
|
||||||
zerver_huddle.append(huddle)
|
zerver_direct_message_group.append(direct_message_group)
|
||||||
|
|
||||||
huddle_dict = huddle_id_to_huddle_map[rc_huddle_id]
|
direct_message_group_dict = huddle_id_to_huddle_map[rc_huddle_id]
|
||||||
huddle_user_ids = set()
|
direct_message_group_user_ids = set()
|
||||||
for rc_user_id in huddle_dict["uids"]:
|
for rc_user_id in direct_message_group_dict["uids"]:
|
||||||
huddle_user_ids.add(user_id_mapper.get(rc_user_id))
|
direct_message_group_user_ids.add(user_id_mapper.get(rc_user_id))
|
||||||
subscriber_handler.set_info(
|
subscriber_handler.set_info(
|
||||||
users=huddle_user_ids,
|
users=direct_message_group_user_ids,
|
||||||
huddle_id=huddle_id,
|
direct_message_group_id=direct_message_group_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
return zerver_huddle
|
return zerver_direct_message_group
|
||||||
|
|
||||||
|
|
||||||
def build_custom_emoji(
|
def build_custom_emoji(
|
||||||
|
@ -679,8 +679,8 @@ def process_messages(
|
||||||
# Message is in a 1:1 or group direct message.
|
# Message is in a 1:1 or group direct message.
|
||||||
rc_channel_id = message["rid"]
|
rc_channel_id = message["rid"]
|
||||||
if rc_channel_id in huddle_id_to_huddle_map:
|
if rc_channel_id in huddle_id_to_huddle_map:
|
||||||
huddle_id = huddle_id_mapper.get(rc_channel_id)
|
direct_message_group_id = huddle_id_mapper.get(rc_channel_id)
|
||||||
message_dict["recipient_id"] = huddle_id_to_recipient_id[huddle_id]
|
message_dict["recipient_id"] = huddle_id_to_recipient_id[direct_message_group_id]
|
||||||
else:
|
else:
|
||||||
rc_member_ids = direct_id_to_direct_map[rc_channel_id]["uids"]
|
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],
|
huddle_id_to_recipient_id: Dict[int, int],
|
||||||
user_id_to_recipient_id: Dict[int, int],
|
user_id_to_recipient_id: Dict[int, int],
|
||||||
) -> None:
|
) -> 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:
|
for recipient in zerver_recipient:
|
||||||
if recipient["type"] == Recipient.STREAM:
|
if recipient["type"] == Recipient.STREAM:
|
||||||
stream_id_to_recipient_id[recipient["type_id"]] = recipient["id"]
|
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"]
|
user_id_to_recipient_id[recipient["type_id"]] = recipient["id"]
|
||||||
|
|
||||||
|
|
||||||
# This is inspired by get_huddle_hash from zerver/models/recipients.py. It
|
# This is inspired by get_direct_message_group_hash
|
||||||
# expects strings identifying Rocket.Chat users, like
|
# from zerver/models/recipients.py. It expects strings
|
||||||
# `LdBZ7kPxtKESyHPEe`, not integer IDs.
|
# identifying Rocket.Chat users, like `LdBZ7kPxtKESyHPEe`,
|
||||||
|
# not integer IDs.
|
||||||
#
|
#
|
||||||
# Its purpose is to be a stable map usable for deduplication/merging
|
# Its purpose is to be a stable map usable for deduplication/merging
|
||||||
# of Rocket.Chat threads involving the same set of people. Thus, its
|
# 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
|
# 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,
|
# equal and thus will have the same actual direct message group hash
|
||||||
# that get_string_huddle_hash(S) = get_string_huddle_hash(T).
|
# once imported, that get_string_direct_message_group_hash(S) =
|
||||||
def get_string_huddle_hash(id_list: List[str]) -> str:
|
# 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))
|
id_list = sorted(set(id_list))
|
||||||
hash_key = ",".join(str(x) for x in id_list)
|
hash_key = ",".join(str(x) for x in id_list)
|
||||||
return hashlib.sha1(hash_key.encode()).hexdigest()
|
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]],
|
huddle_id_to_huddle_map: Dict[str, Dict[str, Any]],
|
||||||
livechat_id_to_livechat_map: Dict[str, Dict[str, Any]],
|
livechat_id_to_livechat_map: Dict[str, Dict[str, Any]],
|
||||||
) -> None:
|
) -> None:
|
||||||
huddle_hashed_channels: Dict[str, Any] = {}
|
direct_message_group_hashed_channels: Dict[str, Any] = {}
|
||||||
for channel in channel_data:
|
for channel in channel_data:
|
||||||
if channel.get("prid"):
|
if channel.get("prid"):
|
||||||
dsc_id_to_dsc_map[channel["_id"]] = channel
|
dsc_id_to_dsc_map[channel["_id"]] = channel
|
||||||
elif channel["t"] == "d":
|
elif channel["t"] == "d":
|
||||||
if len(channel["uids"]) > 2:
|
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(
|
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
|
if channel["msgs"] == 0: # nocoverage
|
||||||
|
@ -926,25 +930,29 @@ def categorize_channels_and_map_with_id(
|
||||||
# contain duplicates of real huddles, with no
|
# contain duplicates of real huddles, with no
|
||||||
# messages in the duplicate. We ignore these
|
# messages in the duplicate. We ignore these
|
||||||
# minor database corruptions in the Rocket.Chat
|
# minor database corruptions in the Rocket.Chat
|
||||||
# export. Doing so is safe, because a huddle with no
|
# export. Doing so is safe, because a direct
|
||||||
# message history has no value in Zulip's data
|
# message group with no message history has no
|
||||||
# model.
|
# value in Zulip's data model.
|
||||||
logging.debug("Skipping huddle with 0 messages: %s", channel)
|
logging.debug("Skipping direct message group with 0 messages: %s", channel)
|
||||||
elif huddle_hash in huddle_hashed_channels: # nocoverage
|
elif (
|
||||||
|
direct_message_group_hash in direct_message_group_hashed_channels
|
||||||
|
): # nocoverage
|
||||||
logging.info(
|
logging.info(
|
||||||
"Mapping huddle hash %s to existing channel: %s",
|
"Mapping direct message group hash %s to existing channel: %s",
|
||||||
huddle_hash,
|
direct_message_group_hash,
|
||||||
huddle_hashed_channels[huddle_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
|
# Ideally, we'd merge the duplicate direct message
|
||||||
# so correctly requires special handling in
|
# groups. Doing so correctly requires special
|
||||||
# convert_huddle_data() and on the message import
|
# handling in convert_direct_message_group_data()
|
||||||
# side as well, since those appear to be mapped
|
# and on the message import side as well, since
|
||||||
# via rocketchat channel IDs and not all of that
|
# those appear to be mapped via rocketchat channel
|
||||||
# information is resolved via the
|
# IDs and not all of that information is resolved
|
||||||
# huddle_id_to_huddle_map.
|
# via the huddle_id_to_huddle_map.
|
||||||
#
|
#
|
||||||
# For now, just throw an exception here rather
|
# For now, just throw an exception here rather
|
||||||
# than during the import process.
|
# than during the import process.
|
||||||
|
@ -953,7 +961,7 @@ def categorize_channels_and_map_with_id(
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
huddle_id_to_huddle_map[channel["_id"]] = channel
|
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:
|
else:
|
||||||
direct_id_to_direct_map[channel["_id"]] = channel
|
direct_id_to_direct_map[channel["_id"]] = channel
|
||||||
elif channel["t"] == "l":
|
elif channel["t"] == "l":
|
||||||
|
@ -1114,20 +1122,20 @@ def do_convert_data(rocketchat_data_dir: str, output_dir: str) -> None:
|
||||||
subscriber_handler=subscriber_handler,
|
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_to_huddle_map=huddle_id_to_huddle_map,
|
||||||
huddle_id_mapper=huddle_id_mapper,
|
huddle_id_mapper=huddle_id_mapper,
|
||||||
user_id_mapper=user_id_mapper,
|
user_id_mapper=user_id_mapper,
|
||||||
subscriber_handler=subscriber_handler,
|
subscriber_handler=subscriber_handler,
|
||||||
)
|
)
|
||||||
realm["zerver_huddle"] = zerver_huddle
|
realm["zerver_huddle"] = zerver_direct_message_group
|
||||||
|
|
||||||
all_users = user_handler.get_all_users()
|
all_users = user_handler.get_all_users()
|
||||||
|
|
||||||
zerver_recipient = build_recipients(
|
zerver_recipient = build_recipients(
|
||||||
zerver_userprofile=all_users,
|
zerver_userprofile=all_users,
|
||||||
zerver_stream=zerver_stream,
|
zerver_stream=zerver_stream,
|
||||||
zerver_huddle=zerver_huddle,
|
zerver_direct_message_group=zerver_direct_message_group,
|
||||||
)
|
)
|
||||||
realm["zerver_recipient"] = zerver_recipient
|
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,
|
zerver_stream=zerver_stream,
|
||||||
)
|
)
|
||||||
|
|
||||||
huddle_subscriptions = build_huddle_subscriptions(
|
direct_message_group_subscriptions = build_direct_message_group_subscriptions(
|
||||||
get_users=subscriber_handler.get_users,
|
get_users=subscriber_handler.get_users,
|
||||||
zerver_recipient=zerver_recipient,
|
zerver_recipient=zerver_recipient,
|
||||||
zerver_huddle=zerver_huddle,
|
zerver_direct_message_group=zerver_direct_message_group,
|
||||||
)
|
)
|
||||||
|
|
||||||
personal_subscriptions = build_personal_subscriptions(
|
personal_subscriptions = build_personal_subscriptions(
|
||||||
zerver_recipient=zerver_recipient,
|
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
|
realm["zerver_subscription"] = zerver_subscription
|
||||||
|
|
||||||
zerver_realmemoji = build_custom_emoji(
|
zerver_realmemoji = build_custom_emoji(
|
||||||
|
|
|
@ -24,7 +24,7 @@ from zerver.data_import.import_util import (
|
||||||
build_attachment,
|
build_attachment,
|
||||||
build_avatar,
|
build_avatar,
|
||||||
build_defaultstream,
|
build_defaultstream,
|
||||||
build_huddle,
|
build_direct_message_group,
|
||||||
build_message,
|
build_message,
|
||||||
build_realm,
|
build_realm,
|
||||||
build_recipient,
|
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
|
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
|
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
|
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.
|
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
|
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
|
8. emoji_url_map, which is maps emoji name to its Slack URL
|
||||||
|
@ -507,7 +507,8 @@ def channels_to_zerver_stream(
|
||||||
Returns:
|
Returns:
|
||||||
1. realm, converted realm data
|
1. realm, converted realm data
|
||||||
2. added_channels, which is a dictionary to map from channel name to channel id, Zulip stream_id
|
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.
|
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
|
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
|
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
|
subscription_id_count = recipient_id_count = 0
|
||||||
stream_id_count = defaultstream_id = 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:
|
def process_channels(channels: List[Dict[str, Any]], invite_only: bool = False) -> None:
|
||||||
nonlocal stream_id_count
|
nonlocal stream_id_count
|
||||||
|
@ -600,20 +601,20 @@ def channels_to_zerver_stream(
|
||||||
private_channels = []
|
private_channels = []
|
||||||
process_channels(private_channels, True)
|
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:
|
def process_mpims(mpims: List[Dict[str, Any]]) -> None:
|
||||||
nonlocal huddle_id_count
|
nonlocal direct_message_group_id_count
|
||||||
nonlocal recipient_id_count
|
nonlocal recipient_id_count
|
||||||
nonlocal subscription_id_count
|
nonlocal subscription_id_count
|
||||||
|
|
||||||
for mpim in mpims:
|
for mpim in mpims:
|
||||||
huddle = build_huddle(huddle_id_count)
|
direct_message_group = build_direct_message_group(direct_message_group_id_count)
|
||||||
realm["zerver_huddle"].append(huddle)
|
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(
|
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)
|
realm["zerver_recipient"].append(recipient)
|
||||||
slack_recipient_name_to_zulip_recipient_id[mpim["name"]] = recipient_id_count
|
slack_recipient_name_to_zulip_recipient_id[mpim["name"]] = recipient_id_count
|
||||||
|
@ -626,7 +627,7 @@ def channels_to_zerver_stream(
|
||||||
subscription_id_count,
|
subscription_id_count,
|
||||||
)
|
)
|
||||||
|
|
||||||
huddle_id_count += 1
|
direct_message_group_id_count += 1
|
||||||
recipient_id_count += 1
|
recipient_id_count += 1
|
||||||
logging.info("%s -> created", mpim["name"])
|
logging.info("%s -> created", mpim["name"])
|
||||||
|
|
||||||
|
@ -1267,10 +1268,10 @@ def fetch_shared_channel_users(
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
private_channels = []
|
private_channels = []
|
||||||
try:
|
try:
|
||||||
huddles = get_data_file(slack_data_dir + "/mpims.json")
|
direct_message_groups = get_data_file(slack_data_dir + "/mpims.json")
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
huddles = []
|
direct_message_groups = []
|
||||||
for channel in public_channels + private_channels + huddles:
|
for channel in public_channels + private_channels + direct_message_groups:
|
||||||
added_channels[channel["name"]] = True
|
added_channels[channel["name"]] = True
|
||||||
for user_id in channel["members"]:
|
for user_id in channel["members"]:
|
||||||
if user_id not in normal_user_ids:
|
if user_id not in normal_user_ids:
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.utils.translation import gettext as _
|
||||||
from zulip_bots.lib import BotIdentity, RateLimit
|
from zulip_bots.lib import BotIdentity, RateLimit
|
||||||
|
|
||||||
from zerver.actions.message_send import (
|
from zerver.actions.message_send import (
|
||||||
internal_send_huddle_message,
|
internal_send_group_direct_message,
|
||||||
internal_send_private_message,
|
internal_send_private_message,
|
||||||
internal_send_stream_message_by_name,
|
internal_send_stream_message_by_name,
|
||||||
)
|
)
|
||||||
|
@ -109,7 +109,7 @@ class EmbeddedBotHandler:
|
||||||
self.user_profile, recipient_user, message["content"]
|
self.user_profile, recipient_user, message["content"]
|
||||||
)
|
)
|
||||||
else:
|
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
|
self.user_profile.realm, self.user_profile, message["content"], emails=recipients
|
||||||
)
|
)
|
||||||
return {"id": message_id}
|
return {"id": message_id}
|
||||||
|
|
|
@ -135,7 +135,7 @@ def bulk_fetch_user_display_recipients(
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from zerver.models import Recipient
|
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:
|
if len(recipient_tuples) == 0:
|
||||||
return {}
|
return {}
|
||||||
|
@ -144,12 +144,16 @@ def bulk_fetch_user_display_recipients(
|
||||||
get_type = lambda tup: tup[1]
|
get_type = lambda tup: tup[1]
|
||||||
|
|
||||||
personal_tuples = [tup for tup in recipient_tuples if get_type(tup) == Recipient.PERSONAL]
|
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
|
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]
|
direct_message_group_recipient_ids = [
|
||||||
huddle_recipient_id_to_user_ids = bulk_get_huddle_user_ids(huddle_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:
|
# Find all user ids whose UserProfiles we will need to fetch:
|
||||||
user_ids_to_fetch: Set[int] = set()
|
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:
|
for ignore_recipient_id, ignore_recipient_type, user_id in personal_tuples:
|
||||||
user_ids_to_fetch.add(user_id)
|
user_ids_to_fetch.add(user_id)
|
||||||
|
|
||||||
for recipient_id in huddle_recipient_ids:
|
for recipient_id in direct_message_group_recipient_ids:
|
||||||
huddle_user_ids = huddle_recipient_id_to_user_ids[recipient_id]
|
direct_message_group_user_ids = huddle_recipient_id_to_user_ids[recipient_id]
|
||||||
user_ids_to_fetch |= huddle_user_ids
|
user_ids_to_fetch |= direct_message_group_user_ids
|
||||||
|
|
||||||
# Fetch the needed user dictionaries.
|
# Fetch the needed user dictionaries.
|
||||||
user_display_recipients = bulk_fetch_single_user_display_recipients(list(user_ids_to_fetch))
|
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]]
|
display_recipients = [user_display_recipients[user_id]]
|
||||||
result[recipient_id] = display_recipients
|
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])
|
user_ids = sorted(huddle_recipient_id_to_user_ids[recipient_id])
|
||||||
display_recipients = [user_display_recipients[user_id] for user_id in user_ids]
|
display_recipients = [user_display_recipients[user_id] for user_id in user_ids]
|
||||||
result[recipient_id] = display_recipients
|
result[recipient_id] = display_recipients
|
||||||
|
@ -191,15 +195,15 @@ def bulk_fetch_display_recipients(
|
||||||
stream_recipients = {
|
stream_recipients = {
|
||||||
recipient for recipient in recipient_tuples if recipient[1] == Recipient.STREAM
|
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)
|
stream_display_recipients = bulk_fetch_stream_names(stream_recipients)
|
||||||
personal_and_huddle_display_recipients = bulk_fetch_user_display_recipients(
|
direct_message_display_recipients = bulk_fetch_user_display_recipients(
|
||||||
personal_and_huddle_recipients
|
direct_message_recipients
|
||||||
)
|
)
|
||||||
|
|
||||||
# Glue the dicts together and return:
|
# 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
|
@return_same_value_during_entire_request
|
||||||
|
|
|
@ -11,7 +11,7 @@ from typing_extensions import override
|
||||||
|
|
||||||
from zerver.actions.message_send import (
|
from zerver.actions.message_send import (
|
||||||
check_send_message,
|
check_send_message,
|
||||||
internal_send_huddle_message,
|
internal_send_group_direct_message,
|
||||||
internal_send_private_message,
|
internal_send_private_message,
|
||||||
internal_send_stream_message,
|
internal_send_stream_message,
|
||||||
)
|
)
|
||||||
|
@ -458,7 +458,7 @@ def process_missed_message(to: str, message: EmailMessage) -> None:
|
||||||
display_recipient = get_display_recipient(recipient)
|
display_recipient = get_display_recipient(recipient)
|
||||||
emails = [user_dict["email"] for user_dict in display_recipient]
|
emails = [user_dict["email"] for user_dict in display_recipient]
|
||||||
recipient_str = ", ".join(emails)
|
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:
|
else:
|
||||||
raise AssertionError("Invalid recipient type!")
|
raise AssertionError("Invalid recipient type!")
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ from zerver.lib.tex import change_katex_to_raw_latex
|
||||||
from zerver.lib.timezone import canonicalize_timezone
|
from zerver.lib.timezone import canonicalize_timezone
|
||||||
from zerver.lib.topic import get_topic_resolution_and_bare_name
|
from zerver.lib.topic import get_topic_resolution_and_bare_name
|
||||||
from zerver.lib.url_encoding import (
|
from zerver.lib.url_encoding import (
|
||||||
huddle_narrow_url,
|
direct_message_group_narrow_url,
|
||||||
personal_narrow_url,
|
personal_narrow_url,
|
||||||
stream_narrow_url,
|
stream_narrow_url,
|
||||||
topic_narrow_url,
|
topic_narrow_url,
|
||||||
|
@ -262,7 +262,7 @@ def build_message_list(
|
||||||
elif message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
|
elif message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
|
||||||
grouping = {"huddle": message.recipient_id}
|
grouping = {"huddle": message.recipient_id}
|
||||||
display_recipient = get_display_recipient(message.recipient)
|
display_recipient = get_display_recipient(message.recipient)
|
||||||
narrow_link = huddle_narrow_url(
|
narrow_link = direct_message_group_narrow_url(
|
||||||
user=user,
|
user=user,
|
||||||
display_recipient=display_recipient,
|
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
|
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
|
address that will send a Zulip message to the correct recipient. This
|
||||||
allows the user to respond to missed direct messages, huddles, and
|
allows the user to respond to missed direct messages, direct message
|
||||||
@-mentions directly from the email.
|
groups, and @-mentions directly from the email.
|
||||||
|
|
||||||
`user_profile` is the user to send the reminder to
|
`user_profile` is the user to send the reminder to
|
||||||
`missed_messages` is a list of dictionaries to Message objects and other data
|
`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})
|
senders = list({m["message"].sender for m in missed_messages})
|
||||||
if missed_messages[0]["message"].recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
|
if missed_messages[0]["message"].recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
|
||||||
display_recipient = get_display_recipient(missed_messages[0]["message"].recipient)
|
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,
|
user=user_profile,
|
||||||
display_recipient=display_recipient,
|
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]
|
other_recipients = [r["full_name"] for r in display_recipient if r["id"] != user_profile.id]
|
||||||
context.update(group_pm=True)
|
context.update(group_pm=True)
|
||||||
if len(other_recipients) == 2:
|
if len(other_recipients) == 2:
|
||||||
huddle_display_name = " and ".join(other_recipients)
|
direct_message_group_display_name = " and ".join(other_recipients)
|
||||||
context.update(huddle_display_name=huddle_display_name)
|
context.update(huddle_display_name=direct_message_group_display_name)
|
||||||
elif len(other_recipients) == 3:
|
elif len(other_recipients) == 3:
|
||||||
huddle_display_name = (
|
direct_message_group_display_name = (
|
||||||
f"{other_recipients[0]}, {other_recipients[1]}, and {other_recipients[2]}"
|
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:
|
else:
|
||||||
huddle_display_name = "{}, and {} others".format(
|
direct_message_group_display_name = "{}, and {} others".format(
|
||||||
", ".join(other_recipients[:2]), len(other_recipients) - 2
|
", ".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:
|
elif missed_messages[0]["message"].recipient.type == Recipient.PERSONAL:
|
||||||
narrow_url = personal_narrow_url(
|
narrow_url = personal_narrow_url(
|
||||||
realm=user_profile.realm,
|
realm=user_profile.realm,
|
||||||
|
|
|
@ -886,7 +886,7 @@ def get_realm_config() -> Config:
|
||||||
"zerver_huddle",
|
"zerver_huddle",
|
||||||
],
|
],
|
||||||
virtual_parent=user_profile_config,
|
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.
|
# 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))
|
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"]
|
realm = context["realm"]
|
||||||
user_profile_ids = {
|
user_profile_ids = {
|
||||||
r["id"] for r in response["zerver_userprofile"] + response["zerver_userprofile_mirrordummy"]
|
r["id"] for r in response["zerver_userprofile"] + response["zerver_userprofile_mirrordummy"]
|
||||||
|
|
|
@ -83,7 +83,7 @@ from zerver.models import (
|
||||||
from zerver.models.groups import SystemGroups
|
from zerver.models.groups import SystemGroups
|
||||||
from zerver.models.presence import PresenceSequence
|
from zerver.models.presence import PresenceSequence
|
||||||
from zerver.models.realms import get_realm
|
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 zerver.models.users import get_system_bot, get_user_profile_by_id
|
||||||
from zproject.backends import AUTH_BACKEND_NAME_MAP
|
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()
|
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]:
|
for direct_message_group in data[table]:
|
||||||
user_id_list = id_map_to_list["huddle_to_user_list"][huddle["id"]]
|
user_id_list = id_map_to_list["huddle_to_user_list"][direct_message_group["id"]]
|
||||||
huddle["huddle_hash"] = get_huddle_hash(user_id_list)
|
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
|
Extract the IDs of the user_profiles involved in a direct message group from
|
||||||
This helps to generate a unique huddle hash from the updated user_profile ids
|
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"] = {
|
id_map_to_list["huddle_to_user_list"] = {
|
||||||
value: [] for value in ID_MAP["recipient_to_huddle_map"].values()
|
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]:
|
for subscription in data[table]:
|
||||||
if subscription["recipient"] in ID_MAP["recipient_to_huddle_map"]:
|
if subscription["recipient"] in ID_MAP["recipient_to_huddle_map"]:
|
||||||
huddle_id = ID_MAP["recipient_to_huddle_map"][subscription["recipient"]]
|
direct_message_group_id = ID_MAP["recipient_to_huddle_map"][subscription["recipient"]]
|
||||||
id_map_to_list["huddle_to_user_list"][huddle_id].append(subscription["user_profile_id"])
|
id_map_to_list["huddle_to_user_list"][direct_message_group_id].append(
|
||||||
|
subscription["user_profile_id"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def fix_customprofilefield(data: TableData) -> None:
|
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:
|
elif related_table == "user_profile" and item["type"] == 1:
|
||||||
pass
|
pass
|
||||||
elif related_table == "huddle" and item["type"] == 3:
|
elif related_table == "huddle" and item["type"] == 3:
|
||||||
# save the recipient id with the huddle id, so that we can extract
|
# save the recipient id with the direct message group id, so that
|
||||||
# the user_profile ids involved in a huddle with the help of the
|
# we can extract the user_profile ids involved in a direct message
|
||||||
# subscription object
|
# group with the help of the subscription object
|
||||||
# check function 'get_huddles_from_subscription'
|
# check function 'get_direct_message_groups_from_subscription'
|
||||||
ID_MAP["recipient_to_huddle_map"][item["id"]] = lookup_table[old_id]
|
ID_MAP["recipient_to_huddle_map"][item["id"]] = lookup_table[old_id]
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
@ -672,9 +676,9 @@ def remove_denormalized_recipient_column_from_data(data: TableData) -> None:
|
||||||
if "recipient" in user_profile_dict:
|
if "recipient" in user_profile_dict:
|
||||||
del user_profile_dict["recipient"]
|
del user_profile_dict["recipient"]
|
||||||
|
|
||||||
for huddle_dict in data["zerver_huddle"]:
|
for direct_message_group_dict in data["zerver_huddle"]:
|
||||||
if "recipient" in huddle_dict:
|
if "recipient" in direct_message_group_dict:
|
||||||
del huddle_dict["recipient"]
|
del direct_message_group_dict["recipient"]
|
||||||
|
|
||||||
|
|
||||||
def get_db_table(model_class: Any) -> str:
|
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:
|
if "zerver_huddle" in data:
|
||||||
update_model_ids(Huddle, data, "huddle")
|
update_model_ids(Huddle, data, "huddle")
|
||||||
# We don't import Huddle yet, since we don't have the data to
|
# We don't import Huddle yet, since we don't have the data to
|
||||||
# compute huddle hashes until we've imported some of the
|
# compute direct message group hashes until we've imported some
|
||||||
# tables below.
|
# of the tables below.
|
||||||
# We can't get huddle hashes without processing subscriptions
|
# We can't get direct message group hashes without processing
|
||||||
# first, during which get_huddles_from_subscription is called.
|
# subscriptions first, during which
|
||||||
|
# get_direct_message_groups_from_subscription is called.
|
||||||
|
|
||||||
re_map_foreign_keys(
|
re_map_foreign_keys(
|
||||||
data,
|
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))
|
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")
|
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")
|
re_map_foreign_keys(data, "zerver_subscription", "recipient", related_table="recipient")
|
||||||
update_model_ids(Subscription, data, "subscription")
|
update_model_ids(Subscription, data, "subscription")
|
||||||
fix_subscriptions_is_user_active_column(data, user_profiles, crossrealm_user_ids)
|
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:
|
if "zerver_huddle" in data:
|
||||||
process_huddle_hash(data, "zerver_huddle")
|
process_direct_message_group_hash(data, "zerver_huddle")
|
||||||
bulk_import_model(data, 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(
|
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
|
direct_message_group.recipient = recipient
|
||||||
huddle.save(update_fields=["recipient"])
|
direct_message_group.save(update_fields=["recipient"])
|
||||||
|
|
||||||
if "zerver_alertword" in data:
|
if "zerver_alertword" in data:
|
||||||
re_map_foreign_keys(data, "zerver_alertword", "user_profile", related_table="user_profile")
|
re_map_foreign_keys(data, "zerver_alertword", "user_profile", related_table="user_profile")
|
||||||
|
|
|
@ -81,14 +81,14 @@ class RawUnreadDirectMessageDict(TypedDict):
|
||||||
other_user_id: int
|
other_user_id: int
|
||||||
|
|
||||||
|
|
||||||
class RawUnreadHuddleDict(TypedDict):
|
class RawUnreadDirectMessageGroupDict(TypedDict):
|
||||||
user_ids_string: str
|
user_ids_string: str
|
||||||
|
|
||||||
|
|
||||||
class RawUnreadMessagesResult(TypedDict):
|
class RawUnreadMessagesResult(TypedDict):
|
||||||
pm_dict: Dict[int, RawUnreadDirectMessageDict]
|
pm_dict: Dict[int, RawUnreadDirectMessageDict]
|
||||||
stream_dict: Dict[int, RawUnreadStreamDict]
|
stream_dict: Dict[int, RawUnreadStreamDict]
|
||||||
huddle_dict: Dict[int, RawUnreadHuddleDict]
|
huddle_dict: Dict[int, RawUnreadDirectMessageGroupDict]
|
||||||
mentions: Set[int]
|
mentions: Set[int]
|
||||||
muted_stream_ids: Set[int]
|
muted_stream_ids: Set[int]
|
||||||
unmuted_stream_msgs: Set[int]
|
unmuted_stream_msgs: Set[int]
|
||||||
|
@ -108,7 +108,7 @@ class UnreadDirectMessageInfo(TypedDict):
|
||||||
unread_message_ids: List[int]
|
unread_message_ids: List[int]
|
||||||
|
|
||||||
|
|
||||||
class UnreadHuddleInfo(TypedDict):
|
class UnreadDirectMessageGroupInfo(TypedDict):
|
||||||
user_ids_string: str
|
user_ids_string: str
|
||||||
unread_message_ids: List[int]
|
unread_message_ids: List[int]
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ class UnreadHuddleInfo(TypedDict):
|
||||||
class UnreadMessagesResult(TypedDict):
|
class UnreadMessagesResult(TypedDict):
|
||||||
pms: List[UnreadDirectMessageInfo]
|
pms: List[UnreadDirectMessageInfo]
|
||||||
streams: List[UnreadStreamInfo]
|
streams: List[UnreadStreamInfo]
|
||||||
huddles: List[UnreadHuddleInfo]
|
huddles: List[UnreadDirectMessageGroupInfo]
|
||||||
mentions: List[int]
|
mentions: List[int]
|
||||||
count: int
|
count: int
|
||||||
old_unreads_missing: bool
|
old_unreads_missing: bool
|
||||||
|
@ -519,7 +519,7 @@ def get_messages_with_usermessage_rows_for_user(
|
||||||
).values_list("message_id", flat=True)
|
).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(
|
display_recipient: List[UserDisplayRecipient] = get_display_recipient_by_id(
|
||||||
recipient_id,
|
recipient_id,
|
||||||
Recipient.DIRECT_MESSAGE_GROUP,
|
Recipient.DIRECT_MESSAGE_GROUP,
|
||||||
|
@ -624,7 +624,7 @@ def extract_unread_data_from_um_rows(
|
||||||
stream_dict: Dict[int, RawUnreadStreamDict] = {}
|
stream_dict: Dict[int, RawUnreadStreamDict] = {}
|
||||||
muted_stream_ids: Set[int] = set()
|
muted_stream_ids: Set[int] = set()
|
||||||
unmuted_stream_msgs: 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()
|
mentions: Set[int] = set()
|
||||||
total_unreads = 0
|
total_unreads = 0
|
||||||
|
|
||||||
|
@ -633,7 +633,7 @@ def extract_unread_data_from_um_rows(
|
||||||
stream_dict=stream_dict,
|
stream_dict=stream_dict,
|
||||||
muted_stream_ids=muted_stream_ids,
|
muted_stream_ids=muted_stream_ids,
|
||||||
unmuted_stream_msgs=unmuted_stream_msgs,
|
unmuted_stream_msgs=unmuted_stream_msgs,
|
||||||
huddle_dict=huddle_dict,
|
huddle_dict=direct_message_group_dict,
|
||||||
mentions=mentions,
|
mentions=mentions,
|
||||||
old_unreads_missing=False,
|
old_unreads_missing=False,
|
||||||
)
|
)
|
||||||
|
@ -668,14 +668,14 @@ def extract_unread_data_from_um_rows(
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
huddle_cache: Dict[int, str] = {}
|
direct_message_group_cache: Dict[int, str] = {}
|
||||||
|
|
||||||
def get_huddle_users(recipient_id: int) -> str:
|
def get_direct_message_group_users(recipient_id: int) -> str:
|
||||||
if recipient_id in huddle_cache:
|
if recipient_id in direct_message_group_cache:
|
||||||
return huddle_cache[recipient_id]
|
return direct_message_group_cache[recipient_id]
|
||||||
|
|
||||||
user_ids_string = huddle_users(recipient_id)
|
user_ids_string = direct_message_group_users(recipient_id)
|
||||||
huddle_cache[recipient_id] = user_ids_string
|
direct_message_group_cache[recipient_id] = user_ids_string
|
||||||
return user_ids_string
|
return user_ids_string
|
||||||
|
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
@ -706,8 +706,8 @@ def extract_unread_data_from_um_rows(
|
||||||
)
|
)
|
||||||
|
|
||||||
elif msg_type == Recipient.DIRECT_MESSAGE_GROUP:
|
elif msg_type == Recipient.DIRECT_MESSAGE_GROUP:
|
||||||
user_ids_string = get_huddle_users(recipient_id)
|
user_ids_string = get_direct_message_group_users(recipient_id)
|
||||||
huddle_dict[message_id] = dict(
|
direct_message_group_dict[message_id] = dict(
|
||||||
user_ids_string=user_ids_string,
|
user_ids_string=user_ids_string,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -791,12 +791,14 @@ def aggregate_pms(
|
||||||
return [lookup_dict[k] for k in sorted_keys]
|
return [lookup_dict[k] for k in sorted_keys]
|
||||||
|
|
||||||
|
|
||||||
def aggregate_huddles(*, input_dict: Dict[int, RawUnreadHuddleDict]) -> List[UnreadHuddleInfo]:
|
def aggregate_direct_message_groups(
|
||||||
lookup_dict: Dict[str, UnreadHuddleInfo] = {}
|
*, input_dict: Dict[int, RawUnreadDirectMessageGroupDict]
|
||||||
|
) -> List[UnreadDirectMessageGroupInfo]:
|
||||||
|
lookup_dict: Dict[str, UnreadDirectMessageGroupInfo] = {}
|
||||||
for message_id, attribute_dict in input_dict.items():
|
for message_id, attribute_dict in input_dict.items():
|
||||||
user_ids_string = attribute_dict["user_ids_string"]
|
user_ids_string = attribute_dict["user_ids_string"]
|
||||||
if user_ids_string not in lookup_dict:
|
if user_ids_string not in lookup_dict:
|
||||||
obj = UnreadHuddleInfo(
|
obj = UnreadDirectMessageGroupInfo(
|
||||||
user_ids_string=user_ids_string,
|
user_ids_string=user_ids_string,
|
||||||
unread_message_ids=[],
|
unread_message_ids=[],
|
||||||
)
|
)
|
||||||
|
@ -817,19 +819,19 @@ def aggregate_unread_data(raw_data: RawUnreadMessagesResult) -> UnreadMessagesRe
|
||||||
pm_dict = raw_data["pm_dict"]
|
pm_dict = raw_data["pm_dict"]
|
||||||
stream_dict = raw_data["stream_dict"]
|
stream_dict = raw_data["stream_dict"]
|
||||||
unmuted_stream_msgs = raw_data["unmuted_stream_msgs"]
|
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"])
|
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)
|
pm_objects = aggregate_pms(input_dict=pm_dict)
|
||||||
stream_objects = aggregate_streams(input_dict=stream_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(
|
result: UnreadMessagesResult = dict(
|
||||||
pms=pm_objects,
|
pms=pm_objects,
|
||||||
streams=stream_objects,
|
streams=stream_objects,
|
||||||
huddles=huddle_objects,
|
huddles=direct_message_groups,
|
||||||
mentions=mentions,
|
mentions=mentions,
|
||||||
count=count,
|
count=count,
|
||||||
old_unreads_missing=raw_data["old_unreads_missing"],
|
old_unreads_missing=raw_data["old_unreads_missing"],
|
||||||
|
@ -892,7 +894,7 @@ def apply_unread_message_event(
|
||||||
user_ids = sorted(user_ids)
|
user_ids = sorted(user_ids)
|
||||||
user_ids_string = ",".join(str(uid) for uid in 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,
|
user_ids_string=user_ids_string,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -993,7 +995,7 @@ def add_message_to_unread_msgs(
|
||||||
else:
|
else:
|
||||||
user_ids.append(my_user_id)
|
user_ids.append(my_user_id)
|
||||||
user_ids_string = ",".join(str(user_id) for user_id in sorted(user_ids))
|
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,
|
user_ids_string=user_ids_string,
|
||||||
)
|
)
|
||||||
elif message_details["type"] == "stream":
|
elif message_details["type"] == "stream":
|
||||||
|
|
|
@ -648,7 +648,7 @@ class NarrowBuilder:
|
||||||
)
|
)
|
||||||
return query.where(maybe_negate(cond))
|
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 = [
|
self_recipient_ids = [
|
||||||
recipient_tuple["recipient_id"]
|
recipient_tuple["recipient_id"]
|
||||||
for recipient_tuple in Subscription.objects.filter(
|
for recipient_tuple in Subscription.objects.filter(
|
||||||
|
@ -693,7 +693,9 @@ class NarrowBuilder:
|
||||||
return query.where(maybe_negate(cond))
|
return query.where(maybe_negate(cond))
|
||||||
|
|
||||||
# all direct messages including another person (group and 1:1)
|
# 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
|
self_recipient_id = self.user_profile.recipient_id
|
||||||
# See note above in `by_dm` about needing bidirectional messages
|
# 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,
|
column("recipient_id", Integer) == narrow_user_profile.recipient_id,
|
||||||
),
|
),
|
||||||
and_(
|
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:
|
except UserProfile.DoesNotExist:
|
||||||
raise BadNarrowOperatorError("unknown user " + str(operand))
|
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_(
|
cond = and_(
|
||||||
column("flags", Integer).op("&")(UserMessage.flags.is_private.mask) != 0,
|
column("flags", Integer).op("&")(UserMessage.flags.is_private.mask) != 0,
|
||||||
column("realm_id", Integer) == self.realm.id,
|
column("realm_id", Integer) == self.realm.id,
|
||||||
|
|
|
@ -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.display_recipient import get_display_recipient
|
||||||
from zerver.lib.emoji_utils import hex_codepoint_to_emoji
|
from zerver.lib.emoji_utils import hex_codepoint_to_emoji
|
||||||
from zerver.lib.exceptions import ErrorCode, JsonableError
|
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.notification_data import get_mentioned_user_group
|
||||||
from zerver.lib.remote_server import (
|
from zerver.lib.remote_server import (
|
||||||
record_push_notifications_recently_working,
|
record_push_notifications_recently_working,
|
||||||
|
@ -1006,7 +1006,7 @@ def get_message_payload(
|
||||||
data["topic"] = message.topic_name()
|
data["topic"] = message.topic_name()
|
||||||
elif message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
|
elif message.recipient.type == Recipient.DIRECT_MESSAGE_GROUP:
|
||||||
data["recipient_type"] = "private"
|
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
|
else: # Recipient.PERSONAL
|
||||||
data["recipient_type"] = "private"
|
data["recipient_type"] = "private"
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,10 @@ from django.core.exceptions import ValidationError
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from zerver.models import Huddle, Recipient, UserProfile
|
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
|
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,
|
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
|
recipient_profiles_map[sender.id] = sender
|
||||||
|
|
||||||
user_ids = list(recipient_profiles_map)
|
user_ids = list(recipient_profiles_map)
|
||||||
if create:
|
if create:
|
||||||
huddle = get_or_create_huddle(user_ids)
|
direct_message_group = get_or_create_direct_message_group(user_ids)
|
||||||
else:
|
else:
|
||||||
# We intentionally let the Huddle.DoesNotExist escape, in the
|
# We intentionally let the Huddle.DoesNotExist escape, in the
|
||||||
# case that there is no such huddle, and the user passed
|
# case that there is no such direct message group, and the user
|
||||||
# create=False
|
# passed create=False
|
||||||
huddle = Huddle.objects.get(huddle_hash=get_huddle_hash(user_ids))
|
direct_message_group = Huddle.objects.get(
|
||||||
|
huddle_hash=get_direct_message_group_hash(user_ids)
|
||||||
|
)
|
||||||
return Recipient(
|
return Recipient(
|
||||||
id=huddle.recipient_id,
|
id=direct_message_group.recipient_id,
|
||||||
type=Recipient.DIRECT_MESSAGE_GROUP,
|
type=Recipient.DIRECT_MESSAGE_GROUP,
|
||||||
type_id=huddle.id,
|
type_id=direct_message_group.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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,
|
realm: Realm,
|
||||||
chunk_size: int = MESSAGE_BATCH_SIZE,
|
chunk_size: int = MESSAGE_BATCH_SIZE,
|
||||||
) -> int:
|
) -> int:
|
||||||
|
@ -226,7 +226,7 @@ def move_expired_personal_and_huddle_messages_to_archive(
|
||||||
|
|
||||||
recipient_types = (Recipient.PERSONAL, Recipient.DIRECT_MESSAGE_GROUP)
|
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
|
# Uses index: zerver_message_realm_recipient_date_sent
|
||||||
query = SQL(
|
query = SQL(
|
||||||
"""
|
"""
|
||||||
|
@ -356,11 +356,9 @@ def archive_messages_by_recipient(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def archive_personal_and_huddle_messages(
|
def archive_direct_messages(realm: Realm, chunk_size: int = MESSAGE_BATCH_SIZE) -> None:
|
||||||
realm: Realm, chunk_size: int = MESSAGE_BATCH_SIZE
|
logger.info("Archiving personal and group direct messages for realm %s", realm.string_id)
|
||||||
) -> None:
|
message_count = move_expired_direct_messages_to_archive(realm, chunk_size)
|
||||||
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)
|
|
||||||
logger.info("Done. Archived %s messages", message_count)
|
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():
|
for realm, streams in get_realms_and_streams_for_archiving():
|
||||||
archive_stream_messages(realm, streams, chunk_size=STREAM_MESSAGE_BATCH_SIZE)
|
archive_stream_messages(realm, streams, chunk_size=STREAM_MESSAGE_BATCH_SIZE)
|
||||||
if realm.message_retention_days != -1:
|
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:
|
# Messages have been archived for the realm, now we can clean up attachments:
|
||||||
delete_expired_attachments(realm)
|
delete_expired_attachments(realm)
|
||||||
|
|
|
@ -1095,7 +1095,7 @@ Output:
|
||||||
)
|
)
|
||||||
return sent_message_result.message_id
|
return sent_message_result.message_id
|
||||||
|
|
||||||
def send_huddle_message(
|
def send_group_direct_message(
|
||||||
self,
|
self,
|
||||||
from_user: UserProfile,
|
from_user: UserProfile,
|
||||||
to_users: List[UserProfile],
|
to_users: List[UserProfile],
|
||||||
|
@ -1980,7 +1980,7 @@ Output:
|
||||||
|
|
||||||
self.send_personal_message(polonius, prospero)
|
self.send_personal_message(polonius, prospero)
|
||||||
self.send_personal_message(shiva, polonius)
|
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)
|
members_group = NamedUserGroup.objects.get(name="role:members", realm=realm)
|
||||||
do_change_realm_permission_group_setting(
|
do_change_realm_permission_group_setting(
|
||||||
|
@ -2069,7 +2069,7 @@ class ZulipTestCase(ZulipTestCaseMixin, TestCase):
|
||||||
return message_id
|
return message_id
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def send_huddle_message(
|
def send_group_direct_message(
|
||||||
self,
|
self,
|
||||||
from_user: UserProfile,
|
from_user: UserProfile,
|
||||||
to_users: List[UserProfile],
|
to_users: List[UserProfile],
|
||||||
|
@ -2078,7 +2078,7 @@ class ZulipTestCase(ZulipTestCaseMixin, TestCase):
|
||||||
read_by_sender: bool = True,
|
read_by_sender: bool = True,
|
||||||
skip_capture_on_commit_callbacks: bool = False,
|
skip_capture_on_commit_callbacks: bool = False,
|
||||||
) -> int:
|
) -> 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
|
defined in 'ZulipTestCaseMixin' with an extra parameter
|
||||||
'skip_capture_on_commit_callbacks'.
|
'skip_capture_on_commit_callbacks'.
|
||||||
|
|
||||||
|
@ -2087,12 +2087,12 @@ class ZulipTestCase(ZulipTestCaseMixin, TestCase):
|
||||||
because they already have 'self.captureOnCommitCallbacks'
|
because they already have 'self.captureOnCommitCallbacks'
|
||||||
(See the comment in 'capture_send_event_calls').
|
(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
|
'self.captureOnCommitCallbacks' for 'send_event_on_commit' or/and
|
||||||
'queue_event_on_commit' to work.
|
'queue_event_on_commit' to work.
|
||||||
"""
|
"""
|
||||||
if skip_capture_on_commit_callbacks:
|
if skip_capture_on_commit_callbacks:
|
||||||
message_id = super().send_huddle_message(
|
message_id = super().send_group_direct_message(
|
||||||
from_user,
|
from_user,
|
||||||
to_users,
|
to_users,
|
||||||
content,
|
content,
|
||||||
|
@ -2100,7 +2100,7 @@ class ZulipTestCase(ZulipTestCaseMixin, TestCase):
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
with self.captureOnCommitCallbacks(execute=True):
|
with self.captureOnCommitCallbacks(execute=True):
|
||||||
message_id = super().send_huddle_message(
|
message_id = super().send_group_direct_message(
|
||||||
from_user,
|
from_user,
|
||||||
to_users,
|
to_users,
|
||||||
content,
|
content,
|
||||||
|
|
|
@ -28,7 +28,9 @@ def personal_narrow_url(*, realm: Realm, sender: UserProfile) -> str:
|
||||||
return base_url + pm_slug
|
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
|
realm = user.realm
|
||||||
other_user_ids = [r["id"] for r in display_recipient if r["id"] != user.id]
|
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"
|
pm_slug = ",".join(str(user_id) for user_id in sorted(other_user_ids)) + "-group"
|
||||||
|
|
|
@ -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)
|
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(
|
users_sharing_any_subscription = get_subscribers_of_target_user_subscriptions([target_user])
|
||||||
[target_user]
|
|
||||||
)
|
|
||||||
users_involved_in_dms_dict = get_users_involved_in_dms_with_target_users([target_user], realm)
|
users_involved_in_dms_dict = get_users_involved_in_dms_with_target_users([target_user], realm)
|
||||||
|
|
||||||
user_ids_who_can_access_target_user = (
|
user_ids_who_can_access_target_user = (
|
||||||
{target_user.id}
|
{target_user.id}
|
||||||
| set(active_non_guest_user_ids_in_realm)
|
| 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]
|
| users_involved_in_dms_dict[target_user.id]
|
||||||
)
|
)
|
||||||
return list(user_ids_who_can_access_target_user)
|
return list(user_ids_who_can_access_target_user)
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django.utils.translation import override as override_language
|
||||||
|
|
||||||
from zerver.actions.message_send import (
|
from zerver.actions.message_send import (
|
||||||
do_send_messages,
|
do_send_messages,
|
||||||
internal_prep_huddle_message,
|
internal_prep_group_direct_message,
|
||||||
internal_prep_stream_message,
|
internal_prep_stream_message,
|
||||||
)
|
)
|
||||||
from zerver.lib.message import SendMessageRequest, remove_single_newlines
|
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",
|
organization_settings_url="/#organization/organization-settings",
|
||||||
move_content_another_stream_help_url="/help/move-content-to-another-channel",
|
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
|
realm, sender, remove_single_newlines(content), recipient_users=administrators
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ from zerver.lib.management import ZulipBaseCommand
|
||||||
from zerver.lib.soft_deactivation import reactivate_user_if_soft_deactivated
|
from zerver.lib.soft_deactivation import reactivate_user_if_soft_deactivated
|
||||||
from zerver.lib.upload import save_attachment_contents
|
from zerver.lib.upload import save_attachment_contents
|
||||||
from zerver.models import AbstractUserMessage, Attachment, Message, Recipient, Stream, UserProfile
|
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
|
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
|
recipient=user_b.recipient, sender=user_a
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
huddle = get_or_create_huddle([user.id for user in user_profiles])
|
direct_message_group = get_or_create_direct_message_group(
|
||||||
limits &= Q(recipient=huddle.recipient)
|
[user.id for user in user_profiles]
|
||||||
|
)
|
||||||
|
limits &= Q(recipient=direct_message_group.recipient)
|
||||||
|
|
||||||
attachments_written: Set[str] = set()
|
attachments_written: Set[str] = set()
|
||||||
messages_query = Message.objects.filter(limits, realm=realm).order_by("date_sent")
|
messages_query = Message.objects.filter(limits, realm=realm).order_by("date_sent")
|
||||||
|
|
|
@ -73,7 +73,7 @@ class Recipient(models.Model):
|
||||||
return self._type_names[self.type]
|
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
|
from zerver.models import Subscription
|
||||||
|
|
||||||
assert recipient.type == Recipient.DIRECT_MESSAGE_GROUP
|
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
|
Takes a list of huddle-type recipient_ids, returns a dict
|
||||||
mapping recipient id to list of user ids in the huddle.
|
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)
|
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))
|
id_list = sorted(set(id_list))
|
||||||
hash_key = ",".join(str(x) for x in id_list)
|
hash_key = ",".join(str(x) for x in id_list)
|
||||||
return hashlib.sha1(hash_key.encode()).hexdigest()
|
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
|
Takes a list of user IDs and returns the Huddle object for the
|
||||||
group consisting of these users. If the Huddle object does not
|
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
|
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():
|
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:
|
if created:
|
||||||
recipient = Recipient.objects.create(
|
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
|
direct_message_group.recipient = recipient
|
||||||
huddle.save(update_fields=["recipient"])
|
direct_message_group.save(update_fields=["recipient"])
|
||||||
subs_to_create = [
|
subs_to_create = [
|
||||||
Subscription(
|
Subscription(
|
||||||
recipient=recipient,
|
recipient=recipient,
|
||||||
|
@ -167,4 +169,4 @@ def get_or_create_huddle(id_list: List[int]) -> Huddle:
|
||||||
.values_list("id", "is_active")
|
.values_list("id", "is_active")
|
||||||
]
|
]
|
||||||
Subscription.objects.bulk_create(subs_to_create)
|
Subscription.objects.bulk_create(subs_to_create)
|
||||||
return huddle
|
return direct_message_group
|
||||||
|
|
|
@ -1039,7 +1039,7 @@ class TestMissedMessageEmailMessages(ZulipTestCase):
|
||||||
self.assertEqual(message.recipient.type_id, user_profile.id)
|
self.assertEqual(message.recipient.type_id, user_profile.id)
|
||||||
self.assertEqual(message.recipient.type, Recipient.PERSONAL)
|
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.
|
# Build dummy messages for message notification email reply.
|
||||||
# Have Othello send Iago and Cordelia a group direct message.
|
# Have Othello send Iago and Cordelia a group direct message.
|
||||||
# Cordelia will reply via email Iago and Othello will receive
|
# 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)
|
mm_address = create_missed_message_address(user_profile, usermessage.message)
|
||||||
|
|
||||||
incoming_valid_message = EmailMessage()
|
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["From"] = self.example_email("cordelia")
|
||||||
incoming_valid_message["To"] = mm_address
|
incoming_valid_message["To"] = mm_address
|
||||||
incoming_valid_message["Reply-to"] = self.example_email("cordelia")
|
incoming_valid_message["Reply-to"] = self.example_email("cordelia")
|
||||||
|
@ -1079,7 +1079,7 @@ class TestMissedMessageEmailMessages(ZulipTestCase):
|
||||||
user_profile = self.example_user("iago")
|
user_profile = self.example_user("iago")
|
||||||
message = most_recent_message(user_profile)
|
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.sender, self.example_user("cordelia"))
|
||||||
self.assertEqual(message.recipient.type, Recipient.DIRECT_MESSAGE_GROUP)
|
self.assertEqual(message.recipient.type, Recipient.DIRECT_MESSAGE_GROUP)
|
||||||
|
|
||||||
|
@ -1087,7 +1087,7 @@ class TestMissedMessageEmailMessages(ZulipTestCase):
|
||||||
user_profile = self.example_user("othello")
|
user_profile = self.example_user("othello")
|
||||||
message = most_recent_message(user_profile)
|
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.sender, self.example_user("cordelia"))
|
||||||
self.assertEqual(message.recipient.type, Recipient.DIRECT_MESSAGE_GROUP)
|
self.assertEqual(message.recipient.type, Recipient.DIRECT_MESSAGE_GROUP)
|
||||||
|
|
||||||
|
|
|
@ -598,14 +598,17 @@ class NormalActionsTest(BaseAction):
|
||||||
is_embedded_update_only=False,
|
is_embedded_update_only=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_huddle_send_message_events(self) -> None:
|
def test_direct_message_group_send_message_events(self) -> None:
|
||||||
huddle = [
|
direct_message_group = [
|
||||||
self.example_user("hamlet"),
|
self.example_user("hamlet"),
|
||||||
self.example_user("othello"),
|
self.example_user("othello"),
|
||||||
]
|
]
|
||||||
with self.verify_action():
|
with self.verify_action():
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
self.example_user("cordelia"), huddle, "hola", skip_capture_on_commit_callbacks=True
|
self.example_user("cordelia"),
|
||||||
|
direct_message_group,
|
||||||
|
"hola",
|
||||||
|
skip_capture_on_commit_callbacks=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_user_creation_events_on_sending_messages(self) -> None:
|
def test_user_creation_events_on_sending_messages(self) -> None:
|
||||||
|
@ -634,7 +637,7 @@ class NormalActionsTest(BaseAction):
|
||||||
desdemona = self.example_user("desdemona")
|
desdemona = self.example_user("desdemona")
|
||||||
|
|
||||||
with self.verify_action(num_events=3) as events:
|
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
|
othello, [polonius, desdemona, bot], "hola", skip_capture_on_commit_callbacks=True
|
||||||
)
|
)
|
||||||
check_realm_user_add("events[0]", events[0])
|
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])
|
do_update_message_flags(user_profile, "remove", "read", [personal_message])
|
||||||
check_update_message_flags_remove("events[0]", events[0])
|
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"),
|
from_user=self.example_user("cordelia"),
|
||||||
to_users=[user_profile, self.example_user("othello")],
|
to_users=[user_profile, self.example_user("othello")],
|
||||||
content=content,
|
content=content,
|
||||||
)
|
)
|
||||||
|
|
||||||
with self.verify_action(state_change_expected=True):
|
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:
|
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])
|
check_update_message_flags_remove("events[0]", events[0])
|
||||||
|
|
||||||
def test_send_message_to_existing_recipient(self) -> None:
|
def test_send_message_to_existing_recipient(self) -> None:
|
||||||
|
|
|
@ -90,7 +90,7 @@ from zerver.models.clients import get_client
|
||||||
from zerver.models.groups import SystemGroups
|
from zerver.models.groups import SystemGroups
|
||||||
from zerver.models.presence import PresenceSequence
|
from zerver.models.presence import PresenceSequence
|
||||||
from zerver.models.realms import get_realm
|
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.streams import get_active_streams, get_stream
|
||||||
from zerver.models.users import get_system_bot, get_user_by_delivery_email
|
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
|
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"
|
cordelia_full_name = "Cordelia, Lear's daughter"
|
||||||
hamlet_full_name = "King Hamlet"
|
hamlet_full_name = "King Hamlet"
|
||||||
othello_full_name = "Othello, the Moor of Venice"
|
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),
|
get_user_id(r, othello_full_name),
|
||||||
]
|
]
|
||||||
|
|
||||||
huddle_hash = get_huddle_hash(user_id_list)
|
direct_message_group_hash = get_direct_message_group_hash(user_id_list)
|
||||||
return huddle_hash
|
return direct_message_group_hash
|
||||||
|
|
||||||
|
|
||||||
class ExportFile(ZulipTestCase):
|
class ExportFile(ZulipTestCase):
|
||||||
|
@ -584,18 +584,18 @@ class RealmImportExportTest(ExportFile):
|
||||||
self.subscribe(self.example_user("hamlet"), "Private D")
|
self.subscribe(self.example_user("hamlet"), "Private D")
|
||||||
self.send_stream_message(self.example_user("prospero"), "Private D", "Hello again stream D")
|
self.send_stream_message(self.example_user("prospero"), "Private D", "Hello again stream D")
|
||||||
|
|
||||||
# Create huddles
|
# Create direct message groups
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
self.example_user("iago"), [self.example_user("cordelia"), self.example_user("AARON")]
|
self.example_user("iago"), [self.example_user("cordelia"), self.example_user("AARON")]
|
||||||
)
|
)
|
||||||
huddle_a = Huddle.objects.last()
|
direct_message_group_a = Huddle.objects.last()
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
self.example_user("ZOE"),
|
self.example_user("ZOE"),
|
||||||
[self.example_user("hamlet"), self.example_user("AARON"), self.example_user("othello")],
|
[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("AARON"),
|
||||||
[self.example_user("cordelia"), self.example_user("ZOE"), self.example_user("othello")],
|
[self.example_user("cordelia"), self.example_user("ZOE"), self.example_user("othello")],
|
||||||
)
|
)
|
||||||
|
@ -720,13 +720,17 @@ class RealmImportExportTest(ExportFile):
|
||||||
.values_list("id", flat=True)
|
.values_list("id", flat=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Third huddle is not exported since none of the members gave consent
|
# Third direct message group is not exported since none of
|
||||||
assert huddle_a is not None and huddle_b is not None
|
# the members gave consent
|
||||||
huddle_recipients = Recipient.objects.filter(
|
assert direct_message_group_a is not None and direct_message_group_b is not None
|
||||||
type_id__in=[huddle_a.id, huddle_b.id], type=Recipient.DIRECT_MESSAGE_GROUP
|
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)
|
pm_query = Q(recipient__in=direct_message_group_recipients) | Q(
|
||||||
exported_huddle_ids = (
|
sender__in=consented_user_ids
|
||||||
|
)
|
||||||
|
exported_direct_message_group_ids = (
|
||||||
Message.objects.filter(pm_query, realm=realm.id)
|
Message.objects.filter(pm_query, realm=realm.id)
|
||||||
.values_list("id", flat=True)
|
.values_list("id", flat=True)
|
||||||
.values_list("id", flat=True)
|
.values_list("id", flat=True)
|
||||||
|
@ -737,14 +741,14 @@ class RealmImportExportTest(ExportFile):
|
||||||
*private_stream_message_ids,
|
*private_stream_message_ids,
|
||||||
stream_b_second_message_id,
|
stream_b_second_message_id,
|
||||||
*exported_pm_ids,
|
*exported_pm_ids,
|
||||||
*exported_huddle_ids,
|
*exported_direct_message_group_ids,
|
||||||
}
|
}
|
||||||
self.assertEqual(self.get_set(data["zerver_message"], "id"), exported_msg_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_b_first_message_id, exported_msg_ids)
|
||||||
|
|
||||||
self.assertNotIn(stream_c_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.assertNotIn(pm_a_msg_id, exported_msg_ids)
|
||||||
self.assertIn(pm_b_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
|
modified_user=hamlet, event_type=RealmAuditLog.USER_CREATED
|
||||||
).update(acting_user_id=cross_realm_bot.id)
|
).update(acting_user_id=cross_realm_bot.id)
|
||||||
|
|
||||||
# data to test import of huddles
|
# data to test import of direct message groups
|
||||||
huddle = [
|
direct_message_group = [
|
||||||
self.example_user("hamlet"),
|
self.example_user("hamlet"),
|
||||||
self.example_user("othello"),
|
self.example_user("othello"),
|
||||||
]
|
]
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
self.example_user("cordelia"),
|
self.example_user("cordelia"),
|
||||||
huddle,
|
direct_message_group,
|
||||||
"test huddle message",
|
"test group direct message",
|
||||||
)
|
)
|
||||||
|
|
||||||
user_mention_message = "@**King Hamlet** Hello"
|
user_mention_message = "@**King Hamlet** Hello"
|
||||||
|
@ -991,8 +995,12 @@ class RealmImportExportTest(ExportFile):
|
||||||
|
|
||||||
self.verify_emoji_code_foreign_keys()
|
self.verify_emoji_code_foreign_keys()
|
||||||
|
|
||||||
# Our huddle hashes change, because hashes use ids that change.
|
# Our direct message group hashes change, because hashes
|
||||||
self.assertNotEqual(get_huddle_hashes(original_realm), get_huddle_hashes(imported_realm))
|
# 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
|
# test to highlight that bs4 which we use to do data-**id
|
||||||
# replacements modifies the HTML sometimes. eg replacing <br>
|
# 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,
|
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.
|
# Huddles don't have a realm column, so we just test all Huddles for simplicity.
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
huddle_object.recipient_id,
|
dm_group.recipient_id,
|
||||||
Recipient.objects.get(
|
Recipient.objects.get(type=Recipient.DIRECT_MESSAGE_GROUP, type_id=dm_group.id).id,
|
||||||
type=Recipient.DIRECT_MESSAGE_GROUP, type_id=huddle_object.id
|
|
||||||
).id,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(ScheduledMessage.objects.filter(realm=imported_realm).count(), 1)
|
self.assertEqual(ScheduledMessage.objects.filter(realm=imported_realm).count(), 1)
|
||||||
|
@ -1268,13 +1274,15 @@ class RealmImportExportTest(ExportFile):
|
||||||
return realmauditlog_event_type
|
return realmauditlog_event_type
|
||||||
|
|
||||||
@getter
|
@getter
|
||||||
def get_huddle_message(r: Realm) -> str:
|
def get_group_direct_message(r: Realm) -> str:
|
||||||
huddle_hash = get_huddle_hashes(r)
|
direct_message_group_hash = get_direct_message_group_hashes(r)
|
||||||
huddle_id = Huddle.objects.get(huddle_hash=huddle_hash).id
|
direct_message_group_id = Huddle.objects.get(huddle_hash=direct_message_group_hash).id
|
||||||
huddle_recipient = Recipient.objects.get(type_id=huddle_id, type=3)
|
direct_message_group_recipient = Recipient.objects.get(
|
||||||
huddle_message = Message.objects.get(recipient=huddle_recipient)
|
type_id=direct_message_group_id, type=3
|
||||||
self.assertEqual(huddle_message.content, "test huddle message")
|
)
|
||||||
return huddle_message.content
|
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
|
@getter
|
||||||
def get_alertwords(r: Realm) -> Set[str]:
|
def get_alertwords(r: Realm) -> Set[str]:
|
||||||
|
@ -1883,12 +1891,16 @@ class SingleUserExportTest(ExportFile):
|
||||||
|
|
||||||
# Try to fool the export again
|
# Try to fool the export again
|
||||||
self.send_personal_message(othello, hamlet)
|
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_hamlet_message_id = self.send_personal_message(cordelia, hamlet, "hi hamlet")
|
||||||
|
|
||||||
hi_peeps_message_id = self.send_huddle_message(cordelia, [hamlet, othello], "hi peeps")
|
hi_peeps_message_id = self.send_group_direct_message(
|
||||||
bye_peeps_message_id = self.send_huddle_message(othello, [cordelia, hamlet], "bye peeps")
|
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")
|
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")
|
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 = [
|
excerpt = [
|
||||||
(rec["id"], rec["content"], rec["recipient_name"])
|
(rec["id"], rec["content"], rec["recipient_name"])
|
||||||
|
@ -1915,8 +1929,8 @@ class SingleUserExportTest(ExportFile):
|
||||||
(smile_message_id, "SMILE!", "Denmark"),
|
(smile_message_id, "SMILE!", "Denmark"),
|
||||||
(hi_stream_message_id, "hi stream", "Denmark"),
|
(hi_stream_message_id, "hi stream", "Denmark"),
|
||||||
(hi_hamlet_message_id, "hi hamlet", hamlet.full_name),
|
(hi_hamlet_message_id, "hi hamlet", hamlet.full_name),
|
||||||
(hi_peeps_message_id, "hi peeps", huddle_name),
|
(hi_peeps_message_id, "hi peeps", direct_message_group_name),
|
||||||
(bye_peeps_message_id, "bye peeps", huddle_name),
|
(bye_peeps_message_id, "bye peeps", direct_message_group_name),
|
||||||
(bye_hamlet_message_id, "bye hamlet", hamlet.full_name),
|
(bye_hamlet_message_id, "bye hamlet", hamlet.full_name),
|
||||||
(hi_myself_message_id, "hi myself", cordelia.full_name),
|
(hi_myself_message_id, "hi myself", cordelia.full_name),
|
||||||
(bye_stream_message_id, "bye stream", "Denmark"),
|
(bye_stream_message_id, "bye stream", "Denmark"),
|
||||||
|
|
|
@ -10,11 +10,11 @@ from zerver.data_import.mattermost import (
|
||||||
build_reactions,
|
build_reactions,
|
||||||
check_user_in_team,
|
check_user_in_team,
|
||||||
convert_channel_data,
|
convert_channel_data,
|
||||||
convert_huddle_data,
|
convert_direct_message_group_data,
|
||||||
convert_user_data,
|
convert_user_data,
|
||||||
create_username_to_user_mapping,
|
create_username_to_user_mapping,
|
||||||
do_convert_data,
|
do_convert_data,
|
||||||
generate_huddle_name,
|
generate_direct_message_group_name,
|
||||||
get_mentioned_user_ids,
|
get_mentioned_user_ids,
|
||||||
label_mirror_dummy_users,
|
label_mirror_dummy_users,
|
||||||
mattermost_data_file_to_dict,
|
mattermost_data_file_to_dict,
|
||||||
|
@ -336,7 +336,7 @@ class MatterMostImporter(ZulipTestCase):
|
||||||
{malfoy_id, pansy_id},
|
{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(
|
fixture_file_name = self.fixture_file_name(
|
||||||
"export.json", "mattermost_fixtures/direct_channel"
|
"export.json", "mattermost_fixtures/direct_channel"
|
||||||
)
|
)
|
||||||
|
@ -358,8 +358,8 @@ class MatterMostImporter(ZulipTestCase):
|
||||||
team_name=team_name,
|
team_name=team_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
zerver_huddle = convert_huddle_data(
|
zerver_huddle = convert_direct_message_group_data(
|
||||||
huddle_data=mattermost_data["direct_channel"],
|
direct_message_group_data=mattermost_data["direct_channel"],
|
||||||
user_data_map=username_to_user,
|
user_data_map=username_to_user,
|
||||||
subscriber_handler=subscriber_handler,
|
subscriber_handler=subscriber_handler,
|
||||||
huddle_id_mapper=huddle_id_mapper,
|
huddle_id_mapper=huddle_id_mapper,
|
||||||
|
@ -369,12 +369,15 @@ class MatterMostImporter(ZulipTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assert_length(zerver_huddle, 1)
|
self.assert_length(zerver_huddle, 1)
|
||||||
huddle_members = mattermost_data["direct_channel"][1]["members"]
|
direct_message_group_members = mattermost_data["direct_channel"][1]["members"]
|
||||||
huddle_name = generate_huddle_name(huddle_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(
|
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:
|
def test_write_emoticon_data(self) -> None:
|
||||||
|
@ -669,8 +672,8 @@ class MatterMostImporter(ZulipTestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
warn_log.output,
|
warn_log.output,
|
||||||
[
|
[
|
||||||
"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 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",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -871,14 +874,16 @@ class MatterMostImporter(ZulipTestCase):
|
||||||
self.assertFalse(stream_messages[3].has_image)
|
self.assertFalse(stream_messages[3].has_image)
|
||||||
self.assertTrue(stream_messages[3].has_link)
|
self.assertTrue(stream_messages[3].has_link)
|
||||||
|
|
||||||
huddle_messages = messages.filter(recipient__type=Recipient.DIRECT_MESSAGE_GROUP).order_by(
|
group_direct_messages = messages.filter(
|
||||||
"date_sent"
|
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(
|
personal_messages = messages.filter(recipient__type=Recipient.PERSONAL).order_by(
|
||||||
"date_sent"
|
"date_sent"
|
||||||
|
@ -909,8 +914,8 @@ class MatterMostImporter(ZulipTestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
warn_log.output,
|
warn_log.output,
|
||||||
[
|
[
|
||||||
"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 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",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -936,8 +941,8 @@ class MatterMostImporter(ZulipTestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
warn_log.output,
|
warn_log.output,
|
||||||
[
|
[
|
||||||
"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 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",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -581,14 +581,14 @@ class TestMessageForIdsDisplayRecipientFetching(ZulipTestCase):
|
||||||
self.assertEqual(messages[0]["display_recipient"], "Verona")
|
self.assertEqual(messages[0]["display_recipient"], "Verona")
|
||||||
self.assertEqual(messages[1]["display_recipient"], "Denmark")
|
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")
|
hamlet = self.example_user("hamlet")
|
||||||
cordelia = self.example_user("cordelia")
|
cordelia = self.example_user("cordelia")
|
||||||
othello = self.example_user("othello")
|
othello = self.example_user("othello")
|
||||||
iago = self.example_user("iago")
|
iago = self.example_user("iago")
|
||||||
message_ids = [
|
message_ids = [
|
||||||
self.send_huddle_message(hamlet, [cordelia, othello], "test"),
|
self.send_group_direct_message(hamlet, [cordelia, othello], "test"),
|
||||||
self.send_huddle_message(cordelia, [hamlet, othello, iago], "test"),
|
self.send_group_direct_message(cordelia, [hamlet, othello, iago], "test"),
|
||||||
]
|
]
|
||||||
|
|
||||||
messages = messages_for_ids(
|
messages = messages_for_ids(
|
||||||
|
@ -619,11 +619,11 @@ class TestMessageForIdsDisplayRecipientFetching(ZulipTestCase):
|
||||||
self.subscribe(hamlet, "Scotland")
|
self.subscribe(hamlet, "Scotland")
|
||||||
|
|
||||||
message_ids = [
|
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_stream_message(cordelia, "Verona", content="test"),
|
||||||
self.send_personal_message(hamlet, cordelia, "test"),
|
self.send_personal_message(hamlet, cordelia, "test"),
|
||||||
self.send_stream_message(cordelia, "Denmark", content="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"),
|
self.send_personal_message(cordelia, othello, "test"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ from zerver.models import (
|
||||||
UserTopic,
|
UserTopic,
|
||||||
)
|
)
|
||||||
from zerver.models.realms import get_realm
|
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.models.streams import get_stream
|
||||||
from zerver.views.message_fetch import get_messages_backend
|
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)",
|
"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
|
# If the group doesn't exist, it's a flat false
|
||||||
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
two_others = f"{self.example_user('cordelia').email},{self.example_user('othello').email}"
|
||||||
term = NarrowParameter(operator="dm", operand=two_others)
|
term = NarrowParameter(operator="dm", operand=two_others)
|
||||||
self._do_add_term_test(term, "WHERE false")
|
self._do_add_term_test(term, "WHERE false")
|
||||||
|
|
||||||
def test_add_term_using_dm_operator_more_than_one_user_as_operand(self) -> None:
|
def test_add_term_using_dm_operator_more_than_one_user_as_operand(self) -> None:
|
||||||
# Make the huddle first
|
# Make the direct message group first
|
||||||
get_or_create_huddle(
|
get_or_create_direct_message_group(
|
||||||
[
|
[
|
||||||
self.example_user("hamlet").id,
|
self.example_user("hamlet").id,
|
||||||
self.example_user("cordelia").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))",
|
"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,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
# If the group doesn't exist, it's a flat true
|
# 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(
|
def test_add_term_using_dm_operator_more_than_one_user_as_operand_and_negated(
|
||||||
self,
|
self,
|
||||||
) -> None: # NEGATED
|
) -> None: # NEGATED
|
||||||
# Make the huddle first
|
# Make the direct message group first
|
||||||
get_or_create_huddle(
|
get_or_create_direct_message_group(
|
||||||
[
|
[
|
||||||
self.example_user("hamlet").id,
|
self.example_user("hamlet").id,
|
||||||
self.example_user("cordelia").id,
|
self.example_user("cordelia").id,
|
||||||
|
@ -464,7 +466,7 @@ class NarrowBuilderTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test with at least one such group direct messages existing
|
# 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")]
|
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_personal_message(me, self.example_user("iago"))
|
||||||
|
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[self.example_user("iago"), self.example_user("cordelia")],
|
[self.example_user("iago"), self.example_user("cordelia")],
|
||||||
)
|
)
|
||||||
|
@ -2227,7 +2229,7 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
# Then deactivate Aaron to test "dm" narrow includes messages
|
# Then deactivate Aaron to test "dm" narrow includes messages
|
||||||
# from deactivated users also.
|
# from deactivated users also.
|
||||||
self.send_personal_message(me, self.example_user("aaron"))
|
self.send_personal_message(me, self.example_user("aaron"))
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[self.example_user("iago"), self.example_user("aaron")],
|
[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:
|
def test_get_messages_with_nonexistent_group_dm(self) -> None:
|
||||||
me = self.example_user("hamlet")
|
me = self.example_user("hamlet")
|
||||||
# Huddle which doesn't match anything gets no results
|
# Direct message group which doesn't match anything gets no results
|
||||||
non_existent_huddle = [
|
non_existent_direct_message_group = [
|
||||||
me.id,
|
me.id,
|
||||||
self.example_user("iago").id,
|
self.example_user("iago").id,
|
||||||
self.example_user("othello").id,
|
self.example_user("othello").id,
|
||||||
]
|
]
|
||||||
self.login_user(me)
|
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()))
|
result = self.get_and_check_messages(dict(narrow=orjson.dumps(narrow).decode()))
|
||||||
self.assertEqual(result["messages"], [])
|
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()))
|
result = self.get_and_check_messages(dict(narrow=orjson.dumps(narrow).decode()))
|
||||||
self.assertEqual([m["id"] for m in result["messages"]], [1, 3])
|
self.assertEqual([m["id"] for m in result["messages"]], [1, 3])
|
||||||
|
|
||||||
|
@ -2295,17 +2299,17 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
|
|
||||||
matching_message_ids = [
|
matching_message_ids = [
|
||||||
# group direct message, sent by current user
|
# group direct message, sent by current user
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[iago, cordelia, othello],
|
[iago, cordelia, othello],
|
||||||
),
|
),
|
||||||
# group direct message, sent by searched user
|
# group direct message, sent by searched user
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
cordelia,
|
cordelia,
|
||||||
[me, othello],
|
[me, othello],
|
||||||
),
|
),
|
||||||
# group direct message, sent by another user
|
# group direct message, sent by another user
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
othello,
|
othello,
|
||||||
[me, cordelia],
|
[me, cordelia],
|
||||||
),
|
),
|
||||||
|
@ -2323,12 +2327,12 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
# direct 1:1 message, current user to self
|
# direct 1:1 message, current user to self
|
||||||
self.send_personal_message(me, me),
|
self.send_personal_message(me, me),
|
||||||
# group direct message, sent by current user
|
# group direct message, sent by current user
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[iago, othello],
|
[iago, othello],
|
||||||
),
|
),
|
||||||
# group direct message, sent by searched user
|
# group direct message, sent by searched user
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
cordelia,
|
cordelia,
|
||||||
[iago, othello],
|
[iago, othello],
|
||||||
),
|
),
|
||||||
|
@ -2352,17 +2356,17 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
othello = self.example_user("othello")
|
othello = self.example_user("othello")
|
||||||
|
|
||||||
message_ids = [
|
message_ids = [
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[iago, cordelia, othello],
|
[iago, cordelia, othello],
|
||||||
),
|
),
|
||||||
self.send_personal_message(me, cordelia),
|
self.send_personal_message(me, cordelia),
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
cordelia,
|
cordelia,
|
||||||
[me, othello],
|
[me, othello],
|
||||||
),
|
),
|
||||||
self.send_personal_message(cordelia, me),
|
self.send_personal_message(cordelia, me),
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
iago,
|
iago,
|
||||||
[cordelia, me],
|
[cordelia, me],
|
||||||
),
|
),
|
||||||
|
@ -2383,11 +2387,11 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
othello = self.example_user("othello")
|
othello = self.example_user("othello")
|
||||||
|
|
||||||
matching_message_ids = [
|
matching_message_ids = [
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[iago, cordelia, othello],
|
[iago, cordelia, othello],
|
||||||
),
|
),
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[cordelia, othello],
|
[cordelia, othello],
|
||||||
),
|
),
|
||||||
|
@ -2395,11 +2399,11 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
|
|
||||||
non_matching_message_ids = [
|
non_matching_message_ids = [
|
||||||
self.send_personal_message(me, cordelia),
|
self.send_personal_message(me, cordelia),
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[iago, othello],
|
[iago, othello],
|
||||||
),
|
),
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
self.example_user("cordelia"),
|
self.example_user("cordelia"),
|
||||||
[iago, othello],
|
[iago, othello],
|
||||||
),
|
),
|
||||||
|
@ -2423,15 +2427,15 @@ class GetOldMessagesTest(ZulipTestCase):
|
||||||
othello = self.example_user("othello")
|
othello = self.example_user("othello")
|
||||||
|
|
||||||
message_ids = [
|
message_ids = [
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[iago, cordelia, othello],
|
[iago, cordelia, othello],
|
||||||
),
|
),
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[cordelia, othello],
|
[cordelia, othello],
|
||||||
),
|
),
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
me,
|
me,
|
||||||
[cordelia, iago],
|
[cordelia, iago],
|
||||||
),
|
),
|
||||||
|
|
|
@ -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")
|
cordelia = self.example_user("cordelia")
|
||||||
othello = self.example_user("othello")
|
othello = self.example_user("othello")
|
||||||
hamlet = self.example_user("hamlet")
|
hamlet = self.example_user("hamlet")
|
||||||
prospero = self.example_user("prospero")
|
prospero = self.example_user("prospero")
|
||||||
|
|
||||||
huddle1_message_ids = [
|
direct_message_group1_message_ids = [
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
cordelia,
|
cordelia,
|
||||||
[hamlet, othello],
|
[hamlet, othello],
|
||||||
)
|
)
|
||||||
for i in range(3)
|
for i in range(3)
|
||||||
]
|
]
|
||||||
|
|
||||||
huddle2_message_ids = [
|
direct_message_group2_message_ids = [
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
cordelia,
|
cordelia,
|
||||||
[hamlet, prospero],
|
[hamlet, prospero],
|
||||||
)
|
)
|
||||||
|
@ -1036,18 +1036,20 @@ class GetUnreadMsgsTest(ZulipTestCase):
|
||||||
user_profile=hamlet,
|
user_profile=hamlet,
|
||||||
)
|
)
|
||||||
|
|
||||||
huddle_dict = raw_unread_data["huddle_dict"]
|
direct_message_group_dict = raw_unread_data["huddle_dict"]
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
set(huddle_dict.keys()),
|
set(direct_message_group_dict.keys()),
|
||||||
set(huddle1_message_ids) | set(huddle2_message_ids),
|
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(
|
self.assertEqual(
|
||||||
huddle_dict[huddle1_message_ids[0]],
|
direct_message_group_dict[direct_message_group1_message_ids[0]],
|
||||||
dict(user_ids_string=huddle_string),
|
dict(user_ids_string=direct_message_group_string),
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_raw_unread_personal(self) -> None:
|
def test_raw_unread_personal(self) -> None:
|
||||||
|
@ -1205,7 +1207,7 @@ class GetUnreadMsgsTest(ZulipTestCase):
|
||||||
content="hello",
|
content="hello",
|
||||||
)
|
)
|
||||||
|
|
||||||
huddle_message_id = self.send_huddle_message(
|
group_direct_message_id = self.send_group_direct_message(
|
||||||
sender,
|
sender,
|
||||||
[user_profile, othello],
|
[user_profile, othello],
|
||||||
"hello3",
|
"hello3",
|
||||||
|
@ -1260,13 +1262,17 @@ class GetUnreadMsgsTest(ZulipTestCase):
|
||||||
unread_stream["unread_message_ids"], [unmuted_topic_muted_stream_message_id]
|
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])
|
str(uid) for uid in sorted([sender_id, user_profile.id, othello.id])
|
||||||
)
|
)
|
||||||
|
|
||||||
unread_huddle = result["huddles"][0]
|
unread_direct_message_group = result["huddles"][0]
|
||||||
self.assertEqual(unread_huddle["user_ids_string"], huddle_string)
|
self.assertEqual(
|
||||||
self.assertEqual(unread_huddle["unread_message_ids"], [huddle_message_id])
|
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"], [])
|
self.assertEqual(result["mentions"], [])
|
||||||
|
|
||||||
|
@ -2497,13 +2503,13 @@ class MarkUnreadTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
self.assertTrue(um.flags.read)
|
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")
|
sender = self.example_user("cordelia")
|
||||||
receiver = self.example_user("hamlet")
|
receiver = self.example_user("hamlet")
|
||||||
user1 = self.example_user("othello")
|
user1 = self.example_user("othello")
|
||||||
message_ids = [
|
message_ids = [
|
||||||
# self.send_huddle_message(sender, receiver, content="Hello") for i in range(4)
|
# self.send_group_direct_message(sender, receiver, content="Hello") for i in range(4)
|
||||||
self.send_huddle_message(sender, [receiver, user1])
|
self.send_group_direct_message(sender, [receiver, user1])
|
||||||
for i in range(4)
|
for i in range(4)
|
||||||
]
|
]
|
||||||
self.login("hamlet")
|
self.login("hamlet")
|
||||||
|
@ -2558,13 +2564,13 @@ class MarkUnreadTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
self.assertTrue(um.flags.read)
|
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")
|
sender = self.example_user("cordelia")
|
||||||
receiver = self.example_user("hamlet")
|
receiver = self.example_user("hamlet")
|
||||||
user1 = self.example_user("othello")
|
user1 = self.example_user("othello")
|
||||||
message_ids = [
|
message_ids = [
|
||||||
# self.send_huddle_message(sender, receiver, content="Hello") for i in range(4)
|
# self.send_group_direct_message(sender, receiver, content="Hello") for i in range(4)
|
||||||
self.send_huddle_message(
|
self.send_group_direct_message(
|
||||||
from_user=sender, to_users=[receiver, user1], content="@**King Hamlet**"
|
from_user=sender, to_users=[receiver, user1], content="@**King Hamlet**"
|
||||||
)
|
)
|
||||||
for i in range(4)
|
for i in range(4)
|
||||||
|
|
|
@ -544,10 +544,10 @@ class TestMessageNotificationEmails(ZulipTestCase):
|
||||||
email_subject = "DMs with Othello, the Moor of Venice"
|
email_subject = "DMs with Othello, the Moor of Venice"
|
||||||
self._test_cases(msg_id, verify_body_include, email_subject)
|
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
|
self, show_message_content: bool = True
|
||||||
) -> None:
|
) -> None:
|
||||||
msg_id = self.send_huddle_message(
|
msg_id = self.send_group_direct_message(
|
||||||
self.example_user("othello"),
|
self.example_user("othello"),
|
||||||
[
|
[
|
||||||
self.example_user("hamlet"),
|
self.example_user("hamlet"),
|
||||||
|
@ -585,8 +585,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
|
||||||
verify_body_does_not_include=verify_body_does_not_include,
|
verify_body_does_not_include=verify_body_does_not_include,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _extra_context_in_missed_huddle_messages_three_others(self) -> None:
|
def _extra_context_in_missed_group_direct_messages_three_others(self) -> None:
|
||||||
msg_id = self.send_huddle_message(
|
msg_id = self.send_group_direct_message(
|
||||||
self.example_user("othello"),
|
self.example_user("othello"),
|
||||||
[
|
[
|
||||||
self.example_user("hamlet"),
|
self.example_user("hamlet"),
|
||||||
|
@ -602,8 +602,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
|
||||||
)
|
)
|
||||||
self._test_cases(msg_id, verify_body_include, email_subject)
|
self._test_cases(msg_id, verify_body_include, email_subject)
|
||||||
|
|
||||||
def _extra_context_in_missed_huddle_messages_many_others(self) -> None:
|
def _extra_context_in_missed_group_direct_messages_many_others(self) -> None:
|
||||||
msg_id = self.send_huddle_message(
|
msg_id = self.send_group_direct_message(
|
||||||
self.example_user("othello"),
|
self.example_user("othello"),
|
||||||
[
|
[
|
||||||
self.example_user("hamlet"),
|
self.example_user("hamlet"),
|
||||||
|
@ -648,8 +648,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
|
||||||
)
|
)
|
||||||
self.assert_length(mail.outbox, 0)
|
self.assert_length(mail.outbox, 0)
|
||||||
|
|
||||||
def _deleted_message_in_missed_huddle_messages(self) -> None:
|
def _deleted_message_in_missed_group_direct_messages(self) -> None:
|
||||||
msg_id = self.send_huddle_message(
|
msg_id = self.send_group_direct_message(
|
||||||
self.example_user("othello"),
|
self.example_user("othello"),
|
||||||
[
|
[
|
||||||
self.example_user("hamlet"),
|
self.example_user("hamlet"),
|
||||||
|
@ -1042,7 +1042,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
|
||||||
show_message_content=False, message_content_disabled_by_user=True
|
show_message_content=False, message_content_disabled_by_user=True
|
||||||
)
|
)
|
||||||
mail.outbox = []
|
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:
|
def test_extra_context_in_missed_stream_messages(self) -> None:
|
||||||
self._extra_context_in_missed_stream_messages_mention()
|
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:
|
def test_extra_context_in_missed_personal_messages(self) -> None:
|
||||||
self._extra_context_in_missed_personal_messages()
|
self._extra_context_in_missed_personal_messages()
|
||||||
|
|
||||||
def test_extra_context_in_missed_huddle_messages_two_others(self) -> None:
|
def test_extra_context_in_missed_group_direct_messages_two_others(self) -> None:
|
||||||
self._extra_context_in_missed_huddle_messages_two_others()
|
self._extra_context_in_missed_group_direct_messages_two_others()
|
||||||
|
|
||||||
def test_extra_context_in_missed_huddle_messages_three_others(self) -> None:
|
def test_extra_context_in_missed_group_direct_messages_three_others(self) -> None:
|
||||||
self._extra_context_in_missed_huddle_messages_three_others()
|
self._extra_context_in_missed_group_direct_messages_three_others()
|
||||||
|
|
||||||
def test_extra_context_in_missed_huddle_messages_many_others(self) -> None:
|
def test_extra_context_in_missed_group_direct_messages_many_others(self) -> None:
|
||||||
self._extra_context_in_missed_huddle_messages_many_others()
|
self._extra_context_in_missed_group_direct_messages_many_others()
|
||||||
|
|
||||||
def test_deleted_message_in_missed_stream_messages(self) -> None:
|
def test_deleted_message_in_missed_stream_messages(self) -> None:
|
||||||
self._deleted_message_in_missed_stream_messages()
|
self._deleted_message_in_missed_stream_messages()
|
||||||
|
@ -1115,8 +1115,8 @@ class TestMessageNotificationEmails(ZulipTestCase):
|
||||||
def test_deleted_message_in_missed_personal_messages(self) -> None:
|
def test_deleted_message_in_missed_personal_messages(self) -> None:
|
||||||
self._deleted_message_in_missed_personal_messages()
|
self._deleted_message_in_missed_personal_messages()
|
||||||
|
|
||||||
def test_deleted_message_in_missed_huddle_messages(self) -> None:
|
def test_deleted_message_in_missed_group_direct_messages(self) -> None:
|
||||||
self._deleted_message_in_missed_huddle_messages()
|
self._deleted_message_in_missed_group_direct_messages()
|
||||||
|
|
||||||
def test_realm_message_content_allowed_in_email_notifications(self) -> None:
|
def test_realm_message_content_allowed_in_email_notifications(self) -> None:
|
||||||
user = self.example_user("hamlet")
|
user = self.example_user("hamlet")
|
||||||
|
|
|
@ -20,7 +20,7 @@ from zerver.actions.message_send import (
|
||||||
extract_stream_indicator,
|
extract_stream_indicator,
|
||||||
internal_prep_private_message,
|
internal_prep_private_message,
|
||||||
internal_prep_stream_message_by_name,
|
internal_prep_stream_message_by_name,
|
||||||
internal_send_huddle_message,
|
internal_send_group_direct_message,
|
||||||
internal_send_private_message,
|
internal_send_private_message,
|
||||||
internal_send_stream_message,
|
internal_send_stream_message,
|
||||||
internal_send_stream_message_by_name,
|
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.constants import MAX_TOPIC_NAME_LENGTH
|
||||||
from zerver.models.groups import SystemGroups
|
from zerver.models.groups import SystemGroups
|
||||||
from zerver.models.realms import PrivateMessagePolicyEnum, WildcardMentionPolicyEnum, get_realm
|
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.streams import get_stream
|
||||||
from zerver.models.users import get_system_bot, get_user
|
from zerver.models.users import get_system_bot, get_user
|
||||||
from zerver.views.message_send import InvalidMirrorInputError
|
from zerver.views.message_send import InvalidMirrorInputError
|
||||||
|
@ -713,14 +713,14 @@ class MessagePOSTTest(ZulipTestCase):
|
||||||
|
|
||||||
msg = self.get_last_message()
|
msg = self.get_last_message()
|
||||||
self.assertEqual("Test message", msg.content)
|
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("hamlet").id,
|
||||||
self.example_user("othello").id,
|
self.example_user("othello").id,
|
||||||
self.example_user("cordelia").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:
|
def test_personal_message_copying_self(self) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -967,9 +967,9 @@ class MessagePOSTTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
self.assert_json_error(result, "Message must have recipients")
|
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(
|
result = self.api_post(
|
||||||
self.mit_user("starnine"),
|
self.mit_user("starnine"),
|
||||||
|
@ -1042,9 +1042,9 @@ class MessagePOSTTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
self.assert_json_error(result, "User not authorized for this query")
|
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 = {
|
msg = {
|
||||||
"type": "direct",
|
"type": "direct",
|
||||||
|
@ -2325,7 +2325,7 @@ class StreamMessagesTest(ZulipTestCase):
|
||||||
|
|
||||||
self.assert_stream_message(non_ascii_stream_name, topic_name="hümbüǵ", content="hümbüǵ")
|
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 = [
|
users = [
|
||||||
self.example_user("hamlet"),
|
self.example_user("hamlet"),
|
||||||
self.example_user("cordelia"),
|
self.example_user("cordelia"),
|
||||||
|
@ -2334,8 +2334,8 @@ class StreamMessagesTest(ZulipTestCase):
|
||||||
self.example_user("othello"),
|
self.example_user("othello"),
|
||||||
]
|
]
|
||||||
|
|
||||||
message1_id = self.send_huddle_message(users[0], users, "test content 1")
|
message1_id = self.send_group_direct_message(users[0], users, "test content 1")
|
||||||
message2_id = self.send_huddle_message(users[0], users, "test content 2")
|
message2_id = self.send_group_direct_message(users[0], users, "test content 2")
|
||||||
|
|
||||||
msg_data = get_raw_unread_data(users[1])
|
msg_data = get_raw_unread_data(users[1])
|
||||||
|
|
||||||
|
@ -2580,7 +2580,7 @@ class InternalPrepTest(ZulipTestCase):
|
||||||
)
|
)
|
||||||
|
|
||||||
with self.assertLogs(level="ERROR") as m:
|
with self.assertLogs(level="ERROR") as m:
|
||||||
internal_send_huddle_message(
|
internal_send_group_direct_message(
|
||||||
realm=realm,
|
realm=realm,
|
||||||
sender=cordelia,
|
sender=cordelia,
|
||||||
emails=[hamlet.email, othello.email],
|
emails=[hamlet.email, othello.email],
|
||||||
|
@ -2840,23 +2840,24 @@ class TestCrossRealmPMs(ZulipTestCase):
|
||||||
# (We don't particularly need this feature, but since users can
|
# (We don't particularly need this feature, but since users can
|
||||||
# already individually send direct messages to cross-realm bots,
|
# already individually send direct messages to cross-realm bots,
|
||||||
# we shouldn't prevent them from sending multiple bots at once.
|
# we shouldn't prevent them from sending multiple bots at once.
|
||||||
# We may revisit this if it's a nuisance for huddles.)
|
# We may revisit this if it's a nuisance for direct message
|
||||||
self.send_huddle_message(user1, [notification_bot, support_bot])
|
# groups.)
|
||||||
|
self.send_group_direct_message(user1, [notification_bot, support_bot])
|
||||||
assert_message_received(notification_bot, user1)
|
assert_message_received(notification_bot, user1)
|
||||||
assert_message_received(support_bot, user1)
|
assert_message_received(support_bot, user1)
|
||||||
|
|
||||||
# Prevent old loophole where I could send direct messages to other
|
# 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.
|
# users as long as I copied a cross-realm bot from the same realm.
|
||||||
with assert_invalid_user():
|
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
|
# Users on three different realms can't send direct messages to
|
||||||
# each other, even if one of the users is a cross-realm bot.
|
# each other, even if one of the users is a cross-realm bot.
|
||||||
with assert_invalid_user():
|
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():
|
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
|
# Users on the different realms cannot send direct messages to
|
||||||
# each other.
|
# each other.
|
||||||
|
@ -2871,7 +2872,7 @@ class TestCrossRealmPMs(ZulipTestCase):
|
||||||
# Users on three different realms cannot send direct messages
|
# Users on three different realms cannot send direct messages
|
||||||
# to each other.
|
# to each other.
|
||||||
with assert_invalid_user():
|
with assert_invalid_user():
|
||||||
self.send_huddle_message(user1, [user2, user3])
|
self.send_group_direct_message(user1, [user2, user3])
|
||||||
|
|
||||||
|
|
||||||
class TestAddressee(ZulipTestCase):
|
class TestAddressee(ZulipTestCase):
|
||||||
|
|
|
@ -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.actions.message_send import get_active_presence_idle_user_ids
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.models import Message, UserPresence, UserProfile
|
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):
|
class MissedMessageTest(ZulipTestCase):
|
||||||
|
@ -64,36 +67,46 @@ class MissedMessageTest(ZulipTestCase):
|
||||||
set_presence(hamlet, "website", ago=15)
|
set_presence(hamlet, "website", ago=15)
|
||||||
assert_active_presence_idle_user_ids([])
|
assert_active_presence_idle_user_ids([])
|
||||||
|
|
||||||
# Hamlet is active now, so only Othello should be in the list for a huddle
|
# Hamlet is active now, so only Othello should be in the list for a group
|
||||||
# message.
|
# direct message.
|
||||||
hamlet_notifications_data.stream_email_notify = False
|
hamlet_notifications_data.stream_email_notify = False
|
||||||
hamlet_notifications_data.dm_push_notify = False
|
hamlet_notifications_data.dm_push_notify = False
|
||||||
othello_notifications_data.dm_push_notify = True
|
othello_notifications_data.dm_push_notify = True
|
||||||
assert_active_presence_idle_user_ids([othello.id])
|
assert_active_presence_idle_user_ids([othello.id])
|
||||||
|
|
||||||
|
|
||||||
class TestBulkGetHuddleUserIds(ZulipTestCase):
|
class TestBulkGetDirectMessageGroupUserIds(ZulipTestCase):
|
||||||
def test_bulk_get_huddle_user_ids(self) -> None:
|
def test_bulk_get_direct_message_group_user_ids(self) -> None:
|
||||||
hamlet = self.example_user("hamlet")
|
hamlet = self.example_user("hamlet")
|
||||||
cordelia = self.example_user("cordelia")
|
cordelia = self.example_user("cordelia")
|
||||||
othello = self.example_user("othello")
|
othello = self.example_user("othello")
|
||||||
iago = self.example_user("iago")
|
iago = self.example_user("iago")
|
||||||
message_ids = [
|
message_ids = [
|
||||||
self.send_huddle_message(hamlet, [cordelia, othello], "test"),
|
self.send_group_direct_message(hamlet, [cordelia, othello], "test"),
|
||||||
self.send_huddle_message(cordelia, [hamlet, othello, iago], "test"),
|
self.send_group_direct_message(cordelia, [hamlet, othello, iago], "test"),
|
||||||
]
|
]
|
||||||
|
|
||||||
messages = Message.objects.filter(id__in=message_ids).order_by("id")
|
messages = Message.objects.filter(id__in=message_ids).order_by("id")
|
||||||
first_huddle_recipient = messages[0].recipient
|
first_direct_message_group_recipient = messages[0].recipient
|
||||||
first_huddle_user_ids = set(get_huddle_user_ids(first_huddle_recipient))
|
first_direct_message_group_user_ids = set(
|
||||||
second_huddle_recipient = messages[1].recipient
|
get_direct_message_group_user_ids(first_direct_message_group_recipient)
|
||||||
second_huddle_user_ids = set(get_huddle_user_ids(second_huddle_recipient))
|
)
|
||||||
|
second_direct_message_group_recipient = messages[1].recipient
|
||||||
huddle_user_ids = bulk_get_huddle_user_ids(
|
second_direct_message_group_user_ids = set(
|
||||||
[first_huddle_recipient.id, second_huddle_recipient.id]
|
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:
|
direct_message_group_user_ids = bulk_get_direct_message_group_user_ids(
|
||||||
self.assertEqual(bulk_get_huddle_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([]), {})
|
||||||
|
|
|
@ -231,18 +231,20 @@ class MutedUsersTests(ZulipTestCase):
|
||||||
|
|
||||||
# Have Cordelia send messages to Hamlet and Othello.
|
# Have Cordelia send messages to Hamlet and Othello.
|
||||||
stream_message = self.send_stream_message(cordelia, "general", "Spam in stream")
|
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_hamlet = self.send_personal_message(cordelia, hamlet, "Spam in direct message")
|
||||||
pm_to_othello = self.send_personal_message(cordelia, othello, "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.
|
# 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, 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)
|
self.assert_usermessage_read_flag(hamlet, pm_to_hamlet, True)
|
||||||
|
|
||||||
# These messages should be unreads for Othello, since he hasn't muted Cordelia.
|
# 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, 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)
|
self.assert_usermessage_read_flag(othello, pm_to_othello, False)
|
||||||
|
|
||||||
def test_existing_messages_from_muted_user_marked_as_read(self) -> None:
|
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.
|
# Have Cordelia send messages to Hamlet and Othello.
|
||||||
stream_message = self.send_stream_message(cordelia, "general", "Spam in stream")
|
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_hamlet = self.send_personal_message(cordelia, hamlet, "Spam in direct message")
|
||||||
pm_to_othello = self.send_personal_message(cordelia, othello, "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.
|
# 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, 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(hamlet, pm_to_hamlet, False)
|
||||||
|
|
||||||
self.assert_usermessage_read_flag(othello, stream_message, 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)
|
self.assert_usermessage_read_flag(othello, pm_to_othello, False)
|
||||||
|
|
||||||
# Hamlet mutes Cordelia.
|
# Hamlet mutes Cordelia.
|
||||||
|
@ -278,12 +282,12 @@ class MutedUsersTests(ZulipTestCase):
|
||||||
|
|
||||||
# The messages sent earlier should be marked as read for Hamlet.
|
# 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, 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)
|
self.assert_usermessage_read_flag(hamlet, pm_to_hamlet, True)
|
||||||
|
|
||||||
# These messages are still unreads for Othello, since he did not mute Cordelia.
|
# 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, 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)
|
self.assert_usermessage_read_flag(othello, pm_to_othello, False)
|
||||||
|
|
||||||
def test_muted_message_send_notifications_not_enqueued(self) -> None:
|
def test_muted_message_send_notifications_not_enqueued(self) -> None:
|
||||||
|
|
|
@ -16,7 +16,7 @@ from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.lib.timezone import canonicalize_timezone
|
from zerver.lib.timezone import canonicalize_timezone
|
||||||
from zerver.models import Message, Recipient, Stream, UserProfile
|
from zerver.models import Message, Recipient, Stream, UserProfile
|
||||||
from zerver.models.realms import get_realm
|
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.streams import get_stream
|
||||||
from zerver.models.users import get_system_bot
|
from zerver.models.users import get_system_bot
|
||||||
from zerver.signals import JUST_CREATED_THRESHOLD, get_device_browser, get_device_os
|
from zerver.signals import JUST_CREATED_THRESHOLD, get_device_browser, get_device_os
|
||||||
|
@ -342,7 +342,7 @@ class TestNotifyNewUser(ZulipTestCase):
|
||||||
)
|
)
|
||||||
# Group DM
|
# Group DM
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
set(get_huddle_user_ids(message.recipient)),
|
set(get_direct_message_group_user_ids(message.recipient)),
|
||||||
expected_group_direct_message_user_ids,
|
expected_group_direct_message_user_ids,
|
||||||
)
|
)
|
||||||
self.assertIn(
|
self.assertIn(
|
||||||
|
|
|
@ -4005,11 +4005,11 @@ class TestGetAPNsPayload(PushNotificationTest):
|
||||||
self.assertDictEqual(payload, expected)
|
self.assertDictEqual(payload, expected)
|
||||||
|
|
||||||
@mock.patch("zerver.lib.push_notifications.push_notifications_configured", return_value=True)
|
@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
|
self, mock_push_notifications: mock.MagicMock
|
||||||
) -> None:
|
) -> None:
|
||||||
user_profile = self.example_user("othello")
|
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")]
|
self.sender, [self.example_user("othello"), self.example_user("cordelia")]
|
||||||
)
|
)
|
||||||
message = Message.objects.get(id=message_id)
|
message = Message.objects.get(id=message_id)
|
||||||
|
@ -4225,7 +4225,7 @@ class TestGetAPNsPayload(PushNotificationTest):
|
||||||
@override_settings(PUSH_NOTIFICATION_REDACT_CONTENT=True)
|
@override_settings(PUSH_NOTIFICATION_REDACT_CONTENT=True)
|
||||||
def test_get_message_payload_apns_redacted_content(self) -> None:
|
def test_get_message_payload_apns_redacted_content(self) -> None:
|
||||||
user_profile = self.example_user("othello")
|
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")]
|
self.sender, [self.example_user("othello"), self.example_user("cordelia")]
|
||||||
)
|
)
|
||||||
message = Message.objects.get(id=message_id)
|
message = Message.objects.get(id=message_id)
|
||||||
|
|
|
@ -616,14 +616,14 @@ class ReactionEventTest(ZulipTestCase):
|
||||||
self.assertEqual(event_user_ids, {iago.id, hamlet.id})
|
self.assertEqual(event_user_ids, {iago.id, hamlet.id})
|
||||||
|
|
||||||
# Group direct message; event should go to all participants.
|
# 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,
|
hamlet,
|
||||||
[polonius, iago],
|
[polonius, iago],
|
||||||
"hello message to multiple receiver",
|
"hello message to multiple receiver",
|
||||||
)
|
)
|
||||||
with self.capture_send_event_calls(expected_num_events=1) as events:
|
with self.capture_send_event_calls(expected_num_events=1) as events:
|
||||||
result = self.api_post(
|
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)
|
self.assert_json_success(result)
|
||||||
event = events[0]["event"]
|
event = events[0]["event"]
|
||||||
|
|
|
@ -55,12 +55,12 @@ class TestReadReceipts(ZulipTestCase):
|
||||||
self.assertTrue(hamlet.id in result.json()["user_ids"])
|
self.assertTrue(hamlet.id in result.json()["user_ids"])
|
||||||
self.assertTrue(sender.id not 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")
|
hamlet = self.example_user("hamlet")
|
||||||
sender = self.example_user("othello")
|
sender = self.example_user("othello")
|
||||||
cordelia = self.example_user("cordelia")
|
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")
|
self.login("hamlet")
|
||||||
|
|
||||||
result = self.client_get(f"/json/messages/{message_id}/read_receipts")
|
result = self.client_get(f"/json/messages/{message_id}/read_receipts")
|
||||||
|
|
|
@ -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_realm import do_change_realm_subdomain, do_create_realm
|
||||||
from zerver.actions.create_user import do_create_user
|
from zerver.actions.create_user import do_create_user
|
||||||
from zerver.actions.message_send import (
|
from zerver.actions.message_send import (
|
||||||
internal_send_huddle_message,
|
internal_send_group_direct_message,
|
||||||
internal_send_private_message,
|
internal_send_private_message,
|
||||||
internal_send_stream_message,
|
internal_send_stream_message,
|
||||||
)
|
)
|
||||||
|
@ -2220,7 +2220,7 @@ class ScrubRealmTest(ZulipTestCase):
|
||||||
notification_bot, get_stream("Scotland", zulip), "test", "test"
|
notification_bot, get_stream("Scotland", zulip), "test", "test"
|
||||||
)
|
)
|
||||||
internal_send_private_message(notification_bot, othello, "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]
|
zulip, notification_bot, "test", emails=[othello.email, iago.email]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2228,7 +2228,7 @@ class ScrubRealmTest(ZulipTestCase):
|
||||||
notification_bot, get_stream("Shakespeare", lear), "test", "test"
|
notification_bot, get_stream("Shakespeare", lear), "test", "test"
|
||||||
)
|
)
|
||||||
internal_send_private_message(notification_bot, king, "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]
|
lear, notification_bot, "test", emails=[cordelia.email, king.email]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ from zerver.data_import.rocketchat import (
|
||||||
build_reactions,
|
build_reactions,
|
||||||
categorize_channels_and_map_with_id,
|
categorize_channels_and_map_with_id,
|
||||||
convert_channel_data,
|
convert_channel_data,
|
||||||
convert_huddle_data,
|
convert_direct_message_group_data,
|
||||||
convert_stream_subscription_data,
|
convert_stream_subscription_data,
|
||||||
do_convert_data,
|
do_convert_data,
|
||||||
map_receiver_id_to_recipient_id,
|
map_receiver_id_to_recipient_id,
|
||||||
|
@ -227,9 +227,11 @@ class RocketChatImporter(ZulipTestCase):
|
||||||
self.assertIn(direct_id, direct_id_to_direct_map)
|
self.assertIn(direct_id, direct_id_to_direct_map)
|
||||||
self.assertEqual(direct_id_to_direct_map[direct_id], rocketchat_data["room"][4])
|
self.assertEqual(direct_id_to_direct_map[direct_id], rocketchat_data["room"][4])
|
||||||
|
|
||||||
huddle_id = rocketchat_data["room"][12]["_id"]
|
direct_message_group_id = rocketchat_data["room"][12]["_id"]
|
||||||
self.assertIn(huddle_id, huddle_id_to_huddle_map)
|
self.assertIn(direct_message_group_id, huddle_id_to_huddle_map)
|
||||||
self.assertEqual(huddle_id_to_huddle_map[huddle_id], rocketchat_data["room"][12])
|
self.assertEqual(
|
||||||
|
huddle_id_to_huddle_map[direct_message_group_id], rocketchat_data["room"][12]
|
||||||
|
)
|
||||||
|
|
||||||
livechat_id = rocketchat_data["room"][14]["_id"]
|
livechat_id = rocketchat_data["room"][14]["_id"]
|
||||||
self.assertIn(livechat_id, livechat_id_to_livechat_map)
|
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.assert_length(subscriber_handler.get_users(stream_id=zerver_stream[6]["id"]), 0)
|
||||||
self.assertTrue(zerver_stream[6]["deactivated"])
|
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")
|
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
||||||
rocketchat_data = rocketchat_data_to_dict(fixture_dir_name)
|
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,
|
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_to_huddle_map=huddle_id_to_huddle_map,
|
||||||
huddle_id_mapper=huddle_id_mapper,
|
huddle_id_mapper=huddle_id_mapper,
|
||||||
user_id_mapper=user_id_mapper,
|
user_id_mapper=user_id_mapper,
|
||||||
subscriber_handler=subscriber_handler,
|
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"]
|
rc_huddle_id = rocketchat_data["room"][12]["_id"]
|
||||||
self.assertTrue(huddle_id_mapper.has(rc_huddle_id))
|
self.assertTrue(huddle_id_mapper.has(rc_huddle_id))
|
||||||
|
|
||||||
huddle_id = huddle_id_mapper.get(rc_huddle_id)
|
direct_message_group_id = huddle_id_mapper.get(rc_huddle_id)
|
||||||
self.assertEqual(subscriber_handler.get_users(huddle_id=huddle_id), {3, 4, 5})
|
self.assertEqual(
|
||||||
|
subscriber_handler.get_users(direct_message_group_id=direct_message_group_id), {3, 4, 5}
|
||||||
|
)
|
||||||
|
|
||||||
def test_write_emoticon_data(self) -> None:
|
def test_write_emoticon_data(self) -> None:
|
||||||
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
fixture_dir_name = self.fixture_file_name("", "rocketchat_fixtures")
|
||||||
|
@ -560,7 +564,7 @@ class RocketChatImporter(ZulipTestCase):
|
||||||
realm_id=realm_id,
|
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_to_huddle_map=huddle_id_to_huddle_map,
|
||||||
huddle_id_mapper=huddle_id_mapper,
|
huddle_id_mapper=huddle_id_mapper,
|
||||||
user_id_mapper=user_id_mapper,
|
user_id_mapper=user_id_mapper,
|
||||||
|
@ -572,7 +576,7 @@ class RocketChatImporter(ZulipTestCase):
|
||||||
zerver_recipient = build_recipients(
|
zerver_recipient = build_recipients(
|
||||||
zerver_userprofile=all_users,
|
zerver_userprofile=all_users,
|
||||||
zerver_stream=zerver_stream,
|
zerver_stream=zerver_stream,
|
||||||
zerver_huddle=zerver_huddle,
|
zerver_direct_message_group=zerver_direct_message_group,
|
||||||
)
|
)
|
||||||
|
|
||||||
stream_id_to_recipient_id: Dict[int, int] = {}
|
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"][11], private_messages)
|
||||||
self.assertIn(rocketchat_data["message"][12], 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"][79], livechat_messages)
|
||||||
self.assertIn(rocketchat_data["message"][83], 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_image)
|
||||||
self.assertTrue(stream_messages[23].has_link)
|
self.assertTrue(stream_messages[23].has_link)
|
||||||
|
|
||||||
huddle_messages = messages.filter(recipient__type=Recipient.DIRECT_MESSAGE_GROUP).order_by(
|
group_direct_messages = messages.filter(
|
||||||
"date_sent"
|
recipient__type=Recipient.DIRECT_MESSAGE_GROUP
|
||||||
)
|
).order_by("date_sent")
|
||||||
huddle_recipients = huddle_messages.values_list("recipient", flat=True)
|
direct_message_group_recipients = group_direct_messages.values_list("recipient", flat=True)
|
||||||
self.assert_length(huddle_messages, 5)
|
self.assert_length(group_direct_messages, 5)
|
||||||
self.assert_length(set(huddle_recipients), 2)
|
self.assert_length(set(direct_message_group_recipients), 2)
|
||||||
self.assertEqual(huddle_messages[0].sender.email, "hermionegranger@email.com")
|
self.assertEqual(group_direct_messages[0].sender.email, "hermionegranger@email.com")
|
||||||
self.assertEqual(huddle_messages[0].content, "Hey people!")
|
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(
|
self.assertRegex(
|
||||||
huddle_messages[2].content,
|
group_direct_messages[2].content,
|
||||||
"This year's curriculum is out.\n\n\\[Hogwarts Curriculum.pdf\\]\\(.*\\)",
|
"This year's curriculum is out.\n\n\\[Hogwarts Curriculum.pdf\\]\\(.*\\)",
|
||||||
)
|
)
|
||||||
self.assertTrue(huddle_messages[2].has_attachment)
|
self.assertTrue(group_direct_messages[2].has_attachment)
|
||||||
self.assertFalse(huddle_messages[2].has_image)
|
self.assertFalse(group_direct_messages[2].has_image)
|
||||||
self.assertTrue(huddle_messages[2].has_link)
|
self.assertTrue(group_direct_messages[2].has_link)
|
||||||
|
|
||||||
personal_messages = messages.filter(recipient__type=Recipient.PERSONAL).order_by(
|
personal_messages = messages.filter(recipient__type=Recipient.PERSONAL).order_by(
|
||||||
"date_sent"
|
"date_sent"
|
||||||
|
|
|
@ -566,7 +566,7 @@ class TestServiceBotEventTriggers(ZulipTestCase):
|
||||||
|
|
||||||
@for_all_bot_types
|
@for_all_bot_types
|
||||||
@patch_queue_publish("zerver.actions.message_send.queue_event_on_commit")
|
@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
|
self, mock_queue_event_on_commit: mock.Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
self.second_bot_profile.bot_type = self.bot_profile.bot_type
|
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
|
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)
|
self.assertEqual(mock_queue_event_on_commit.call_count, 2)
|
||||||
|
|
||||||
@for_all_bot_types
|
@for_all_bot_types
|
||||||
@patch_queue_publish("zerver.actions.message_send.queue_event_on_commit")
|
@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
|
self, mock_queue_event_on_commit: mock.Mock
|
||||||
) -> None:
|
) -> None:
|
||||||
sender = self.second_bot_profile
|
sender = self.second_bot_profile
|
||||||
recipients = [self.user_profile, self.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)
|
self.assertFalse(mock_queue_event_on_commit.called)
|
||||||
|
|
|
@ -78,7 +78,7 @@ from zerver.models import (
|
||||||
UserProfile,
|
UserProfile,
|
||||||
)
|
)
|
||||||
from zerver.models.realms import get_realm
|
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.streams import get_stream
|
||||||
from zerver.models.users import get_system_bot, get_user, get_user_by_delivery_email
|
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
|
from zerver.views.auth import redirect_and_log_into_subdomain, start_two_factor_auth
|
||||||
|
@ -2899,7 +2899,7 @@ class UserSignUpTest(ZulipTestCase):
|
||||||
last_message.content,
|
last_message.content,
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
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,
|
expected_group_direct_message_user_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -314,7 +314,7 @@ class SlackImporter(ZulipTestCase):
|
||||||
[ # Private channels ("groups")
|
[ # Private channels ("groups")
|
||||||
{"name": "private", "members": ["U061A1R2R", "U11111111"]},
|
{"name": "private", "members": ["U061A1R2R", "U11111111"]},
|
||||||
],
|
],
|
||||||
[ # Huddles ("mpims")
|
[ # Direct message groups ("mpims")
|
||||||
{
|
{
|
||||||
"name": "mpdm-foo--bar--baz-1",
|
"name": "mpdm-foo--bar--baz-1",
|
||||||
"members": ["U061A1R2R", "U061A5N1G", "U22222222"],
|
"members": ["U061A1R2R", "U061A5N1G", "U22222222"],
|
||||||
|
|
|
@ -58,7 +58,7 @@ class UserSoftDeactivationTests(ZulipTestCase):
|
||||||
|
|
||||||
# We are sending this message to ensure that users have at least
|
# We are sending this message to ensure that users have at least
|
||||||
# one UserMessage row.
|
# 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:
|
with self.assertLogs(logger_string, level="INFO") as m:
|
||||||
do_soft_deactivate_users(users)
|
do_soft_deactivate_users(users)
|
||||||
|
@ -112,7 +112,7 @@ class UserSoftDeactivationTests(ZulipTestCase):
|
||||||
self.example_user("iago"),
|
self.example_user("iago"),
|
||||||
self.example_user("cordelia"),
|
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:
|
with self.assertLogs(logger_string, level="INFO") as m:
|
||||||
do_soft_deactivate_users(users)
|
do_soft_deactivate_users(users)
|
||||||
|
|
|
@ -179,7 +179,7 @@ class TutorialTests(ZulipTestCase):
|
||||||
bot = get_system_bot(settings.WELCOME_BOT, user1.realm_id)
|
bot = get_system_bot(settings.WELCOME_BOT, user1.realm_id)
|
||||||
content = "whatever"
|
content = "whatever"
|
||||||
self.login_user(user1)
|
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)
|
user1_messages = message_stream_count(user1)
|
||||||
self.assertEqual(most_recent_message(user1).content, content)
|
self.assertEqual(most_recent_message(user1).content, content)
|
||||||
# Welcome bot should still respond to initial direct message
|
# Welcome bot should still respond to initial direct message
|
||||||
|
|
|
@ -2,7 +2,7 @@ import orjson
|
||||||
|
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.models import Huddle
|
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):
|
class TypingValidateOperatorTest(ZulipTestCase):
|
||||||
|
@ -202,8 +202,8 @@ class TypingHappyPathTestDirectMessages(ZulipTestCase):
|
||||||
expected_recipient_emails = {user.email for user in expected_recipients}
|
expected_recipient_emails = {user.email for user in expected_recipients}
|
||||||
expected_recipient_ids = {user.id for user in expected_recipients}
|
expected_recipient_ids = {user.id for user in expected_recipients}
|
||||||
|
|
||||||
huddle_hash = get_huddle_hash(list(expected_recipient_ids))
|
direct_message_group_hash = get_direct_message_group_hash(list(expected_recipient_ids))
|
||||||
self.assertFalse(Huddle.objects.filter(huddle_hash=huddle_hash).exists())
|
self.assertFalse(Huddle.objects.filter(huddle_hash=direct_message_group_hash).exists())
|
||||||
|
|
||||||
params = dict(
|
params = dict(
|
||||||
to=orjson.dumps([user.id for user in recipient_users]).decode(),
|
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_json_success(result)
|
||||||
self.assert_length(events, 1)
|
self.assert_length(events, 1)
|
||||||
|
|
||||||
# We should not be adding new Huddles just because
|
# We should not be adding new Direct Message groups
|
||||||
# a user started typing in the compose box. Let's
|
# just because a user started typing in the compose
|
||||||
# wait till they send an actual message.
|
# box. Let's wait till they send an actual message.
|
||||||
self.assertFalse(Huddle.objects.filter(huddle_hash=huddle_hash).exists())
|
self.assertFalse(Huddle.objects.filter(huddle_hash=direct_message_group_hash).exists())
|
||||||
|
|
||||||
event = events[0]["event"]
|
event = events[0]["event"]
|
||||||
event_recipient_emails = {user["email"] for user in event["recipients"]}
|
event_recipient_emails = {user["email"] for user in event["recipients"]}
|
||||||
|
|
|
@ -2782,19 +2782,19 @@ class DeleteUserTest(ZulipTestCase):
|
||||||
self.assertGreater(len(personal_message_ids_to_hamlet), 0)
|
self.assertGreater(len(personal_message_ids_to_hamlet), 0)
|
||||||
self.assertTrue(Message.objects.filter(realm_id=realm.id, sender=hamlet).exists())
|
self.assertTrue(Message.objects.filter(realm_id=realm.id, sender=hamlet).exists())
|
||||||
|
|
||||||
huddle_message_ids_from_cordelia = [
|
group_direct_message_ids_from_cordelia = [
|
||||||
self.send_huddle_message(cordelia, [hamlet, othello]) for i in range(3)
|
self.send_group_direct_message(cordelia, [hamlet, othello]) for i in range(3)
|
||||||
]
|
]
|
||||||
huddle_message_ids_from_hamlet = [
|
group_direct_message_ids_from_hamlet = [
|
||||||
self.send_huddle_message(hamlet, [cordelia, othello]) for i in range(3)
|
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(
|
Subscription.objects.filter(
|
||||||
user_profile=hamlet, recipient__type=Recipient.DIRECT_MESSAGE_GROUP
|
user_profile=hamlet, recipient__type=Recipient.DIRECT_MESSAGE_GROUP
|
||||||
).values_list("recipient_id", flat=True)
|
).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)
|
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(replacement_dummy_user.date_joined, hamlet_date_joined)
|
||||||
|
|
||||||
self.assertEqual(Message.objects.filter(id__in=personal_message_ids_to_hamlet).count(), 0)
|
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
|
# Group direct messages from hamlet should have been deleted, but messages of other
|
||||||
# be kept.
|
# participants should be kept.
|
||||||
self.assertEqual(Message.objects.filter(id__in=huddle_message_ids_from_hamlet).count(), 0)
|
self.assertEqual(
|
||||||
self.assertEqual(Message.objects.filter(id__in=huddle_message_ids_from_cordelia).count(), 3)
|
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(
|
self.assertEqual(
|
||||||
Message.objects.filter(realm_id=realm.id, sender_id=hamlet_user_id).count(), 0
|
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
|
# Verify that the dummy user is subscribed to the deleted user's direct message groups,
|
||||||
# in a correct state.
|
# to keep direct message group's data in a correct state.
|
||||||
for recipient_id in huddle_with_hamlet_recipient_ids:
|
for recipient_id in direct_message_group_with_hamlet_recipient_ids:
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
Subscription.objects.filter(
|
Subscription.objects.filter(
|
||||||
user_profile=replacement_dummy_user, recipient_id=recipient_id
|
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.assertGreater(len(personal_message_ids_to_hamlet), 0)
|
||||||
self.assertTrue(Message.objects.filter(realm_id=realm.id, sender=hamlet).exists())
|
self.assertTrue(Message.objects.filter(realm_id=realm.id, sender=hamlet).exists())
|
||||||
|
|
||||||
huddle_message_ids_from_cordelia = [
|
group_direct_message_ids_from_cordelia = [
|
||||||
self.send_huddle_message(cordelia, [hamlet, othello]) for i in range(3)
|
self.send_group_direct_message(cordelia, [hamlet, othello]) for i in range(3)
|
||||||
]
|
]
|
||||||
huddle_message_ids_from_hamlet = [
|
group_direct_message_ids_from_hamlet = [
|
||||||
self.send_huddle_message(hamlet, [cordelia, othello]) for i in range(3)
|
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(
|
Subscription.objects.filter(
|
||||||
user_profile=hamlet, recipient__type=Recipient.DIRECT_MESSAGE_GROUP
|
user_profile=hamlet, recipient__type=Recipient.DIRECT_MESSAGE_GROUP
|
||||||
).values_list("recipient_id", flat=True)
|
).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(
|
original_messages_from_hamlet_count = Message.objects.filter(
|
||||||
realm_id=realm.id, sender_id=hamlet_user_id
|
realm_id=realm.id, sender_id=hamlet_user_id
|
||||||
|
@ -2885,12 +2889,12 @@ class DeleteUserTest(ZulipTestCase):
|
||||||
len(personal_message_ids_to_hamlet),
|
len(personal_message_ids_to_hamlet),
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
Message.objects.filter(id__in=huddle_message_ids_from_hamlet).count(),
|
Message.objects.filter(id__in=group_direct_message_ids_from_hamlet).count(),
|
||||||
len(huddle_message_ids_from_hamlet),
|
len(group_direct_message_ids_from_hamlet),
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
Message.objects.filter(id__in=huddle_message_ids_from_cordelia).count(),
|
Message.objects.filter(id__in=group_direct_message_ids_from_cordelia).count(),
|
||||||
len(huddle_message_ids_from_cordelia),
|
len(group_direct_message_ids_from_cordelia),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
@ -2898,9 +2902,9 @@ class DeleteUserTest(ZulipTestCase):
|
||||||
original_messages_from_hamlet_count,
|
original_messages_from_hamlet_count,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Verify that the dummy user is subscribed to the deleted user's huddles, to keep huddle data
|
# Verify that the dummy user is subscribed to the deleted user's direct message groups,
|
||||||
# in a correct state.
|
# to keep direct message group's data in a correct state.
|
||||||
for recipient_id in huddle_with_hamlet_recipient_ids:
|
for recipient_id in direct_message_group_with_hamlet_recipient_ids:
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
Subscription.objects.filter(
|
Subscription.objects.filter(
|
||||||
user_profile=replacement_dummy_user, recipient_id=recipient_id
|
user_profile=replacement_dummy_user, recipient_id=recipient_id
|
||||||
|
|
|
@ -19,7 +19,7 @@ from zerver.lib.zulip_update_announcements import (
|
||||||
)
|
)
|
||||||
from zerver.models.messages import Message
|
from zerver.models.messages import Message
|
||||||
from zerver.models.realms import get_realm
|
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.streams import get_stream
|
||||||
from zerver.models.users import get_system_bot
|
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.sender, notification_bot)
|
||||||
self.assertEqual(group_direct_message.date_sent, now)
|
self.assertEqual(group_direct_message.date_sent, now)
|
||||||
self.assertEqual(
|
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,
|
expected_group_direct_message_user_ids,
|
||||||
)
|
)
|
||||||
self.assertEqual(realm.zulip_update_announcements_level, 0)
|
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.sender, notification_bot)
|
||||||
self.assertEqual(group_direct_message.date_sent, now)
|
self.assertEqual(group_direct_message.date_sent, now)
|
||||||
self.assertEqual(
|
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,
|
expected_group_direct_message_user_ids,
|
||||||
)
|
)
|
||||||
self.assertEqual(realm.zulip_update_announcements_level, 0)
|
self.assertEqual(realm.zulip_update_announcements_level, 0)
|
||||||
|
|
|
@ -70,7 +70,7 @@ from zerver.models import (
|
||||||
from zerver.models.alert_words import flush_alert_word
|
from zerver.models.alert_words import flush_alert_word
|
||||||
from zerver.models.clients import get_client
|
from zerver.models.clients import get_client
|
||||||
from zerver.models.realms import WildcardMentionPolicyEnum, get_realm
|
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.streams import get_stream
|
||||||
from zerver.models.users import get_user, get_user_by_delivery_email, get_user_profile_by_id
|
from zerver.models.users import get_user, get_user_by_delivery_email, get_user_profile_by_id
|
||||||
from zilencer.models import RemoteRealm, RemoteZulipServer, RemoteZulipServerAuditLog
|
from zilencer.models import RemoteRealm, RemoteZulipServer, RemoteZulipServerAuditLog
|
||||||
|
@ -929,7 +929,9 @@ class Command(ZulipBaseCommand):
|
||||||
|
|
||||||
# Create several initial huddles
|
# Create several initial huddles
|
||||||
for i in range(options["num_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
|
# Create several initial pairs for personals
|
||||||
personals_pairs = [
|
personals_pairs = [
|
||||||
|
|
Loading…
Reference in New Issue