diff --git a/zerver/lib/topic_link_util.py b/zerver/lib/topic_link_util.py index cfba9a3c44..7df86341bd 100644 --- a/zerver/lib/topic_link_util.py +++ b/zerver/lib/topic_link_util.py @@ -45,10 +45,10 @@ def encode_hash_component(s: str) -> str: def get_fallback_markdown_link( - stream_id: int, stream_name: str, topic_name: str | None = None + stream_id: int, stream_name: str, topic_name: str | None = None, message_id: int | None = None ) -> str: """ - Generates the markdown link syntax for a stream or topic link. + Generates the markdown link syntax for a stream/topic/message link. """ escape = escape_invalid_stream_topic_characters link = f"#narrow/channel/{stream_id}-{encode_hash_component(stream_name.replace(' ', '-'))}" @@ -59,9 +59,26 @@ def get_fallback_markdown_link( topic_name = Message.EMPTY_TOPIC_FALLBACK_NAME text += f" > {escape(topic_name)}" + if message_id is not None: + link += f"/near/{message_id}" + text += " @ 💬" + return f"[{text}]({link})" +def get_message_link_syntax( + stream_id: int, stream_name: str, topic_name: str, message_id: int +) -> str: + # If the stream/topic name is such that it will + # generate an invalid #**stream>topic@message_id** syntax, + # we revert to generating the normal markdown syntax for a link. + if will_produce_broken_stream_topic_link(topic_name) or will_produce_broken_stream_topic_link( + stream_name + ): + return get_fallback_markdown_link(stream_id, stream_name, topic_name, message_id) + return f"#**{stream_name}>{topic_name}@{message_id}**" + + def get_stream_topic_link_syntax(stream_id: int, stream_name: str, topic_name: str) -> str: # If the stream/topic name is such that it will generate an invalid #**stream>topic** syntax, # we revert to generating the normal markdown syntax for a link. diff --git a/zerver/tests/test_topic_link_util.py b/zerver/tests/test_topic_link_util.py index 235ebdb27e..0da276b40e 100644 --- a/zerver/tests/test_topic_link_util.py +++ b/zerver/tests/test_topic_link_util.py @@ -1,5 +1,9 @@ from zerver.lib.test_classes import ZulipTestCase -from zerver.lib.topic_link_util import get_stream_link_syntax, get_stream_topic_link_syntax +from zerver.lib.topic_link_util import ( + get_message_link_syntax, + get_stream_link_syntax, + get_stream_topic_link_syntax, +) class TestTopicLinkUtil(ZulipTestCase): @@ -76,3 +80,22 @@ class TestTopicLinkUtil(ZulipTestCase): get_stream_topic_link_syntax(sweden_id, "Sw*den", ""), f"[#Sw*den > general chat](#narrow/channel/{sweden_id}-Sw*den/topic/)", ) + + def test_message_link_syntax(self) -> None: + sweden_id = self.make_stream("Sweden").id + self.assertEqual( + get_message_link_syntax(sweden_id, "Sweden", "topic", 123), + "#**Sweden>topic@123**", + ) + self.assertEqual( + get_message_link_syntax(sweden_id, "Sweden", "", 123), + "#**Sweden>@123**", + ) + self.assertEqual( + get_message_link_syntax(sweden_id, "Sw*den", "topic", 123), + f"[#Sw*den > topic @ 💬](#narrow/channel/{sweden_id}-Sw*den/topic/topic/near/123)", + ) + self.assertEqual( + get_message_link_syntax(sweden_id, "Sw*den", "", 123), + f"[#Sw*den > general chat @ 💬](#narrow/channel/{sweden_id}-Sw*den/topic//near/123)", + )