kopia lustrzana https://gitlab.com/jaywink/federation
Merge branch 'root_target' into 'master'
Add support for root parent for Comment entity See merge request jaywink/federation!149merge-requests/150/head
commit
761ae5c5de
|
@ -22,6 +22,10 @@
|
|||
|
||||
ActivityPub profiles will parse these values from incoming profile documents. Diaspora entities will default to the inboxes in the specification.
|
||||
|
||||
* Added support for Diaspora `Comment` entity `thread_parent_guid` attribute.
|
||||
|
||||
* Added `root_target_id` and `root_target_guid` to `Comment` base entity. This allows referring to a parent object up the hierarchy chain for threaded comments.
|
||||
|
||||
### Changed
|
||||
|
||||
* **Backwards incompatible.** Lowest compatible Python version is now 3.6.
|
||||
|
|
|
@ -5,7 +5,7 @@ from dirty_validators.basic import Email
|
|||
from federation.entities.activitypub.enums import ActivityType
|
||||
from federation.entities.mixins import (
|
||||
PublicMixin, TargetIDMixin, ParticipationMixin, CreatedAtMixin, RawContentMixin, OptionalRawContentMixin,
|
||||
EntityTypeMixin, ProviderDisplayNameMixin)
|
||||
EntityTypeMixin, ProviderDisplayNameMixin, RootTargetIDMixin)
|
||||
|
||||
|
||||
class Accept(CreatedAtMixin, TargetIDMixin):
|
||||
|
@ -34,7 +34,7 @@ class Image(PublicMixin, OptionalRawContentMixin, CreatedAtMixin):
|
|||
self._required += ["remote_path", "remote_name"]
|
||||
|
||||
|
||||
class Comment(RawContentMixin, ParticipationMixin, CreatedAtMixin):
|
||||
class Comment(RawContentMixin, ParticipationMixin, CreatedAtMixin, RootTargetIDMixin):
|
||||
"""Represents a comment, linked to another object."""
|
||||
participation = "comment"
|
||||
url = ""
|
||||
|
|
|
@ -15,7 +15,8 @@ class DiasporaComment(DiasporaRelayableMixin, Comment):
|
|||
element = etree.Element(self._tag_name)
|
||||
struct_to_xml(element, [
|
||||
{"guid": self.guid},
|
||||
{"parent_guid": self.target_guid},
|
||||
{"parent_guid": self.root_target_guid or self.target_guid},
|
||||
{"thread_parent_guid": self.target_guid},
|
||||
{"author_signature": self.signature},
|
||||
{"parent_author_signature": self.parent_signature},
|
||||
{"text": self.raw_content},
|
||||
|
|
|
@ -188,6 +188,9 @@ def transform_attributes(attrs, cls):
|
|||
elif key in ("target_guid", "root_guid", "parent_guid"):
|
||||
transformed["target_id"] = value
|
||||
transformed["target_guid"] = value
|
||||
elif key == "thread_parent_guid":
|
||||
transformed["root_target_id"] = value
|
||||
transformed["root_target_guid"] = value
|
||||
elif key in ("first_name", "last_name"):
|
||||
values = [attrs.get('first_name'), attrs.get('last_name')]
|
||||
values = [v for v in values if v]
|
||||
|
|
|
@ -137,6 +137,12 @@ class TargetIDMixin(BaseEntity):
|
|||
self._required += ["target_id"]
|
||||
|
||||
|
||||
class RootTargetIDMixin(BaseEntity):
|
||||
root_target_id = ""
|
||||
root_target_handle = ""
|
||||
root_target_guid = ""
|
||||
|
||||
|
||||
class ParticipationMixin(TargetIDMixin):
|
||||
"""Reflects a participation to something."""
|
||||
participation = ""
|
||||
|
|
|
@ -27,6 +27,19 @@ class TestEntitiesConvertToXML:
|
|||
assert len(result.find("created_at").text) > 0
|
||||
result.find("created_at").text = "" # timestamp makes testing painful
|
||||
converted = b"<comment><guid>guid</guid><parent_guid>target_guid</parent_guid>" \
|
||||
b"<thread_parent_guid>target_guid</thread_parent_guid>" \
|
||||
b"<author_signature>signature</author_signature><parent_author_signature>" \
|
||||
b"</parent_author_signature><text>raw_content</text><author>alice@example.com</author>" \
|
||||
b"<created_at></created_at></comment>"
|
||||
assert etree.tostring(result) == converted
|
||||
|
||||
def test_nested_comment_to_xml(self, diasporanestedcomment):
|
||||
result = diasporanestedcomment.to_xml()
|
||||
assert result.tag == "comment"
|
||||
assert len(result.find("created_at").text) > 0
|
||||
result.find("created_at").text = "" # timestamp makes testing painful
|
||||
converted = b"<comment><guid>guid</guid><parent_guid>target_guid</parent_guid>" \
|
||||
b"<thread_parent_guid>thread_target_guid</thread_parent_guid>" \
|
||||
b"<author_signature>signature</author_signature><parent_author_signature>" \
|
||||
b"</parent_author_signature><text>raw_content</text><author>alice@example.com</author>" \
|
||||
b"<created_at></created_at></comment>"
|
||||
|
@ -122,13 +135,15 @@ class TestDiasporaRelayableMixin:
|
|||
guid="guid",
|
||||
target_id="target_guid",
|
||||
target_guid="target_guid",
|
||||
root_target_id="target_guid",
|
||||
root_target_guid="target_guid",
|
||||
)
|
||||
entity.sign(get_dummy_private_key())
|
||||
assert entity.signature == "OWvW/Yxw4uCnx0WDn0n5/B4uhyZ8Pr6h3FZaw8J7PCXyPluOfYXFoHO21bykP8c2aVnuJNHe+lmeAkUC" \
|
||||
"/kHnl4yxk/jqe3uroW842OWvsyDRQ11vHxhIqNMjiepFPkZmXX3vqrYYh5FrC/tUsZrEc8hHoOIHXFR2" \
|
||||
"kGD0gPV+4EEG6pbMNNZ+SBVun0hvruX8iKQVnBdc/+zUI9+T/MZmLyqTq/CvuPxDyHzQPSHi68N9rJyr" \
|
||||
"4Xa1K+R33Xq8eHHxs8LVNRqzaHGeD3DX8yBu/vP9TYmZsiWlymbuGwLCa4Yfv/VS1hQZovhg6YTxV4CR" \
|
||||
"v4ToGL+CAJ7UHEugRRBwDw=="
|
||||
assert entity.signature == "XZYggFdQHOicguZ0ReVJkYiK5othHgBgAtwnSmm4NR31qeLa76Ur/i2B5Xi9dtopDlNS8EbFy+MLJ1ds" \
|
||||
"ovDjPsVC1nLZrL57y0v+HtwJas6hQqNbvmEyr1q6X+0p1i93eINzt/7bxcP5uEGxy8J4ItsJzbDVLlC5" \
|
||||
"3ZtIg7pmhR0ltqNqBHrgL8WDokfGKFlXqANchbD+Xeyv2COGbI78LwplVdYjHW1+jefjpYhMCxayIvMv" \
|
||||
"WS8TV1hMTqUz+zSqoCHU04RgjjGW8e8vINDblQwMfEMeJ5T6OP5RiU3zCqDc3uL2zxHHh9IGC+clVuhP" \
|
||||
"HTv8tHUHNLgc2vIzRtGh6w=="
|
||||
|
||||
def test_signing_like_works(self):
|
||||
entity = DiasporaLike(
|
||||
|
|
|
@ -18,7 +18,7 @@ from federation.tests.fixtures.payloads import (
|
|||
DIASPORA_POST_WITH_PHOTOS, DIASPORA_CONTACT,
|
||||
DIASPORA_PROFILE_EMPTY_TAGS, DIASPORA_RESHARE,
|
||||
DIASPORA_RESHARE_WITH_EXTRA_PROPERTIES, DIASPORA_POST_SIMPLE_WITH_MENTION,
|
||||
DIASPORA_PROFILE_FIRST_NAME_ONLY)
|
||||
DIASPORA_PROFILE_FIRST_NAME_ONLY, DIASPORA_POST_COMMENT_NESTED)
|
||||
|
||||
|
||||
class TestDiasporaEntityMappersReceive:
|
||||
|
@ -71,6 +71,7 @@ class TestDiasporaEntityMappersReceive:
|
|||
assert isinstance(comment, DiasporaComment)
|
||||
assert isinstance(comment, Comment)
|
||||
assert comment.target_guid == "((parent_guidparent_guidparent_guidparent_guid))"
|
||||
assert comment.root_target_guid == ""
|
||||
assert comment.guid == "((guidguidguidguidguidguid))"
|
||||
assert comment.handle == "alice@alice.diaspora.example.org"
|
||||
assert comment.participation == "comment"
|
||||
|
@ -81,6 +82,26 @@ class TestDiasporaEntityMappersReceive:
|
|||
]
|
||||
mock_validate.assert_called_once_with()
|
||||
|
||||
@patch("federation.entities.diaspora.mappers.DiasporaComment._validate_signatures")
|
||||
def test_message_to_objects_nested_comment(self, mock_validate):
|
||||
entities = message_to_objects(DIASPORA_POST_COMMENT_NESTED, "alice@alice.diaspora.example.org",
|
||||
sender_key_fetcher=Mock())
|
||||
assert len(entities) == 1
|
||||
comment = entities[0]
|
||||
assert isinstance(comment, DiasporaComment)
|
||||
assert isinstance(comment, Comment)
|
||||
assert comment.target_guid == "((parent_guidparent_guidparent_guidparent_guid))"
|
||||
assert comment.root_target_guid == "((threadparentguid))"
|
||||
assert comment.guid == "((guidguidguidguidguidguid))"
|
||||
assert comment.handle == "alice@alice.diaspora.example.org"
|
||||
assert comment.participation == "comment"
|
||||
assert comment.raw_content == "((text))"
|
||||
assert comment.signature == "((signature))"
|
||||
assert comment._xml_tags == [
|
||||
"guid", "parent_guid", "thread_parent_guid", "text", "author",
|
||||
]
|
||||
mock_validate.assert_called_once_with()
|
||||
|
||||
@patch("federation.entities.diaspora.mappers.DiasporaLike._validate_signatures")
|
||||
def test_message_to_objects_like(self, mock_validate):
|
||||
entities = message_to_objects(
|
||||
|
|
|
@ -118,6 +118,22 @@ def diasporacomment():
|
|||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def diasporanestedcomment():
|
||||
return DiasporaComment(
|
||||
raw_content="raw_content",
|
||||
signature="signature",
|
||||
id="guid",
|
||||
guid="guid",
|
||||
actor_id="alice@example.com",
|
||||
handle="alice@example.com",
|
||||
target_id="thread_target_guid",
|
||||
target_guid="thread_target_guid",
|
||||
root_target_id="target_guid",
|
||||
root_target_guid="target_guid",
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def diasporacontact():
|
||||
return DiasporaContact(
|
||||
|
|
|
@ -91,6 +91,18 @@ DIASPORA_POST_COMMENT = """
|
|||
</comment>
|
||||
"""
|
||||
|
||||
DIASPORA_POST_COMMENT_NESTED = """
|
||||
<comment>
|
||||
<guid>((guidguidguidguidguidguid))</guid>
|
||||
<parent_guid>((parent_guidparent_guidparent_guidparent_guid))</parent_guid>
|
||||
<thread_parent_guid>((threadparentguid))</thread_parent_guid>
|
||||
<author_signature>((base64-encoded data))</author_signature>
|
||||
<text>((text))</text>
|
||||
<author>alice@alice.diaspora.example.org</author>
|
||||
<author_signature>((signature))</author_signature>
|
||||
</comment>
|
||||
"""
|
||||
|
||||
DIASPORA_POST_LIKE = """
|
||||
<like>
|
||||
<parent_type>Post</parent_type>
|
||||
|
|
Ładowanie…
Reference in New Issue