urls: Generate narrow links in backend with "channel" operator.

This commit is contained in:
Lauryn Menard 2024-10-04 16:54:16 +02:00 committed by Tim Abbott
parent 240c4d85ae
commit 70ab893d34
12 changed files with 53 additions and 53 deletions

View File

@ -2008,7 +2008,7 @@ class StreamPattern(CompiledInlineProcessor):
# provide more clarity to API clients. # provide more clarity to API clients.
# Also do the same for StreamTopicPattern. # Also do the same for StreamTopicPattern.
stream_url = encode_stream(stream_id, name) stream_url = encode_stream(stream_id, name)
el.set("href", f"/#narrow/stream/{stream_url}") el.set("href", f"/#narrow/channel/{stream_url}")
text = f"#{name}" text = f"#{name}"
el.text = markdown.util.AtomicString(text) el.text = markdown.util.AtomicString(text)
return el, m.start(), m.end() return el, m.start(), m.end()
@ -2037,7 +2037,7 @@ class StreamTopicPattern(CompiledInlineProcessor):
el.set("data-stream-id", str(stream_id)) el.set("data-stream-id", str(stream_id))
stream_url = encode_stream(stream_id, stream_name) stream_url = encode_stream(stream_id, stream_name)
topic_url = hash_util_encode(topic_name) topic_url = hash_util_encode(topic_name)
link = f"/#narrow/stream/{stream_url}/topic/{topic_url}" link = f"/#narrow/channel/{stream_url}/topic/{topic_url}"
el.set("href", link) el.set("href", link)
text = f"#{stream_name} > {topic_name}" text = f"#{stream_name} > {topic_name}"
el.text = markdown.util.AtomicString(text) el.text = markdown.util.AtomicString(text)

View File

@ -11,7 +11,7 @@ def is_same_server_message_link(url: str) -> bool:
if hostname not in {None, settings.EXTERNAL_HOST_WITHOUT_PORT}: if hostname not in {None, settings.EXTERNAL_HOST_WITHOUT_PORT}:
return False return False
# A message link always has category `narrow`, section `stream` # A message link always has category `narrow`, section `channel`
# or `dm`, and ends with `/near/<message_id>`, where <message_id> # or `dm`, and ends with `/near/<message_id>`, where <message_id>
# is a sequence of digits. The URL fragment of a message link has # is a sequence of digits. The URL fragment of a message link has
# at least 5 parts. e.g. '#narrow/dm/9,15-dm/near/43' # at least 5 parts. e.g. '#narrow/dm/9,15-dm/near/43'
@ -23,4 +23,4 @@ def is_same_server_message_link(url: str) -> bool:
section = fragment_parts[1] section = fragment_parts[1]
ends_with_near_message_id = fragment_parts[-2] == "near" and fragment_parts[-1].isdigit() ends_with_near_message_id = fragment_parts[-2] == "near" and fragment_parts[-1].isdigit()
return category == "narrow" and section in {"stream", "dm"} and ends_with_near_message_id return category == "narrow" and section in {"channel", "dm"} and ends_with_near_message_id

View File

@ -39,12 +39,12 @@ def direct_message_group_narrow_url(
def stream_narrow_url(realm: Realm, stream: Stream) -> str: def stream_narrow_url(realm: Realm, stream: Stream) -> str:
base_url = f"{realm.url}/#narrow/stream/" base_url = f"{realm.url}/#narrow/channel/"
return base_url + encode_stream(stream.id, stream.name) return base_url + encode_stream(stream.id, stream.name)
def topic_narrow_url(*, realm: Realm, stream: Stream, topic_name: str) -> str: def topic_narrow_url(*, realm: Realm, stream: Stream, topic_name: str) -> str:
base_url = f"{realm.url}/#narrow/stream/" base_url = f"{realm.url}/#narrow/channel/"
return f"{base_url}{encode_stream(stream.id, stream.name)}/topic/{hash_util_encode(topic_name)}" return f"{base_url}{encode_stream(stream.id, stream.name)}/topic/{hash_util_encode(topic_name)}"
@ -74,7 +74,7 @@ def near_stream_message_url(realm: Realm, message: dict[str, Any]) -> str:
parts = [ parts = [
realm.url, realm.url,
"#narrow", "#narrow",
"stream", "channel",
encoded_stream, encoded_stream,
"topic", "topic",
encoded_topic_name, encoded_topic_name,

View File

@ -488,9 +488,9 @@
}, },
{ {
"name": "fragment_link", "name": "fragment_link",
"input": "[foo](http://zulip.testserver/#narrow/stream/1-Denmark)", "input": "[foo](http://zulip.testserver/#narrow/channel/1-Denmark)",
"expected_output": "<p><a href=\"#narrow/stream/1-Denmark\">foo</a></p>", "expected_output": "<p><a href=\"#narrow/channel/1-Denmark\">foo</a></p>",
"marked_expected_output": "<p><a href=\"http://zulip.testserver/#narrow/stream/1-Denmark\">foo</a></p>" "marked_expected_output": "<p><a href=\"http://zulip.testserver/#narrow/channel/1-Denmark\">foo</a></p>"
}, },
{ {
"name": "not_fragment_link", "name": "not_fragment_link",
@ -1050,9 +1050,9 @@
}, },
{ {
"name": "normal_quote_and_reply", "name": "normal_quote_and_reply",
"input": "@_**Zoe|7** [said](http://zulip.testserver/#narrow/stream/13-social/topic/party/near/103):\n```quote\nHow are you?\n```\n\nGreat", "input": "@_**Zoe|7** [said](http://zulip.testserver/#narrow/channel/13-social/topic/party/near/103):\n```quote\nHow are you?\n```\n\nGreat",
"expected_output": "<p><span class=\"user-mention silent\" data-user-id=\"7\">Zoe</span> <a href=\"#narrow/stream/13-social/topic/party/near/103\">said</a>:</p>\n<blockquote>\n<p>How are you?</p>\n</blockquote>\n<p>Great</p>", "expected_output": "<p><span class=\"user-mention silent\" data-user-id=\"7\">Zoe</span> <a href=\"#narrow/channel/13-social/topic/party/near/103\">said</a>:</p>\n<blockquote>\n<p>How are you?</p>\n</blockquote>\n<p>Great</p>",
"marked_expected_output": "<p><span class=\"user-mention silent\" data-user-id=\"7\">Zoe</span> <a href=\"http://zulip.testserver/#narrow/stream/13-social/topic/party/near/103\">said</a>:</p>\n<blockquote>\n<p>How are you?</p>\n</blockquote>\n<p>Great</p>", "marked_expected_output": "<p><span class=\"user-mention silent\" data-user-id=\"7\">Zoe</span> <a href=\"http://zulip.testserver/#narrow/channel/13-social/topic/party/near/103\">said</a>:</p>\n<blockquote>\n<p>How are you?</p>\n</blockquote>\n<p>Great</p>",
"text_content": "[…]\nGreat" "text_content": "[…]\nGreat"
}, },
{ {
@ -1316,8 +1316,8 @@
"" ""
], ],
[ [
"http://zulip.testserver/#narrow/stream/1-Denmark", "http://zulip.testserver/#narrow/channel/1-Denmark",
"<p><a href=\"#narrow/stream/1-Denmark\">http://zulip.testserver/#narrow/stream/1-Denmark</a></p>", "<p><a href=\"#narrow/channel/1-Denmark\">http://zulip.testserver/#narrow/channel/1-Denmark</a></p>",
"" ""
], ],
[ [

View File

@ -11,17 +11,17 @@
}, },
{ {
"name": "stream_message_link", "name": "stream_message_link",
"message_link": "#narrow/stream/8-design/topic/desktop/near/82", "message_link": "#narrow/channel/8-design/topic/desktop/near/82",
"expected_output": true "expected_output": true
}, },
{ {
"name": "stream_link", "name": "stream_link",
"message_link": "#narrow/stream/8-design", "message_link": "#narrow/channel/8-design",
"expected_output": false "expected_output": false
}, },
{ {
"name": "topic_link", "name": "topic_link",
"message_link": "#narrow/stream/8-design/topic/desktop", "message_link": "#narrow/channel/8-design/topic/desktop",
"expected_output": false "expected_output": false
}, },
{ {

View File

@ -4747,9 +4747,9 @@ class GoogleAuthBackendTest(SocialAuthBase):
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertEqual(res["Location"], "http://zulip.testserver/user_uploads/path_to_image") self.assertEqual(res["Location"], "http://zulip.testserver/user_uploads/path_to_image")
res = test_redirect_to_next_url("/#narrow/stream/7-test-here") res = test_redirect_to_next_url("/#narrow/channel/7-test-here")
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertEqual(res["Location"], "http://zulip.testserver/#narrow/stream/7-test-here") self.assertEqual(res["Location"], "http://zulip.testserver/#narrow/channel/7-test-here")
def test_log_into_subdomain_when_token_is_malformed(self) -> None: def test_log_into_subdomain_when_token_is_malformed(self) -> None:
data: ExternalAuthDataDict = { data: ExternalAuthDataDict = {
@ -5600,7 +5600,7 @@ class TestDevAuthBackend(ZulipTestCase):
# to the backend. Rather we depend upon the browser's behaviour of persisting # to the backend. Rather we depend upon the browser's behaviour of persisting
# hash anchors in between redirect requests. See below stackoverflow conversation # hash anchors in between redirect requests. See below stackoverflow conversation
# https://stackoverflow.com/questions/5283395/url-hash-is-persisting-between-redirects # https://stackoverflow.com/questions/5283395/url-hash-is-persisting-between-redirects
res = do_local_login("/accounts/login/local/?next=#narrow/stream/7-test-here") res = do_local_login("/accounts/login/local/?next=#narrow/channel/7-test-here")
self.assertEqual(res.status_code, 302) self.assertEqual(res.status_code, 302)
self.assertEqual(res["Location"], "http://zulip.testserver") self.assertEqual(res["Location"], "http://zulip.testserver")

View File

@ -509,7 +509,7 @@ class TestDigestEmailMessages(ZulipTestCase):
realm, recently_created_streams, can_access_public=True realm, recently_created_streams, can_access_public=True
) )
self.assertEqual(stream_count, 1) self.assertEqual(stream_count, 1)
expected_html = f"<a href='http://zulip.testserver/#narrow/stream/{stream.id}-New-stream'>New stream</a>" expected_html = f"<a href='http://zulip.testserver/#narrow/channel/{stream.id}-New-stream'>New stream</a>"
self.assertEqual(stream_info["html"][0], expected_html) self.assertEqual(stream_info["html"][0], expected_html)
# guests don't see our stream # guests don't see our stream

View File

@ -588,10 +588,10 @@ class MarkdownLinkTest(ZulipTestCase):
sender_user_profile = self.example_user("othello") sender_user_profile = self.example_user("othello")
message = Message(sender=sender_user_profile, sending_client=get_client("test")) message = Message(sender=sender_user_profile, sending_client=get_client("test"))
msg = "http://zulip.testserver/#narrow/stream/999-hello" msg = "http://zulip.testserver/#narrow/channel/999-hello"
self.assertEqual( self.assertEqual(
markdown_convert(msg, message_realm=realm, message=message).rendered_content, markdown_convert(msg, message_realm=realm, message=message).rendered_content,
'<p><a href="#narrow/stream/999-hello">http://zulip.testserver/#narrow/stream/999-hello</a></p>', '<p><a href="#narrow/channel/999-hello">http://zulip.testserver/#narrow/channel/999-hello</a></p>',
) )
msg = f"http://zulip.testserver/user_uploads/{realm.id}/ff/file.txt" msg = f"http://zulip.testserver/user_uploads/{realm.id}/ff/file.txt"
@ -622,10 +622,10 @@ class MarkdownLinkTest(ZulipTestCase):
sender_user_profile = self.example_user("othello") sender_user_profile = self.example_user("othello")
message = Message(sender=sender_user_profile, sending_client=get_client("test")) message = Message(sender=sender_user_profile, sending_client=get_client("test"))
msg = "[hello](http://zulip.testserver/#narrow/stream/999-hello)" msg = "[hello](http://zulip.testserver/#narrow/channel/999-hello)"
self.assertEqual( self.assertEqual(
markdown_convert(msg, message_realm=realm, message=message).rendered_content, markdown_convert(msg, message_realm=realm, message=message).rendered_content,
'<p><a href="#narrow/stream/999-hello">hello</a></p>', '<p><a href="#narrow/channel/999-hello">hello</a></p>',
) )
msg = f"[hello](http://zulip.testserver/user_uploads/{realm.id}/ff/file.txt)" msg = f"[hello](http://zulip.testserver/user_uploads/{realm.id}/ff/file.txt)"
@ -2984,7 +2984,7 @@ class MarkdownStreamMentionTests(ZulipTestCase):
content = "#**Denmark**" content = "#**Denmark**"
self.assertEqual( self.assertEqual(
render_message_markdown(msg, content).rendered_content, render_message_markdown(msg, content).rendered_content,
f'<p><a class="stream" data-stream-id="{denmark.id}" href="/#narrow/stream/{denmark.id}-Denmark">#{denmark.name}</a></p>', f'<p><a class="stream" data-stream-id="{denmark.id}" href="/#narrow/channel/{denmark.id}-Denmark">#{denmark.name}</a></p>',
) )
def test_invalid_stream_followed_by_valid_mention(self) -> None: def test_invalid_stream_followed_by_valid_mention(self) -> None:
@ -2998,7 +2998,7 @@ class MarkdownStreamMentionTests(ZulipTestCase):
content = "#**Invalid** and #**Denmark**" content = "#**Invalid** and #**Denmark**"
self.assertEqual( self.assertEqual(
render_message_markdown(msg, content).rendered_content, render_message_markdown(msg, content).rendered_content,
f'<p>#<strong>Invalid</strong> and <a class="stream" data-stream-id="{denmark.id}" href="/#narrow/stream/{denmark.id}-Denmark">#{denmark.name}</a></p>', f'<p>#<strong>Invalid</strong> and <a class="stream" data-stream-id="{denmark.id}" href="/#narrow/channel/{denmark.id}-Denmark">#{denmark.name}</a></p>',
) )
def test_stream_multiple(self) -> None: def test_stream_multiple(self) -> None:
@ -3017,10 +3017,10 @@ class MarkdownStreamMentionTests(ZulipTestCase):
"<p>Look to " "<p>Look to "
'<a class="stream" ' '<a class="stream" '
f'data-stream-id="{denmark.id}" ' f'data-stream-id="{denmark.id}" '
f'href="/#narrow/stream/{denmark.id}-Denmark">#{denmark.name}</a> and ' f'href="/#narrow/channel/{denmark.id}-Denmark">#{denmark.name}</a> and '
'<a class="stream" ' '<a class="stream" '
f'data-stream-id="{scotland.id}" ' f'data-stream-id="{scotland.id}" '
f'href="/#narrow/stream/{scotland.id}-Scotland">#{scotland.name}</a>, ' f'href="/#narrow/channel/{scotland.id}-Scotland">#{scotland.name}</a>, '
"there something</p>", "there something</p>",
) )
@ -3032,7 +3032,7 @@ class MarkdownStreamMentionTests(ZulipTestCase):
content = "#**CaseSens**" content = "#**CaseSens**"
self.assertEqual( self.assertEqual(
render_message_markdown(msg, content).rendered_content, render_message_markdown(msg, content).rendered_content,
f'<p><a class="stream" data-stream-id="{case_sens.id}" href="/#narrow/stream/{case_sens.id}-{case_sens.name}">#{case_sens.name}</a></p>', f'<p><a class="stream" data-stream-id="{case_sens.id}" href="/#narrow/channel/{case_sens.id}-{case_sens.name}">#{case_sens.name}</a></p>',
) )
def test_stream_case_sensitivity_nonmatching(self) -> None: def test_stream_case_sensitivity_nonmatching(self) -> None:
@ -3060,7 +3060,7 @@ class MarkdownStreamMentionTests(ZulipTestCase):
content = "#**Denmark>some topic**" content = "#**Denmark>some topic**"
self.assertEqual( self.assertEqual(
render_message_markdown(msg, content).rendered_content, render_message_markdown(msg, content).rendered_content,
f'<p><a class="stream-topic" data-stream-id="{denmark.id}" href="/#narrow/stream/{denmark.id}-Denmark/topic/some.20topic">#{denmark.name} &gt; some topic</a></p>', f'<p><a class="stream-topic" data-stream-id="{denmark.id}" href="/#narrow/channel/{denmark.id}-Denmark/topic/some.20topic">#{denmark.name} &gt; some topic</a></p>',
) )
def test_topic_atomic_string(self) -> None: def test_topic_atomic_string(self) -> None:
@ -3082,7 +3082,7 @@ class MarkdownStreamMentionTests(ZulipTestCase):
content = "#**Denmark>#1234**" content = "#**Denmark>#1234**"
self.assertEqual( self.assertEqual(
render_message_markdown(msg, content).rendered_content, render_message_markdown(msg, content).rendered_content,
f'<p><a class="stream-topic" data-stream-id="{denmark.id}" href="/#narrow/stream/{denmark.id}-Denmark/topic/.231234">#{denmark.name} &gt; #1234</a></p>', f'<p><a class="stream-topic" data-stream-id="{denmark.id}" href="/#narrow/channel/{denmark.id}-Denmark/topic/.231234">#{denmark.name} &gt; #1234</a></p>',
) )
def test_topic_multiple(self) -> None: def test_topic_multiple(self) -> None:
@ -3099,11 +3099,11 @@ class MarkdownStreamMentionTests(ZulipTestCase):
render_message_markdown(msg, content).rendered_content, render_message_markdown(msg, content).rendered_content,
"<p>This has two links: " "<p>This has two links: "
f'<a class="stream-topic" data-stream-id="{denmark.id}" ' f'<a class="stream-topic" data-stream-id="{denmark.id}" '
f'href="/#narrow/stream/{denmark.id}-{denmark.name}/topic/some.20topic">' f'href="/#narrow/channel/{denmark.id}-{denmark.name}/topic/some.20topic">'
f"#{denmark.name} &gt; some topic</a>" f"#{denmark.name} &gt; some topic</a>"
" and " " and "
f'<a class="stream-topic" data-stream-id="{scotland.id}" ' f'<a class="stream-topic" data-stream-id="{scotland.id}" '
f'href="/#narrow/stream/{scotland.id}-{scotland.name}/topic/other.20topic">' f'href="/#narrow/channel/{scotland.id}-{scotland.name}/topic/other.20topic">'
f"#{scotland.name} &gt; other topic</a>" f"#{scotland.name} &gt; other topic</a>"
".</p>", ".</p>",
) )
@ -3125,7 +3125,7 @@ class MarkdownStreamMentionTests(ZulipTestCase):
msg = Message(sender=sender_user_profile, sending_client=get_client("test"), realm=realm) msg = Message(sender=sender_user_profile, sending_client=get_client("test"), realm=realm)
content = "#**привет**" content = "#**привет**"
quoted_name = ".D0.BF.D1.80.D0.B8.D0.B2.D0.B5.D1.82" quoted_name = ".D0.BF.D1.80.D0.B8.D0.B2.D0.B5.D1.82"
href = f"/#narrow/stream/{uni.id}-{quoted_name}" href = f"/#narrow/channel/{uni.id}-{quoted_name}"
self.assertEqual( self.assertEqual(
render_message_markdown(msg, content).rendered_content, render_message_markdown(msg, content).rendered_content,
f'<p><a class="stream" data-stream-id="{uni.id}" href="{href}">#{uni.name}</a></p>', f'<p><a class="stream" data-stream-id="{uni.id}" href="{href}">#{uni.name}</a></p>',
@ -3148,7 +3148,7 @@ class MarkdownStreamMentionTests(ZulipTestCase):
stream = self.make_stream(stream_name="Stream #1234", realm=realm) stream = self.make_stream(stream_name="Stream #1234", realm=realm)
msg = Message(sender=sender_user_profile, sending_client=get_client("test"), realm=realm) msg = Message(sender=sender_user_profile, sending_client=get_client("test"), realm=realm)
content = "#**Stream #1234**" content = "#**Stream #1234**"
href = f"/#narrow/stream/{stream.id}-Stream-.231234" href = f"/#narrow/channel/{stream.id}-Stream-.231234"
self.assertEqual( self.assertEqual(
render_message_markdown(msg, content).rendered_content, render_message_markdown(msg, content).rendered_content,
f'<p><a class="stream" data-stream-id="{stream.id}" href="{href}">#{stream.name}</a></p>', f'<p><a class="stream" data-stream-id="{stream.id}" href="{href}">#{stream.name}</a></p>',
@ -3290,7 +3290,7 @@ class MarkdownApiTests(ZulipTestCase):
stream_id = get_stream("Denmark", get_realm("zulip")).id stream_id = get_stream("Denmark", get_realm("zulip")).id
self.assertEqual( self.assertEqual(
response_dict["rendered"], response_dict["rendered"],
f'<p>This mentions <a class="stream" data-stream-id="{stream_id}" href="/#narrow/stream/{stream_id}-Denmark">#Denmark</a> and <span class="user-mention" data-user-id="{user_id}">@King Hamlet</span>.</p>', f'<p>This mentions <a class="stream" data-stream-id="{stream_id}" href="/#narrow/channel/{stream_id}-Denmark">#Denmark</a> and <span class="user-mention" data-user-id="{user_id}">@King Hamlet</span>.</p>',
) )

View File

@ -1220,7 +1220,7 @@ class TestMessageNotificationEmails(ZulipTestCase):
"Come and join us in #**Verona**.", "Come and join us in #**Verona**.",
) )
stream_id = get_stream("Verona", get_realm("zulip")).id stream_id = get_stream("Verona", get_realm("zulip")).id
href = f"http://zulip.testserver/#narrow/stream/{stream_id}-Verona" href = f"http://zulip.testserver/#narrow/channel/{stream_id}-Verona"
verify_body_include = [ verify_body_include = [
f'<a class="stream" href="{href}" data-stream-id="{stream_id}">#Verona</a' f'<a class="stream" href="{href}" data-stream-id="{stream_id}">#Verona</a'
] ]
@ -1493,13 +1493,13 @@ class TestMessageNotificationEmails(ZulipTestCase):
# A narrow URL which begins with a '#'. # A narrow URL which begins with a '#'.
test_data = ( test_data = (
'<p><a href="#narrow/stream/test/topic/test.20topic/near/142"' '<p><a href="#narrow/channel/test/topic/test.20topic/near/142"'
' title="#narrow/stream/test/topic/test.20topic/near/142">Conversation</a></p>' ' title="#narrow/channel/test/topic/test.20topic/near/142">Conversation</a></p>'
) )
actual_output = convert(test_data) actual_output = convert(test_data)
expected_output = ( expected_output = (
'<div><p><a href="http://example.com/#narrow/stream/test/topic/test.20topic/near/142"' '<div><p><a href="http://example.com/#narrow/channel/test/topic/test.20topic/near/142"'
' title="http://example.com/#narrow/stream/test/topic/test.20topic/near/142">Conversation</a></p></div>' ' title="http://example.com/#narrow/channel/test/topic/test.20topic/near/142">Conversation</a></p></div>'
) )
self.assertEqual(actual_output, expected_output) self.assertEqual(actual_output, expected_output)

View File

@ -132,13 +132,13 @@ class DoRestCallTests(ZulipTestCase):
self.assertEqual( self.assertEqual(
m.output, m.output,
[ [
f'WARNING:root:Message http://zulip.testserver/#narrow/stream/999-Verona/topic/Foo/near/ triggered an outgoing webhook, returning status code 500.\n Content of response (in quotes): "{final_response.text}"' f'WARNING:root:Message http://zulip.testserver/#narrow/channel/999-Verona/topic/Foo/near/ triggered an outgoing webhook, returning status code 500.\n Content of response (in quotes): "{final_response.text}"'
], ],
) )
bot_owner_notification = self.get_last_message() bot_owner_notification = self.get_last_message()
self.assertEqual( self.assertEqual(
bot_owner_notification.content, bot_owner_notification.content,
"""[A message](http://zulip.testserver/#narrow/stream/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook. """[A message](http://zulip.testserver/#narrow/channel/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook.
The webhook got a response with status code *500*.""", The webhook got a response with status code *500*.""",
) )
@ -196,7 +196,7 @@ The webhook got a response with status code *500*.""",
self.assertEqual( self.assertEqual(
m.output, m.output,
[ [
f'WARNING:root:Message http://zulip.testserver/#narrow/stream/999-Verona/topic/Foo/near/ triggered an outgoing webhook, returning status code 400.\n Content of response (in quotes): "{final_response.text}"' f'WARNING:root:Message http://zulip.testserver/#narrow/channel/999-Verona/topic/Foo/near/ triggered an outgoing webhook, returning status code 400.\n Content of response (in quotes): "{final_response.text}"'
], ],
) )
@ -205,7 +205,7 @@ The webhook got a response with status code *500*.""",
bot_owner_notification = self.get_last_message() bot_owner_notification = self.get_last_message()
self.assertEqual( self.assertEqual(
bot_owner_notification.content, bot_owner_notification.content,
"""[A message](http://zulip.testserver/#narrow/stream/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook. """[A message](http://zulip.testserver/#narrow/channel/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook.
The webhook got a response with status code *400*.""", The webhook got a response with status code *400*.""",
) )
@ -291,7 +291,7 @@ The webhook got a response with status code *400*.""",
bot_owner_notification = self.get_last_message() bot_owner_notification = self.get_last_message()
self.assertEqual( self.assertEqual(
bot_owner_notification.content, bot_owner_notification.content,
"""[A message](http://zulip.testserver/#narrow/stream/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook. """[A message](http://zulip.testserver/#narrow/channel/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook.
When trying to send a request to the webhook service, an exception of type RequestException occurred: When trying to send a request to the webhook service, an exception of type RequestException occurred:
``` ```
I'm a generic exception :( I'm a generic exception :(
@ -322,7 +322,7 @@ I'm a generic exception :(
bot_owner_notification = self.get_last_message() bot_owner_notification = self.get_last_message()
self.assertEqual( self.assertEqual(
bot_owner_notification.content, bot_owner_notification.content,
"""[A message](http://zulip.testserver/#narrow/stream/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook. """[A message](http://zulip.testserver/#narrow/channel/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook.
The outgoing webhook server attempted to send a message in Zulip, but that request resulted in the following error: The outgoing webhook server attempted to send a message in Zulip, but that request resulted in the following error:
> Widgets: API programmer sent invalid JSON content\nThe response contains the following payload:\n```\n'{"content": "whatever", "widget_content": "test"}'\n```""", > Widgets: API programmer sent invalid JSON content\nThe response contains the following payload:\n```\n'{"content": "whatever", "widget_content": "test"}'\n```""",
) )
@ -349,7 +349,7 @@ The outgoing webhook server attempted to send a message in Zulip, but that reque
bot_owner_notification = self.get_last_message() bot_owner_notification = self.get_last_message()
self.assertEqual( self.assertEqual(
bot_owner_notification.content, bot_owner_notification.content,
"""[A message](http://zulip.testserver/#narrow/stream/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook. """[A message](http://zulip.testserver/#narrow/channel/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook.
The outgoing webhook server attempted to send a message in Zulip, but that request resulted in the following error: The outgoing webhook server attempted to send a message in Zulip, but that request resulted in the following error:
> Invalid response format\nThe response contains the following payload:\n```\n'true'\n```""", > Invalid response format\nThe response contains the following payload:\n```\n'true'\n```""",
) )
@ -378,7 +378,7 @@ The outgoing webhook server attempted to send a message in Zulip, but that reque
bot_owner_notification = self.get_last_message() bot_owner_notification = self.get_last_message()
self.assertEqual( self.assertEqual(
bot_owner_notification.content, bot_owner_notification.content,
"""[A message](http://zulip.testserver/#narrow/stream/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook. """[A message](http://zulip.testserver/#narrow/channel/999-Verona/topic/Foo/near/) to your bot @_**Outgoing Webhook** triggered an outgoing webhook.
The outgoing webhook server attempted to send a message in Zulip, but that request resulted in the following error: The outgoing webhook server attempted to send a message in Zulip, but that request resulted in the following error:
> Invalid JSON in response\nThe response contains the following payload:\n```\n"this isn't valid json"\n```""", > Invalid JSON in response\nThe response contains the following payload:\n```\n"this isn't valid json"\n```""",
) )

View File

@ -5124,7 +5124,7 @@ class TestPushNotificationsContent(ZulipTestCase):
}, },
{ {
"name": "stream_names", "name": "stream_names",
"rendered_content": f'<p>Testing stream names <a class="stream" data-stream-id="{stream.id}" href="/#narrow/stream/Verona">#Verona</a>.</p>', "rendered_content": f'<p>Testing stream names <a class="stream" data-stream-id="{stream.id}" href="/#narrow/channel/Verona">#Verona</a>.</p>',
"expected_output": "Testing stream names #Verona.", "expected_output": "Testing stream names #Verona.",
}, },
] ]

View File

@ -4352,7 +4352,7 @@ class SubscriptionAPITest(ZulipTestCase):
self.assertEqual(msg.recipient.type_id, new_stream_announcements_stream.id) self.assertEqual(msg.recipient.type_id, new_stream_announcements_stream.id)
self.assertEqual(msg.sender_id, self.notification_bot(realm).id) self.assertEqual(msg.sender_id, self.notification_bot(realm).id)
stream_id = Stream.objects.latest("id").id stream_id = Stream.objects.latest("id").id
expected_rendered_msg = f'<p><span class="user-mention silent" data-user-id="{user.id}">{user.full_name}</span> created a new channel <a class="stream" data-stream-id="{stream_id}" href="/#narrow/stream/{stream_id}-{invite_streams[0]}">#{invite_streams[0]}</a>.</p>' expected_rendered_msg = f'<p><span class="user-mention silent" data-user-id="{user.id}">{user.full_name}</span> created a new channel <a class="stream" data-stream-id="{stream_id}" href="/#narrow/channel/{stream_id}-{invite_streams[0]}">#{invite_streams[0]}</a>.</p>'
self.assertEqual(msg.rendered_content, expected_rendered_msg) self.assertEqual(msg.rendered_content, expected_rendered_msg)
def test_successful_subscriptions_notifies_with_escaping(self) -> None: def test_successful_subscriptions_notifies_with_escaping(self) -> None: