mirror of https://github.com/zulip/zulip.git
message_edit: Fix non-alternating resolve topic notifications.
Previously, it was possible for an unusual series of topic-edit actions to result in Notification Bot reporting that a topic was marked as resolved that had already been marked as resolved, etc.
This commit is contained in:
parent
b2dd15fd86
commit
e231a03eff
|
@ -5643,13 +5643,37 @@ def maybe_send_resolve_topic_notifications(
|
||||||
old_topic: str,
|
old_topic: str,
|
||||||
new_topic: str,
|
new_topic: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
# Note that topics will have already been stripped in check_update_message.
|
||||||
|
#
|
||||||
|
# This logic is designed to treat removing a weird "✔ ✔✔ "
|
||||||
|
# prefix as unresolving the topic.
|
||||||
if old_topic.lstrip(RESOLVED_TOPIC_PREFIX) != new_topic.lstrip(RESOLVED_TOPIC_PREFIX):
|
if old_topic.lstrip(RESOLVED_TOPIC_PREFIX) != new_topic.lstrip(RESOLVED_TOPIC_PREFIX):
|
||||||
return
|
return
|
||||||
|
|
||||||
if new_topic.startswith(RESOLVED_TOPIC_PREFIX):
|
if new_topic.startswith(RESOLVED_TOPIC_PREFIX) and not old_topic.startswith(
|
||||||
|
RESOLVED_TOPIC_PREFIX
|
||||||
|
):
|
||||||
notification_string = _("{user} has marked this topic as resolved.")
|
notification_string = _("{user} has marked this topic as resolved.")
|
||||||
else:
|
elif old_topic.startswith(RESOLVED_TOPIC_PREFIX) and not new_topic.startswith(
|
||||||
|
RESOLVED_TOPIC_PREFIX
|
||||||
|
):
|
||||||
notification_string = _("{user} has marked this topic as unresolved.")
|
notification_string = _("{user} has marked this topic as unresolved.")
|
||||||
|
else:
|
||||||
|
# If there's some other weird topic that does not toggle the
|
||||||
|
# state of "topic starts with RESOLVED_TOPIC_PREFIX", we do
|
||||||
|
# nothing. Any other logic could result in cases where we send
|
||||||
|
# these notifications in a non-alternating fashion.
|
||||||
|
#
|
||||||
|
# Note that it is still possible for an individual topic to
|
||||||
|
# have multiple "This topic was marked as resolved"
|
||||||
|
# notifications in a row: one can send new messages to the
|
||||||
|
# pre-resolve topic and then resolve the topic created that
|
||||||
|
# way to get multiple in the resolved topic. And then an
|
||||||
|
# administrator can the messages in between. We consider this
|
||||||
|
# to be a fundamental risk of irresponsible message deletion,
|
||||||
|
# not a bug with the "resolve topics" feature.
|
||||||
|
return
|
||||||
|
|
||||||
sender = get_system_bot(settings.NOTIFICATION_BOT)
|
sender = get_system_bot(settings.NOTIFICATION_BOT)
|
||||||
user_mention = f"@_**{user_profile.full_name}|{user_profile.id}**"
|
user_mention = f"@_**{user_profile.full_name}|{user_profile.id}**"
|
||||||
with override_language(stream.realm.default_language):
|
with override_language(stream.realm.default_language):
|
||||||
|
|
|
@ -2005,6 +2005,32 @@ class EditMessageTest(EditMessageTestCase):
|
||||||
f"@_**Iago|{admin_user.id}** has marked this topic as resolved.",
|
f"@_**Iago|{admin_user.id}** has marked this topic as resolved.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Now move to a weird state and confirm no new messages
|
||||||
|
weird_topic = "✔ ✔✔" + original_topic
|
||||||
|
result = self.client_patch(
|
||||||
|
"/json/messages/" + str(id1),
|
||||||
|
{
|
||||||
|
"message_id": id1,
|
||||||
|
"topic": weird_topic,
|
||||||
|
"propagate_mode": "change_all",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assert_json_success(result)
|
||||||
|
for msg_id in [id1, id2]:
|
||||||
|
msg = Message.objects.get(id=msg_id)
|
||||||
|
self.assertEqual(
|
||||||
|
weird_topic,
|
||||||
|
msg.topic_name(),
|
||||||
|
)
|
||||||
|
|
||||||
|
messages = get_topic_messages(admin_user, stream, weird_topic)
|
||||||
|
self.assert_length(messages, 3)
|
||||||
|
self.assertEqual(
|
||||||
|
messages[2].content,
|
||||||
|
f"@_**Iago|{admin_user.id}** has marked this topic as resolved.",
|
||||||
|
)
|
||||||
|
|
||||||
unresolved_topic = original_topic
|
unresolved_topic = original_topic
|
||||||
result = self.client_patch(
|
result = self.client_patch(
|
||||||
"/json/messages/" + str(id1),
|
"/json/messages/" + str(id1),
|
||||||
|
|
Loading…
Reference in New Issue