122 lines
3.3 KiB
Rust
122 lines
3.3 KiB
Rust
use crate::{
|
|
errors::ApiError, extractors::OptionalAuthUser, handlers::feed::to_thought_response,
|
|
state::AppState,
|
|
};
|
|
use api_types::{
|
|
requests::PaginationQuery,
|
|
responses::{ActorConnectionPageResponse, ActorConnectionResponse},
|
|
};
|
|
use application::use_cases::federation_management::{
|
|
get_actor_connections_page, get_remote_actor_posts,
|
|
};
|
|
use axum::{
|
|
extract::{Path, Query, State},
|
|
Json,
|
|
};
|
|
use domain::models::feed::PageParams;
|
|
|
|
pub async fn remote_actor_posts_handler(
|
|
State(s): State<AppState>,
|
|
Path(handle): Path<String>,
|
|
Query(q): Query<PaginationQuery>,
|
|
OptionalAuthUser(viewer): OptionalAuthUser,
|
|
) -> Result<Json<serde_json::Value>, ApiError> {
|
|
let page = PageParams {
|
|
page: q.page(),
|
|
per_page: q.per_page(),
|
|
};
|
|
let result = get_remote_actor_posts(
|
|
&*s.federation,
|
|
&*s.ap_repo,
|
|
&*s.feed,
|
|
&*s.federation_scheduler,
|
|
&handle,
|
|
page,
|
|
viewer.as_ref(),
|
|
)
|
|
.await?;
|
|
Ok(Json(serde_json::json!({
|
|
"total": result.total,
|
|
"page": result.page,
|
|
"per_page": result.per_page,
|
|
"items": result.items.iter().map(to_thought_response).collect::<Vec<_>>(),
|
|
})))
|
|
}
|
|
|
|
pub async fn actor_followers_handler(
|
|
State(s): State<AppState>,
|
|
Path(handle): Path<String>,
|
|
Query(q): Query<PaginationQuery>,
|
|
) -> Result<Json<ActorConnectionPageResponse>, ApiError> {
|
|
actor_connections_handler(s, handle, "followers", q.page() as u32).await
|
|
}
|
|
|
|
pub async fn actor_following_handler(
|
|
State(s): State<AppState>,
|
|
Path(handle): Path<String>,
|
|
Query(q): Query<PaginationQuery>,
|
|
) -> Result<Json<ActorConnectionPageResponse>, ApiError> {
|
|
actor_connections_handler(s, handle, "following", q.page() as u32).await
|
|
}
|
|
|
|
async fn actor_connections_handler(
|
|
s: AppState,
|
|
handle: String,
|
|
connection_type: &str,
|
|
page: u32,
|
|
) -> Result<Json<ActorConnectionPageResponse>, ApiError> {
|
|
let (items, has_more) = get_actor_connections_page(
|
|
&*s.federation,
|
|
&*s.remote_actor_connections,
|
|
&*s.federation_scheduler,
|
|
&handle,
|
|
connection_type,
|
|
page,
|
|
)
|
|
.await?;
|
|
Ok(Json(ActorConnectionPageResponse {
|
|
items: items
|
|
.into_iter()
|
|
.map(|a| ActorConnectionResponse {
|
|
handle: a.handle,
|
|
display_name: a.display_name,
|
|
avatar_url: a.avatar_url,
|
|
url: a.url,
|
|
})
|
|
.collect(),
|
|
page,
|
|
has_more,
|
|
}))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::testing::make_state;
|
|
use axum::{body::Body, http::Request, routing::get, Router};
|
|
use tower::ServiceExt;
|
|
|
|
fn app() -> Router {
|
|
Router::new()
|
|
.route(
|
|
"/federation/actors/{handle}/posts",
|
|
get(remote_actor_posts_handler),
|
|
)
|
|
.with_state(make_state())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn unknown_actor_returns_404() {
|
|
let resp = app()
|
|
.oneshot(
|
|
Request::builder()
|
|
.uri("/federation/actors/%40alice%40example.com/posts")
|
|
.body(Body::empty())
|
|
.unwrap(),
|
|
)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(resp.status(), 404);
|
|
}
|
|
}
|