webhooks: Support configuring destination stream by id.

This commit is contained in:
PIG208 2021-06-30 20:15:27 +08:00 committed by Tim Abbott
parent efa19597bb
commit 0740c94517
3 changed files with 60 additions and 2 deletions

View File

@ -2680,6 +2680,20 @@ def check_send_stream_message(
return do_send_messages([message])[0]
def check_send_stream_message_by_id(
sender: UserProfile,
client: Client,
stream_id: int,
topic: str,
body: str,
realm: Optional[Realm] = None,
) -> int:
addressee = Addressee.for_stream_id(stream_id, topic)
message = check_message(sender, client, addressee, body, realm)
return do_send_messages([message])[0]
def check_send_private_message(
sender: UserProfile, client: Client, receiving_user: UserProfile, body: str
) -> int:

View File

@ -10,6 +10,7 @@ from django.utils.translation import gettext as _
from zerver.lib.actions import (
check_send_private_message,
check_send_stream_message,
check_send_stream_message_by_id,
send_rate_limited_pm_notification_to_bot_owner,
)
from zerver.lib.exceptions import ErrorCode, JsonableError, StreamDoesNotExistError
@ -114,7 +115,7 @@ def check_send_webhook_message(
# double escape their URLs in a manner that escaped space characters
# (%20) are never properly decoded. We work around that by making sure
# that the URL parameters are decoded on our end.
if unquote_url_parameters:
if stream is not None and unquote_url_parameters:
stream = unquote(stream)
if user_specified_topic is not None:
@ -123,7 +124,12 @@ def check_send_webhook_message(
topic = unquote(topic)
try:
check_send_stream_message(user_profile, request.client, stream, topic, body)
if stream.isdecimal():
check_send_stream_message_by_id(
user_profile, request.client, int(stream), topic, body
)
else:
check_send_stream_message(user_profile, request.client, stream, topic, body)
except StreamDoesNotExistError:
# A PM will be sent to the bot_owner by check_message, notifying
# that the webhook bot just tried to send a message to a non-existent

View File

@ -5,6 +5,7 @@ from unittest.mock import MagicMock, patch
from django.http import HttpRequest
from zerver.decorator import webhook_view
from zerver.lib.actions import do_rename_stream
from zerver.lib.exceptions import InvalidJSONError, JsonableError
from zerver.lib.send_email import FromAddress
from zerver.lib.test_classes import WebhookTestCase, ZulipTestCase
@ -134,6 +135,43 @@ class WebhooksCommonTestCase(ZulipTestCase):
self.assertEqual(djangoified_headers, expected_djangoified_headers)
class WebhookURLConfigurationTestCase(WebhookTestCase):
STREAM_NAME = "helloworld"
WEBHOOK_DIR_NAME = "helloworld"
URL_TEMPLATE = "/api/v1/external/helloworld?stream={stream}&api_key={api_key}"
def setUp(self) -> None:
super().setUp()
stream = self.subscribe(self.test_user, self.STREAM_NAME)
# In actual webhook tests, we will not need to use stream id.
# We assign stream id to STREAM_NAME for testing URL configuration only.
self.STREAM_NAME = str(stream.id)
do_rename_stream(stream, "helloworld_renamed", self.test_user)
self.url = self.build_webhook_url()
def test_trigger_stream_message_by_id(self) -> None:
# check_webhook cannot be used here as it
# subscribes the test user to self.STREAM_NAME
payload = self.get_body("hello")
self.send_webhook_payload(
self.test_user, self.url, payload, content_type="application/json"
)
expected_topic = "Hello World"
expected_message = "Hello! I am happy to be here! :smile:\nThe Wikipedia featured article for today is **[Marilyn Monroe](https://en.wikipedia.org/wiki/Marilyn_Monroe)**"
msg = self.get_last_message()
self.assert_stream_message(
message=msg,
stream_name="helloworld_renamed",
topic_name=expected_topic,
content=expected_message,
)
class MissingEventHeaderTestCase(WebhookTestCase):
STREAM_NAME = "groove"
URL_TEMPLATE = "/api/v1/external/groove?stream={stream}&api_key={api_key}"