Skip to content

Commit

Permalink
Fix mention user url
Browse files Browse the repository at this point in the history
  • Loading branch information
mtomilov committed Feb 12, 2025
1 parent 7974254 commit 8002f93
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 11 deletions.
9 changes: 6 additions & 3 deletions h/presenters/mention_json.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
from typing import Any

from pyramid.request import Request

from h.models import Mention
from h.util.user import format_userid
from h.util.user import format_userid, get_user_url


class MentionJSONPresenter:
"""Present a mention in the JSON format returned by API requests."""

def __init__(self, mention: Mention):
def __init__(self, mention: Mention, request: Request):
self._mention = mention
self._request = request

def asdict(self) -> dict[str, Any]:
return {
Expand All @@ -18,5 +21,5 @@ def asdict(self) -> dict[str, Any]:
),
"username": self._mention.user.username,
"display_name": self._mention.user.display_name,
"link": self._mention.user.uri,
"link": get_user_url(self._mention.user, self._request),
}
9 changes: 8 additions & 1 deletion h/services/annotation_json.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from copy import deepcopy

from pyramid.request import Request

from h.models import Annotation, User
from h.presenters import DocumentJSONPresenter
from h.presenters.mention_json import MentionJSONPresenter
Expand Down Expand Up @@ -27,6 +29,7 @@ def __init__( # noqa: PLR0913
user_service: UserService,
mention_service: MentionService,
feature_service: FeatureService,
request: Request,
):
"""
Instantiate the service.
Expand All @@ -36,13 +39,16 @@ def __init__( # noqa: PLR0913
:param flag_service: FlagService instance
:param user_service: UserService instance
:param mention_service: MentionService instance
:param feature_service: FeatureService instance
:param request: The current request
"""
self._annotation_read_service = annotation_read_service
self._links_service = links_service
self._flag_service = flag_service
self._user_service = user_service
self._mention_service = mention_service
self._feature_service = feature_service
self._request = request

def present(self, annotation: Annotation):
"""
Expand Down Expand Up @@ -83,7 +89,7 @@ def present(self, annotation: Annotation):
)
if self._feature_service.enabled("at_mentions"): # pragma: no cover
model["mentions"] = [
MentionJSONPresenter(mention).asdict()
MentionJSONPresenter(mention, self._request).asdict()
for mention in annotation.mentions
]

Expand Down Expand Up @@ -201,4 +207,5 @@ def factory(_context, request):
user_service=request.find_service(name="user"),
mention_service=request.find_service(MentionService),
feature_service=request.find_service(name="feature"),
request=request,
)
5 changes: 3 additions & 2 deletions h/services/mention.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class MentionService:
"""A service for managing user mentions."""

def __init__(self, session: Session, user_service: UserService):
def __init__(self, session: Session, user_service: UserService) -> None:
self._session = session
self._user_service = user_service

Expand Down Expand Up @@ -75,5 +75,6 @@ def _parse_userids(text: str) -> list[str]:
def factory(_context, request) -> MentionService:
"""Return a MentionService instance for the passed context and request."""
return MentionService(
session=request.db, user_service=request.find_service(name="user")
session=request.db,
user_service=request.find_service(name="user"),
)
9 changes: 9 additions & 0 deletions h/util/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import re

from pyramid.request import Request

from h.exceptions import InvalidUserId


Expand All @@ -23,3 +25,10 @@ def split_user(userid):

def format_userid(username, authority):
return f"acct:{username}@{authority}"


def get_user_url(user, request: Request) -> str | None:
if user.authority == request.default_authority:
return request.route_url("activity.user_search", username=user.username)

return None
14 changes: 9 additions & 5 deletions tests/unit/h/presenters/mention_json_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@


class TestMentionJSONPresenter:
def test_as_dict(self, user, annotation):
def test_as_dict(self, user, annotation, pyramid_request):
mention = Mention(annotation=annotation, user=user, username=user.username)

data = MentionJSONPresenter(mention).asdict()
data = MentionJSONPresenter(mention, pyramid_request).asdict()

assert data == {
"userid": user.userid,
"original_userid": user.userid,
"username": user.username,
"display_name": user.display_name,
"link": user.uri,
"link": f"http://example.com/users/{user.username}",
}

def test_as_dict_with_different_username(self, user, annotation):
def test_as_dict_with_different_username(self, user, annotation, pyramid_request):
new_username = "new_username"
mention = Mention(annotation=annotation, user=user, username=new_username)

data = MentionJSONPresenter(mention).asdict()
data = MentionJSONPresenter(mention, pyramid_request).asdict()

assert data["original_userid"] == format_userid(new_username, user.authority)

Expand All @@ -34,3 +34,7 @@ def user(self, factories):
@pytest.fixture
def annotation(self, factories):
return factories.Annotation.build()

@pytest.fixture(autouse=True)
def routes(self, pyramid_config):
pyramid_config.add_route("activity.user_search", "/users/{username}")
3 changes: 3 additions & 0 deletions tests/unit/h/services/annotation_json_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ def service(
user_service,
mention_service,
feature_service,
pyramid_request,
):
return AnnotationJSONService(
annotation_read_service=annotation_read_service,
Expand All @@ -222,6 +223,7 @@ def service(
user_service=user_service,
mention_service=mention_service,
feature_service=feature_service,
request=pyramid_request,
)

@pytest.fixture
Expand Down Expand Up @@ -272,6 +274,7 @@ def test_it(
user_service=user_service,
mention_service=mention_service,
feature_service=feature_service,
request=pyramid_request,
)
assert service == AnnotationJSONService.return_value

Expand Down
20 changes: 20 additions & 0 deletions tests/unit/h/util/user_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,23 @@ def test_split_user():
def test_split_user_no_match():
with pytest.raises(InvalidUserId):
user_util.split_user("donkeys")


class TestGetUserURL:
def test_it(self, pyramid_request, user):
assert (
user_util.get_user_url(user, pyramid_request)
== f"http://example.com/users/{user.username}"
)

def test_it_returns_none_if_authority_does_not_match(self, pyramid_request, user):
pyramid_request.default_authority = "foo.org"
assert user_util.get_user_url(user, pyramid_request) is None

@pytest.fixture
def user(self, factories):
return factories.User.build()

@pytest.fixture(autouse=True)
def routes(self, pyramid_config):
pyramid_config.add_route("activity.user_search", "/users/{username}")

0 comments on commit 8002f93

Please sign in to comment.