feat: implement remote unfollow — wire FederationActionPort through delete_follow handler
This commit is contained in:
@@ -137,6 +137,27 @@ pub async fn follow_user(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn unfollow_actor(
|
||||
follows: &dyn FollowRepository,
|
||||
users: &dyn UserRepository,
|
||||
federation: &dyn FederationActionPort,
|
||||
events: &dyn EventPublisher,
|
||||
follower_id: &UserId,
|
||||
username: &str,
|
||||
) -> Result<(), DomainError> {
|
||||
if username.contains('@') {
|
||||
federation.unfollow_remote(follower_id, username).await
|
||||
} else {
|
||||
let uname = Username::new(username)
|
||||
.map_err(|_| DomainError::InvalidInput("invalid username".into()))?;
|
||||
let target = users
|
||||
.find_by_username(&uname)
|
||||
.await?
|
||||
.ok_or(DomainError::NotFound)?;
|
||||
unfollow_user(follows, events, follower_id, &target.id).await
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn unfollow_user(
|
||||
follows: &dyn FollowRepository,
|
||||
events: &dyn EventPublisher,
|
||||
@@ -370,6 +391,48 @@ mod tests {
|
||||
assert!(store.follows.lock().unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn unfollow_actor_local_routes_to_unfollow_user() {
|
||||
let store = TestStore::default();
|
||||
let alice = user("alice");
|
||||
let bob = user("bob");
|
||||
store.users.lock().unwrap().push(bob.clone());
|
||||
// Create an existing follow first
|
||||
store
|
||||
.follows
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(domain::models::social::Follow {
|
||||
follower_id: alice.id.clone(),
|
||||
following_id: bob.id.clone(),
|
||||
state: domain::models::social::FollowState::Accepted,
|
||||
ap_id: None,
|
||||
created_at: chrono::Utc::now(),
|
||||
});
|
||||
unfollow_actor(&store, &store, &store, &store, &alice.id, "bob")
|
||||
.await
|
||||
.unwrap();
|
||||
assert!(store.follows.lock().unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn unfollow_actor_remote_routes_to_federation() {
|
||||
let store = TestStore::default();
|
||||
let alice = user("alice");
|
||||
unfollow_actor(
|
||||
&store,
|
||||
&store,
|
||||
&store,
|
||||
&store,
|
||||
&alice.id,
|
||||
"@bob@example.com",
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
// TestStore.unfollow_remote is a no-op — just verify it doesn't error
|
||||
assert!(store.follows.lock().unwrap().is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn boost_and_unboost() {
|
||||
let store = TestStore::default();
|
||||
|
||||
Reference in New Issue
Block a user