microblog.pub/tests/factories.py

141 lines
3.7 KiB
Python

from uuid import uuid4
import factory # type: ignore
from Crypto.PublicKey import RSA
from sqlalchemy import orm
from app import activitypub as ap
from app import actor
from app import models
from app.actor import RemoteActor
from app.ap_object import RemoteObject
from app.database import engine
_Session = orm.scoped_session(orm.sessionmaker(bind=engine))
def generate_key() -> tuple[str, str]:
k = RSA.generate(1024)
return k.exportKey("PEM").decode(), k.publickey().exportKey("PEM").decode()
def build_follow_activity(
from_remote_actor: actor.RemoteActor,
for_remote_actor: actor.RemoteActor,
outbox_public_id: str | None = None,
) -> ap.RawObject:
return {
"@context": ap.AS_CTX,
"type": "Follow",
"id": from_remote_actor.ap_id + "/follow/" + (outbox_public_id or uuid4().hex),
"actor": from_remote_actor.ap_id,
"object": for_remote_actor.ap_id,
}
def build_accept_activity(
from_remote_actor: actor.RemoteActor,
for_remote_object: RemoteObject,
outbox_public_id: str | None = None,
) -> ap.RawObject:
return {
"@context": ap.AS_CTX,
"type": "Accept",
"id": from_remote_actor.ap_id + "/accept/" + (outbox_public_id or uuid4().hex),
"actor": from_remote_actor.ap_id,
"object": for_remote_object.ap_id,
}
class BaseModelMeta:
sqlalchemy_session = _Session
sqlalchemy_session_persistence = "commit"
class RemoteActorFactory(factory.Factory):
class Meta:
model = RemoteActor
exclude = (
"base_url",
"username",
"public_key",
)
class Params:
icon_url = None
summary = "I like unit tests"
ap_actor = factory.LazyAttribute(
lambda o: {
"@context": ap.AS_CTX,
"type": "Person",
"id": o.base_url,
"following": o.base_url + "/following",
"followers": o.base_url + "/followers",
# "featured": ID + "/featured",
"inbox": o.base_url + "/inbox",
"outbox": o.base_url + "/outbox",
"preferredUsername": o.username,
"name": o.username,
"summary": o.summary,
"endpoints": {},
"url": o.base_url,
"manuallyApprovesFollowers": False,
"attachment": [],
"icon": {},
"publicKey": {
"id": f"{o.base_url}#main-key",
"owner": o.base_url,
"publicKeyPem": o.public_key,
},
}
)
class ActorFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta(BaseModelMeta):
model = models.Actor
# ap_actor
# ap_id
ap_type = "Person"
@classmethod
def from_remote_actor(cls, ra):
return cls(
ap_type=ra.ap_type,
ap_actor=ra.ap_actor,
ap_id=ra.ap_id,
)
class OutboxObjectFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta(BaseModelMeta):
model = models.OutboxObject
# public_id
# relates_to_inbox_object_id
# relates_to_outbox_object_id
@classmethod
def from_remote_object(cls, public_id, ro):
return cls(
public_id=public_id,
ap_type=ro.ap_type,
ap_id=ro.ap_id,
ap_context=ro.context,
ap_object=ro.ap_object,
visibility=ro.visibility,
og_meta=ro.og_meta,
activity_object_ap_id=ro.activity_object_ap_id,
is_hidden_from_homepage=True if ro.in_reply_to else False,
)
class OutgoingActivityFactory(factory.alchemy.SQLAlchemyModelFactory):
class Meta(BaseModelMeta):
model = models.OutgoingActivity
# recipient
# outbox_object_id