feat(application): add get_remote_friends use case
This commit is contained in:
@@ -96,6 +96,20 @@ pub async fn list_remote_following(
|
|||||||
federation.get_remote_following(user_id).await
|
federation.get_remote_following(user_id).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_remote_friends(
|
||||||
|
federation: &dyn FederationActionPort,
|
||||||
|
user_id: &UserId,
|
||||||
|
) -> Result<Vec<RemoteActor>, DomainError> {
|
||||||
|
use std::collections::HashSet;
|
||||||
|
let following = federation.get_remote_following(user_id).await?;
|
||||||
|
let followers = federation.get_remote_followers(user_id).await?;
|
||||||
|
let follower_urls: HashSet<&str> = followers.iter().map(|a| a.url.as_str()).collect();
|
||||||
|
Ok(following
|
||||||
|
.into_iter()
|
||||||
|
.filter(|a| follower_urls.contains(a.url.as_str()))
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn remove_remote_following(
|
pub async fn remove_remote_following(
|
||||||
follows: &dyn FollowRepository,
|
follows: &dyn FollowRepository,
|
||||||
users: &dyn UserReader,
|
users: &dyn UserReader,
|
||||||
|
|||||||
@@ -1,6 +1,25 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use chrono::Utc;
|
||||||
|
use domain::models::remote_actor::RemoteActor;
|
||||||
use domain::testing::TestStore;
|
use domain::testing::TestStore;
|
||||||
|
|
||||||
|
fn remote_actor(url: &str, handle: &str) -> RemoteActor {
|
||||||
|
RemoteActor {
|
||||||
|
url: url.to_string(),
|
||||||
|
handle: handle.to_string(),
|
||||||
|
display_name: None,
|
||||||
|
avatar_url: None,
|
||||||
|
bio: None,
|
||||||
|
banner_url: None,
|
||||||
|
also_known_as: None,
|
||||||
|
outbox_url: None,
|
||||||
|
followers_url: None,
|
||||||
|
following_url: None,
|
||||||
|
attachment: vec![],
|
||||||
|
last_fetched_at: Utc::now(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn list_pending_returns_empty_by_default() {
|
async fn list_pending_returns_empty_by_default() {
|
||||||
let store = TestStore::default();
|
let store = TestStore::default();
|
||||||
@@ -51,3 +70,41 @@ async fn list_remote_following_returns_empty_by_default() {
|
|||||||
let result = list_remote_following(&store, &uid).await.unwrap();
|
let result = list_remote_following(&store, &uid).await.unwrap();
|
||||||
assert!(result.is_empty());
|
assert!(result.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_remote_friends_returns_intersection() {
|
||||||
|
let store = TestStore::default();
|
||||||
|
let uid = UserId::new();
|
||||||
|
|
||||||
|
let bob = remote_actor("https://bob.example.com/users/bob", "bob@bob.example.com");
|
||||||
|
let carol = remote_actor(
|
||||||
|
"https://carol.example.com/users/carol",
|
||||||
|
"carol@carol.example.com",
|
||||||
|
);
|
||||||
|
|
||||||
|
// uid follows bob and carol
|
||||||
|
store
|
||||||
|
.remote_following
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.extend([bob.clone(), carol.clone()]);
|
||||||
|
// only bob follows back
|
||||||
|
store.remote_followers.lock().unwrap().push(bob.clone());
|
||||||
|
|
||||||
|
let friends = get_remote_friends(&store, &uid).await.unwrap();
|
||||||
|
assert_eq!(friends.len(), 1);
|
||||||
|
assert_eq!(friends[0].url, bob.url);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_remote_friends_empty_when_no_mutual() {
|
||||||
|
let store = TestStore::default();
|
||||||
|
let uid = UserId::new();
|
||||||
|
|
||||||
|
let bob = remote_actor("https://bob.example.com/users/bob", "bob@bob.example.com");
|
||||||
|
store.remote_following.lock().unwrap().push(bob.clone());
|
||||||
|
// bob does NOT follow back
|
||||||
|
|
||||||
|
let friends = get_remote_friends(&store, &uid).await.unwrap();
|
||||||
|
assert!(friends.is_empty());
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user