More tests

main
Thomas Sileo 2022-07-26 19:06:20 +02:00
parent c07d17ba9b
commit 0ab0eaec34
3 changed files with 85 additions and 91 deletions

View File

@ -281,7 +281,7 @@ class Follower(Base):
updated_at = Column(DateTime(timezone=True), nullable=False, default=now) updated_at = Column(DateTime(timezone=True), nullable=False, default=now)
actor_id = Column(Integer, ForeignKey("actor.id"), nullable=False, unique=True) actor_id = Column(Integer, ForeignKey("actor.id"), nullable=False, unique=True)
actor = relationship(Actor, uselist=False) actor: Mapped[Actor] = relationship(Actor, uselist=False)
inbox_object_id = Column(Integer, ForeignKey("inbox.id"), nullable=False) inbox_object_id = Column(Integer, ForeignKey("inbox.id"), nullable=False)
inbox_object = relationship(InboxObject, uselist=False) inbox_object = relationship(InboxObject, uselist=False)

View File

@ -1,7 +1,5 @@
from copy import deepcopy from copy import deepcopy
import pytest
from app import activitypub as ap from app import activitypub as ap
from app import ldsig from app import ldsig
from app.key import Key from app.key import Key
@ -30,7 +28,6 @@ _SAMPLE_CREATE = {
} }
@pytest.mark.skip(reason="Working but slow")
def test_linked_data_sig(): def test_linked_data_sig():
privkey, pubkey = factories.generate_key() privkey, pubkey = factories.generate_key()
ra = factories.RemoteActorFactory( ra = factories.RemoteActorFactory(

View File

@ -7,6 +7,7 @@ from fastapi.testclient import TestClient
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from app import activitypub as ap from app import activitypub as ap
from app import actor
from app import models from app import models
from app import webfinger from app import webfinger
from app.actor import LOCAL_ACTOR from app.actor import LOCAL_ACTOR
@ -29,18 +30,47 @@ def test_outbox__no_activities(
assert json_response["orderedItems"] == [] assert json_response["orderedItems"] == []
def test_send_follow_request( def _setup_remote_actor(respx_mock: respx.MockRouter) -> actor.RemoteActor:
db: Session,
client: TestClient,
respx_mock: respx.MockRouter,
) -> None:
# given a remote actor
ra = factories.RemoteActorFactory( ra = factories.RemoteActorFactory(
base_url="https://example.com", base_url="https://example.com",
username="toto", username="toto",
public_key="pk", public_key="pk",
) )
respx_mock.get(ra.ap_id).mock(return_value=httpx.Response(200, json=ra.ap_actor)) respx_mock.get(ra.ap_id).mock(return_value=httpx.Response(200, json=ra.ap_actor))
return ra
def _remote_actor_as_follower(ra: actor.RemoteActor) -> models.Follower:
actor = factories.ActorFactory.from_remote_actor(ra)
follow_id = uuid4().hex
follow_from_inbox = RemoteObject(
factories.build_follow_activity(
from_remote_actor=ra,
for_remote_actor=LOCAL_ACTOR,
outbox_public_id=follow_id,
),
ra,
)
inbox_object = factories.InboxObjectFactory.from_remote_object(
follow_from_inbox, actor
)
follower = factories.FollowerFactory(
inbox_object_id=inbox_object.id,
actor_id=actor.id,
ap_actor_id=actor.ap_id,
)
return follower
def test_send_follow_request(
db: Session,
client: TestClient,
respx_mock: respx.MockRouter,
) -> None:
# given a remote actor
ra = _setup_remote_actor(respx_mock)
response = client.post( response = client.post(
"/admin/actions/follow", "/admin/actions/follow",
@ -73,12 +103,7 @@ def test_send_create_activity__no_followers_and_with_mention(
respx_mock: respx.MockRouter, respx_mock: respx.MockRouter,
) -> None: ) -> None:
# given a remote actor # given a remote actor
ra = factories.RemoteActorFactory( ra = _setup_remote_actor(respx_mock)
base_url="https://example.com",
username="toto",
public_key="pk",
)
respx_mock.get(ra.ap_id).mock(return_value=httpx.Response(200, json=ra.ap_actor))
with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id): with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id):
response = client.post( response = client.post(
@ -111,32 +136,10 @@ def test_send_create_activity__with_followers(
respx_mock: respx.MockRouter, respx_mock: respx.MockRouter,
) -> None: ) -> None:
# given a remote actor # given a remote actor
ra = factories.RemoteActorFactory( ra = _setup_remote_actor(respx_mock)
base_url="https://example.com",
username="toto",
public_key="pk",
)
respx_mock.get(ra.ap_id).mock(return_value=httpx.Response(200, json=ra.ap_actor))
actor = factories.ActorFactory.from_remote_actor(ra)
follow_id = uuid4().hex # who is a follower
follow_from_inbox = RemoteObject( follower = _remote_actor_as_follower(ra)
factories.build_follow_activity(
from_remote_actor=ra,
for_remote_actor=LOCAL_ACTOR,
outbox_public_id=follow_id,
),
ra,
)
inbox_object = factories.InboxObjectFactory.from_remote_object(
follow_from_inbox, actor
)
follower = factories.FollowerFactory(
inbox_object_id=inbox_object.id,
actor_id=actor.id,
ap_actor_id=actor.ap_id,
)
with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id): with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id):
response = client.post( response = client.post(
@ -169,32 +172,10 @@ def test_send_create_activity__question__one_of(
respx_mock: respx.MockRouter, respx_mock: respx.MockRouter,
) -> None: ) -> None:
# given a remote actor # given a remote actor
ra = factories.RemoteActorFactory( ra = _setup_remote_actor(respx_mock)
base_url="https://example.com",
username="toto",
public_key="pk",
)
respx_mock.get(ra.ap_id).mock(return_value=httpx.Response(200, json=ra.ap_actor))
actor = factories.ActorFactory.from_remote_actor(ra)
follow_id = uuid4().hex # who is a follower
follow_from_inbox = RemoteObject( follower = _remote_actor_as_follower(ra)
factories.build_follow_activity(
from_remote_actor=ra,
for_remote_actor=LOCAL_ACTOR,
outbox_public_id=follow_id,
),
ra,
)
inbox_object = factories.InboxObjectFactory.from_remote_object(
follow_from_inbox, actor
)
follower = factories.FollowerFactory(
inbox_object_id=inbox_object.id,
actor_id=actor.id,
ap_actor_id=actor.ap_id,
)
with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id): with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id):
response = client.post( response = client.post(
@ -235,32 +216,10 @@ def test_send_create_activity__question__any_of(
respx_mock: respx.MockRouter, respx_mock: respx.MockRouter,
) -> None: ) -> None:
# given a remote actor # given a remote actor
ra = factories.RemoteActorFactory( ra = _setup_remote_actor(respx_mock)
base_url="https://example.com",
username="toto",
public_key="pk",
)
respx_mock.get(ra.ap_id).mock(return_value=httpx.Response(200, json=ra.ap_actor))
actor = factories.ActorFactory.from_remote_actor(ra)
follow_id = uuid4().hex # who is a follower
follow_from_inbox = RemoteObject( follower = _remote_actor_as_follower(ra)
factories.build_follow_activity(
from_remote_actor=ra,
for_remote_actor=LOCAL_ACTOR,
outbox_public_id=follow_id,
),
ra,
)
inbox_object = factories.InboxObjectFactory.from_remote_object(
follow_from_inbox, actor
)
follower = factories.FollowerFactory(
inbox_object_id=inbox_object.id,
actor_id=actor.id,
ap_actor_id=actor.ap_id,
)
with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id): with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id):
response = client.post( response = client.post(
@ -295,3 +254,41 @@ def test_send_create_activity__question__any_of(
outgoing_activity = db.query(models.OutgoingActivity).one() outgoing_activity = db.query(models.OutgoingActivity).one()
assert outgoing_activity.outbox_object_id == outbox_object.id assert outgoing_activity.outbox_object_id == outbox_object.id
assert outgoing_activity.recipient == follower.actor.inbox_url assert outgoing_activity.recipient == follower.actor.inbox_url
def test_send_create_activity__article(
db: Session,
client: TestClient,
respx_mock: respx.MockRouter,
) -> None:
# given a remote actor
ra = _setup_remote_actor(respx_mock)
# who is a follower
follower = _remote_actor_as_follower(ra)
with mock.patch.object(webfinger, "get_actor_url", return_value=ra.ap_id):
response = client.post(
"/admin/actions/new",
data={
"redirect_url": "http://testserver/",
"content": "hi followers",
"visibility": ap.VisibilityEnum.PUBLIC.name,
"csrf_token": generate_csrf_token(),
"name": "Article",
},
cookies=generate_admin_session_cookies(),
)
# Then the server returns a 302
assert response.status_code == 302
# And the Follow activity was created in the outbox
outbox_object = db.query(models.OutboxObject).one()
assert outbox_object.ap_type == "Article"
assert outbox_object.ap_object["name"] == "Article"
# And an outgoing activity was queued
outgoing_activity = db.query(models.OutgoingActivity).one()
assert outgoing_activity.outbox_object_id == outbox_object.id
assert outgoing_activity.recipient == follower.actor.inbox_url