mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 13:03:29 +00:00
streams: Handle empty topic only streams being used for announcements.
This commit updates code to send messages to "general chat" topic if streams used for announcements for "New user signups", "New created streams", "Moderation requests" and "Zulip updates" have topics policy set to allow only "general chat" messages.
This commit is contained in:
@@ -66,6 +66,7 @@ from zerver.models import (
|
||||
)
|
||||
from zerver.models.groups import SystemGroups
|
||||
from zerver.models.realm_audit_logs import AuditLogEventType
|
||||
from zerver.models.streams import StreamTopicsPolicyEnum
|
||||
from zerver.models.users import ExternalAuthID, active_user_ids, bot_owner_user_ids, get_system_bot
|
||||
from zerver.tornado.django_api import send_event_on_commit
|
||||
|
||||
@@ -82,6 +83,11 @@ def send_message_to_signup_notification_stream(
|
||||
|
||||
with override_language(realm.default_language):
|
||||
topic_name = _("signups")
|
||||
if (
|
||||
signup_announcements_stream.topics_policy
|
||||
== StreamTopicsPolicyEnum.empty_topic_only.value
|
||||
):
|
||||
topic_name = ""
|
||||
|
||||
internal_send_stream_message(sender, signup_announcements_stream, topic_name, message)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ from zerver.lib.message import is_1_to_1_message, truncate_content
|
||||
from zerver.lib.topic_link_util import get_message_link_syntax
|
||||
from zerver.models import Message, Realm, UserProfile
|
||||
from zerver.models.recipients import Recipient
|
||||
from zerver.models.streams import StreamTopicsPolicyEnum
|
||||
from zerver.models.users import get_system_bot
|
||||
|
||||
# We shrink the truncate length for the reported message to ensure
|
||||
@@ -104,9 +105,13 @@ def send_message_report(
|
||||
)
|
||||
content += reported_message_preview_block
|
||||
|
||||
topic_name = _("{fullname}'s moderation requests").format(fullname=reported_user.full_name)
|
||||
if moderation_request_channel.topics_policy == StreamTopicsPolicyEnum.empty_topic_only.value:
|
||||
topic_name = ""
|
||||
|
||||
internal_send_stream_message(
|
||||
sender=get_system_bot(settings.NOTIFICATION_BOT, moderation_request_channel.realm.id),
|
||||
stream=moderation_request_channel,
|
||||
topic_name=_("{fullname}'s moderation requests").format(fullname=reported_user.full_name),
|
||||
topic_name=topic_name,
|
||||
content=content,
|
||||
)
|
||||
|
||||
@@ -19,6 +19,7 @@ from zerver.lib.message import SendMessageRequest, remove_single_newlines
|
||||
from zerver.lib.topic import messages_for_topic
|
||||
from zerver.models.realm_audit_logs import AuditLogEventType, RealmAuditLog
|
||||
from zerver.models.realms import Realm
|
||||
from zerver.models.streams import StreamTopicsPolicyEnum
|
||||
from zerver.models.users import UserProfile, get_system_bot
|
||||
|
||||
|
||||
@@ -483,12 +484,25 @@ def get_realms_behind_zulip_update_announcements_level(level: int) -> QuerySet[R
|
||||
return realms
|
||||
|
||||
|
||||
def get_topic_name_for_zulip_update_announcements(realm: Realm) -> str:
|
||||
assert realm.zulip_update_announcements_stream is not None
|
||||
|
||||
with override_language(realm.default_language):
|
||||
topic_name = str(realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME)
|
||||
|
||||
if (
|
||||
realm.zulip_update_announcements_stream.topics_policy
|
||||
== StreamTopicsPolicyEnum.empty_topic_only.value
|
||||
):
|
||||
topic_name = ""
|
||||
|
||||
return topic_name
|
||||
|
||||
|
||||
def internal_prep_group_direct_message_for_old_realm(
|
||||
realm: Realm, sender: UserProfile
|
||||
) -> SendMessageRequest | None:
|
||||
administrators = list(realm.get_human_admin_users())
|
||||
with override_language(realm.default_language):
|
||||
topic_name = str(realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME)
|
||||
if realm.zulip_update_announcements_stream is None:
|
||||
content = """
|
||||
Zulip now supports [configuring]({organization_settings_url}) a channel where Zulip will
|
||||
@@ -500,6 +514,7 @@ a channel within one week, your organization will not miss any update messages.
|
||||
organization_settings_url="/#organization/organization-settings",
|
||||
)
|
||||
else:
|
||||
topic_name = get_topic_name_for_zulip_update_announcements(realm)
|
||||
content = """
|
||||
Starting tomorrow, users in your organization will receive [updates]({zulip_update_announcements_help_url})
|
||||
about new Zulip features in #**{zulip_update_announcements_stream}>{topic_name}**.
|
||||
@@ -560,8 +575,8 @@ def internal_prep_zulip_update_announcements_stream_messages(
|
||||
message_requests = []
|
||||
stream = realm.zulip_update_announcements_stream
|
||||
assert stream is not None
|
||||
with override_language(realm.default_language):
|
||||
topic_name = str(realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME)
|
||||
topic_name = get_topic_name_for_zulip_update_announcements(realm)
|
||||
|
||||
while current_level < latest_level:
|
||||
content = get_zulip_update_announcements_message_for_level(level=current_level + 1)
|
||||
message_requests.append(
|
||||
@@ -671,11 +686,9 @@ def send_zulip_update_announcements_to_realm(realm: Realm, skip_delay: bool) ->
|
||||
return
|
||||
|
||||
# Send an introductory message just before the first update message.
|
||||
with override_language(realm.default_language):
|
||||
topic_name = str(realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME)
|
||||
|
||||
stream = realm.zulip_update_announcements_stream
|
||||
assert stream.recipient_id is not None
|
||||
topic_name = get_topic_name_for_zulip_update_announcements(realm)
|
||||
topic_has_messages = messages_for_topic(realm.id, stream.recipient_id, topic_name).exists()
|
||||
|
||||
if not topic_has_messages:
|
||||
|
||||
@@ -2,6 +2,7 @@ from django.conf import settings
|
||||
from typing_extensions import Any, override
|
||||
|
||||
from zerver.actions.realm_settings import do_set_realm_moderation_request_channel
|
||||
from zerver.actions.streams import do_set_stream_property
|
||||
from zerver.lib.markdown.fenced_code import get_unused_fence
|
||||
from zerver.lib.mention import silent_mention_syntax_for_user
|
||||
from zerver.lib.message import truncate_content
|
||||
@@ -15,6 +16,7 @@ from zerver.lib.topic_link_util import (
|
||||
from zerver.models import UserProfile
|
||||
from zerver.models.messages import Message
|
||||
from zerver.models.recipients import get_or_create_direct_message_group
|
||||
from zerver.models.streams import StreamTopicsPolicyEnum
|
||||
from zerver.models.users import get_system_bot
|
||||
|
||||
|
||||
@@ -373,3 +375,23 @@ class ReportMessageTest(ZulipTestCase):
|
||||
)
|
||||
|
||||
self.assert_json_success(result)
|
||||
|
||||
def test_message_report_to_channel_with_topics_disabled(self) -> None:
|
||||
notification_bot = get_system_bot(settings.NOTIFICATION_BOT, self.realm.id)
|
||||
do_set_stream_property(
|
||||
self.moderation_request_channel,
|
||||
"topics_policy",
|
||||
StreamTopicsPolicyEnum.empty_topic_only.value,
|
||||
self.hamlet,
|
||||
)
|
||||
|
||||
result = self.report_message(
|
||||
self.hamlet,
|
||||
self.reported_message_id,
|
||||
report_type="harassment",
|
||||
)
|
||||
self.assert_json_success(result)
|
||||
report_msg = self.get_last_message()
|
||||
self.assertEqual(report_msg.sender_id, notification_bot.id)
|
||||
self.assertEqual(report_msg.topic_name(), "")
|
||||
self.assertIn("reported", report_msg.content)
|
||||
|
||||
@@ -10,6 +10,7 @@ from typing_extensions import override
|
||||
|
||||
from corporate.lib.stripe import get_latest_seat_count
|
||||
from zerver.actions.create_user import notify_new_user
|
||||
from zerver.actions.streams import do_set_stream_property
|
||||
from zerver.actions.user_settings import do_change_user_setting
|
||||
from zerver.lib.initial_password import initial_password
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
@@ -17,7 +18,7 @@ from zerver.lib.timezone import canonicalize_timezone
|
||||
from zerver.models import Message, Recipient, Stream, UserProfile
|
||||
from zerver.models.realms import get_realm
|
||||
from zerver.models.recipients import get_direct_message_group_user_ids
|
||||
from zerver.models.streams import get_stream
|
||||
from zerver.models.streams import StreamTopicsPolicyEnum, get_stream
|
||||
from zerver.models.users import get_system_bot
|
||||
from zerver.signals import JUST_CREATED_THRESHOLD, get_device_browser, get_device_os
|
||||
|
||||
@@ -286,6 +287,7 @@ class TestNotifyNewUser(ZulipTestCase):
|
||||
self.assertEqual(message.recipient.type, Recipient.STREAM)
|
||||
actual_stream = Stream.objects.get(id=message.recipient.type_id)
|
||||
self.assertEqual(actual_stream.name, "core team")
|
||||
self.assertEqual(message.topic_name(), "signups")
|
||||
self.assertIn(
|
||||
f"@_**Cordelia, Lear's daughter|{new_user.id}** joined this organization.",
|
||||
message.content,
|
||||
@@ -297,6 +299,28 @@ class TestNotifyNewUser(ZulipTestCase):
|
||||
notify_new_user(new_user)
|
||||
self.assertEqual(self.get_message_count(), message_count + 1)
|
||||
|
||||
def test_notify_realm_of_new_user_in_empty_topic_only_channel(self) -> None:
|
||||
realm = get_realm("zulip")
|
||||
iago = self.example_user("iago")
|
||||
stream = get_stream("core team", realm)
|
||||
realm.signup_announcements_stream = stream
|
||||
realm.save(update_fields=["signup_announcements_stream"])
|
||||
do_set_stream_property(
|
||||
stream, "topics_policy", StreamTopicsPolicyEnum.empty_topic_only.value, iago
|
||||
)
|
||||
|
||||
new_user = self.example_user("cordelia")
|
||||
message_count = self.get_message_count()
|
||||
|
||||
notify_new_user(new_user)
|
||||
self.assertEqual(self.get_message_count(), message_count + 1)
|
||||
message = self.get_last_message()
|
||||
self.assertEqual(message.topic_name(), "")
|
||||
self.assertIn(
|
||||
f"@_**Cordelia, Lear's daughter|{new_user.id}** joined this organization.",
|
||||
message.content,
|
||||
)
|
||||
|
||||
def test_notify_realm_of_new_user_in_manual_license_management(self) -> None:
|
||||
realm = get_realm("zulip")
|
||||
admin_user_ids = set(realm.get_human_admin_users().values_list("id", flat=True))
|
||||
|
||||
@@ -30,6 +30,7 @@ from zerver.actions.streams import (
|
||||
deactivated_streams_by_old_name,
|
||||
do_change_stream_group_based_setting,
|
||||
do_deactivate_stream,
|
||||
do_set_stream_property,
|
||||
do_unarchive_stream,
|
||||
)
|
||||
from zerver.actions.user_groups import bulk_add_members_to_user_groups, check_add_user_group
|
||||
@@ -3431,6 +3432,7 @@ class SubscriptionAPITest(ZulipTestCase):
|
||||
self.assertEqual(msg.recipient.type, Recipient.STREAM)
|
||||
self.assertEqual(msg.recipient.type_id, new_stream_announcements_stream.id)
|
||||
self.assertEqual(msg.sender_id, self.notification_bot(self.test_realm).id)
|
||||
self.assertEqual(msg.topic_name(), "new channels")
|
||||
expected_msg = f"@_**{invitee_full_name}|{invitee.id}** created a new channel #**{invite_streams[0]}**."
|
||||
self.assertEqual(msg.content, expected_msg)
|
||||
|
||||
@@ -3444,6 +3446,41 @@ class SubscriptionAPITest(ZulipTestCase):
|
||||
)
|
||||
self.assertEqual(msg.content, expected_msg)
|
||||
|
||||
def test_sucessful_subscription_notifies_in_empty_topic_only_stream(self) -> None:
|
||||
invitee = self.example_user("iago")
|
||||
invitee_full_name = "Iago"
|
||||
|
||||
current_stream = self.get_streams(invitee)[0]
|
||||
invite_streams = self.make_random_stream_names([current_stream])[:1]
|
||||
|
||||
new_stream_announcements_stream = get_stream(current_stream, self.test_realm)
|
||||
self.test_realm.new_stream_announcements_stream_id = new_stream_announcements_stream.id
|
||||
self.test_realm.save()
|
||||
|
||||
do_set_stream_property(
|
||||
new_stream_announcements_stream,
|
||||
"topics_policy",
|
||||
StreamTopicsPolicyEnum.empty_topic_only.value,
|
||||
invitee,
|
||||
)
|
||||
|
||||
self.subscribe_via_post(
|
||||
invitee,
|
||||
invite_streams,
|
||||
extra_post_data=dict(
|
||||
announce="true",
|
||||
principals=orjson.dumps([self.user_profile.id]).decode(),
|
||||
),
|
||||
)
|
||||
|
||||
msg = self.get_second_to_last_message()
|
||||
self.assertEqual(msg.recipient.type, Recipient.STREAM)
|
||||
self.assertEqual(msg.recipient.type_id, new_stream_announcements_stream.id)
|
||||
self.assertEqual(msg.sender_id, self.notification_bot(self.test_realm).id)
|
||||
self.assertEqual(msg.topic_name(), "")
|
||||
expected_msg = f"@_**{invitee_full_name}|{invitee.id}** created a new channel #**{invite_streams[0]}**."
|
||||
self.assertEqual(msg.content, expected_msg)
|
||||
|
||||
def test_successful_cross_realm_notification(self) -> None:
|
||||
"""
|
||||
Calling POST /json/users/me/subscriptions in a new realm
|
||||
|
||||
@@ -9,7 +9,7 @@ from django.utils.timezone import now as timezone_now
|
||||
from typing_extensions import override
|
||||
|
||||
from zerver.actions.create_realm import do_create_realm
|
||||
from zerver.actions.streams import do_deactivate_stream
|
||||
from zerver.actions.streams import do_deactivate_stream, do_set_stream_property
|
||||
from zerver.data_import.mattermost import do_convert_data
|
||||
from zerver.lib.import_realm import do_import_realm
|
||||
from zerver.lib.message import remove_single_newlines
|
||||
@@ -21,7 +21,7 @@ from zerver.lib.zulip_update_announcements import (
|
||||
from zerver.models.messages import Message
|
||||
from zerver.models.realms import get_realm
|
||||
from zerver.models.recipients import Recipient, get_direct_message_group_user_ids
|
||||
from zerver.models.streams import get_stream
|
||||
from zerver.models.streams import StreamTopicsPolicyEnum, get_stream
|
||||
from zerver.models.users import get_system_bot
|
||||
|
||||
|
||||
@@ -129,6 +129,42 @@ class ZulipUpdateAnnouncementsTest(ZulipTestCase):
|
||||
self.assertEqual(stream_messages[1].content, "Announcement message 3.")
|
||||
self.assertEqual(stream_messages[2].content, "Announcement message 4.")
|
||||
self.assertEqual(realm.zulip_update_announcements_level, 4)
|
||||
self.assertEqual(
|
||||
stream_messages[0].topic_name(), realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME
|
||||
)
|
||||
self.assertEqual(
|
||||
stream_messages[1].topic_name(), realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME
|
||||
)
|
||||
self.assertEqual(
|
||||
stream_messages[2].topic_name(), realm.ZULIP_UPDATE_ANNOUNCEMENTS_TOPIC_NAME
|
||||
)
|
||||
|
||||
# Test sending updates with announcements stream allowing empty topics only.
|
||||
iago = self.example_user("iago")
|
||||
do_set_stream_property(
|
||||
verona, "topics_policy", StreamTopicsPolicyEnum.empty_topic_only.value, iago
|
||||
)
|
||||
|
||||
new_updates = [
|
||||
ZulipUpdateAnnouncement(
|
||||
level=5,
|
||||
message="Announcement message 5.",
|
||||
),
|
||||
]
|
||||
self.zulip_update_announcements.extend(new_updates)
|
||||
with time_machine.travel(now + timedelta(days=15), tick=False):
|
||||
send_zulip_update_announcements(skip_delay=False)
|
||||
realm.refresh_from_db()
|
||||
stream_messages = Message.objects.filter(
|
||||
realm=realm,
|
||||
sender=notification_bot,
|
||||
recipient__type_id=verona.id,
|
||||
date_sent__gte=now + timedelta(days=15),
|
||||
).order_by("id")
|
||||
self.assert_length(stream_messages, 1)
|
||||
self.assertEqual(stream_messages[0].topic_name(), "")
|
||||
self.assertEqual(stream_messages[0].content, "Announcement message 5.")
|
||||
self.assertEqual(realm.zulip_update_announcements_level, 5)
|
||||
|
||||
def test_send_zulip_update_announcements_with_stream_configured(self) -> None:
|
||||
with mock.patch(
|
||||
|
||||
@@ -975,6 +975,11 @@ def send_messages_for_new_subscribers(
|
||||
else:
|
||||
content = _("{user_name} created a new channel {new_channels}.")
|
||||
topic_name = _("new channels")
|
||||
if (
|
||||
new_stream_announcements_stream.topics_policy
|
||||
== StreamTopicsPolicyEnum.empty_topic_only.value
|
||||
):
|
||||
topic_name = ""
|
||||
|
||||
content = content.format(
|
||||
user_name=silent_mention_syntax_for_user(user_profile),
|
||||
|
||||
Reference in New Issue
Block a user