This commit is contained in:
2026-08-02 10:13:49 +02:00
parent ba51dde1c2
commit 9dbb7ffd5b
9 changed files with 558 additions and 108 deletions
+104 -5
View File
@@ -67,9 +67,14 @@ pub fn build_server_tree(
channels: Vec<ChannelWithPermissions>,
categories: Vec<CategoryWithPermissions>,
) -> ServerTreeResponse {
let order_map: HashMap<Uuid, i64> = orders
let order_map: HashMap<(Option<Uuid>, Uuid), i64> = orders
.into_iter()
.map(|order| (order.resource_id, order.order_key))
.map(|order| {
(
(order.parent_category_id, order.resource_id),
order.order_key,
)
})
.collect();
let mut category_channels: HashMap<Uuid, Vec<ChannelWithPermissions>> = HashMap::new();
@@ -88,7 +93,12 @@ pub fn build_server_tree(
// Trier les canaux dans chaque catégorie par leur order_key
for chans in category_channels.values_mut() {
chans.sort_by_key(|c| order_map.get(&c.channel.id).copied().unwrap_or(i64::MAX));
chans.sort_by_key(|c| {
order_map
.get(&(c.channel.category_id, c.channel.id))
.copied()
.unwrap_or(i64::MAX)
});
}
// Préparer les éléments racine (catégories & canaux orphelins) avec leur order_key
@@ -96,7 +106,7 @@ pub fn build_server_tree(
for cat_with_perm in categories {
let cat_id = cat_with_perm.category.id;
let order_key = order_map.get(&cat_id).copied().unwrap_or(i64::MAX);
let order_key = order_map.get(&(None, cat_id)).copied().unwrap_or(i64::MAX);
let chans = category_channels.remove(&cat_id).unwrap_or_default();
let cat_perm_bits = cat_with_perm.permissions.map(|p| p.bits()).unwrap_or(0);
@@ -121,7 +131,7 @@ pub fn build_server_tree(
for chan_with_perm in orphan_channels {
let order_key = order_map
.get(&chan_with_perm.channel.id)
.get(&(None, chan_with_perm.channel.id))
.copied()
.unwrap_or(i64::MAX);
let chan_perm_bits = chan_with_perm.permissions.map(|p| p.bits()).unwrap_or(0);
@@ -142,3 +152,92 @@ pub fn build_server_tree(
ServerTreeResponse { items }
}
#[cfg(test)]
mod tests {
use super::*;
use crate::models::{category, channel};
use crate::permissions::ChannelPermission;
use chrono::Utc;
fn channel(id: Uuid, category_id: Option<Uuid>, name: &str) -> ChannelWithPermissions {
ChannelWithPermissions {
channel: channel::Model {
id,
server_id: Some(Uuid::new_v4()),
category_id,
channel_type: channel::ChannelType::Text,
name: Some(name.to_owned()),
created_at: Utc::now(),
updated_at: Utc::now(),
},
permissions: Some(ChannelPermission::empty()),
}
}
#[test]
fn sorts_channels_by_order_key_within_each_category() {
let category_id = Uuid::new_v4();
let first_id = Uuid::new_v4();
let second_id = Uuid::new_v4();
let category = CategoryWithPermissions {
category: category::Model {
id: category_id,
server_id: Uuid::new_v4(),
name: "Discussion".to_owned(),
created_at: Utc::now(),
updated_at: Utc::now(),
},
permissions: Some(ChannelPermission::empty()),
};
let orders = vec![
server_item_order::Model {
id: Uuid::new_v4(),
server_id: category.category.server_id,
resource_id: category_id,
resource_type: server_item_order::OrderedResourceType::Category,
parent_category_id: None,
order_key: 1,
created_at: Utc::now(),
updated_at: Utc::now(),
},
server_item_order::Model {
id: Uuid::new_v4(),
server_id: category.category.server_id,
resource_id: first_id,
resource_type: server_item_order::OrderedResourceType::Channel,
parent_category_id: Some(category_id),
order_key: 2,
created_at: Utc::now(),
updated_at: Utc::now(),
},
server_item_order::Model {
id: Uuid::new_v4(),
server_id: category.category.server_id,
resource_id: second_id,
resource_type: server_item_order::OrderedResourceType::Channel,
parent_category_id: Some(category_id),
order_key: 1,
created_at: Utc::now(),
updated_at: Utc::now(),
},
];
let response = build_server_tree(
orders,
vec![
channel(first_id, Some(category_id), "second"),
channel(second_id, Some(category_id), "first"),
],
vec![category],
);
let ServerExplorerItemResponse::Category(_, channels) = &response.items[0] else {
panic!("expected a category");
};
assert_eq!(channels[0].name.as_deref(), Some("first"));
assert_eq!(channels[1].name.as_deref(), Some("second"));
}
}