mirror of https://github.com/zulip/zulip.git
api: Update `update_message` event required fields.
Makes `edit_timestamp` and `user_id` required fields for all `update_message` events. Adds `rendering_only` as another required field to signal if events are only updating the rendered content of the message, which is currently the case for adding inline url previews. Updates `test_event.py` so that `do_update_message` and `do_update_embedded_data` refer to the same testing schema for `update_message` events, and therefore reflect the same required fields for the `update_message` event. The OpenAPI definition for `update_message` events is also updated to reflect the required field and descriptions of various properties are updated for the addition of the `rendering_only` property.
This commit is contained in:
parent
7077871111
commit
aaa627229e
|
@ -20,6 +20,19 @@ format used by the Zulip server that they are interacting with.
|
|||
|
||||
## Changes in Zulip 5.0
|
||||
|
||||
**Feature level 114**
|
||||
|
||||
* [`GET /events`](/api/get-events): Added `rendering_only` field to
|
||||
`update_message` event type to indicate if the message change only
|
||||
updated the rendering of the message or if it was the result of a
|
||||
user interaction.
|
||||
|
||||
* [`GET /events`](/api/get-events): Updated `update_message` event type
|
||||
to always include `edit_timestamp` and `user_id` fields. If the event
|
||||
only updates the rendering of the message, then the `user_id` field
|
||||
will be present, but with a value of null as the update was not the
|
||||
result of a user interaction.
|
||||
|
||||
**Feature level 113**
|
||||
|
||||
* `GET /realm/emoji`, `POST /realm/emoji/{emoji_name}`, [`GET
|
||||
|
|
|
@ -33,7 +33,7 @@ DESKTOP_WARNING_VERSION = "5.4.3"
|
|||
# Changes should be accompanied by documentation explaining what the
|
||||
# new level means in templates/zerver/api/changelog.md, as well as
|
||||
# "**Changes**" entries in the endpoint's documentation in `zulip.yaml`.
|
||||
API_FEATURE_LEVEL = 113
|
||||
API_FEATURE_LEVEL = 114
|
||||
|
||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
||||
# only when going from an old version of the code to a newer version. Bump
|
||||
|
|
|
@ -6561,7 +6561,14 @@ def do_update_embedded_data(
|
|||
content: Optional[str],
|
||||
rendering_result: MessageRenderingResult,
|
||||
) -> None:
|
||||
event: Dict[str, Any] = {"type": "update_message", "message_id": message.id}
|
||||
timestamp = timezone_now()
|
||||
event: Dict[str, Any] = {
|
||||
"type": "update_message",
|
||||
"user_id": None,
|
||||
"edit_timestamp": datetime_to_timestamp(timestamp),
|
||||
"message_id": message.id,
|
||||
"rendering_only": True,
|
||||
}
|
||||
changed_messages = [message]
|
||||
rendered_content: Optional[str] = None
|
||||
|
||||
|
@ -6630,6 +6637,7 @@ def do_update_message(
|
|||
"user_id": user_profile.id,
|
||||
"edit_timestamp": datetime_to_timestamp(timestamp),
|
||||
"message_id": target_message.id,
|
||||
"rendering_only": False,
|
||||
}
|
||||
|
||||
edit_history_event: Dict[str, Any] = {
|
||||
|
|
|
@ -1516,13 +1516,15 @@ def check_update_global_notifications(
|
|||
assert isinstance(setting, setting_type)
|
||||
|
||||
|
||||
# user_id field is null for embedded variant of update_message
|
||||
update_message_required_fields = [
|
||||
("type", Equals("update_message")),
|
||||
("user_id", int),
|
||||
("user_id", OptionalType(int)),
|
||||
("edit_timestamp", int),
|
||||
("message_id", int),
|
||||
("flags", ListType(str)),
|
||||
("message_ids", ListType(int)),
|
||||
("rendering_only", bool),
|
||||
]
|
||||
|
||||
update_message_stream_fields: List[Tuple[str, object]] = [
|
||||
|
@ -1531,11 +1533,14 @@ update_message_stream_fields: List[Tuple[str, object]] = [
|
|||
]
|
||||
|
||||
update_message_content_fields: List[Tuple[str, object]] = [
|
||||
("content", str),
|
||||
("is_me_message", bool),
|
||||
("orig_content", str),
|
||||
("orig_rendered_content", str),
|
||||
("prev_rendered_content_version", int),
|
||||
]
|
||||
|
||||
update_message_content_or_embedded_data_fields: List[Tuple[str, object]] = [
|
||||
("content", str),
|
||||
("rendered_content", str),
|
||||
]
|
||||
|
||||
|
@ -1566,14 +1571,13 @@ update_message_change_stream_or_topic_fields: List[Tuple[str, object]] = [
|
|||
update_message_optional_fields = (
|
||||
update_message_stream_fields
|
||||
+ update_message_content_fields
|
||||
+ update_message_content_or_embedded_data_fields
|
||||
+ update_message_topic_fields
|
||||
+ update_message_change_stream_fields
|
||||
+ update_message_change_stream_or_topic_fields
|
||||
)
|
||||
|
||||
# The schema here does not include the "embedded"
|
||||
# variant of update_message; it is for message
|
||||
# and topic editing.
|
||||
# The schema here includes the embedded variant of update_message
|
||||
update_message_event = event_dict_type(
|
||||
required_keys=update_message_required_fields,
|
||||
optional_keys=update_message_optional_fields,
|
||||
|
@ -1588,6 +1592,7 @@ def check_update_message(
|
|||
has_content: bool,
|
||||
has_topic: bool,
|
||||
has_new_stream_id: bool,
|
||||
is_embedded_update_only: bool,
|
||||
) -> None:
|
||||
# Always check the basic schema first.
|
||||
_check_update_message(var_name, event)
|
||||
|
@ -1601,6 +1606,7 @@ def check_update_message(
|
|||
|
||||
if has_content:
|
||||
expected_keys.update(tup[0] for tup in update_message_content_fields)
|
||||
expected_keys.update(tup[0] for tup in update_message_content_or_embedded_data_fields)
|
||||
|
||||
if has_topic:
|
||||
expected_keys.update(tup[0] for tup in update_message_topic_fields)
|
||||
|
@ -1610,21 +1616,16 @@ def check_update_message(
|
|||
expected_keys.update(tup[0] for tup in update_message_change_stream_fields)
|
||||
expected_keys.update(tup[0] for tup in update_message_change_stream_or_topic_fields)
|
||||
|
||||
if is_embedded_update_only:
|
||||
expected_keys.update(tup[0] for tup in update_message_content_or_embedded_data_fields)
|
||||
assert event["user_id"] is None
|
||||
else:
|
||||
assert isinstance(event["user_id"], int)
|
||||
|
||||
assert event["rendering_only"] == is_embedded_update_only
|
||||
assert expected_keys == actual_keys
|
||||
|
||||
|
||||
update_message_embedded_event = event_dict_type(
|
||||
required_keys=[
|
||||
("type", Equals("update_message")),
|
||||
("flags", ListType(str)),
|
||||
("content", str),
|
||||
("message_id", int),
|
||||
("message_ids", ListType(int)),
|
||||
("rendered_content", str),
|
||||
]
|
||||
)
|
||||
check_update_message_embedded = make_checker(update_message_embedded_event)
|
||||
|
||||
update_message_flags_add_event = event_dict_type(
|
||||
required_keys=[
|
||||
("type", Equals("update_message_flags")),
|
||||
|
|
|
@ -1966,9 +1966,14 @@ paths:
|
|||
- type: object
|
||||
additionalProperties: false
|
||||
description: |
|
||||
Event sent when a message has been edited.
|
||||
Event sent when a message's content, topic and/or
|
||||
stream has been edited or when a message's content
|
||||
has a rendering update, such as for an
|
||||
[inline URL preview][inline-url-previews].
|
||||
Sent to all users who had received the original
|
||||
message.
|
||||
|
||||
[inline-url-previews]: https://zulip.readthedocs.io/en/latest/subsystems/sending-messages.html#inline-url-previews
|
||||
properties:
|
||||
id:
|
||||
$ref: "#/components/schemas/EventIdSchema"
|
||||
|
@ -1979,20 +1984,42 @@ paths:
|
|||
- update_message
|
||||
user_id:
|
||||
type: integer
|
||||
nullable: true
|
||||
description: |
|
||||
The ID of the user who sent the message.
|
||||
|
||||
Not present if update_message event is for providing inline URL
|
||||
preview in message.
|
||||
Null when event is for a rendering update of the original message,
|
||||
such as for an [inline URL preview][inline-url-previews].
|
||||
|
||||
**Changes**: As of Zulip 5.0 (feature level 114), this field
|
||||
is present for all `update_message` events. Previously, this
|
||||
field was omitted for [inline URL preview][inline-url-previews]
|
||||
updates.
|
||||
rendering_only:
|
||||
type: boolean
|
||||
description: |
|
||||
Whether the event only updates the rendered content of the message.
|
||||
|
||||
This field should be used by clients to determine if the event
|
||||
only provides a rendering update to the message content,
|
||||
such as for an [inline URL preview][inline-url-previews].
|
||||
When `True`, the event does not reflect a user-generated edit
|
||||
and does not modify the message history.
|
||||
|
||||
**Changes**: New in Zulip 5.0 (feature level 114). Clients can
|
||||
correctly identify these rendering update event with earlier
|
||||
Zulip versions by checking whether the `user_id` field was omitted.
|
||||
message_id:
|
||||
type: integer
|
||||
description: |
|
||||
The ID of the message which was edited.
|
||||
The ID of the message which was edited or updated.
|
||||
|
||||
This field should be used to apply content edits to the client's
|
||||
cached message history. If the stream or topic was changed, the
|
||||
set of moved messages is encoded in the separate `message_ids`
|
||||
field, which is guaranteed to include `message_id`.
|
||||
cached message history, or to apply rendered content updates.
|
||||
|
||||
If the stream or topic was changed, the set of moved messages is
|
||||
encoded in the separate `message_ids` field, which is guaranteed
|
||||
to include `message_id`.
|
||||
message_ids:
|
||||
type: array
|
||||
items:
|
||||
|
@ -2033,19 +2060,21 @@ paths:
|
|||
The time when this message edit operation was processed by the
|
||||
server.
|
||||
|
||||
Not present if update_message event is for providing inline URL
|
||||
preview in message.
|
||||
**Changes**: As of Zulip 5.0 (feature level 114), this field
|
||||
is present for all `update_message` events. Previously, this
|
||||
field was omitted for [inline URL preview][inline-url-previews]
|
||||
updates.
|
||||
stream_name:
|
||||
type: string
|
||||
description: |
|
||||
Only present if the message was originally sent to a stream.
|
||||
Only present if the message was edited and originally sent to a stream.
|
||||
|
||||
The name of the stream that the message was sent to. Clients
|
||||
are recommended to use the `stream_id` field instead.
|
||||
stream_id:
|
||||
type: integer
|
||||
description: |
|
||||
Only present if the message was originally sent to a stream.
|
||||
Only present if the message was edited and originally sent to a stream.
|
||||
|
||||
The pre-edit stream for all of the messages with IDs in
|
||||
`message_ids`.
|
||||
|
@ -2068,9 +2097,12 @@ paths:
|
|||
topic and/or stream.
|
||||
|
||||
The choice the editing user made about which messages should be
|
||||
affected by a stream/topic edit: just the one indicated in
|
||||
`message_id`, messages in the same topic that had been sent
|
||||
after this one, or all messages in that topic.
|
||||
affected by a stream/topic edit:
|
||||
|
||||
- `change_one` => Just change the one indicated in `message_id`.
|
||||
- `change_later` => Change messages in the same topic that had
|
||||
been sent after this one.
|
||||
- `change_all`=> Change all messages in that topic.
|
||||
|
||||
This parameter should be used to decide whether to change
|
||||
navigation and compose box state in response to the edit. For
|
||||
|
@ -2159,14 +2191,18 @@ paths:
|
|||
content:
|
||||
type: string
|
||||
description: |
|
||||
Only present if this event changed the message content.
|
||||
Only present if this event changed the message content or
|
||||
updated the message content for an
|
||||
[inline URL preview][inline-url-previews].
|
||||
|
||||
The new content of the message with ID `message_id`, in the
|
||||
original Markdown.
|
||||
rendered_content:
|
||||
type: string
|
||||
description: |
|
||||
Only present if this event changed the message content.
|
||||
Only present if this event changed the message content or
|
||||
updated the message content for an
|
||||
[inline URL preview][inline-url-previews].
|
||||
|
||||
The new content of the message with ID `message_id`,
|
||||
rendered in HTML.
|
||||
|
@ -2182,9 +2218,12 @@ paths:
|
|||
required:
|
||||
- "type"
|
||||
- "id"
|
||||
- "user_id"
|
||||
- "message_id"
|
||||
- "message_ids"
|
||||
- "flags"
|
||||
- "edit_timestamp"
|
||||
- "rendering_only"
|
||||
example:
|
||||
{
|
||||
"type": "update_message",
|
||||
|
@ -2205,6 +2244,7 @@ paths:
|
|||
"topic_links": [],
|
||||
"message_ids": [58, 57],
|
||||
"flags": [],
|
||||
"rendering_only": false,
|
||||
"id": 0,
|
||||
}
|
||||
- type: object
|
||||
|
|
|
@ -154,7 +154,6 @@ from zerver.lib.event_schema import (
|
|||
check_update_display_settings,
|
||||
check_update_global_notifications,
|
||||
check_update_message,
|
||||
check_update_message_embedded,
|
||||
check_update_message_flags_add,
|
||||
check_update_message_flags_remove,
|
||||
check_user_group_add,
|
||||
|
@ -466,6 +465,7 @@ class NormalActionsTest(BaseAction):
|
|||
has_content=True,
|
||||
has_topic=False,
|
||||
has_new_stream_id=False,
|
||||
is_embedded_update_only=False,
|
||||
)
|
||||
|
||||
def test_huddle_send_message_events(self) -> None:
|
||||
|
@ -526,6 +526,7 @@ class NormalActionsTest(BaseAction):
|
|||
has_content=True,
|
||||
has_topic=False,
|
||||
has_new_stream_id=False,
|
||||
is_embedded_update_only=False,
|
||||
)
|
||||
|
||||
# Verify stream message editing - topic only
|
||||
|
@ -555,15 +556,25 @@ class NormalActionsTest(BaseAction):
|
|||
has_content=False,
|
||||
has_topic=True,
|
||||
has_new_stream_id=False,
|
||||
is_embedded_update_only=False,
|
||||
)
|
||||
|
||||
# Verify special case of embedded content update
|
||||
content = "embed_content"
|
||||
rendering_result = render_markdown(message, content)
|
||||
events = self.verify_action(
|
||||
lambda: do_update_embedded_data(self.user_profile, message, content, rendering_result),
|
||||
state_change_expected=False,
|
||||
)
|
||||
check_update_message_embedded("events[0]", events[0])
|
||||
check_update_message(
|
||||
"events[0]",
|
||||
events[0],
|
||||
is_stream_message=False,
|
||||
has_content=False,
|
||||
has_topic=False,
|
||||
has_new_stream_id=False,
|
||||
is_embedded_update_only=True,
|
||||
)
|
||||
|
||||
# Verify move topic to different stream.
|
||||
|
||||
|
@ -602,6 +613,7 @@ class NormalActionsTest(BaseAction):
|
|||
has_content=False,
|
||||
has_topic=False,
|
||||
has_new_stream_id=True,
|
||||
is_embedded_update_only=False,
|
||||
)
|
||||
|
||||
def test_update_message_flags(self) -> None:
|
||||
|
|
Loading…
Reference in New Issue