use crate::http::test_support::{request, state, user}; use crate::permissions::ServerPermission; use axum::{body::{to_bytes, Body}, http::{Method, StatusCode}, Router}; use serde_json::{json, Value}; use tower::ServiceExt; async fn call(router: &Router, method: Method, uri: &str, body: Value, actor: crate::models::user::Model) -> axum::response::Response { let mut req = request(method, uri, Body::from(body.to_string()), Some(actor)); req.headers_mut().insert("content-type", "application/json".parse().unwrap()); router.clone().oneshot(req).await.unwrap() } #[tokio::test] async fn category_permissions_over_http() { let state = state().await; let server = state.default_server.id; let actor = user(&state, false).await; let router = super::routes::router().with_state(state.clone()); let list = format!("/categories?server_id={server}"); // La lecture est réservée aux membres du serveur. assert_eq!( call(&router, Method::GET, &list, json!(null), actor.clone()) .await .status(), StatusCode::FORBIDDEN ); state.repositories.server.add_user(server, actor.id).await.unwrap(); assert_eq!( call(&router, Method::GET, &list, json!(null), actor.clone()) .await .status(), StatusCode::OK ); let payload = json!({"server_id":server,"name":"test-category"}); // Être membre suffit pour lire, mais pas pour gérer les catégories. assert_eq!( call(&router, Method::POST, "/categories", payload.clone(), actor.clone()) .await .status(), StatusCode::FORBIDDEN ); state.repositories.server.set_user_permission(server, actor.id, ServerPermission::MANAGE_CATEGORIES.bits()).await.unwrap(); let created = call(&router, Method::POST, "/categories", payload, actor.clone()).await; assert_eq!(created.status(), StatusCode::CREATED); let id: Value = serde_json::from_slice(&to_bytes(created.into_body(), 1024 * 1024).await.unwrap()).unwrap(); let uri = format!("/categories/{}", id["id"].as_str().unwrap()); assert_eq!( call(&router, Method::GET, &uri, json!(null), actor.clone()) .await .status(), StatusCode::OK ); // Le retrait du droit de gestion bloque modification et suppression. state.repositories.server.set_user_permission(server, actor.id, 0).await.unwrap(); assert_eq!( call(&router, Method::PUT, &uri, json!({"name":"renamed"}), actor.clone()) .await .status(), StatusCode::FORBIDDEN ); assert_eq!( call(&router, Method::DELETE, &uri, json!(null), actor.clone()) .await .status(), StatusCode::FORBIDDEN ); state.repositories.server.set_user_permission(server, actor.id, ServerPermission::MANAGE_CATEGORIES.bits()).await.unwrap(); assert_eq!( call(&router, Method::PUT, &uri, json!({"name":"renamed"}), actor.clone()) .await .status(), StatusCode::OK ); assert_eq!( call(&router, Method::DELETE, &uri, json!(null), actor) .await .status(), StatusCode::NO_CONTENT ); }