From e3edc4d829a6fb4be0a8ba5d92eaa609a2a1c702 Mon Sep 17 00:00:00 2001 From: Steve Howell Date: Wed, 26 Apr 2017 15:03:21 -0700 Subject: [PATCH] Send welcome messages for new streams. --- tools/lib/capitalization.py | 2 ++ zerver/lib/actions.py | 33 ++++++++++++++++++++++ zerver/tests/test_subs.py | 55 +++++++++++++++++++++++++++++++------ zerver/views/streams.py | 7 ++++- 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/tools/lib/capitalization.py b/tools/lib/capitalization.py index 9c1bb82411..045a8d49de 100644 --- a/tools/lib/capitalization.py +++ b/tools/lib/capitalization.py @@ -81,6 +81,8 @@ IGNORED_PHRASES = [ r"more conversations", # We should probably just delete this string from translations r'activation key', + # this is used as a topic + r'^hello$', # TO CLEAN UP # Just want to avoid churning login.html right now diff --git a/zerver/lib/actions.py b/zerver/lib/actions.py index 94fe3fe094..601838c8ad 100644 --- a/zerver/lib/actions.py +++ b/zerver/lib/actions.py @@ -949,6 +949,36 @@ def check_typing_notification(sender, notification_to, operator): raise ValueError('Forbidden recipient type') return {'sender': sender, 'recipient': recipient, 'op': operator} +def stream_welcome_message(stream): + # type: (Stream) -> Text + content = _('Welcome to #**%s**.') % (stream.name,) + + if stream.description: + content += '\n\n**' + _('Description') + '**: ' + content += stream.description + + return content + +def prep_stream_welcome_message(stream): + # type: (Stream) -> Optional[Dict[str, Any]] + realm = stream.realm + sender_email = settings.WELCOME_BOT + recipient_type_name = 'stream' + recipients = stream.name + subject = _('hello') + + content = stream_welcome_message(stream) + + message = internal_prep_message( + realm=realm, + sender_email=sender_email, + recipient_type_name=recipient_type_name, + recipients=recipients, + subject=subject, + content=content) + + return message + def create_stream_if_needed(realm, stream_name, invite_only=False, stream_description = ""): # type: (Realm, Text, bool, Text) -> Tuple[Stream, bool] (stream, created) = Stream.objects.get_or_create( @@ -1199,6 +1229,9 @@ def check_message(sender, client, message_type_name, message_to, elif sender.is_bot and subscribed_to_stream(sender.bot_owner, stream): # Or you're a bot and your owner is subscribed. pass + elif sender.email == settings.WELCOME_BOT: + # The welcome bot welcomes folks to the stream. + pass else: # All other cases are an error. raise JsonableError(_("Not authorized to send to stream '%s'") % (stream.name,)) diff --git a/zerver/tests/test_subs.py b/zerver/tests/test_subs.py index 02ea4a7e80..2ee9e69cfa 100644 --- a/zerver/tests/test_subs.py +++ b/zerver/tests/test_subs.py @@ -3,6 +3,7 @@ from __future__ import absolute_import from typing import Any, Dict, List, Mapping, Optional, Sequence, Set, Text +from django.conf import settings from django.http import HttpRequest, HttpResponse from zerver.lib import cache @@ -45,6 +46,7 @@ from zerver.lib.actions import ( get_user_profile_by_email, set_default_streams, check_stream_name, create_stream_if_needed, create_streams_if_needed, active_user_ids, do_deactivate_stream, + stream_welcome_message, ) from zerver.views.streams import ( @@ -99,6 +101,33 @@ class TestCreateStreams(ZulipTestCase): for stream in existing_streams: self.assertTrue(stream.invite_only) + def test_welcome_message(self): + # type: () -> None + realm = get_realm('zulip') + name = u'New Stream' + + new_stream, _ = create_stream_if_needed( + realm=realm, + stream_name=name + ) + welcome_message = stream_welcome_message(new_stream) + + self.assertEqual( + welcome_message, + u'Welcome to #**New Stream**.' + ) + + new_stream.description = 'Talk about **stuff**.' + + welcome_message = stream_welcome_message(new_stream) + + self.assertEqual( + welcome_message, + 'Welcome to #**New Stream**.' + '\n\n' + '**Description**: Talk about **stuff**.' + ) + class RecipientTest(ZulipTestCase): def test_recipient(self): # type: () -> None @@ -1233,7 +1262,7 @@ class SubscriptionAPITest(ZulipTestCase): with tornado_redirected_to_list(events): self.helper_check_subs_before_and_after_add(self.streams + add_streams, {}, add_streams, self.streams, self.test_email, self.streams + add_streams) - self.assert_length(events, 6) + self.assert_length(events, 8) def test_successful_subscriptions_add_with_announce(self): # type: () -> None @@ -1261,7 +1290,7 @@ class SubscriptionAPITest(ZulipTestCase): with tornado_redirected_to_list(events): self.helper_check_subs_before_and_after_add(self.streams + add_streams, other_params, add_streams, self.streams, self.test_email, self.streams + add_streams) - self.assertEqual(len(events), 7) + self.assertEqual(len(events), 9) def test_successful_subscriptions_notifies_pm(self): # type: () -> None @@ -1283,7 +1312,7 @@ class SubscriptionAPITest(ZulipTestCase): ) self.assert_json_success(result) - msg = self.get_last_message() + msg = self.get_second_to_last_message() self.assertEqual(msg.recipient.type, Recipient.PERSONAL) self.assertEqual(msg.sender_id, get_user_profile_by_email('notification-bot@zulip.com').id) @@ -1319,7 +1348,7 @@ class SubscriptionAPITest(ZulipTestCase): ) self.assert_json_success(result) - msg = self.get_last_message() + msg = self.get_second_to_last_message() self.assertEqual(msg.recipient.type, Recipient.STREAM) self.assertEqual(msg.sender_id, get_user_profile_by_email('notification-bot@zulip.com').id) @@ -1357,7 +1386,7 @@ class SubscriptionAPITest(ZulipTestCase): ) self.assert_json_success(result) - msg = self.get_last_message() + msg = self.get_second_to_last_message() self.assertEqual(msg.recipient.type, Recipient.STREAM) self.assertEqual(msg.sender_id, get_user_profile_by_email('notification-bot@zulip.com').id) @@ -1390,7 +1419,7 @@ class SubscriptionAPITest(ZulipTestCase): ) self.assert_json_success(result) - msg = self.get_last_message() + msg = self.get_second_to_last_message() self.assertEqual(msg.sender_id, get_user_profile_by_email('notification-bot@zulip.com').id) expected_msg = "%s just created a new stream #**%s**." % (invitee_full_name, invite_streams[0]) @@ -1462,8 +1491,16 @@ class SubscriptionAPITest(ZulipTestCase): self.helper_check_subs_before_and_after_add(streams_to_sub, {"principals": ujson.dumps([invitee])}, streams[:1], current_streams, invitee, streams_to_sub, invite_only=invite_only) - # verify that the user was sent a message informing them about the subscription + + # verify that a welcome message was sent to the stream msg = self.get_last_message() + self.assertEqual(msg.recipient.type, msg.recipient.STREAM) + self.assertEqual(msg.subject, u'hello') + self.assertEqual(msg.sender.email, settings.WELCOME_BOT) + self.assertIn('Welcome to #**', msg.content) + + # verify that the user was sent a message informing them about the subscription + msg = self.get_second_to_last_message() self.assertEqual(msg.recipient.type, msg.recipient.PERSONAL) self.assertEqual(msg.sender_id, get_user_profile_by_email("notification-bot@zulip.com").id) @@ -1499,9 +1536,9 @@ class SubscriptionAPITest(ZulipTestCase): streams_to_sub, dict(principals=ujson.dumps([email1, email2])), ) - self.assert_length(queries, 52) + self.assert_length(queries, 67) - self.assert_length(events, 8) + self.assert_length(events, 9) for ev in [x for x in events if x['event']['type'] not in ('message', 'stream')]: if isinstance(ev['event']['subscriptions'][0], dict): self.assertEqual(ev['event']['op'], 'add') diff --git a/zerver/views/streams.py b/zerver/views/streams.py index 86cfe2c7bc..b8ecdf4218 100644 --- a/zerver/views/streams.py +++ b/zerver/views/streams.py @@ -16,7 +16,8 @@ from zerver.lib.actions import bulk_remove_subscriptions, \ bulk_add_subscriptions, do_send_messages, get_subscriber_emails, do_rename_stream, \ do_deactivate_stream, do_change_stream_invite_only, do_add_default_stream, \ do_change_stream_description, do_get_streams, \ - do_remove_default_stream, get_topic_history_for_stream + do_remove_default_stream, get_topic_history_for_stream, \ + prep_stream_welcome_message from zerver.lib.response import json_success, json_error, json_response from zerver.lib.streams import access_stream_by_id, access_stream_by_name, \ check_stream_name, check_stream_name_available, filter_stream_authorization, \ @@ -300,6 +301,10 @@ def add_subscriptions_backend(request, user_profile, "private", realm_user_dict['email'], "", msg)) + if not user_profile.realm.is_zephyr_mirror_realm: + for stream in created_streams: + notifications.append(prep_stream_welcome_message(stream)) + if len(notifications) > 0: do_send_messages(notifications)