edit_history: Add support for empty topic name.

This commit is a part of the work to support empty string
as a topic name.

Previously, empty string was not a valid topic name.

Adds `allow_empty_topic_name` boolean parameter to
`GET /messages/{message_id}/history` endpoint to decide whether
the topic names in the fetched messages can be empty strings.

If False, the topic names in the fetched response will have the
value of `realm_empty_topic_display_name` field in `POST /register`
response replacing "" for channel messages.
This commit is contained in:
Prakhar Pratyush
2024-11-15 15:41:54 +05:30
committed by Tim Abbott
parent 01f749c0b8
commit 293db85f67
5 changed files with 83 additions and 4 deletions

View File

@@ -49,6 +49,10 @@ format used by the Zulip server that they are interacting with.
boolean parameter to decide whether the topic names in the fetched messages boolean parameter to decide whether the topic names in the fetched messages
can be empty strings. can be empty strings.
* [`GET /messages/{message_id}/history`](/api/get-message-history):
Added `allow_empty_topic_name` boolean parameter to decide whether the
topic names in the fetched message history objects can be empty strings.
**Feature level 333** **Feature level 333**
* [Message formatting](/api/message-formatting): System groups can now * [Message formatting](/api/message-formatting): System groups can now

View File

@@ -327,3 +327,11 @@ def maybe_rename_general_chat_to_empty_topic(topic_name: str) -> str:
if topic_name == Message.EMPTY_TOPIC_FALLBACK_NAME: if topic_name == Message.EMPTY_TOPIC_FALLBACK_NAME:
topic_name = "" topic_name = ""
return topic_name return topic_name
def maybe_rename_empty_topic_to_general_chat(
topic_name: str, is_channel_message: bool, allow_empty_topic_name: bool
) -> str:
if is_channel_message and topic_name == "" and not allow_empty_topic_name:
return Message.EMPTY_TOPIC_FALLBACK_NAME
return topic_name

View File

@@ -7310,6 +7310,21 @@ paths:
[edit-settings]: /help/view-a-messages-edit-history [edit-settings]: /help/view-a-messages-edit-history
parameters: parameters:
- $ref: "#/components/parameters/MessageId" - $ref: "#/components/parameters/MessageId"
- name: allow_empty_topic_name
in: query
description: |
Whether the topic names i.e. `topic` and `prev_topic` fields in
the `message_history` objects returned can be empty string.
If `false`, the value of `realm_empty_topic_display_name`
found in the [`POST /register`](/api/register-queue) response is
returned replacing the empty string as the topic name.
**Changes**: New in Zulip 10.0 (feature level 334).
schema:
type: boolean
default: false
example: true
x-response-description: | x-response-description: |
Please note that the original message's snapshot only contains the fields Please note that the original message's snapshot only contains the fields
`topic`, `content`, `rendered_content`, `timestamp` and `user_id`. This `topic`, `content`, `rendered_content`, `timestamp` and `user_id`. This

View File

@@ -686,3 +686,44 @@ class EmptyTopicNameTest(ZulipTestCase):
) )
data = self.assert_json_success(result) data = self.assert_json_success(result)
self.assertEqual(data["message"]["edit_history"][0]["topic"], "") self.assertEqual(data["message"]["edit_history"][0]["topic"], "")
def test_get_message_edit_history(self) -> None:
hamlet = self.example_user("hamlet")
self.login_user(hamlet)
message_id = self.send_stream_message(hamlet, "Denmark", topic_name="")
message_id_2 = self.send_stream_message(
hamlet, "Denmark", topic_name=Message.EMPTY_TOPIC_FALLBACK_NAME
)
params = {"topic": "new topic name"}
result = self.client_patch(f"/json/messages/{message_id}", params)
self.assert_json_success(result)
result = self.client_patch(f"/json/messages/{message_id_2}", params)
self.assert_json_success(result)
params = {"allow_empty_topic_name": "false"}
result = self.client_get(f"/json/messages/{message_id}/history", params)
data = self.assert_json_success(result)
self.assertEqual(data["message_history"][0]["topic"], Message.EMPTY_TOPIC_FALLBACK_NAME)
self.assertEqual(
data["message_history"][1]["prev_topic"], Message.EMPTY_TOPIC_FALLBACK_NAME
)
result = self.client_get(f"/json/messages/{message_id_2}/history", params)
data = self.assert_json_success(result)
self.assertEqual(data["message_history"][0]["topic"], Message.EMPTY_TOPIC_FALLBACK_NAME)
self.assertEqual(
data["message_history"][1]["prev_topic"], Message.EMPTY_TOPIC_FALLBACK_NAME
)
params = {"allow_empty_topic_name": "true"}
result = self.client_get(f"/json/messages/{message_id}/history", params)
data = self.assert_json_success(result)
self.assertEqual(data["message_history"][0]["topic"], "")
self.assertEqual(data["message_history"][1]["prev_topic"], "")
result = self.client_get(f"/json/messages/{message_id_2}/history", params)
data = self.assert_json_success(result)
self.assertEqual(data["message_history"][0]["topic"], "")
self.assertEqual(data["message_history"][1]["prev_topic"], "")

View File

@@ -23,13 +23,16 @@ from zerver.lib.message import (
from zerver.lib.request import RequestNotes from zerver.lib.request import RequestNotes
from zerver.lib.response import json_success from zerver.lib.response import json_success
from zerver.lib.timestamp import datetime_to_timestamp from zerver.lib.timestamp import datetime_to_timestamp
from zerver.lib.topic import maybe_rename_empty_topic_to_general_chat
from zerver.lib.typed_endpoint import OptionalTopic, PathOnly, typed_endpoint from zerver.lib.typed_endpoint import OptionalTopic, PathOnly, typed_endpoint
from zerver.lib.types import EditHistoryEvent, FormattedEditHistoryEvent from zerver.lib.types import EditHistoryEvent, FormattedEditHistoryEvent
from zerver.models import Message, UserProfile from zerver.models import Message, UserProfile
def fill_edit_history_entries( def fill_edit_history_entries(
raw_edit_history: list[EditHistoryEvent], message: Message raw_edit_history: list[EditHistoryEvent],
message: Message,
allow_empty_topic_name: bool,
) -> list[FormattedEditHistoryEvent]: ) -> list[FormattedEditHistoryEvent]:
""" """
This fills out the message edit history entries from the database This fills out the message edit history entries from the database
@@ -39,7 +42,10 @@ def fill_edit_history_entries(
""" """
prev_content = message.content prev_content = message.content
prev_rendered_content = message.rendered_content prev_rendered_content = message.rendered_content
prev_topic_name = message.topic_name() is_channel_message = message.is_stream_message()
prev_topic_name = maybe_rename_empty_topic_to_general_chat(
message.topic_name(), is_channel_message, allow_empty_topic_name
)
# Make sure that the latest entry in the history corresponds to the # Make sure that the latest entry in the history corresponds to the
# message's last edit time # message's last edit time
@@ -58,7 +64,9 @@ def fill_edit_history_entries(
} }
if "prev_topic" in edit_history_event: if "prev_topic" in edit_history_event:
prev_topic_name = edit_history_event["prev_topic"] prev_topic_name = maybe_rename_empty_topic_to_general_chat(
edit_history_event["prev_topic"], is_channel_message, allow_empty_topic_name
)
formatted_entry["prev_topic"] = prev_topic_name formatted_entry["prev_topic"] = prev_topic_name
# Fill current values for content/rendered_content. # Fill current values for content/rendered_content.
@@ -99,6 +107,7 @@ def get_message_edit_history(
user_profile: UserProfile, user_profile: UserProfile,
*, *,
message_id: PathOnly[NonNegativeInt], message_id: PathOnly[NonNegativeInt],
allow_empty_topic_name: Json[bool] = False,
) -> HttpResponse: ) -> HttpResponse:
if not user_profile.realm.allow_edit_history: if not user_profile.realm.allow_edit_history:
raise JsonableError(_("Message edit history is disabled in this organization")) raise JsonableError(_("Message edit history is disabled in this organization"))
@@ -111,7 +120,9 @@ def get_message_edit_history(
raw_edit_history = [] raw_edit_history = []
# Fill in all the extra data that will make it usable # Fill in all the extra data that will make it usable
message_edit_history = fill_edit_history_entries(raw_edit_history, message) message_edit_history = fill_edit_history_entries(
raw_edit_history, message, allow_empty_topic_name
)
return json_success(request, data={"message_history": list(reversed(message_edit_history))}) return json_success(request, data={"message_history": list(reversed(message_edit_history))})