scheduled-messages: Update scheduled message objects in the API for type.

Updates the objects in the API for scheduled messages so that those
for stream messages return the `to` property as an integer since it
is always the unique stream ID and so that those for direct messages
do not have a `topic` property since direct messages never have a
topic.

Also makes small update so that web app scheduled messages overlay
has the correct stream ID.
This commit is contained in:
Lauryn Menard 2023-04-28 17:42:23 +02:00 committed by Tim Abbott
parent 4718eaa213
commit 7739703111
5 changed files with 56 additions and 23 deletions

View File

@ -26,7 +26,7 @@ function format(scheduled_messages) {
const msg_render_context = {...msg}; const msg_render_context = {...msg};
if (msg.type === "stream") { if (msg.type === "stream") {
msg_render_context.is_stream = true; msg_render_context.is_stream = true;
msg_render_context.stream_id = msg.to[0]; msg_render_context.stream_id = msg.to;
msg_render_context.stream_name = stream_data.maybe_get_stream_name( msg_render_context.stream_name = stream_data.maybe_get_stream_name(
msg_render_context.stream_id, msg_render_context.stream_id,
); );

View File

@ -1,9 +1,14 @@
from typing import List from typing import List, Union
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from zerver.lib.exceptions import ResourceNotFoundError from zerver.lib.exceptions import ResourceNotFoundError
from zerver.models import ScheduledMessage, ScheduledMessageDict, UserProfile from zerver.models import (
DirectScheduledMessageAPI,
ScheduledMessage,
StreamScheduledMessageAPI,
UserProfile,
)
def access_scheduled_message( def access_scheduled_message(
@ -15,11 +20,13 @@ def access_scheduled_message(
raise ResourceNotFoundError(_("Scheduled message does not exist")) raise ResourceNotFoundError(_("Scheduled message does not exist"))
def get_undelivered_scheduled_messages(user_profile: UserProfile) -> List[ScheduledMessageDict]: def get_undelivered_scheduled_messages(
user_profile: UserProfile,
) -> List[Union[DirectScheduledMessageAPI, StreamScheduledMessageAPI]]:
scheduled_messages = ScheduledMessage.objects.filter( scheduled_messages = ScheduledMessage.objects.filter(
sender=user_profile, delivered=False, delivery_type=ScheduledMessage.SEND_LATER sender=user_profile, delivered=False, delivery_type=ScheduledMessage.SEND_LATER
).order_by("scheduled_timestamp") ).order_by("scheduled_timestamp")
scheduled_message_dicts: List[ScheduledMessageDict] = [ scheduled_message_dicts: List[Union[DirectScheduledMessageAPI, StreamScheduledMessageAPI]] = [
scheduled_message.to_dict() for scheduled_message in scheduled_messages scheduled_message.to_dict() for scheduled_message in scheduled_messages
] ]
return scheduled_message_dicts return scheduled_message_dicts

View File

@ -4281,13 +4281,22 @@ class ScheduledMessageNotificationEmail(models.Model):
scheduled_timestamp = models.DateTimeField(db_index=True) scheduled_timestamp = models.DateTimeField(db_index=True)
class ScheduledMessageDict(TypedDict): class StreamScheduledMessageAPI(TypedDict):
scheduled_message_id: int
to: int
type: str
content: str
rendered_content: str
topic: str
deliver_at: int
class DirectScheduledMessageAPI(TypedDict):
scheduled_message_id: int scheduled_message_id: int
to: List[int] to: List[int]
type: str type: str
content: str content: str
rendered_content: str rendered_content: str
topic: str
deliver_at: int deliver_at: int
@ -4326,15 +4335,31 @@ class ScheduledMessage(models.Model):
def set_topic_name(self, topic_name: str) -> None: def set_topic_name(self, topic_name: str) -> None:
self.subject = topic_name self.subject = topic_name
def to_dict(self) -> ScheduledMessageDict: def to_dict(self) -> Union[StreamScheduledMessageAPI, DirectScheduledMessageAPI]:
recipient, recipient_type_str = get_recipient_ids(self.recipient, self.sender.id) recipient, recipient_type_str = get_recipient_ids(self.recipient, self.sender.id)
return ScheduledMessageDict( if recipient_type_str == "private":
# The topic for direct messages should always be an empty string.
assert self.topic_name() == ""
return DirectScheduledMessageAPI(
scheduled_message_id=self.id, scheduled_message_id=self.id,
to=recipient, to=recipient,
type=recipient_type_str, type=recipient_type_str,
content=self.content, content=self.content,
rendered_content=self.rendered_content, rendered_content=self.rendered_content,
deliver_at=int(self.scheduled_timestamp.timestamp() * 1000),
)
# The recipient for stream messages should always just be the unique stream ID.
assert len(recipient) == 1
return StreamScheduledMessageAPI(
scheduled_message_id=self.id,
to=recipient[0],
type=recipient_type_str,
content=self.content,
rendered_content=self.rendered_content,
topic=self.topic_name(), topic=self.topic_name(),
deliver_at=int(self.scheduled_timestamp.timestamp() * 1000), deliver_at=int(self.scheduled_timestamp.timestamp() * 1000),
) )

View File

@ -17358,21 +17358,23 @@ components:
- stream - stream
- private - private
to: to:
type: array oneOf:
description: | - type: integer
An array of the tentative target audience IDs. For "stream" - type: array
messages, this should contain exactly 1 ID, the ID of the
target stream. For private messages, this should be an array
of target user IDs. This cannot be an empty array since
scheduled messages are always addressed.
items: items:
type: integer type: integer
description: |
The scheduled message's tentative target audience.
For stream messages, it will be the unique ID of the target
stream. For private messages, it will be an array with the
target users' IDs.
topic: topic:
type: string type: string
description: | description: |
For stream scheduled message, the tentative topic name. For private messages, Only present if `type` is `"stream"`.
this will be ignored and should ideally
be the empty string. Should not contain null bytes. The topic for the stream message.
content: content:
type: string type: string
description: | description: |
@ -17392,7 +17394,6 @@ components:
- scheduled_message_id - scheduled_message_id
- type - type
- to - to
- topic
- content - content
- rendered_content - rendered_content
- deliver_at - deliver_at

View File

@ -221,7 +221,7 @@ class ScheduledMessageTest(ZulipTestCase):
scheduled_messages[0]["scheduled_message_id"], self.last_scheduled_message().id scheduled_messages[0]["scheduled_message_id"], self.last_scheduled_message().id
) )
self.assertEqual(scheduled_messages[0]["content"], content) self.assertEqual(scheduled_messages[0]["content"], content)
self.assertEqual(scheduled_messages[0]["to"], [self.get_stream_id("Verona")]) self.assertEqual(scheduled_messages[0]["to"], self.get_stream_id("Verona"))
self.assertEqual(scheduled_messages[0]["type"], "stream") self.assertEqual(scheduled_messages[0]["type"], "stream")
self.assertEqual(scheduled_messages[0]["topic"], "Test topic") self.assertEqual(scheduled_messages[0]["topic"], "Test topic")
self.assertEqual( self.assertEqual(