Collapse linkify mentions (#123)

This commit is contained in:
Michael Manfre 2022-12-05 23:44:26 -05:00 committed by GitHub
parent 5b82c76def
commit 64cea557be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 6 deletions

View File

@ -276,6 +276,8 @@ class Post(StatorModel):
possible_matches[mention.username] = url
possible_matches[f"{mention.username}@{mention.domain_id}"] = url
collapse_name: dict[str, str] = {}
def replacer(match):
precursor = match.group(1)
handle = match.group(2).lower()
@ -284,6 +286,10 @@ class Post(StatorModel):
else:
short_handle = handle
if handle in possible_matches:
if short_handle not in collapse_name:
collapse_name[short_handle] = handle
elif collapse_name.get(short_handle) != handle:
short_handle = handle
return f'{precursor}<a href="{possible_matches[handle]}">@{short_handle}</a>'
else:
return match.group()

View File

@ -32,7 +32,9 @@ def test_fetch_post(httpx_mock: HTTPXMock, config_system):
@pytest.mark.django_db
def test_linkify_mentions_remote(identity, remote_identity):
def test_linkify_mentions_remote(
identity, identity2, remote_identity, remote_identity2
):
"""
Tests that we can linkify post mentions properly for remote use
"""
@ -77,9 +79,28 @@ def test_linkify_mentions_remote(identity, remote_identity):
== '<p>Hey <a href="https://remote.test/@test/">@test</a></p>'
)
# Test that collapsing only applies to the first unique, short username
post = Post.objects.create(
content="<p>Hey @TeSt@remote.test and @test@remote2.test</p>",
author=identity,
local=True,
)
post.mentions.set([remote_identity, remote_identity2])
assert post.safe_content_remote() == (
'<p>Hey <a href="https://remote.test/@test/">@test</a> '
'and <a href="https://remote2.test/@test/">@test@remote2.test</a></p>'
)
post.content = "<p>Hey @TeSt, @Test@remote.test and @test</p>"
assert post.safe_content_remote() == (
'<p>Hey <a href="https://remote2.test/@test/">@test</a>, '
'<a href="https://remote.test/@test/">@test@remote.test</a> '
'and <a href="https://remote2.test/@test/">@test</a></p>'
)
@pytest.mark.django_db
def test_linkify_mentions_local(identity, remote_identity):
def test_linkify_mentions_local(identity, identity2, remote_identity):
"""
Tests that we can linkify post mentions properly for local use
"""
@ -96,14 +117,16 @@ def test_linkify_mentions_local(identity, remote_identity):
)
# Test a full username (local)
post = Post.objects.create(
content="<p>@test@example.com, welcome!</p>",
content="<p>@test@example.com, welcome! @test@example2.com @test@example.com</p>",
author=identity,
local=True,
)
post.mentions.add(identity)
assert (
post.safe_content_local()
== '<p><a href="/@test@example.com/">@test</a>, welcome!</p>'
post.mentions.add(identity2)
assert post.safe_content_local() == (
'<p><a href="/@test@example.com/">@test</a>, welcome!'
' <a href="/@test@example2.com/">@test@example2.com</a>'
' <a href="/@test@example.com/">@test</a></p>'
)
# Test a full username (remote) with no <p>
post = Post.objects.create(

View File

@ -78,6 +78,12 @@ def domain() -> Domain:
return Domain.objects.create(domain="example.com", local=True, public=True)
@pytest.fixture
@pytest.mark.django_db
def domain2() -> Domain:
return Domain.objects.create(domain="example2.com", local=True, public=True)
@pytest.fixture
@pytest.mark.django_db
def identity(user, domain) -> Identity:
@ -95,6 +101,23 @@ def identity(user, domain) -> Identity:
return identity
@pytest.fixture
@pytest.mark.django_db
def identity2(user, domain2) -> Identity:
"""
Creates a basic test identity with a user and domain.
"""
identity = Identity.objects.create(
actor_uri="https://example2.com/@test@example2.com/",
username="test",
domain=domain2,
name="Test User Domain2",
local=True,
)
identity.users.set([user])
return identity
@pytest.fixture
def other_identity(user, domain) -> Identity:
"""
@ -128,6 +151,23 @@ def remote_identity() -> Identity:
)
@pytest.fixture
@pytest.mark.django_db
def remote_identity2() -> Identity:
"""
Creates a basic remote test identity with a domain.
"""
domain = Domain.objects.create(domain="remote2.test", local=False)
return Identity.objects.create(
actor_uri="https://remote2.test/test-actor/",
profile_uri="https://remote2.test/@test/",
username="test",
domain=domain,
name="Test2 Remote User",
local=False,
)
@pytest.fixture
def stator(config_system) -> StatorRunner:
"""