More tests

This commit is contained in:
Thomas Sileo 2022-06-22 22:17:07 +02:00
parent 01a409dc78
commit a2cfc36dab
3 changed files with 97 additions and 7 deletions

View File

@ -6,6 +6,7 @@ from typing import Any
import httpx import httpx
from app import config from app import config
from app.config import AP_CONTENT_TYPE # noqa: F401
from app.httpsig import auth from app.httpsig import auth
from app.key import get_pubkey_as_pem from app.key import get_pubkey_as_pem

View File

@ -1,7 +1,9 @@
from urllib.parse import urlparse
from uuid import uuid4 from uuid import uuid4
import factory # type: ignore import factory # type: ignore
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from dateutil.parser import isoparse
from sqlalchemy import orm from sqlalchemy import orm
from app import activitypub as ap from app import activitypub as ap
@ -10,6 +12,7 @@ from app import models
from app.actor import RemoteActor from app.actor import RemoteActor
from app.ap_object import RemoteObject from app.ap_object import RemoteObject
from app.database import engine from app.database import engine
from app.database import now
_Session = orm.scoped_session(orm.sessionmaker(bind=engine)) _Session = orm.scoped_session(orm.sessionmaker(bind=engine))
@ -47,6 +50,36 @@ def build_accept_activity(
} }
def build_note_object(
from_remote_actor: actor.RemoteActor,
outbox_public_id: str | None = None,
content: str = "Hello",
to: list[str] = None,
cc: list[str] = None,
tags: list[ap.RawObject] = None,
) -> ap.RawObject:
published = now().replace(microsecond=0).isoformat().replace("+00:00", "Z")
context = from_remote_actor.ap_id + "/ctx/" + uuid4().hex
note_id = outbox_public_id or uuid4().hex
return {
"@context": ap.AS_CTX,
"type": "Note",
"id": from_remote_actor.ap_id + "/note/" + note_id,
"attributedTo": from_remote_actor.ap_id,
"content": content,
"to": to or [ap.AS_PUBLIC],
"cc": cc or [],
"published": published,
"context": context,
"conversation": context,
"url": from_remote_actor.ap_id + "/note/" + note_id,
"tag": tags or [],
"summary": None,
"inReplyTo": None,
"sensitive": False,
}
class BaseModelMeta: class BaseModelMeta:
sqlalchemy_session = _Session sqlalchemy_session = _Session
sqlalchemy_session_persistence = "commit" sqlalchemy_session_persistence = "commit"
@ -138,3 +171,36 @@ class OutgoingActivityFactory(factory.alchemy.SQLAlchemyModelFactory):
# recipient # recipient
# outbox_object_id # outbox_object_id
class InboxObjectFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta(BaseModelMeta):
model = models.InboxObject
@classmethod
def from_remote_object(
cls,
ro: RemoteObject,
actor: models.Actor,
relates_to_inbox_object_id: int | None = None,
relates_to_outbox_object_id: int | None = None,
):
ap_published_at = now()
if "published" in ro.ap_object:
ap_published_at = isoparse(ro.ap_object["published"])
return cls(
server=urlparse(ro.ap_id).netloc,
actor_id=actor.id,
ap_actor_id=actor.ap_id,
ap_type=ro.ap_type,
ap_id=ro.ap_id,
ap_context=ro.context,
ap_published_at=ap_published_at,
ap_object=ro.ap_object,
visibility=ro.visibility,
relates_to_inbox_object_id=relates_to_inbox_object_id,
relates_to_outbox_object_id=relates_to_outbox_object_id,
activity_object_ap_id=ro.activity_object_ap_id,
# Hide replies from the stream
is_hidden_from_stream=True if ro.in_reply_to else False,
)

View File

@ -1,6 +1,8 @@
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from app import activitypub as ap
from app.actor import LOCAL_ACTOR
from app.database import Session from app.database import Session
_ACCEPTED_AP_HEADERS = [ _ACCEPTED_AP_HEADERS = [
@ -11,20 +13,41 @@ _ACCEPTED_AP_HEADERS = [
] ]
@pytest.mark.anyio def test_index__html(db: Session, client: TestClient):
def test_index(db: Session, client: TestClient):
response = client.get("/") response = client.get("/")
assert response.status_code == 200 assert response.status_code == 200
assert response.headers["content-type"].startswith("text/html")
@pytest.mark.parametrize("accept", _ACCEPTED_AP_HEADERS) @pytest.mark.parametrize("accept", _ACCEPTED_AP_HEADERS)
def test__ap_version(client, db, accept: str) -> None: def test_index__ap(db: Session, client: TestClient, accept: str):
response = client.get("/followers", headers={"Accept": accept}) response = client.get("/", headers={"Accept": accept})
assert response.status_code == 200 assert response.status_code == 200
assert response.headers["content-type"] == "application/activity+json" assert response.headers["content-type"] == ap.AP_CONTENT_TYPE
assert response.json() == LOCAL_ACTOR.ap_actor
def test_followers__ap(client, db) -> None:
response = client.get("/followers", headers={"Accept": ap.AP_CONTENT_TYPE})
assert response.status_code == 200
assert response.headers["content-type"] == ap.AP_CONTENT_TYPE
assert response.json()["id"].endswith("/followers") assert response.json()["id"].endswith("/followers")
def test__html(client, db) -> None: def test_followers__html(client, db) -> None:
response = client.get("/followers", headers={"Accept": "application/activity+json"}) response = client.get("/followers")
assert response.status_code == 200 assert response.status_code == 200
assert response.headers["content-type"].startswith("text/html")
def test_following__ap(client, db) -> None:
response = client.get("/following", headers={"Accept": ap.AP_CONTENT_TYPE})
assert response.status_code == 200
assert response.headers["content-type"] == ap.AP_CONTENT_TYPE
assert response.json()["id"].endswith("/following")
def test_following__html(client, db) -> None:
response = client.get("/following")
assert response.status_code == 200
assert response.headers["content-type"].startswith("text/html")