use super::handlers; use crate::core::state::AppState; use axum::{Router, routing::get}; pub fn router() -> Router { Router::new() .route("/emojis", get(handlers::get_all).post(handlers::create)) .route( "/emojis/{id}", get(handlers::get_by_id) .put(handlers::update) .delete(handlers::delete), ) .route("/emojis/{id}/asset", get(handlers::asset)) } #[cfg(test)] mod permission_tests { use super::*; use crate::models::{emoji, server_user, server_user_permission}; use crate::permissions::ServerPermission; use crate::routes::message::routes::permission_tests::Fixture; use axum::{ body::Body, http::{Method, StatusCode}, }; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set}; use uuid::Uuid; #[tokio::test] async fn emoji_create_requires_manage_server() { let fixture = Fixture::new().await; // Un membre sans MANAGE_SERVER ne peut pas créer d'emoji. let boundary = "emoji-permission-test"; let body = format!( "--{boundary}\r\nContent-Disposition: form-data; name=\"server_id\"\r\n\r\n{}\r\n--{boundary}\r\nContent-Disposition: form-data; name=\"name\"\r\n\r\nwave\r\n--{boundary}\r\nContent-Disposition: form-data; name=\"emoji_type\"\r\n\r\nunicode\r\n--{boundary}\r\nContent-Disposition: form-data; name=\"unicode_sequence\"\r\n\r\n👋\r\n--{boundary}--\r\n", fixture.state.default_server.id ); let mime = format!("multipart/form-data; boundary={boundary}"); assert_eq!( fixture .request( router(), Method::POST, "/emojis", Body::from(body.clone()), Some(&mime) ) .await, StatusCode::FORBIDDEN ); server_user_permission::ActiveModel { id: Set(Uuid::new_v4()), server_id: Set(fixture.state.default_server.id), user_id: Set(fixture.user.id), permissions: Set(ServerPermission::MANAGE_SERVER.bits() as i64), } .insert(&fixture.state.db) .await .unwrap(); assert_eq!( fixture .request( router(), Method::POST, "/emojis", Body::from(body), Some(&mime) ) .await, StatusCode::CREATED ); } #[tokio::test] async fn emoji_read_requires_membership() { let fixture = Fixture::new().await; // L'emoji de serveur est lisible par un membre, mais pas par un utilisateur retiré. let item = emoji::ActiveModel { id: Set(Uuid::new_v4()), server_id: Set(Some(fixture.state.default_server.id)), name: Set("wave".into()), emoji_type: Set("unicode".into()), unicode_sequence: Set(Some("👋".into())), supports_skin_tone: Set(false), file_path: Set(None), mime_type: Set(None), file_size: Set(None), is_animated: Set(false), sha256: Set(None), created_at: Set(chrono::Utc::now()), updated_at: Set(chrono::Utc::now()), } .insert(&fixture.state.db) .await .unwrap(); let uri = format!("/emojis/{}", item.id); assert_eq!( fixture .request(router(), Method::GET, &uri, Body::empty(), None) .await, StatusCode::OK ); server_user::Entity::delete_many() .filter(server_user::Column::UserId.eq(fixture.user.id)) .exec(&fixture.state.db) .await .unwrap(); assert_eq!( fixture .request(router(), Method::GET, &uri, Body::empty(), None) .await, StatusCode::FORBIDDEN ); } #[tokio::test] async fn emoji_update_and_delete_require_manage_server() { // Les deux opérations sont contrôlées séparément avec une fixture fraîche. for method in [Method::PUT, Method::DELETE] { let fixture = Fixture::new().await; let item = emoji::ActiveModel { id: Set(Uuid::new_v4()), server_id: Set(Some(fixture.state.default_server.id)), name: Set("wave".into()), emoji_type: Set("unicode".into()), unicode_sequence: Set(Some("👋".into())), supports_skin_tone: Set(false), file_path: Set(None), mime_type: Set(None), file_size: Set(None), is_animated: Set(false), sha256: Set(None), created_at: Set(chrono::Utc::now()), updated_at: Set(chrono::Utc::now()), } .insert(&fixture.state.db) .await .unwrap(); let uri = format!("/emojis/{}", item.id); let body = || Body::from(r#"{"name":"newwave"}"#); assert_eq!( fixture .request( router(), method.clone(), &uri, body(), Some("application/json") ) .await, StatusCode::FORBIDDEN ); server_user_permission::ActiveModel { id: Set(Uuid::new_v4()), server_id: Set(fixture.state.default_server.id), user_id: Set(fixture.user.id), permissions: Set(ServerPermission::MANAGE_SERVER.bits() as i64), } .insert(&fixture.state.db) .await .unwrap(); let expected = if method == Method::PUT { StatusCode::OK } else { StatusCode::NO_CONTENT }; assert_eq!( fixture .request(router(), method, &uri, body(), Some("application/json")) .await, expected ); } } }