Merge pull request #28 from jaywink/request-entity

Add Relationship entity
merge-requests/130/head
Jason Robinson 2016-07-18 22:43:17 +03:00 zatwierdzone przez GitHub
commit 8b880f89a0
8 zmienionych plików z 109 dodań i 9 usunięć

Wyświetl plik

@ -1,5 +1,8 @@
## [unreleased]
## Added
- Relationship base entity which represents relationships between two handles. Types can be following, sharing, ignoring and blocking. The Diaspora counterpart, DiasporaRequest, which represents a sharing/following request is outwards a single entity, but incoming a double entity, handled by creating both a sharing and following version of the relationship.
## Changed
- Unlock most of the direct dependencies to a certain version range. Unlock all of test requirements to any version.

Wyświetl plik

@ -154,3 +154,27 @@ class Reaction(GUIDMixin, ParticipationMixin, CreatedAtMixin, HandleMixin):
raise ValueError("reaction should be one of: {valid}".format(
valid=", ".join(self._reaction_valid_values)
))
class Relationship(CreatedAtMixin, HandleMixin):
"""Represents a """
target_handle = ""
relationship = ""
_relationship_valid_values = ["sharing", "following", "ignoring", "blocking"]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._required += ["relationship", "target_handle"]
def validate_target_handle(self):
validator = Email()
if not validator.is_valid(self.target_handle):
raise ValueError("Target handle is not valid")
def validate_relationship(self):
"""Ensure relationship is of a certain type."""
if self.relationship not in self._relationship_valid_values:
raise ValueError("relationship should be one of: {valid}".format(
valid=", ".join(self._relationship_valid_values)
))

Wyświetl plik

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from lxml import etree
from federation.entities.base import Comment, Post, Reaction
from federation.entities.base import Comment, Post, Reaction, Relationship
from federation.entities.diaspora.utils import format_dt, struct_to_xml
@ -53,3 +53,17 @@ class DiasporaLike(Reaction):
{'diaspora_handle': self.handle},
])
return element
class DiasporaRequest(Relationship):
"""Diaspora relationship request."""
relationship = "sharing"
def to_xml(self):
"""Convert to XML message."""
element = etree.Element("request")
struct_to_xml(element, [
{"sender_handle": self.handle},
{"recipient_handle": self.target_handle},
])
return element

Wyświetl plik

@ -3,14 +3,15 @@ from datetime import datetime
from lxml import etree
from federation.entities.base import Image
from federation.entities.diaspora.entities import DiasporaPost, DiasporaComment, DiasporaLike
from federation.entities.base import Image, Relationship
from federation.entities.diaspora.entities import DiasporaPost, DiasporaComment, DiasporaLike, DiasporaRequest
MAPPINGS = {
"status_message": DiasporaPost,
"photo": Image,
"comment": DiasporaComment,
"like": DiasporaLike,
"request": DiasporaRequest,
}
BOOLEAN_KEYS = [
@ -41,6 +42,11 @@ def message_to_objects(message):
transformed = transform_attributes(attrs)
entity = cls(**transformed)
entities.append(entity)
if cls == DiasporaRequest:
# We support sharing/following separately, so also generate base Relationship for the following part
transformed.update({"relationship": "following"})
entity = Relationship(**transformed)
entities.append(entity)
return entities
@ -50,8 +56,10 @@ def transform_attributes(attrs):
for key, value in attrs.items():
if key in ["raw_message", "text"]:
transformed["raw_content"] = value
elif key == "diaspora_handle":
elif key in ["diaspora_handle", "sender_handle"]:
transformed["handle"] = value
elif key == "recipient_handle":
transformed["target_handle"] = value
elif key == "parent_guid":
transformed["target_guid"] = value
elif key in BOOLEAN_KEYS:

Wyświetl plik

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from lxml import etree
from federation.entities.diaspora.entities import DiasporaComment, DiasporaPost, DiasporaLike
from federation.entities.diaspora.entities import DiasporaComment, DiasporaPost, DiasporaLike, DiasporaRequest
class TestEntitiesConvertToXML(object):
@ -33,3 +33,11 @@ class TestEntitiesConvertToXML(object):
b"<author_signature></author_signature><positive>true</positive>" \
b"<diaspora_handle>handle</diaspora_handle></like>"
assert etree.tostring(result) == converted
def test_request_to_xml(self):
entity = DiasporaRequest(handle="bob@example.com", target_handle="alice@example.com", relationship="following")
result = entity.to_xml()
assert result.tag == "request"
converted = b"<request><sender_handle>bob@example.com</sender_handle>" \
b"<recipient_handle>alice@example.com</recipient_handle></request>"
assert etree.tostring(result) == converted

Wyświetl plik

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from federation.entities.base import Comment, Post, Reaction
from federation.entities.diaspora.entities import DiasporaPost, DiasporaComment, DiasporaLike
from federation.entities.base import Comment, Post, Reaction, Relationship
from federation.entities.diaspora.entities import DiasporaPost, DiasporaComment, DiasporaLike, DiasporaRequest
from federation.entities.diaspora.mappers import message_to_objects
from federation.tests.fixtures.payloads import DIASPORA_POST_SIMPLE, DIASPORA_POST_COMMENT, DIASPORA_POST_LIKE
from federation.tests.fixtures.payloads import DIASPORA_POST_SIMPLE, DIASPORA_POST_COMMENT, DIASPORA_POST_LIKE, \
DIASPORA_REQUEST
class TestDiasporaEntityMappersReceive(object):
@ -44,3 +45,19 @@ class TestDiasporaEntityMappersReceive(object):
assert like.handle == "alice@alice.diaspora.example.org"
assert like.participation == "reaction"
assert like.reaction == "like"
def test_message_to_objects_request(self):
entities = message_to_objects(DIASPORA_REQUEST)
assert len(entities) == 2
sharing = entities[0]
assert isinstance(sharing, DiasporaRequest)
assert isinstance(sharing, Relationship)
following = entities[1]
assert not isinstance(following, DiasporaRequest)
assert isinstance(following, Relationship)
assert sharing.handle == "bob@example.com"
assert following.handle == "bob@example.com"
assert sharing.target_handle == "alice@alice.diaspora.example.org"
assert following.target_handle == "alice@alice.diaspora.example.org"
assert sharing.relationship == "sharing"
assert following.relationship == "following"

Wyświetl plik

@ -3,7 +3,7 @@ from unittest.mock import Mock
import pytest
from federation.entities.base import BaseEntity
from federation.entities.base import BaseEntity, Relationship
from federation.tests.factories.entities import TaggedPostFactory, PostFactory
@ -31,3 +31,19 @@ class TestEntityRequiredAttributes(object):
entity._required = ["foobar"]
with pytest.raises(ValueError):
entity.validate()
class TestRelationshipEntity(object):
def test_instance_creation(self):
entity = Relationship(handle="bob@example.com", target_handle="alice@example.com", relationship="following")
assert entity
def test_instance_creation_validates_relationship_value(self):
with pytest.raises(ValueError):
entity = Relationship(handle="bob@example.com", target_handle="alice@example.com", relationship="hating")
entity.validate()
def test_instance_creation_validates_target_handle_value(self):
with pytest.raises(ValueError):
entity = Relationship(handle="bob@example.com", target_handle="fefle.com", relationship="following")
entity.validate()

Wyświetl plik

@ -67,3 +67,13 @@ DIASPORA_POST_LIKE = """<XML>
</post>
</XML>
"""
DIASPORA_REQUEST = """<XML>
<post>
<request>
<sender_handle>bob@example.com</sender_handle>
<recipient_handle>alice@alice.diaspora.example.org</recipient_handle>
</request>
</post>
</XML>
"""