Files
oxspeak_server/src/routes/emoji/routes.rs
T
2026-09-24 21:10:11 +02:00

177 lines
6.2 KiB
Rust

use super::handlers;
use crate::core::state::AppState;
use axum::{Router, routing::get};
pub fn router() -> Router<AppState> {
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
);
}
}
}