use super::handlers; use crate::core::state::AppState; use axum::{ Router, routing::{get, post}, }; pub fn router() -> Router { Router::new() .route("/conversations", get(handlers::list).post(handlers::create)) .route("/conversations/{id}/fork", post(handlers::fork)) } #[cfg(test)] mod tests { use super::*; use crate::http::test_support::{request, state, user}; use axum::{body::{to_bytes, Body}, http::{Method, StatusCode}}; use tower::ServiceExt; #[tokio::test] async fn conversation_routes_respect_authentication_and_membership() { let state = state().await; let owner = user(&state, false).await; let guest = user(&state, false).await; let outsider = user(&state, true).await; let routes = router().with_state(state); let list = routes.clone().oneshot(request(Method::GET, "/conversations", Body::empty(), Some(owner.clone()))).await.unwrap(); assert_eq!(list.status(), StatusCode::OK); let create_body = format!(r#"{{"user_ids":["{}"]}}"#, guest.id); let mut create = request(Method::POST, "/conversations", Body::from(create_body.clone()), Some(owner.clone())); create.headers_mut().insert("content-type", "application/json".parse().unwrap()); let created = routes.clone().oneshot(create).await.unwrap(); assert_eq!(created.status(), StatusCode::OK); let bytes = to_bytes(created.into_body(), 1024 * 1024).await.unwrap(); let id = serde_json::from_slice::(&bytes).unwrap()["id"].as_str().unwrap().to_string(); let fork_uri = format!("/conversations/{id}/fork"); let fork_body = r#"{"user_ids":[]}"#; let mut forbidden = request(Method::POST, &fork_uri, Body::from(fork_body), Some(outsider)); forbidden.headers_mut().insert("content-type", "application/json".parse().unwrap()); assert_eq!(routes.clone().oneshot(forbidden).await.unwrap().status(), StatusCode::FORBIDDEN); let mut allowed = request(Method::POST, &fork_uri, Body::from(fork_body), Some(guest)); allowed.headers_mut().insert("content-type", "application/json".parse().unwrap()); assert_eq!(routes.clone().oneshot(allowed).await.unwrap().status(), StatusCode::OK); for (method, uri, body) in [(Method::GET, "/conversations", ""), (Method::POST, "/conversations", create_body.as_str()), (Method::POST, fork_uri.as_str(), fork_body)] { let result = routes.clone().oneshot(request(method, uri, Body::from(body.to_string()), None)).await.unwrap(); assert_eq!(result.status(), StatusCode::UNAUTHORIZED, "{uri}"); } } }