scheduledmessages: Start using/expecting delivery_type as a param.

This commit is contained in:
Aditya Bansal
2018-01-12 17:08:45 +05:30
committed by showell
parent dcce8e7219
commit f272ea9087
5 changed files with 76 additions and 29 deletions

View File

@@ -350,6 +350,7 @@ function patch_request_for_scheduling(request) {
new_request.content = message; new_request.content = message;
new_request.deliver_at = deliver_at; new_request.deliver_at = deliver_at;
new_request.delivery_type = 'send_later';
new_request.tz_guess = moment.tz.guess(); new_request.tz_guess = moment.tz.guess();
return new_request; return new_request;
} }

View File

@@ -1041,6 +1041,10 @@ def do_schedule_messages(messages: Sequence[Optional[MutableMapping[str, Any]]])
scheduled_message.stream = message['stream'] scheduled_message.stream = message['stream']
scheduled_message.realm = message['realm'] scheduled_message.realm = message['realm']
scheduled_message.scheduled_timestamp = message['deliver_at'] scheduled_message.scheduled_timestamp = message['deliver_at']
if message['delivery_type'] == 'send_later':
scheduled_message.delivery_type = ScheduledMessage.SEND_LATER
elif message['delivery_type'] == 'remind':
scheduled_message.delivery_type = ScheduledMessage.REMIND
scheduled_messages.append(scheduled_message) scheduled_messages.append(scheduled_message)
@@ -1690,7 +1694,7 @@ def check_send_message(sender: UserProfile, client: Client, message_type_name: T
def check_schedule_message(sender: UserProfile, client: Client, def check_schedule_message(sender: UserProfile, client: Client,
message_type_name: Text, message_to: Sequence[Text], message_type_name: Text, message_to: Sequence[Text],
topic_name: Optional[Text], message_content: Text, topic_name: Optional[Text], message_content: Text,
deliver_at: datetime.datetime, delivery_type: Text, deliver_at: datetime.datetime,
realm: Optional[Realm]=None, realm: Optional[Realm]=None,
forwarder_user_profile: Optional[UserProfile]=None forwarder_user_profile: Optional[UserProfile]=None
) -> int: ) -> int:
@@ -1704,6 +1708,7 @@ def check_schedule_message(sender: UserProfile, client: Client,
message_content, realm=realm, message_content, realm=realm,
forwarder_user_profile=forwarder_user_profile) forwarder_user_profile=forwarder_user_profile)
message['deliver_at'] = deliver_at message['deliver_at'] = deliver_at
message['delivery_type'] = delivery_type
return do_schedule_messages([message])[0] return do_schedule_messages([message])[0]
def check_stream_name(stream_name: Text) -> None: def check_stream_name(stream_name: Text) -> None:

View File

@@ -10,7 +10,7 @@ from django.utils.timezone import now as timezone_now
from zerver.lib.context_managers import lockfile from zerver.lib.context_managers import lockfile
from zerver.lib.logging_util import log_to_file from zerver.lib.logging_util import log_to_file
from zerver.models import ScheduledMessage, Message from zerver.models import ScheduledMessage, Message, get_user
from zerver.lib.actions import do_send_messages from zerver.lib.actions import do_send_messages
from zerver.lib.addressee import Addressee from zerver.lib.addressee import Addressee
@@ -27,13 +27,21 @@ Usage: ./manage.py deliver_scheduled_messages
def construct_message(self, scheduled_message: ScheduledMessage) -> Dict[str, Any]: def construct_message(self, scheduled_message: ScheduledMessage) -> Dict[str, Any]:
message = Message() message = Message()
message.sender = scheduled_message.sender original_sender = scheduled_message.sender
message.content = scheduled_message.content message.content = scheduled_message.content
message.recipient = scheduled_message.recipient message.recipient = scheduled_message.recipient
message.subject = scheduled_message.subject message.subject = scheduled_message.subject
message.pub_date = timezone_now() message.pub_date = timezone_now()
message.sending_client = scheduled_message.sending_client message.sending_client = scheduled_message.sending_client
delivery_type = scheduled_message.delivery_type
if delivery_type == ScheduledMessage.SEND_LATER:
message.sender = original_sender
elif delivery_type == ScheduledMessage.REMIND:
message.sender = get_user(settings.REMINDER_BOT, original_sender.realm)
whos_reminding = ('%s asked me to do a reminder about:\n' % (original_sender.full_name))
message.content = whos_reminding + message.content
return {'message': message, 'stream': scheduled_message.stream, return {'message': message, 'stream': scheduled_message.stream,
'realm': scheduled_message.realm} 'realm': scheduled_message.realm}

View File

@@ -1280,7 +1280,8 @@ class ScheduledMessageTest(ZulipTestCase):
return ScheduledMessage.objects.all().order_by('-id')[0] return ScheduledMessage.objects.all().order_by('-id')[0]
def do_schedule_message(self, msg_type: str, to: str, msg: str, def do_schedule_message(self, msg_type: str, to: str, msg: str,
defer_until: str, tz_guess: str='', defer_until: str='', tz_guess: str='',
delivery_type: str='send_later',
realm_str: str='zulip') -> HttpResponse: realm_str: str='zulip') -> HttpResponse:
self.login(self.example_email("hamlet")) self.login(self.example_email("hamlet"))
@@ -1288,15 +1289,18 @@ class ScheduledMessageTest(ZulipTestCase):
if msg_type == 'stream': if msg_type == 'stream':
subject = 'Test subject' subject = 'Test subject'
result = self.client_post("/json/messages", payload = {"type": msg_type,
{"type": msg_type, "to": to,
"to": to, "client": "test suite",
"client": "test suite", "content": msg,
"content": msg, "subject": subject,
"subject": subject, "realm_str": realm_str,
"realm_str": realm_str, "delivery_type": delivery_type,
"deliver_at": defer_until, "tz_guess": tz_guess}
"tz_guess": tz_guess}) if defer_until:
payload["deliver_at"] = defer_until
result = self.client_post("/json/messages", payload)
return result return result
def test_schedule_message(self) -> None: def test_schedule_message(self) -> None:
@@ -1311,27 +1315,44 @@ class ScheduledMessageTest(ZulipTestCase):
self.assert_json_success(result) self.assert_json_success(result)
self.assertEqual(message.content, 'Test message 1') self.assertEqual(message.content, 'Test message 1')
self.assertEqual(message.scheduled_timestamp, convert_to_UTC(defer_until)) self.assertEqual(message.scheduled_timestamp, convert_to_UTC(defer_until))
self.assertEqual(message.delivery_type, ScheduledMessage.SEND_LATER)
# Scheduling a message for reminders.
result = self.do_schedule_message('stream', 'Verona',
content + ' 2', defer_until_str,
delivery_type='remind')
message = self.last_scheduled_message()
self.assert_json_success(result)
self.assertEqual(message.delivery_type, ScheduledMessage.REMIND)
# Scheduling a private message is successful. # Scheduling a private message is successful.
result = self.do_schedule_message('private', self.example_email("othello"), result = self.do_schedule_message('private', self.example_email("othello"),
content + ' 2', defer_until_str) content + ' 3', defer_until_str)
message = self.last_scheduled_message()
self.assert_json_success(result)
self.assertEqual(message.content, 'Test message 2')
self.assertEqual(message.scheduled_timestamp, convert_to_UTC(defer_until))
# Scheduling a message while guessing timezone.
tz_guess = 'Asia/Kolkata'
result = self.do_schedule_message('stream', 'Verona', content + ' 3',
defer_until_str, tz_guess=tz_guess)
message = self.last_scheduled_message() message = self.last_scheduled_message()
self.assert_json_success(result) self.assert_json_success(result)
self.assertEqual(message.content, 'Test message 3') self.assertEqual(message.content, 'Test message 3')
self.assertEqual(message.scheduled_timestamp, convert_to_UTC(defer_until))
self.assertEqual(message.delivery_type, ScheduledMessage.SEND_LATER)
result = self.do_schedule_message('private', self.example_email("othello"),
content + ' 4', defer_until_str,
delivery_type='remind')
message = self.last_scheduled_message()
self.assert_json_success(result)
self.assertEqual(message.delivery_type, ScheduledMessage.REMIND)
# Scheduling a message while guessing timezone.
tz_guess = 'Asia/Kolkata'
result = self.do_schedule_message('stream', 'Verona', content + ' 5',
defer_until_str, tz_guess=tz_guess)
message = self.last_scheduled_message()
self.assert_json_success(result)
self.assertEqual(message.content, 'Test message 5')
local_tz = get_timezone(tz_guess) local_tz = get_timezone(tz_guess)
# Since mypy is not able to recognize localize and normalize as attributes of tzinfo we use ignore. # Since mypy is not able to recognize localize and normalize as attributes of tzinfo we use ignore.
utz_defer_until = local_tz.normalize(local_tz.localize(defer_until)) # type: ignore # Reason in comment on previous line. utz_defer_until = local_tz.normalize(local_tz.localize(defer_until)) # type: ignore # Reason in comment on previous line.
self.assertEqual(message.scheduled_timestamp, self.assertEqual(message.scheduled_timestamp,
convert_to_UTC(utz_defer_until)) convert_to_UTC(utz_defer_until))
self.assertEqual(message.delivery_type, ScheduledMessage.SEND_LATER)
# Test with users timezone setting as set to some timezone rather than # Test with users timezone setting as set to some timezone rather than
# empty. This will help interpret timestamp in users local timezone. # empty. This will help interpret timestamp in users local timezone.
@@ -1339,15 +1360,16 @@ class ScheduledMessageTest(ZulipTestCase):
user.timezone = 'US/Pacific' user.timezone = 'US/Pacific'
user.save(update_fields=['timezone']) user.save(update_fields=['timezone'])
result = self.do_schedule_message('stream', 'Verona', result = self.do_schedule_message('stream', 'Verona',
content + ' 4', defer_until_str) content + ' 6', defer_until_str)
message = self.last_scheduled_message() message = self.last_scheduled_message()
self.assert_json_success(result) self.assert_json_success(result)
self.assertEqual(message.content, 'Test message 4') self.assertEqual(message.content, 'Test message 6')
local_tz = get_timezone(user.timezone) local_tz = get_timezone(user.timezone)
# Since mypy is not able to recognize localize and normalize as attributes of tzinfo we use ignore. # Since mypy is not able to recognize localize and normalize as attributes of tzinfo we use ignore.
utz_defer_until = local_tz.normalize(local_tz.localize(defer_until)) # type: ignore # Reason in comment on previous line. utz_defer_until = local_tz.normalize(local_tz.localize(defer_until)) # type: ignore # Reason in comment on previous line.
self.assertEqual(message.scheduled_timestamp, self.assertEqual(message.scheduled_timestamp,
convert_to_UTC(utz_defer_until)) convert_to_UTC(utz_defer_until))
self.assertEqual(message.delivery_type, ScheduledMessage.SEND_LATER)
def test_scheduling_in_past(self) -> None: def test_scheduling_in_past(self) -> None:
# Scheduling a message in past should fail. # Scheduling a message in past should fail.
@@ -1369,6 +1391,13 @@ class ScheduledMessageTest(ZulipTestCase):
content + ' 1', defer_until) content + ' 1', defer_until)
self.assert_json_error(result, 'Invalid timestamp for scheduling message.') self.assert_json_error(result, 'Invalid timestamp for scheduling message.')
def test_missing_deliver_at(self) -> None:
content = "Test message"
result = self.do_schedule_message('stream', 'Verona',
content + ' 1')
self.assert_json_error(result, 'Missing deliver_at in a request for delayed message delivery')
class EditMessageTest(ZulipTestCase): class EditMessageTest(ZulipTestCase):
def check_message(self, msg_id: int, subject: Optional[Text]=None, def check_message(self, msg_id: int, subject: Optional[Text]=None,
content: Optional[Text]=None) -> Message: content: Optional[Text]=None) -> Message:

View File

@@ -908,7 +908,7 @@ def same_realm_jabber_user(user_profile: UserProfile, email: Text) -> bool:
def handle_deferred_message(sender: UserProfile, client: Client, def handle_deferred_message(sender: UserProfile, client: Client,
message_type_name: Text, message_to: Sequence[Text], message_type_name: Text, message_to: Sequence[Text],
topic_name: Optional[Text], topic_name: Optional[Text],
message_content: Text, message_content: Text, delivery_type: Text,
defer_until: Text, tz_guess: Text, defer_until: Text, tz_guess: Text,
forwarder_user_profile: UserProfile, forwarder_user_profile: UserProfile,
realm: Optional[Realm]) -> HttpResponse: realm: Optional[Realm]) -> HttpResponse:
@@ -934,7 +934,7 @@ def handle_deferred_message(sender: UserProfile, client: Client,
return json_error(_("Invalid timestamp for scheduling message. Choose a time in future.")) return json_error(_("Invalid timestamp for scheduling message. Choose a time in future."))
check_schedule_message(sender, client, message_type_name, message_to, check_schedule_message(sender, client, message_type_name, message_to,
topic_name, message_content, topic_name, message_content, delivery_type,
deliver_at, realm=realm, deliver_at, realm=realm,
forwarder_user_profile=forwarder_user_profile) forwarder_user_profile=forwarder_user_profile)
return json_success({"deliver_at": str(deliver_at_usertz)}) return json_success({"deliver_at": str(deliver_at_usertz)})
@@ -953,6 +953,7 @@ def send_message_backend(request: HttpRequest, user_profile: UserProfile,
realm_str: Optional[Text]=REQ('realm_str', default=None), realm_str: Optional[Text]=REQ('realm_str', default=None),
local_id: Optional[Text]=REQ(default=None), local_id: Optional[Text]=REQ(default=None),
queue_id: Optional[Text]=REQ(default=None), queue_id: Optional[Text]=REQ(default=None),
delivery_type: Optional[Text]=REQ('delivery_type', default='send_now'),
defer_until: Optional[Text]=REQ('deliver_at', default=None), defer_until: Optional[Text]=REQ('deliver_at', default=None),
tz_guess: Optional[Text]=REQ('tz_guess', default=None)) -> HttpResponse: tz_guess: Optional[Text]=REQ('tz_guess', default=None)) -> HttpResponse:
client = request.client client = request.client
@@ -999,10 +1000,13 @@ def send_message_backend(request: HttpRequest, user_profile: UserProfile,
else: else:
sender = user_profile sender = user_profile
if defer_until: if (delivery_type == 'send_later' or delivery_type == 'remind') and defer_until is None:
return json_error(_("Missing deliver_at in a request for delayed message delivery"))
if delivery_type == 'send_later' or delivery_type == 'remind' and defer_until:
return handle_deferred_message(sender, client, message_type_name, return handle_deferred_message(sender, client, message_type_name,
message_to, topic_name, message_content, message_to, topic_name, message_content,
defer_until, tz_guess, delivery_type, defer_until, tz_guess,
forwarder_user_profile=user_profile, forwarder_user_profile=user_profile,
realm=realm) realm=realm)