message_edit: Apply topic edit restrictions to "(no topic)" messages.

Previously, editing topic of "(no topic)" messages was allowed
irrespective of time limit or the "edit_topic_policy" setting.
Since we are working in the direction of having "no topic" messages
feel reasonable, this commit changes the code to not consider them
as a special case and topic editing restrictions apply to them as
well now like all other messages.

We still highlight the topic edit icon in recipient bar without
hovering for "no topic" messages, but it is only shown when user
has permission to edit topics.
This commit is contained in:
Sahil Batra 2023-03-16 18:02:30 +05:30 committed by Tim Abbott
parent 61fa24fd5e
commit 440f9e397a
7 changed files with 28 additions and 32 deletions

View File

@ -20,6 +20,11 @@ format used by the Zulip server that they are interacting with.
## Changes in Zulip 7.0 ## Changes in Zulip 7.0
**Feature level 172**
* [`PATCH /messages/{message_id}`](/api/update-message): Topic editing
restrictions now apply to messages without a topic as well.
**Feature level 171**: **Feature level 171**:
* [`POST /fetch_api_key`](/api/fetch-api-key), * [`POST /fetch_api_key`](/api/fetch-api-key),

View File

@ -54,10 +54,6 @@ export function is_topic_editable(message, edit_limit_seconds_buffer = 0) {
return false; return false;
} }
if (message.topic === compose.empty_topic_placeholder()) {
return true;
}
if (!settings_data.user_can_move_messages_to_another_topic()) { if (!settings_data.user_can_move_messages_to_another_topic()) {
return false; return false;
} }

View File

@ -156,14 +156,21 @@ function set_timestr(message_container) {
function set_topic_edit_properties(group, message) { function set_topic_edit_properties(group, message) {
group.always_visible_topic_edit = false; group.always_visible_topic_edit = false;
group.on_hover_topic_edit = false; group.on_hover_topic_edit = false;
const is_topic_editable = message_edit.is_topic_editable(message);
// if a user who can edit a topic, can resolve it as well // if a user who can edit a topic, can resolve it as well
group.user_can_resolve_topic = message_edit.is_topic_editable(message); group.user_can_resolve_topic = is_topic_editable;
if (!is_topic_editable) {
return;
}
// Messages with no topics should always have an edit icon visible // Messages with no topics should always have an edit icon visible
// to encourage updating them. Admins can also edit any topic. // to encourage updating them. Admins can also edit any topic.
if (message.topic === compose.empty_topic_placeholder()) { if (message.topic === compose.empty_topic_placeholder()) {
group.always_visible_topic_edit = true; group.always_visible_topic_edit = true;
} else if (message_edit.is_topic_editable(message)) { } else {
group.on_hover_topic_edit = true; group.on_hover_topic_edit = true;
} }
} }

View File

@ -112,7 +112,7 @@ run_test("is_topic_editable", ({override}) => {
assert.equal(message_edit.is_topic_editable(message), false); assert.equal(message_edit.is_topic_editable(message), false);
message.topic = "translated: (no topic)"; message.topic = "translated: (no topic)";
assert.equal(message_edit.is_topic_editable(message), true); assert.equal(message_edit.is_topic_editable(message), false);
message.topic = "test topic"; message.topic = "test topic";
override(settings_data, "user_can_move_messages_to_another_topic", () => false); override(settings_data, "user_can_move_messages_to_another_topic", () => false);

View File

@ -106,22 +106,6 @@ def validate_message_edit_payload(
raise JsonableError(_("Widgets cannot be edited.")) raise JsonableError(_("Widgets cannot be edited."))
def can_edit_topic(
user_profile: UserProfile,
is_no_topic_msg: bool,
) -> bool:
# We allow anyone to edit (no topic) messages to help tend them.
if is_no_topic_msg:
return True
# The can_move_messages_to_another_topic helper returns whether the user can edit
# the topic or not based on edit_topic_policy setting and the user's role.
if user_profile.can_move_messages_to_another_topic():
return True
return False
def maybe_send_resolve_topic_notifications( def maybe_send_resolve_topic_notifications(
*, *,
user_profile: UserProfile, user_profile: UserProfile,
@ -995,9 +979,7 @@ def check_update_message(
): ):
raise JsonableError(_("You don't have permission to edit this message")) raise JsonableError(_("You don't have permission to edit this message"))
is_no_topic_msg = message.topic_name() == "(no topic)" if topic_name is not None and not user_profile.can_move_messages_to_another_topic():
if topic_name is not None and not can_edit_topic(user_profile, is_no_topic_msg):
raise JsonableError(_("You don't have permission to edit this message")) raise JsonableError(_("You don't have permission to edit this message"))
# If there is a change to the content, check that it hasn't been too long # If there is a change to the content, check that it hasn't been too long
@ -1019,7 +1001,6 @@ def check_update_message(
and user_profile.realm.move_messages_within_stream_limit_seconds is not None and user_profile.realm.move_messages_within_stream_limit_seconds is not None
and not user_profile.is_realm_admin and not user_profile.is_realm_admin
and not user_profile.is_moderator and not user_profile.is_moderator
and not is_no_topic_msg
): ):
deadline_seconds = ( deadline_seconds = (
user_profile.realm.move_messages_within_stream_limit_seconds + edit_limit_buffer user_profile.realm.move_messages_within_stream_limit_seconds + edit_limit_buffer

View File

@ -6520,6 +6520,11 @@ paths:
Before Zulip 7.0 (feature level 159), message senders were allowed Before Zulip 7.0 (feature level 159), message senders were allowed
to edit the topic indefinitely. to edit the topic indefinitely.
**Changes**: Before Zulip 7.0 (feature level 172), anyone could add
a topic to messages without topic regardless of topic edit
permissions. Now topic editing restrictions apply to messages without a
topic as well.
[config-message-editing]: /help/restrict-message-editing-and-deletion [config-message-editing]: /help/restrict-message-editing-and-deletion
x-curl-examples-parameters: x-curl-examples-parameters:
oneOf: oneOf:

View File

@ -1195,6 +1195,13 @@ class EditMessageTest(EditMessageTestCase):
id_, "G", "The time limit for editing this message's topic has passed", "hamlet" id_, "G", "The time limit for editing this message's topic has passed", "hamlet"
) )
# topic edit permissions apply on "no topic" messages as well
message.set_topic_name("(no topic)")
message.save()
do_edit_message_assert_error(
id_, "G", "The time limit for editing this message's topic has passed", "cordelia"
)
# set the topic edit limit to two weeks # set the topic edit limit to two weeks
do_set_realm_property( do_set_realm_property(
hamlet.realm, hamlet.realm,
@ -1205,11 +1212,6 @@ class EditMessageTest(EditMessageTestCase):
do_edit_message_assert_success(id_, "G", "cordelia") do_edit_message_assert_success(id_, "G", "cordelia")
do_edit_message_assert_success(id_, "H", "hamlet") do_edit_message_assert_success(id_, "H", "hamlet")
# anyone should be able to edit "no topic" indefinitely
message.set_topic_name("(no topic)")
message.save()
do_edit_message_assert_success(id_, "D", "cordelia")
@mock.patch("zerver.actions.message_edit.send_event") @mock.patch("zerver.actions.message_edit.send_event")
def test_edit_topic_public_history_stream(self, mock_send_event: mock.MagicMock) -> None: def test_edit_topic_public_history_stream(self, mock_send_event: mock.MagicMock) -> None:
stream_name = "Macbeth" stream_name = "Macbeth"