forked from forks/microblog.pub
More tests and bugfixes
This commit is contained in:
parent
166fc91c54
commit
12feb38a8f
3 changed files with 76 additions and 9 deletions
|
@ -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
20
app.py
|
@ -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},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
||||||
|
@ -94,16 +102,54 @@ def test_federation():
|
||||||
instance1.drop_db()
|
instance1.drop_db()
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue