refactor: replace native_db with memdb and add tests

This commit is contained in:
rustmailer
2026-05-14 02:29:23 +08:00
parent 0abaa66a40
commit 5406c4322c
102 changed files with 7225 additions and 2735 deletions
+12 -12
View File
@@ -16,12 +16,12 @@ pub struct ClientContext {
}
impl ClientContext {
pub async fn require_any_permission(
pub fn require_any_permission(
&self,
requirements: Vec<(Option<u64>, &str)>,
) -> BichonResult<()> {
for (account_id, permission) in requirements {
if self.has_permission(account_id, permission).await {
if self.has_permission(account_id, permission) {
return Ok(());
}
}
@@ -31,18 +31,18 @@ impl ClientContext {
))
}
pub async fn check_has_permission(
pub fn check_has_permission(
user: &UserModel,
account_id: Option<u64>,
permission: &str,
) -> bool {
if user.is_admin().await {
if user.is_admin() {
return true;
}
let mut global_perms = HashSet::new();
for rid in &user.global_roles {
if let Some(role) = UserRole::find(*rid).await.ok().flatten() {
if let Some(role) = UserRole::find(*rid).ok().flatten() {
global_perms.extend(role.permissions);
}
}
@@ -53,7 +53,7 @@ impl ClientContext {
if let Some(aid) = account_id {
if let Some(role_id) = user.account_access_map.get(&aid) {
if let Some(role) = UserRole::find(*role_id).await.ok().flatten() {
if let Some(role) = UserRole::find(*role_id).ok().flatten() {
if role.permissions.contains(&permission.to_string())
|| Self::check_account_logic(&role.permissions, permission)
{
@@ -66,14 +66,14 @@ impl ClientContext {
false
}
pub async fn has_permission(&self, account_id: Option<u64>, permission: &str) -> bool {
if self.user.is_admin().await {
pub fn has_permission(&self, account_id: Option<u64>, permission: &str) -> bool {
if self.user.is_admin() {
return true;
}
let mut global_perms = HashSet::new();
for rid in &self.user.global_roles {
if let Some(role) = UserRole::find(*rid).await.ok().flatten() {
if let Some(role) = UserRole::find(*rid).ok().flatten() {
global_perms.extend(role.permissions);
}
}
@@ -84,7 +84,7 @@ impl ClientContext {
if let Some(aid) = account_id {
if let Some(role_id) = self.user.account_access_map.get(&aid) {
if let Some(role) = UserRole::find(*role_id).await.ok().flatten() {
if let Some(role) = UserRole::find(*role_id).ok().flatten() {
if role.permissions.contains(&permission.to_string())
|| Self::check_account_logic(&role.permissions, permission)
{
@@ -126,12 +126,12 @@ impl ClientContext {
}
}
pub async fn require_permission(
pub fn require_permission(
&self,
account_id: Option<u64>,
permission: &str,
) -> BichonResult<()> {
if self.has_permission(account_id, permission).await {
if self.has_permission(account_id, permission) {
Ok(())
} else {
Err(raise_error!(
+80
View File
@@ -178,3 +178,83 @@ impl<T> Paginated<T> {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn paginate_vec_full_list_without_pagination() {
let items: Vec<i32> = (1..=10).collect();
let result = paginate_vec(&items, None, None).unwrap();
assert_eq!(result.items.len(), 10);
assert_eq!(result.total_items, 10);
assert_eq!(result.page, None);
assert_eq!(result.total_pages, None);
}
#[test]
fn paginate_vec_first_page() {
let items: Vec<i32> = (1..=25).collect();
let result = paginate_vec(&items, Some(1), Some(10)).unwrap();
assert_eq!(result.items, vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
assert_eq!(result.total_items, 25);
assert_eq!(result.total_pages, Some(3));
assert_eq!(result.page, Some(1));
}
#[test]
fn paginate_vec_last_partial_page() {
let items: Vec<i32> = (1..=25).collect();
let result = paginate_vec(&items, Some(3), Some(10)).unwrap();
assert_eq!(result.items, vec![21, 22, 23, 24, 25]);
assert_eq!(result.total_items, 25);
assert_eq!(result.total_pages, Some(3));
}
#[test]
fn paginate_vec_page_beyond_range_returns_empty() {
let items: Vec<i32> = (1..=10).collect();
let result = paginate_vec(&items, Some(5), Some(10)).unwrap();
assert_eq!(result.items.len(), 0);
assert_eq!(result.total_items, 10);
}
#[test]
fn paginate_vec_empty_list() {
let items: Vec<i32> = vec![];
let result = paginate_vec(&items, Some(1), Some(10)).unwrap();
assert_eq!(result.items.len(), 0);
assert_eq!(result.total_items, 0);
assert_eq!(result.total_pages, Some(0));
}
#[test]
fn paginate_vec_zero_page_returns_error() {
let items: Vec<i32> = (1..=10).collect();
assert!(paginate_vec(&items, Some(0), Some(10)).is_err());
}
#[test]
fn paginate_vec_zero_page_size_returns_error() {
let items: Vec<i32> = (1..=10).collect();
assert!(paginate_vec(&items, Some(1), Some(0)).is_err());
}
#[test]
fn paginate_vec_single_item() {
let items = vec![42];
let result = paginate_vec(&items, Some(1), Some(10)).unwrap();
assert_eq!(result.items, vec![42]);
assert_eq!(result.total_items, 1);
assert_eq!(result.total_pages, Some(1));
}
#[test]
fn paginate_vec_exact_page_boundary() {
let items: Vec<i32> = (1..=20).collect();
let result = paginate_vec(&items, Some(2), Some(10)).unwrap();
assert_eq!(result.items, vec![11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);
assert_eq!(result.total_pages, Some(2));
}
}