Improve tests

This commit is contained in:
Thomas Sileo 2022-07-26 20:26:34 +02:00
parent 0ab0eaec34
commit 23832574bc
3 changed files with 69 additions and 60 deletions

View file

@ -9,8 +9,11 @@ from app import activitypub as ap
from app import models from app import models
from app.actor import LOCAL_ACTOR from app.actor import LOCAL_ACTOR
from app.ap_object import RemoteObject from app.ap_object import RemoteObject
from app.incoming_activities import process_next_incoming_activity
from tests import factories from tests import factories
from tests.utils import mock_httpsig_checker from tests.utils import mock_httpsig_checker
from tests.utils import run_async
from tests.utils import setup_remote_actor
def test_inbox_requires_httpsig( def test_inbox_requires_httpsig(
@ -56,8 +59,7 @@ def test_inbox_follow_request(
# Then the server returns a 204 # Then the server returns a 204
assert response.status_code == 202 assert response.status_code == 202
# TODO: processing incoming activity instead run_async(process_next_incoming_activity)
return
# And the actor was saved in DB # And the actor was saved in DB
saved_actor = db.query(models.Actor).one() saved_actor = db.query(models.Actor).one()
@ -89,12 +91,7 @@ def test_inbox_accept_follow_request(
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_in_db = factories.ActorFactory.from_remote_actor(ra) actor_in_db = factories.ActorFactory.from_remote_actor(ra)
# And a Follow activity in the outbox # And a Follow activity in the outbox
@ -129,8 +126,7 @@ def test_inbox_accept_follow_request(
# Then the server returns a 204 # Then the server returns a 204
assert response.status_code == 202 assert response.status_code == 202
# TODO: processing incoming activity instead run_async(process_next_incoming_activity)
return
# And the Accept activity was saved in the inbox # And the Accept activity was saved in the inbox
inbox_activity = db.query(models.InboxObject).one() inbox_activity = db.query(models.InboxObject).one()

View file

@ -1,20 +1,16 @@
from unittest import mock from unittest import mock
from uuid import uuid4
import httpx
import respx import respx
from fastapi.testclient import TestClient 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.ap_object import RemoteObject
from app.config import generate_csrf_token from app.config import generate_csrf_token
from tests import factories
from tests.utils import generate_admin_session_cookies from tests.utils import generate_admin_session_cookies
from tests.utils import setup_remote_actor
from tests.utils import setup_remote_actor_as_follower
def test_outbox__no_activities( def test_outbox__no_activities(
@ -30,47 +26,13 @@ def test_outbox__no_activities(
assert json_response["orderedItems"] == [] assert json_response["orderedItems"] == []
def _setup_remote_actor(respx_mock: respx.MockRouter) -> actor.RemoteActor:
ra = factories.RemoteActorFactory(
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))
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( def test_send_follow_request(
db: Session, db: Session,
client: TestClient, client: TestClient,
respx_mock: respx.MockRouter, respx_mock: respx.MockRouter,
) -> None: ) -> None:
# given a remote actor # given a remote actor
ra = _setup_remote_actor(respx_mock) ra = setup_remote_actor(respx_mock)
response = client.post( response = client.post(
"/admin/actions/follow", "/admin/actions/follow",
@ -103,7 +65,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 = _setup_remote_actor(respx_mock) ra = setup_remote_actor(respx_mock)
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(
@ -136,10 +98,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 = _setup_remote_actor(respx_mock) ra = setup_remote_actor(respx_mock)
# who is a follower # who is a follower
follower = _remote_actor_as_follower(ra) follower = setup_remote_actor_as_follower(ra)
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(
@ -172,10 +134,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 = _setup_remote_actor(respx_mock) ra = setup_remote_actor(respx_mock)
# who is a follower # who is a follower
follower = _remote_actor_as_follower(ra) follower = setup_remote_actor_as_follower(ra)
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(
@ -216,10 +178,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 = _setup_remote_actor(respx_mock) ra = setup_remote_actor(respx_mock)
# who is a follower # who is a follower
follower = _remote_actor_as_follower(ra) follower = setup_remote_actor_as_follower(ra)
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(
@ -262,10 +224,10 @@ def test_send_create_activity__article(
respx_mock: respx.MockRouter, respx_mock: respx.MockRouter,
) -> None: ) -> None:
# given a remote actor # given a remote actor
ra = _setup_remote_actor(respx_mock) ra = setup_remote_actor(respx_mock)
# who is a follower # who is a follower
follower = _remote_actor_as_follower(ra) follower = setup_remote_actor_as_follower(ra)
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(

View file

@ -1,12 +1,21 @@
import asyncio
from contextlib import contextmanager from contextlib import contextmanager
from typing import Any from typing import Any
from uuid import uuid4
import fastapi import fastapi
import httpx
import respx
from app import actor from app import actor
from app import httpsig from app import httpsig
from app import models
from app.actor import LOCAL_ACTOR
from app.ap_object import RemoteObject
from app.config import session_serializer from app.config import session_serializer
from app.database import async_session
from app.main import app from app.main import app
from tests import factories
@contextmanager @contextmanager
@ -28,3 +37,45 @@ def mock_httpsig_checker(ra: actor.RemoteActor):
def generate_admin_session_cookies() -> dict[str, Any]: def generate_admin_session_cookies() -> dict[str, Any]:
return {"session": session_serializer.dumps({"is_logged_in": True})} return {"session": session_serializer.dumps({"is_logged_in": True})}
def setup_remote_actor(respx_mock: respx.MockRouter) -> actor.RemoteActor:
ra = factories.RemoteActorFactory(
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))
return ra
def setup_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 run_async(func, *args, **kwargs):
async def _func():
async with async_session() as db:
return await func(db, *args, **kwargs)
asyncio.run(_func())