More tests and bugfixes

This commit is contained in:
Thomas Sileo 2018-05-27 14:21:06 +02:00
parent 166fc91c54
commit 12feb38a8f
3 changed files with 76 additions and 9 deletions

View file

@ -1,3 +1,4 @@
import logging
import json import json
import binascii import binascii
import os import os
@ -21,6 +22,8 @@ import tasks
from typing import List, Optional, Dict, Any, Union from typing import List, Optional, Dict, Any, Union
from typing import TypeVar from typing import TypeVar
logger = logging.getLogger(__name__)
A = TypeVar('A', bound='BaseActivity') A = TypeVar('A', bound='BaseActivity')
ObjectType = Dict[str, Any] ObjectType = Dict[str, Any]
ObjectOrIDType = Union[str, ObjectType] ObjectOrIDType = Union[str, ObjectType]
@ -454,6 +457,9 @@ class Follow(BaseActivity):
def _undo_inbox(self) -> None: def _undo_inbox(self) -> None:
DB.followers.delete_one({'remote_actor': self.get_actor().id}) DB.followers.delete_one({'remote_actor': self.get_actor().id})
def _undo_outbox(self) -> None:
DB.following.delete_one({'remote_actor': self.get_object().id})
def build_accept(self) -> BaseActivity: def build_accept(self) -> BaseActivity:
return self._build_reply(ActivityTypes.ACCEPT) return self._build_reply(ActivityTypes.ACCEPT)
@ -517,12 +523,17 @@ class Undo(BaseActivity):
return False return False
def _post_to_outbox(self, obj_id: str, activity: ObjectType, recipients: List[str]) -> None: def _post_to_outbox(self, obj_id: str, activity: ObjectType, recipients: List[str]) -> None:
logger.debug('processing undo to outbox')
logger.debug('self={}'.format(self))
obj = self.get_object() obj = self.get_object()
logger.debug('obj={}'.format(obj))
DB.outbox.update_one({'remote_id': obj.id}, {'$set': {'meta.undo': True}}) DB.outbox.update_one({'remote_id': obj.id}, {'$set': {'meta.undo': True}})
try: try:
obj._undo_outbox() obj._undo_outbox()
logger.debug(f'_undo_outbox called for {obj}')
except NotImplementedError: except NotImplementedError:
logger.debug(f'_undo_outbox not implemented for {obj}')
pass pass

20
app.py
View file

@ -615,16 +615,25 @@ def ui_like():
like.post_to_outbox() like.post_to_outbox()
return redirect(request.args.get('redirect')) return redirect(request.args.get('redirect'))
@app.route('/ui/undo') @app.route('/api/undo', methods=['GET', 'POST'])
@login_required @api_required
def ui_undo(): def api_undo():
oid = request.args.get('id') oid = request.args.get('id')
doc =DB.outbox.find_one({'id': oid}) doc = DB.outbox.find_one({'$or': [{'id': oid}, {'remote_id': oid}]})
undo_id = None
if doc: if doc:
obj = activitypub.parse_activity(doc.get('activity')) obj = activitypub.parse_activity(doc.get('activity'))
# FIXME(tsileo): detect already undo-ed and make this API call idempotent
undo = obj.build_undo() undo = obj.build_undo()
undo.post_to_outbox() undo.post_to_outbox()
return redirect(request.args.get('redirect')) undo_id = undo.id
if request.args.get('redirect'):
return redirect(request.args.get('redirect'))
return Response(
status=201,
headers={'Microblogpub-Created-Activity': undo_id},
)
@app.route('/stream') @app.route('/stream')
@login_required @login_required
@ -823,6 +832,7 @@ def api_follow():
follow.post_to_outbox() follow.post_to_outbox()
return Response( return Response(
status=201, status=201,
headers={'Microblogpub-Created-Activity': follow.id},
) )

View file

@ -58,6 +58,15 @@ class Instance(object):
# We need to wait for the Follow/Accept dance # We need to wait for the Follow/Accept dance
time.sleep(10) time.sleep(10)
return resp.headers.get('microblogpub-created-activity')
def undo(self, oid: str) -> None:
resp = self.session.get(f'{self.host_url}/api/undo', params={'id': oid})
assert resp.status_code == 201
# We need to wait for the Follow/Accept dance
time.sleep(10)
return resp.headers.get('microblogpub-created-activity')
def followers(self): def followers(self):
resp = self.session.get(f'{self.host_url}/followers', headers={'Accept': 'application/activity+json'}) resp = self.session.get(f'{self.host_url}/followers', headers={'Accept': 'application/activity+json'})
@ -81,8 +90,7 @@ class Instance(object):
return resp.json() return resp.json()
def test_federation(): def _instances():
"""Ensure the homepage is accessible."""
instance1 = Instance('http://localhost:5006', 'http://instance1_web_1:5005') instance1 = Instance('http://localhost:5006', 'http://instance1_web_1:5005')
instance1.ping() instance1.ping()
@ -95,15 +103,53 @@ def test_federation():
instance2.login() instance2.login()
instance2.drop_db() instance2.drop_db()
return instance1, instance2
def test_follow():
instance1, instance2 = _instances()
# Instance1 follows instance2 # Instance1 follows instance2
instance1.follow(instance2) instance1.follow(instance2)
instance1_debug = instance1.debug() instance1_debug = instance1.debug()
print(f'instance1_debug={instance1_debug}')
assert instance1_debug['inbox'] == 1 # An Accept activity should be there
assert instance1_debug['outbox'] == 1 # We've sent a Follow activity
instance2_debug = instance2.debug()
print(f'instance2_debug={instance2_debug}')
assert instance2_debug['inbox'] == 1 # An Follow activity should be there
assert instance2_debug['outbox'] == 1 # We've sent a Accept activity
assert instance2.followers() == [instance1.docker_url]
assert instance1.following() == [instance2.docker_url]
def test_follow_unfollow():
instance1, instance2 = _instances()
# Instance1 follows instance2
follow_id = instance1.follow(instance2)
instance1_debug = instance1.debug()
assert instance1_debug['inbox'] == 1 # An Accept activity should be there assert instance1_debug['inbox'] == 1 # An Accept activity should be there
assert instance1_debug['outbox'] == 1 # We've sent a Follow activity assert instance1_debug['outbox'] == 1 # We've sent a Follow activity
instance2_debug = instance2.debug() instance2_debug = instance2.debug()
assert instance1_debug['inbox'] == 1 # An Follow activity should be there assert instance2_debug['inbox'] == 1 # An Follow activity should be there
assert instance1_debug['outbox'] == 1 # We've sent a Accept activity assert instance2_debug['outbox'] == 1 # We've sent a Accept activity
assert instance2.followers() == [instance1.docker_url] assert instance2.followers() == [instance1.docker_url]
assert instance1.following() == [instance2.docker_url] assert instance1.following() == [instance2.docker_url]
instance1.undo(follow_id)
assert instance2.followers() == []
assert instance1.following() == []
instance1_debug = instance1.debug()
assert instance1_debug['inbox'] == 1 # An Accept activity should be there
assert instance1_debug['outbox'] == 2 # We've sent a Follow and a Undo activity
instance2_debug = instance2.debug()
assert instance2_debug['inbox'] == 2 # An Follow and Undo activity should be there
assert instance2_debug['outbox'] == 1 # We've sent a Accept activity