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};
if (msg.type === "stream") {
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_id,
);

View File

@ -1,9 +1,14 @@
from typing import List
from typing import List, Union
from django.utils.translation import gettext as _
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(
@ -15,11 +20,13 @@ def access_scheduled_message(
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(
sender=user_profile, delivered=False, delivery_type=ScheduledMessage.SEND_LATER
).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
]
return scheduled_message_dicts

View File

@ -4281,13 +4281,22 @@ class ScheduledMessageNotificationEmail(models.Model):
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
to: List[int]
type: str
content: str
rendered_content: str
topic: str
deliver_at: int
@ -4326,15 +4335,31 @@ class ScheduledMessage(models.Model):
def set_topic_name(self, topic_name: str) -> None:
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)
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,
to=recipient,
type=recipient_type_str,
content=self.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(),
deliver_at=int(self.scheduled_timestamp.timestamp() * 1000),
)

View File

@ -17358,21 +17358,23 @@ components:
- stream
- private
to:
type: array
description: |
An array of the tentative target audience IDs. For "stream"
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.
oneOf:
- type: integer
- type: array
items:
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:
type: string
description: |
For stream scheduled message, the tentative topic name. For private messages,
this will be ignored and should ideally
be the empty string. Should not contain null bytes.
Only present if `type` is `"stream"`.
The topic for the stream message.
content:
type: string
description: |
@ -17392,7 +17394,6 @@ components:
- scheduled_message_id
- type
- to
- topic
- content
- rendered_content
- deliver_at

View File

@ -221,7 +221,7 @@ class ScheduledMessageTest(ZulipTestCase):
scheduled_messages[0]["scheduled_message_id"], self.last_scheduled_message().id
)
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]["topic"], "Test topic")
self.assertEqual(