mirror of
https://github.com/zulip/zulip.git
synced 2025-11-14 02:48:00 +00:00
request: Extract out methods from 'scheduled_messages' to reuse.
This is a prep commit that extracts the following two methods from '/actions/scheduled_messages' to reuse in the next commit. * extract_stream_id * extract_direct_message_recipient_ids The 'to' parameter for 'POST /typing' will follow the same pattern in the next commit as we currently have for the 'to' parameter in 'POST /scheduled_messages', so we can reuse these functions.
This commit is contained in:
committed by
Tim Abbott
parent
39ec5b9f66
commit
8b12cc606a
@@ -2,7 +2,6 @@ import datetime
|
|||||||
import logging
|
import logging
|
||||||
from typing import List, Optional, Sequence, Tuple
|
from typing import List, Optional, Sequence, Tuple
|
||||||
|
|
||||||
import orjson
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.utils.timezone import now as timezone_now
|
from django.utils.timezone import now as timezone_now
|
||||||
@@ -18,6 +17,7 @@ from zerver.actions.uploads import check_attachment_reference_change, do_claim_a
|
|||||||
from zerver.lib.addressee import Addressee
|
from zerver.lib.addressee import Addressee
|
||||||
from zerver.lib.exceptions import JsonableError, RealmDeactivatedError, UserDeactivatedError
|
from zerver.lib.exceptions import JsonableError, RealmDeactivatedError, UserDeactivatedError
|
||||||
from zerver.lib.message import SendMessageRequest, render_markdown, truncate_topic
|
from zerver.lib.message import SendMessageRequest, render_markdown, truncate_topic
|
||||||
|
from zerver.lib.recipient_parsing import extract_direct_message_recipient_ids, extract_stream_id
|
||||||
from zerver.lib.scheduled_messages import access_scheduled_message
|
from zerver.lib.scheduled_messages import access_scheduled_message
|
||||||
from zerver.lib.string_validation import check_stream_topic
|
from zerver.lib.string_validation import check_stream_topic
|
||||||
from zerver.models import (
|
from zerver.models import (
|
||||||
@@ -34,31 +34,6 @@ from zerver.tornado.django_api import send_event
|
|||||||
SCHEDULED_MESSAGE_LATE_CUTOFF_MINUTES = 10
|
SCHEDULED_MESSAGE_LATE_CUTOFF_MINUTES = 10
|
||||||
|
|
||||||
|
|
||||||
def extract_stream_id(req_to: str) -> List[int]:
|
|
||||||
# Recipient should only be a single stream ID.
|
|
||||||
try:
|
|
||||||
stream_id = int(req_to)
|
|
||||||
except ValueError:
|
|
||||||
raise JsonableError(_("Invalid data type for stream ID"))
|
|
||||||
return [stream_id]
|
|
||||||
|
|
||||||
|
|
||||||
def extract_direct_message_recipient_ids(req_to: str) -> List[int]:
|
|
||||||
try:
|
|
||||||
user_ids = orjson.loads(req_to)
|
|
||||||
except orjson.JSONDecodeError:
|
|
||||||
user_ids = req_to
|
|
||||||
|
|
||||||
if not isinstance(user_ids, list):
|
|
||||||
raise JsonableError(_("Invalid data type for recipients"))
|
|
||||||
|
|
||||||
for user_id in user_ids:
|
|
||||||
if not isinstance(user_id, int):
|
|
||||||
raise JsonableError(_("Recipient list may only contain user IDs"))
|
|
||||||
|
|
||||||
return list(set(user_ids))
|
|
||||||
|
|
||||||
|
|
||||||
def check_schedule_message(
|
def check_schedule_message(
|
||||||
sender: UserProfile,
|
sender: UserProfile,
|
||||||
client: Client,
|
client: Client,
|
||||||
@@ -182,7 +157,8 @@ def edit_scheduled_message(
|
|||||||
# Update message recipient if changed.
|
# Update message recipient if changed.
|
||||||
if message_to is not None:
|
if message_to is not None:
|
||||||
if updated_recipient_type_name == "stream":
|
if updated_recipient_type_name == "stream":
|
||||||
updated_recipient = extract_stream_id(message_to)
|
stream_id = extract_stream_id(message_to)
|
||||||
|
updated_recipient = [stream_id]
|
||||||
else:
|
else:
|
||||||
updated_recipient = extract_direct_message_recipient_ids(message_to)
|
updated_recipient = extract_direct_message_recipient_ids(message_to)
|
||||||
else:
|
else:
|
||||||
|
|||||||
31
zerver/lib/recipient_parsing.py
Normal file
31
zerver/lib/recipient_parsing.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
|
import orjson
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
|
||||||
|
|
||||||
|
def extract_stream_id(req_to: str) -> int:
|
||||||
|
# Recipient should only be a single stream ID.
|
||||||
|
try:
|
||||||
|
stream_id = int(req_to)
|
||||||
|
except ValueError:
|
||||||
|
raise JsonableError(_("Invalid data type for stream ID"))
|
||||||
|
return stream_id
|
||||||
|
|
||||||
|
|
||||||
|
def extract_direct_message_recipient_ids(req_to: str) -> List[int]:
|
||||||
|
try:
|
||||||
|
user_ids = orjson.loads(req_to)
|
||||||
|
except orjson.JSONDecodeError:
|
||||||
|
user_ids = req_to
|
||||||
|
|
||||||
|
if not isinstance(user_ids, list):
|
||||||
|
raise JsonableError(_("Invalid data type for recipients"))
|
||||||
|
|
||||||
|
for user_id in user_ids:
|
||||||
|
if not isinstance(user_id, int):
|
||||||
|
raise JsonableError(_("Recipient list may only contain user IDs"))
|
||||||
|
|
||||||
|
return list(set(user_ids))
|
||||||
46
zerver/tests/test_recipient_parsing.py
Normal file
46
zerver/tests/test_recipient_parsing.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import orjson
|
||||||
|
|
||||||
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.recipient_parsing import extract_direct_message_recipient_ids, extract_stream_id
|
||||||
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TestRecipientParsing(ZulipTestCase):
|
||||||
|
def test_extract_stream_id(self) -> None:
|
||||||
|
# stream message recipient = single stream ID.
|
||||||
|
stream_id = extract_stream_id("1")
|
||||||
|
self.assertEqual(stream_id, 1)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(JsonableError, "Invalid data type for stream ID"):
|
||||||
|
extract_stream_id("1,2")
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(JsonableError, "Invalid data type for stream ID"):
|
||||||
|
extract_stream_id("[1]")
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(JsonableError, "Invalid data type for stream ID"):
|
||||||
|
extract_stream_id("general")
|
||||||
|
|
||||||
|
def test_extract_recipient_ids(self) -> None:
|
||||||
|
# direct message recipients = user IDs.
|
||||||
|
user_ids = "[3,2,1]"
|
||||||
|
result = sorted(extract_direct_message_recipient_ids(user_ids))
|
||||||
|
self.assertEqual(result, [1, 2, 3])
|
||||||
|
|
||||||
|
# JSON list w/duplicates
|
||||||
|
user_ids = orjson.dumps([3, 3, 12]).decode()
|
||||||
|
result = sorted(extract_direct_message_recipient_ids(user_ids))
|
||||||
|
self.assertEqual(result, [3, 12])
|
||||||
|
|
||||||
|
# Invalid data
|
||||||
|
user_ids = "1, 12"
|
||||||
|
with self.assertRaisesRegex(JsonableError, "Invalid data type for recipients"):
|
||||||
|
extract_direct_message_recipient_ids(user_ids)
|
||||||
|
|
||||||
|
user_ids = orjson.dumps(dict(recipient=12)).decode()
|
||||||
|
with self.assertRaisesRegex(JsonableError, "Invalid data type for recipients"):
|
||||||
|
extract_direct_message_recipient_ids(user_ids)
|
||||||
|
|
||||||
|
# Heterogeneous lists are not supported
|
||||||
|
user_ids = orjson.dumps([3, 4, "eeshan@example.com"]).decode()
|
||||||
|
with self.assertRaisesRegex(JsonableError, "Recipient list may only contain user IDs"):
|
||||||
|
extract_direct_message_recipient_ids(user_ids)
|
||||||
@@ -11,12 +11,9 @@ from django.utils.timezone import now as timezone_now
|
|||||||
|
|
||||||
from zerver.actions.scheduled_messages import (
|
from zerver.actions.scheduled_messages import (
|
||||||
SCHEDULED_MESSAGE_LATE_CUTOFF_MINUTES,
|
SCHEDULED_MESSAGE_LATE_CUTOFF_MINUTES,
|
||||||
extract_direct_message_recipient_ids,
|
|
||||||
extract_stream_id,
|
|
||||||
try_deliver_one_scheduled_message,
|
try_deliver_one_scheduled_message,
|
||||||
)
|
)
|
||||||
from zerver.actions.users import change_user_is_active
|
from zerver.actions.users import change_user_is_active
|
||||||
from zerver.lib.exceptions import JsonableError
|
|
||||||
from zerver.lib.test_classes import ZulipTestCase
|
from zerver.lib.test_classes import ZulipTestCase
|
||||||
from zerver.lib.test_helpers import most_recent_message
|
from zerver.lib.test_helpers import most_recent_message
|
||||||
from zerver.lib.timestamp import timestamp_to_datetime
|
from zerver.lib.timestamp import timestamp_to_datetime
|
||||||
@@ -717,42 +714,3 @@ class ScheduledMessageTest(ZulipTestCase):
|
|||||||
[scheduled_message.id],
|
[scheduled_message.id],
|
||||||
)
|
)
|
||||||
self.assertEqual(scheduled_message.has_attachment, True)
|
self.assertEqual(scheduled_message.has_attachment, True)
|
||||||
|
|
||||||
def test_extract_stream_id(self) -> None:
|
|
||||||
# Scheduled stream message recipient = single stream ID.
|
|
||||||
stream_id = extract_stream_id("1")
|
|
||||||
self.assertEqual(stream_id, [1])
|
|
||||||
|
|
||||||
with self.assertRaisesRegex(JsonableError, "Invalid data type for stream ID"):
|
|
||||||
extract_stream_id("1,2")
|
|
||||||
|
|
||||||
with self.assertRaisesRegex(JsonableError, "Invalid data type for stream ID"):
|
|
||||||
extract_stream_id("[1]")
|
|
||||||
|
|
||||||
with self.assertRaisesRegex(JsonableError, "Invalid data type for stream ID"):
|
|
||||||
extract_stream_id("general")
|
|
||||||
|
|
||||||
def test_extract_recipient_ids(self) -> None:
|
|
||||||
# Scheduled direct message recipients = user IDs.
|
|
||||||
user_ids = "[3,2,1]"
|
|
||||||
result = sorted(extract_direct_message_recipient_ids(user_ids))
|
|
||||||
self.assertEqual(result, [1, 2, 3])
|
|
||||||
|
|
||||||
# JSON list w/duplicates
|
|
||||||
user_ids = orjson.dumps([3, 3, 12]).decode()
|
|
||||||
result = sorted(extract_direct_message_recipient_ids(user_ids))
|
|
||||||
self.assertEqual(result, [3, 12])
|
|
||||||
|
|
||||||
# Invalid data
|
|
||||||
user_ids = "1, 12"
|
|
||||||
with self.assertRaisesRegex(JsonableError, "Invalid data type for recipients"):
|
|
||||||
extract_direct_message_recipient_ids(user_ids)
|
|
||||||
|
|
||||||
user_ids = orjson.dumps(dict(recipient=12)).decode()
|
|
||||||
with self.assertRaisesRegex(JsonableError, "Invalid data type for recipients"):
|
|
||||||
extract_direct_message_recipient_ids(user_ids)
|
|
||||||
|
|
||||||
# Heterogeneous lists are not supported
|
|
||||||
user_ids = orjson.dumps([3, 4, "eeshan@example.com"]).decode()
|
|
||||||
with self.assertRaisesRegex(JsonableError, "Recipient list may only contain user IDs"):
|
|
||||||
extract_direct_message_recipient_ids(user_ids)
|
|
||||||
|
|||||||
@@ -8,10 +8,9 @@ from zerver.actions.scheduled_messages import (
|
|||||||
check_schedule_message,
|
check_schedule_message,
|
||||||
delete_scheduled_message,
|
delete_scheduled_message,
|
||||||
edit_scheduled_message,
|
edit_scheduled_message,
|
||||||
extract_direct_message_recipient_ids,
|
|
||||||
extract_stream_id,
|
|
||||||
)
|
)
|
||||||
from zerver.lib.exceptions import JsonableError
|
from zerver.lib.exceptions import JsonableError
|
||||||
|
from zerver.lib.recipient_parsing import extract_direct_message_recipient_ids, extract_stream_id
|
||||||
from zerver.lib.request import REQ, RequestNotes, has_request_variables
|
from zerver.lib.request import REQ, RequestNotes, has_request_variables
|
||||||
from zerver.lib.response import json_success
|
from zerver.lib.response import json_success
|
||||||
from zerver.lib.scheduled_messages import get_undelivered_scheduled_messages
|
from zerver.lib.scheduled_messages import get_undelivered_scheduled_messages
|
||||||
@@ -133,7 +132,8 @@ def create_scheduled_message_backend(
|
|||||||
assert client is not None
|
assert client is not None
|
||||||
|
|
||||||
if recipient_type_name == "stream":
|
if recipient_type_name == "stream":
|
||||||
message_to = extract_stream_id(req_to)
|
stream_id = extract_stream_id(req_to)
|
||||||
|
message_to = [stream_id]
|
||||||
else:
|
else:
|
||||||
message_to = extract_direct_message_recipient_ids(req_to)
|
message_to = extract_direct_message_recipient_ids(req_to)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user