feat(presentation): add GET /users/me/friends handler and route
This commit is contained in:
@@ -4,11 +4,15 @@ use crate::{
|
|||||||
errors::ApiError,
|
errors::ApiError,
|
||||||
extractors::{AuthUser, Deps},
|
extractors::{AuthUser, Deps},
|
||||||
};
|
};
|
||||||
use api_types::requests::SetTopFriendsRequest;
|
use api_types::requests::{PaginationQuery, SetTopFriendsRequest};
|
||||||
use api_types::responses::TopFriendsResponse;
|
use api_types::responses::{PagedResponse, TopFriendsResponse, UserResponse};
|
||||||
use application::use_cases::profile::{get_top_friends, get_user_by_username, set_top_friends};
|
use application::use_cases::profile::{get_top_friends, get_user_by_username, set_top_friends};
|
||||||
use application::use_cases::social::*;
|
use application::use_cases::social::*;
|
||||||
use axum::{extract::Path, http::StatusCode, Json};
|
use axum::{
|
||||||
|
extract::{Path, Query},
|
||||||
|
http::StatusCode,
|
||||||
|
Json,
|
||||||
|
};
|
||||||
use domain::{
|
use domain::{
|
||||||
ports::{
|
ports::{
|
||||||
BlockRepository, BoostRepository, EventPublisher, FederationActionPort, FollowRepository,
|
BlockRepository, BoostRepository, EventPublisher, FederationActionPort, FollowRepository,
|
||||||
@@ -150,5 +154,33 @@ pub async fn get_top_friends_handler(
|
|||||||
Ok(Json(TopFriendsResponse { top_friends }))
|
Ok(Json(TopFriendsResponse { top_friends }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[utoipa::path(
|
||||||
|
get, path = "/users/me/friends",
|
||||||
|
params(PaginationQuery),
|
||||||
|
responses(
|
||||||
|
(status = 200, description = "Local mutual follows (paginated)", body = inline(PagedResponse<UserResponse>)),
|
||||||
|
(status = 401, description = "Unauthorized"),
|
||||||
|
),
|
||||||
|
security(("bearer_auth" = []))
|
||||||
|
)]
|
||||||
|
pub async fn get_friends_handler(
|
||||||
|
Deps(d): Deps<SocialDeps>,
|
||||||
|
AuthUser(uid): AuthUser,
|
||||||
|
Query(q): Query<PaginationQuery>,
|
||||||
|
) -> Result<Json<PagedResponse<UserResponse>>, ApiError> {
|
||||||
|
use domain::models::feed::PageParams;
|
||||||
|
let page = PageParams {
|
||||||
|
page: q.page(),
|
||||||
|
per_page: q.per_page(),
|
||||||
|
};
|
||||||
|
let result = get_local_friends(&*d.follows, &uid, &page).await?;
|
||||||
|
Ok(Json(PagedResponse {
|
||||||
|
items: result.items.iter().map(to_user_response).collect(),
|
||||||
|
total: result.total,
|
||||||
|
page: result.page,
|
||||||
|
per_page: result.per_page,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
|
use super::get_friends_handler;
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::testing::make_state;
|
use crate::testing::make_state;
|
||||||
use axum::{
|
use axum::{
|
||||||
body::Body,
|
body::Body,
|
||||||
http::Request,
|
http::Request,
|
||||||
routing::{delete, post},
|
routing::{delete, get, post},
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use tower::ServiceExt;
|
use tower::ServiceExt;
|
||||||
@@ -32,6 +33,24 @@ async fn follow_without_auth_returns_401() {
|
|||||||
assert_eq!(resp.status(), 401);
|
assert_eq!(resp.status(), 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn get_friends_without_auth_returns_401() {
|
||||||
|
let app = Router::new()
|
||||||
|
.route("/users/me/friends", get(get_friends_handler))
|
||||||
|
.with_state(make_state());
|
||||||
|
let resp = app
|
||||||
|
.oneshot(
|
||||||
|
Request::builder()
|
||||||
|
.method("GET")
|
||||||
|
.uri("/users/me/friends")
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(resp.status(), 401);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn unfollow_remote_without_auth_returns_401() {
|
async fn unfollow_remote_without_auth_returns_401() {
|
||||||
let resp = app()
|
let resp = app()
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ use utoipa::OpenApi;
|
|||||||
crate::handlers::social::delete_block,
|
crate::handlers::social::delete_block,
|
||||||
crate::handlers::social::put_top_friends,
|
crate::handlers::social::put_top_friends,
|
||||||
crate::handlers::social::get_top_friends_handler,
|
crate::handlers::social::get_top_friends_handler,
|
||||||
|
crate::handlers::social::get_friends_handler,
|
||||||
),
|
),
|
||||||
components(schemas(SetTopFriendsRequest))
|
components(schemas(SetTopFriendsRequest))
|
||||||
)]
|
)]
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ pub fn router() -> Router<AppState> {
|
|||||||
put(users::upload_banner).layer(DefaultBodyLimit::max(10 * 1024 * 1024)),
|
put(users::upload_banner).layer(DefaultBodyLimit::max(10 * 1024 * 1024)),
|
||||||
)
|
)
|
||||||
.route("/users/me/following", get(users::get_me_following))
|
.route("/users/me/following", get(users::get_me_following))
|
||||||
|
.route("/users/me/friends", get(social::get_friends_handler))
|
||||||
.route("/users/me/top-friends", put(social::put_top_friends))
|
.route("/users/me/top-friends", put(social::put_top_friends))
|
||||||
.route("/users/{username}", get(users::get_user))
|
.route("/users/{username}", get(users::get_user))
|
||||||
.route(
|
.route(
|
||||||
|
|||||||
Reference in New Issue
Block a user