test: move domain tests to tests/

Self dev-dep w/ test-helpers for domain::testing. Also moved social blanket-impl + InMemoryStore tests (public API only). No private-item exceptions.
This commit is contained in:
2026-10-25 22:34:08 +01:00
parent 1e6e9ddf6b
commit a2c713c1fa
39 changed files with 257 additions and 274 deletions

View File

@@ -0,0 +1,42 @@
use domain::ports::noop::{NoopApBackfill, NoopApDocument, NoopInstanceBlocklist};
use domain::ports::{ApBackfillPort, ApDocumentPort, InstanceBlocklistPort};
#[tokio::test]
async fn noop_document_returns_empty_strings() {
let p = NoopApDocument;
assert_eq!(p.actor_json("anything").await.unwrap(), "");
assert_eq!(
p.followers_collection_json(uuid::Uuid::nil(), None)
.await
.unwrap(),
""
);
assert_eq!(
p.following_collection_json(uuid::Uuid::nil(), Some(2))
.await
.unwrap(),
""
);
}
#[tokio::test]
async fn noop_blocklist_returns_empty_and_ok() {
let p = NoopInstanceBlocklist;
assert!(p.get_blocked_domains().await.unwrap().is_empty());
p.add_blocked_domain("evil.example", Some("spam"))
.await
.unwrap();
p.remove_blocked_domain("evil.example").await.unwrap();
}
#[tokio::test]
async fn noop_backfill_returns_empty_and_ok() {
let p = NoopApBackfill;
assert!(p.get_following(uuid::Uuid::nil()).await.unwrap().is_empty());
p.import_remote_outbox("https://a/outbox", "https://a")
.await
.unwrap();
p.run_backfill_for_follower(uuid::Uuid::nil(), "https://a/inbox".into())
.await
.unwrap();
}

View File

@@ -0,0 +1,162 @@
use async_trait::async_trait;
use domain::errors::DomainError;
use domain::ports::{
BlockQuery, FollowGraphQuery, FollowTargetResolver, LocalSocial, ResolvedFollow, SocialCommand,
};
use domain::value_objects::SocialIdentity;
use std::sync::Arc;
struct Stub;
#[async_trait]
impl SocialCommand for Stub {
async fn follow(
&self,
_: &domain::value_objects::UserId,
_: &domain::value_objects::FollowTarget,
) -> Result<(), DomainError> {
Ok(())
}
async fn unfollow(
&self,
_: &domain::value_objects::UserId,
_: &domain::value_objects::SocialIdentity,
) -> Result<(), DomainError> {
Ok(())
}
async fn accept_follow(
&self,
_: &domain::value_objects::UserId,
_: &domain::value_objects::SocialIdentity,
) -> Result<(), DomainError> {
Ok(())
}
async fn reject_follow(
&self,
_: &domain::value_objects::UserId,
_: &domain::value_objects::SocialIdentity,
) -> Result<(), DomainError> {
Ok(())
}
async fn remove_follower(
&self,
_: &domain::value_objects::UserId,
_: &domain::value_objects::SocialIdentity,
) -> Result<(), DomainError> {
Ok(())
}
async fn block(
&self,
_: &domain::value_objects::UserId,
_: &domain::value_objects::SocialIdentity,
) -> Result<(), DomainError> {
Ok(())
}
async fn unblock(
&self,
_: &domain::value_objects::UserId,
_: &domain::value_objects::SocialIdentity,
) -> Result<(), DomainError> {
Ok(())
}
}
#[async_trait]
impl FollowGraphQuery for Stub {
async fn get_following(
&self,
_: &domain::value_objects::UserId,
) -> Result<Vec<domain::value_objects::SocialActor>, DomainError> {
Ok(vec![])
}
async fn get_followers(
&self,
_: &domain::value_objects::UserId,
) -> Result<Vec<domain::value_objects::SocialActor>, DomainError> {
Ok(vec![])
}
async fn get_pending_followers(
&self,
_: &domain::value_objects::UserId,
) -> Result<Vec<domain::value_objects::SocialActor>, DomainError> {
Ok(vec![])
}
async fn get_pending_following(
&self,
_: &domain::value_objects::UserId,
) -> Result<Vec<domain::value_objects::SocialActor>, DomainError> {
Ok(vec![])
}
async fn count_following(
&self,
_: &domain::value_objects::UserId,
) -> Result<usize, DomainError> {
Ok(0)
}
async fn count_followers(
&self,
_: &domain::value_objects::UserId,
) -> Result<usize, DomainError> {
Ok(0)
}
async fn count_pending_followers(
&self,
_: &domain::value_objects::UserId,
) -> Result<usize, DomainError> {
Ok(0)
}
async fn get_relation(
&self,
_: &domain::value_objects::UserId,
_: &domain::value_objects::SocialIdentity,
) -> Result<domain::value_objects::FollowRelation, DomainError> {
Err(DomainError::NotFound("stub".into()))
}
}
#[async_trait]
impl BlockQuery for Stub {
async fn get_blocked(
&self,
_: &domain::value_objects::UserId,
) -> Result<Vec<domain::value_objects::SocialActor>, DomainError> {
Ok(vec![])
}
}
#[async_trait]
impl FollowTargetResolver for Stub {
async fn resolve_target(
&self,
target: &domain::value_objects::FollowTarget,
) -> Result<SocialIdentity, DomainError> {
match target {
domain::value_objects::FollowTarget::Identity(id) => Ok(id.clone()),
domain::value_objects::FollowTarget::Handle(handle) => Ok(SocialIdentity::Remote {
actor_url: handle.clone(),
}),
}
}
}
#[async_trait]
impl ResolvedFollow for Stub {
async fn follow_resolved(
&self,
_: &domain::value_objects::UserId,
_: &SocialIdentity,
) -> Result<(), DomainError> {
Ok(())
}
}
#[test]
fn blanket_impl_yields_a_trait_object() {
let local: Arc<dyn LocalSocial> = Arc::new(Stub);
// Reachable through each supertrait without a separate Arc.
let _: &dyn SocialCommand = local.as_ref();
let _: &dyn FollowGraphQuery = local.as_ref();
let _: &dyn BlockQuery = local.as_ref();
let _: &dyn FollowTargetResolver = local.as_ref();
let _: &dyn ResolvedFollow = local.as_ref();
}