Skip to content

Commit

Permalink
inject user's URLs for user mentions into comments as well as posts
Browse files Browse the repository at this point in the history
fixes #589. needed for #523.
  • Loading branch information
snarfed committed Jan 4, 2016
1 parent 4c50ab6 commit c698d74
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 30 deletions.
2 changes: 1 addition & 1 deletion handlers.py
Expand Up @@ -238,7 +238,7 @@ def get_item(self, id):

class CommentHandler(ItemHandler):
def get_item(self, post_id, id):
cmt = self.source.gr_source.get_comment(
cmt = self.source.get_comment(
id, activity_id=post_id, activity_author_id=self.source.key.id())
if not cmt:
return None
Expand Down
36 changes: 28 additions & 8 deletions models.py
Expand Up @@ -283,24 +283,36 @@ def search_for_links(self):
def get_activities_response(self, **kwargs):
"""Returns recent posts and embedded comments for this source.
Adds this user's web site URLs to their user mention (in tags).
May be overridden by subclasses.
"""
kwargs.setdefault('group_id', gr_source.SELF)
resp = self.gr_source.get_activities_response(**kwargs)

user_tag_id = self.user_tag_id()
for activity in resp['items']:
for tag in activity.get('object', {}).get('tags', []):
if tag.get('id') == user_tag_id:
tag.setdefault('urls', []).extend([{'value': u} for u in self.domain_urls])

self._inject_user_urls(activity)
return resp

def get_activities(self, **kwargs):
return self.get_activities_response(**kwargs)['items']

def get_comment(self, comment_id, activity_id=None, activity_author_id=None):
"""Returns a comment from this source.
Passes through to granary by default. May be overridden
by subclasses.
Args:
comment_id: string, site-specific comment id
activity_id: string, site-specific activity id
activity_author_id: string, site-specific activity author id, optional
Returns: dict, decoded ActivityStreams comment object, or None
"""
comment = self.gr_source.get_comment(comment_id, activity_id=activity_id,
activity_author_id=activity_author_id)
if comment:
self._inject_user_urls(comment)
return comment

def get_like(self, activity_user_id, activity_id, like_user_id):
"""Returns an ActivityStreams 'like' activity object.
Expand All @@ -314,6 +326,14 @@ def get_like(self, activity_user_id, activity_id, like_user_id):
"""
return self.gr_source.get_like(activity_user_id, activity_id, like_user_id)

def _inject_user_urls(self, activity):
"""Adds this user's web site URLs to their user mentions (in tags), in place."""
obj = activity.get('object') or activity
user_tag_id = self.user_tag_id()
for tag in obj.get('tags', []):
if tag.get('id') == user_tag_id:
tag.setdefault('urls', []).extend([{'value': u} for u in self.domain_urls])

def create_comment(self, post_url, author_name, author_url, content):
"""Creates a new comment in the source silo.
Expand Down
66 changes: 45 additions & 21 deletions test/test_handlers.py
Expand Up @@ -18,7 +18,8 @@ class HandlersTest(testutil.HandlerTest):
def setUp(self):
super(HandlersTest, self).setUp()
self.source = testutil.FakeSource.new(
self.handler, domains=['or.ig', 'fa.ke'])
self.handler, domains=['or.ig', 'fa.ke'],
domain_urls=['http://or.ig', 'https://fa.ke'])
self.source.put()
self.activities = [{
'object': {
Expand All @@ -29,6 +30,12 @@ def setUp(self):
'id': self.source.user_tag_id(),
'image': {'url': 'http://example.com/ryan/image'},
},
'tags': [{
'id': 'tag:fa.ke,2013:nobody',
}, {
'id': self.source.user_tag_id(),
'objectType': 'person',
}],
'upstreamDuplicates': ['http://or.ig/post'],
}}]
FakeGrSource.activities = self.activities
Expand Down Expand Up @@ -71,6 +78,12 @@ def test_post_html(self):
<a class="u-mention" href="http://other/link"></a>
</div>
<span class="u-category h-card h-card">
<a class="u-url" href="http://or.ig">http://or.ig</a>
<a class="u-url" href="https://fa.ke"></a>
</span>
</article>
""" % {'key': self.source.key.id()})

Expand All @@ -79,26 +92,33 @@ def test_post_json(self):
'/post/fake/%s/000?format=json' % self.source.key.string_id(), scheme='https')
self.assertEqual(200, resp.status_int, resp.body)
self.assert_equals({
'type': ['h-entry'],
'properties': {
'uid': ['tag:fa.ke,2013:000'],
'url': ['http://fa.ke/000', 'http://or.ig/post'],
'content': [{ 'html': """\
'type': ['h-entry'],
'properties': {
'uid': ['tag:fa.ke,2013:000'],
'url': ['http://fa.ke/000', 'http://or.ig/post'],
'content': [{ 'html': """\
asdf http://other/link qwert
<a class="u-mention" href="http://other/link"></a>
""",
'value': 'asdf http://other/link qwert',
}],
'author': [{
'type': ['h-card'],
'properties': {
'uid': [self.source.user_tag_id()],
'url': ['http://fa.ke/%s' % self.source.key.id()],
'photo': ['https://example.com/ryan/image'],
},
}],
'value': 'asdf http://other/link qwert',
}],
'author': [{
'type': ['h-card'],
'properties': {
'uid': [self.source.user_tag_id()],
'url': ['http://fa.ke/%s' % self.source.key.id()],
'photo': ['https://example.com/ryan/image'],
},
}],
'category': [{
'type': ['h-card'],
'properties': {
'uid': [self.source.user_tag_id()],
'url': ['http://or.ig', 'https://fa.ke'],
},
}, json.loads(resp.body))
}],
},
}, json.loads(resp.body))

def test_bad_source_type(self):
resp = handlers.application.get_response('/post/not_a_type/%s/000' %
Expand Down Expand Up @@ -167,6 +187,7 @@ def test_comment(self):
'content': 'qwert',
'inReplyTo': [{'url': 'http://fa.ke/000'}],
'author': {'image': {'url': 'http://example.com/ryan/image'}},
'tags': self.activities[0]['object']['tags'],
}

self.check_response('/comment/fake/%s/000/a1-b2.c3', """\
Expand All @@ -184,6 +205,12 @@ def test_comment(self):
<a class="u-mention" href="http://other/link"></a>
</div>
<span class="u-category h-card h-card">
<a class="u-url" href="http://or.ig">http://or.ig</a>
<a class="u-url" href="https://fa.ke"></a>
</span>
<a class="u-in-reply-to" href="http://fa.ke/000"></a>
<a class="u-in-reply-to" href="http://or.ig/post"></a>
Expand Down Expand Up @@ -233,10 +260,6 @@ def test_repost_with_syndicated_post_and_mentions(self):
original='http://or.ig/post',
syndication='http://example.com/original/post').put()

# needed to make original_post_discovery use the SyndicatedPost
self.source.domain_urls = ['http://unused']
self.source.put()

FakeGrSource.share = {
'objectType': 'activity',
'verb': 'share',
Expand Down Expand Up @@ -355,6 +378,7 @@ def test_original_post_urls_follow_redirects(self):
'http://or.ig/post', redirected_url='http://or.ig/post/redirect').InAnyOrder()
self.expect_requests_head(
'http://other/link', redirected_url='http://other/link/redirect').InAnyOrder()
self.expect_requests_head('http://fa.ke/000')
self.mox.ReplayAll()

self.check_response('/comment/fake/%s/000/111', """\
Expand Down
19 changes: 19 additions & 0 deletions test/test_models.py
Expand Up @@ -222,6 +222,25 @@ def test_get_activities_injects_web_site_urls_into_user_mentions(self):
{'value': 'http://site1/'}, {'value': 'http://site2/'}]
self.assert_equals([mention], got['items'])

def test_get_comment_injects_web_site_urls_into_user_mentions(self):
source = FakeSource.new(None, domain_urls=['http://site1/', 'http://site2/'])
source.put()

user_id = 'tag:fa.ke,2013:%s' % source.key.id()
FakeGrSource.comment = {
'id': 'tag:fa.ke,2013:a1-b2.c3',
'tags': [
{'id': 'tag:fa.ke,2013:nobody'},
{'id': user_id},
],
}

# check that we inject their web sites
self.assert_equals({
'id': 'tag:fa.ke,2013:%s' % source.key.id(),
'urls': [{'value': 'http://site1/'}, {'value': 'http://site2/'}],
}, super(FakeSource, source).get_comment('x')['tags'][1])

def test_create_new_already_exists(self):
long_ago = datetime.datetime(year=1901, month=2, day=3)
props = {
Expand Down

0 comments on commit c698d74

Please sign in to comment.