mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 13:03:29 +00:00
Extract get_service_bot_events().
There are several reasons to extract this function:
* It's easy to unit test without extensive mocking.
* It will show up when we profile code.
* It is something that you can mostly ignore for
most messages.
The main reason to extract this, though, is that we are about
to do some fairly complex splicing of data for the use case
of mentioning service bots on streams they are not subscribed to,
and we want to localize the complexity.
This commit is contained in:
@@ -863,6 +863,46 @@ def get_recipient_info(recipient, sender_id):
|
||||
) # type: RecipientInfoResult
|
||||
return info
|
||||
|
||||
def get_service_bot_events(sender, service_bot_tuples, mentioned_user_ids, recipient_type):
|
||||
# type: (UserProfile, List[Tuple[int, int]], Set[int], int) -> Dict[str, List[Dict[str, Any]]]
|
||||
# TODO: Right now, service bots need to be subscribed to a stream in order to
|
||||
# receive messages when mentioned; we will want to change that structure.
|
||||
# Prepare to collect service queue events triggered by the message.
|
||||
|
||||
event_dict = defaultdict(list) # type: Dict[str, List[Dict[str, Any]]]
|
||||
|
||||
# Avoid infinite loops by preventing messages sent by bots from generating
|
||||
# Service events.
|
||||
if sender.is_bot:
|
||||
return event_dict
|
||||
|
||||
for user_profile_id, bot_type in service_bot_tuples:
|
||||
if bot_type == UserProfile.OUTGOING_WEBHOOK_BOT:
|
||||
queue_name = 'outgoing_webhooks'
|
||||
elif bot_type == UserProfile.EMBEDDED_BOT:
|
||||
queue_name = 'embedded_bots'
|
||||
else:
|
||||
logging.error(
|
||||
'Unexpected bot_type for Service bot id=%s: %s' %
|
||||
(user_profile_id, bot_type))
|
||||
continue
|
||||
|
||||
# Mention triggers, primarily for stream messages
|
||||
if user_profile_id in mentioned_user_ids:
|
||||
trigger = 'mention'
|
||||
# PM triggers for personal and huddle messsages
|
||||
elif recipient_type != Recipient.STREAM:
|
||||
trigger = 'private_message'
|
||||
else:
|
||||
continue
|
||||
|
||||
event_dict[queue_name].append({
|
||||
'trigger': trigger,
|
||||
'user_profile_id': user_profile_id,
|
||||
})
|
||||
|
||||
return event_dict
|
||||
|
||||
def do_send_messages(messages_maybe_none):
|
||||
# type: (Sequence[Optional[MutableMapping[str, Any]]]) -> List[int]
|
||||
# Filter out messages which didn't pass internal_prep_message properly
|
||||
@@ -935,41 +975,12 @@ def do_send_messages(messages_maybe_none):
|
||||
|
||||
ums.extend(user_messages)
|
||||
|
||||
# Prepare to collect service queue events triggered by the message.
|
||||
message['message'].service_queue_events = defaultdict(list)
|
||||
|
||||
# Avoid infinite loops by preventing messages sent by bots from generating
|
||||
# Service events.
|
||||
sender = message['message'].sender
|
||||
if sender.is_bot:
|
||||
continue
|
||||
|
||||
# TODO: Right now, service bots need to be subscribed to a stream in order to
|
||||
# receive messages when mentioned; we will want to change that structure.
|
||||
for user_profile_id, bot_type in message['service_bot_tuples']:
|
||||
if bot_type == UserProfile.OUTGOING_WEBHOOK_BOT:
|
||||
queue_name = 'outgoing_webhooks'
|
||||
elif bot_type == UserProfile.EMBEDDED_BOT:
|
||||
queue_name = 'embedded_bots'
|
||||
else:
|
||||
logging.error(
|
||||
'Unexpected bot_type for Service bot id=%s: %s' %
|
||||
(user_profile_id, bot_type))
|
||||
continue
|
||||
|
||||
# Mention triggers, primarily for stream messages
|
||||
if user_profile_id in mentioned_user_ids:
|
||||
trigger = 'mention'
|
||||
# PM triggers for personal and huddle messsages
|
||||
elif message['message'].recipient.type != Recipient.STREAM:
|
||||
trigger = 'private_message'
|
||||
else:
|
||||
continue
|
||||
|
||||
message['message'].service_queue_events[queue_name].append({
|
||||
'trigger': trigger,
|
||||
'user_profile_id': user_profile_id,
|
||||
})
|
||||
message['message'].service_queue_events = get_service_bot_events(
|
||||
sender=message['message'].sender,
|
||||
service_bot_tuples=message['service_bot_tuples'],
|
||||
mentioned_user_ids=mentioned_user_ids,
|
||||
recipient_type=message['message'].recipient.type,
|
||||
)
|
||||
|
||||
bulk_insert_ums(ums)
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ from __future__ import print_function
|
||||
import mock
|
||||
from typing import Any, Union, Mapping, Callable
|
||||
|
||||
from zerver.lib.actions import do_create_user
|
||||
from zerver.lib.actions import (
|
||||
do_create_user,
|
||||
get_service_bot_events,
|
||||
)
|
||||
from zerver.lib.test_classes import ZulipTestCase
|
||||
from zerver.models import (
|
||||
get_realm,
|
||||
@@ -18,6 +21,69 @@ BOT_TYPE_TO_QUEUE_NAME = {
|
||||
UserProfile.EMBEDDED_BOT: 'embedded_bots',
|
||||
}
|
||||
|
||||
class TestServiceBotBasics(ZulipTestCase):
|
||||
def _get_outgoing_bot(self):
|
||||
# type: () -> UserProfile
|
||||
outgoing_bot = do_create_user(
|
||||
email="bar-bot@zulip.com",
|
||||
password="test",
|
||||
realm=get_realm("zulip"),
|
||||
full_name="BarBot",
|
||||
short_name='bb',
|
||||
bot_type=UserProfile.OUTGOING_WEBHOOK_BOT,
|
||||
bot_owner=self.example_user('cordelia'),
|
||||
)
|
||||
|
||||
return outgoing_bot
|
||||
|
||||
def test_service_events_for_pms(self):
|
||||
# type: () -> None
|
||||
sender = self.example_user('hamlet')
|
||||
assert(not sender.is_bot)
|
||||
|
||||
outgoing_bot = self._get_outgoing_bot()
|
||||
|
||||
event_dict = get_service_bot_events(
|
||||
sender=sender,
|
||||
service_bot_tuples=[
|
||||
(outgoing_bot.id, outgoing_bot.bot_type),
|
||||
],
|
||||
mentioned_user_ids=set(),
|
||||
recipient_type=Recipient.PERSONAL,
|
||||
)
|
||||
|
||||
expected = dict(
|
||||
outgoing_webhooks=[
|
||||
dict(trigger='private_message', user_profile_id=outgoing_bot.id),
|
||||
],
|
||||
)
|
||||
|
||||
self.assertEqual(event_dict, expected)
|
||||
|
||||
def test_service_events_for_stream_mentions(self):
|
||||
# type: () -> None
|
||||
sender = self.example_user('hamlet')
|
||||
assert(not sender.is_bot)
|
||||
|
||||
outgoing_bot = self._get_outgoing_bot()
|
||||
|
||||
event_dict = get_service_bot_events(
|
||||
sender=sender,
|
||||
service_bot_tuples=[
|
||||
(outgoing_bot.id, outgoing_bot.bot_type),
|
||||
],
|
||||
mentioned_user_ids={outgoing_bot.id},
|
||||
recipient_type=Recipient.STREAM,
|
||||
)
|
||||
|
||||
expected = dict(
|
||||
outgoing_webhooks=[
|
||||
dict(trigger='mention', user_profile_id=outgoing_bot.id),
|
||||
],
|
||||
)
|
||||
|
||||
self.assertEqual(event_dict, expected)
|
||||
|
||||
class TestServiceBotEventTriggers(ZulipTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
Reference in New Issue
Block a user