Fixed mention linking with mixed case usernames (#265)

This commit is contained in:
Michael Manfre 2022-12-24 23:04:25 -05:00 committed by GitHub
parent da00a67cb5
commit ab398758a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 12 deletions

View file

@ -139,24 +139,26 @@ class ContentRenderer:
url = str(mention.urls.view) url = str(mention.urls.view)
else: else:
url = mention.absolute_profile_uri() url = mention.absolute_profile_uri()
possible_matches[mention.username] = url possible_matches[mention.username.lower()] = url
possible_matches[f"{mention.username}@{mention.domain_id}"] = url possible_matches[f"{mention.username.lower()}@{mention.domain_id}"] = url
collapse_name: dict[str, str] = {} collapse_name: dict[str, str] = {}
def replacer(match): def replacer(match):
precursor = match.group(1) precursor = match.group(1)
handle = match.group(2).lower() handle = match.group(2)
if "@" in handle: if "@" in handle:
short_handle = handle.split("@", 1)[0] short_handle = handle.split("@", 1)[0]
else: else:
short_handle = handle short_handle = handle
if handle in possible_matches: handle_hash = handle.lower()
if short_handle not in collapse_name: short_hash = short_handle.lower()
collapse_name[short_handle] = handle if handle_hash in possible_matches:
elif collapse_name.get(short_handle) != handle: if short_hash not in collapse_name:
collapse_name[short_hash] = handle_hash
elif collapse_name.get(short_hash) != handle_hash:
short_handle = handle short_handle = handle
return f'{precursor}<a href="{possible_matches[handle]}">@{short_handle}</a>' return f'{precursor}<a href="{possible_matches[handle_hash]}">@{short_handle}</a>'
else: else:
return match.group() return match.group()

View file

@ -87,7 +87,7 @@ def test_linkify_mentions_remote(
post.mentions.add(remote_identity) post.mentions.add(remote_identity)
assert ( assert (
post.safe_content_remote() post.safe_content_remote()
== '<p>Hey <a href="https://remote.test/@test/">@test</a></p>' == '<p>Hey <a href="https://remote.test/@test/">@TeSt</a></p>'
) )
# Test trailing dot (remote) # Test trailing dot (remote)
@ -110,14 +110,14 @@ def test_linkify_mentions_remote(
) )
post.mentions.set([remote_identity, remote_identity2]) post.mentions.set([remote_identity, remote_identity2])
assert post.safe_content_remote() == ( assert post.safe_content_remote() == (
'<p>Hey <a href="https://remote.test/@test/">@test</a> ' '<p>Hey <a href="https://remote.test/@test/">@TeSt</a> '
'and <a href="https://remote2.test/@test/">@test@remote2.test</a></p>' 'and <a href="https://remote2.test/@test/">@test@remote2.test</a></p>'
) )
post.content = "<p>Hey @TeSt, @Test@remote.test and @test</p>" post.content = "<p>Hey @TeSt, @Test@remote.test and @test</p>"
assert post.safe_content_remote() == ( assert post.safe_content_remote() == (
'<p>Hey <a href="https://remote2.test/@test/">@test</a>, ' '<p>Hey <a href="https://remote2.test/@test/">@TeSt</a>, '
'<a href="https://remote.test/@test/">@test@remote.test</a> ' '<a href="https://remote.test/@test/">@Test@remote.test</a> '
'and <a href="https://remote2.test/@test/">@test</a></p>' 'and <a href="https://remote2.test/@test/">@test</a></p>'
) )

View file

@ -62,3 +62,28 @@ def test_link_preservation():
) )
== 'Hello <a href="/@andrew@aeracode.org/">@andrew</a>, I want to link to this <a href="/tags/hashtag/" class="hashtag">#hashtag</a>: <a href="http://example.com/@andrew/#notahashtag" rel="nofollow">here</a> and rewrite <a href="/tags/thishashtag/" class="hashtag">#thishashtag</a>' == 'Hello <a href="/@andrew@aeracode.org/">@andrew</a>, I want to link to this <a href="/tags/hashtag/" class="hashtag">#hashtag</a>: <a href="http://example.com/@andrew/#notahashtag" rel="nofollow">here</a> and rewrite <a href="/tags/thishashtag/" class="hashtag">#thishashtag</a>'
) )
@pytest.mark.django_db
def test_link_mixcase_mentions():
renderer = ContentRenderer(local=True)
fake_mention = Mock()
fake_mention.username = "Manfre"
fake_mention.domain_id = "manfre.net"
fake_mention.urls.view = "/@Manfre@manfre.net/"
fake_mention2 = Mock()
fake_mention2.username = "manfre"
fake_mention2.domain_id = "takahe.social"
fake_mention2.urls.view = "https://takahe.social/@manfre@takahe.social/"
fake_post = Mock()
fake_post.mentions.all.return_value = [fake_mention, fake_mention2]
fake_post.author.domain.uri_domain = "example.com"
fake_post.emojis.all.return_value = []
assert (
renderer.render_post(
"@Manfre@manfre.net @mAnFrE@takahe.social @manfre@manfre.net",
fake_post,
)
== '<a href="/@Manfre@manfre.net/">@Manfre</a> <a href="https://takahe.social/@manfre@takahe.social/">@mAnFrE@takahe.social</a> <a href="/@Manfre@manfre.net/">@manfre</a>'
)