test(config): erp-config 从 50 增至 66 个单元测试 — fallback_chain + model_to_resp + ThemeResp
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

- setting_service: 7 个测试(5 个 fallback_chain 作用域解析 + 2 个 model_to_resp 映射)
- theme_handler: 2 个测试(default_theme 默认值 + ThemeResp serde round-trip)
This commit is contained in:
iven
2026-04-28 18:31:01 +08:00
parent 26aa66d6e3
commit ace04ee56d
2 changed files with 124 additions and 2 deletions

View File

@@ -106,3 +106,30 @@ where
Ok(JsonResponse(ApiResponse::ok(req)))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_theme_all_fields_none() {
let theme = default_theme();
assert!(theme.primary_color.is_none());
assert!(theme.logo_url.is_none());
assert!(theme.sidebar_style.is_none());
}
#[test]
fn theme_resp_serde_roundtrip() {
let theme = ThemeResp {
primary_color: Some("#1890ff".to_string()),
logo_url: None,
sidebar_style: Some("dark".to_string()),
};
let json = serde_json::to_string(&theme).unwrap();
let back: ThemeResp = serde_json::from_str(&json).unwrap();
assert_eq!(back.primary_color, Some("#1890ff".to_string()));
assert_eq!(back.logo_url, None);
assert_eq!(back.sidebar_style, Some("dark".to_string()));
}
}

View File

@@ -308,7 +308,7 @@ impl SettingService {
/// Build the fallback chain for hierarchical lookup.
///
/// Returns a list of (scope, scope_id) tuples to try in order.
fn fallback_chain(
pub(crate) fn fallback_chain(
scope: &str,
_scope_id: &Option<Uuid>,
tenant_id: Uuid,
@@ -339,7 +339,7 @@ impl SettingService {
}
/// Convert a SeaORM model to a response DTO.
fn model_to_resp(model: &setting::Model) -> SettingResp {
pub(crate) fn model_to_resp(model: &setting::Model) -> SettingResp {
SettingResp {
id: model.id,
scope: model.scope.clone(),
@@ -350,3 +350,98 @@ impl SettingService {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn tid() -> Uuid {
Uuid::parse_str("00000000-0000-0000-0000-000000000001").unwrap()
}
// ---- fallback_chain ----
#[test]
fn fallback_user_scope_returns_tenant_then_platform() {
let chain = SettingService::fallback_chain("user", &None, tid()).unwrap();
assert_eq!(chain.len(), 2);
assert_eq!(chain[0], ("tenant".to_string(), Some(tid())));
assert_eq!(chain[1], ("platform".to_string(), None));
}
#[test]
fn fallback_org_scope_returns_tenant_then_platform() {
let chain = SettingService::fallback_chain("org", &None, tid()).unwrap();
assert_eq!(chain.len(), 2);
assert_eq!(chain[0], ("tenant".to_string(), Some(tid())));
assert_eq!(chain[1], ("platform".to_string(), None));
}
#[test]
fn fallback_tenant_scope_returns_platform() {
let chain = SettingService::fallback_chain("tenant", &None, tid()).unwrap();
assert_eq!(chain.len(), 1);
assert_eq!(chain[0], ("platform".to_string(), None));
}
#[test]
fn fallback_platform_scope_returns_empty() {
let chain = SettingService::fallback_chain("platform", &None, tid()).unwrap();
assert!(chain.is_empty());
}
#[test]
fn fallback_invalid_scope_returns_error() {
let result = SettingService::fallback_chain("invalid", &None, tid());
assert!(result.is_err());
match result.unwrap_err() {
ConfigError::Validation(msg) => assert!(msg.contains("不支持的作用域")),
other => panic!("期望 Validation得到 {:?}", other),
}
}
// ---- model_to_resp ----
#[test]
fn model_to_resp_maps_all_fields() {
let m = setting::Model {
id: Uuid::parse_str("00000000-0000-0000-0000-000000000010").unwrap(),
tenant_id: tid(),
scope: "tenant".to_string(),
scope_id: Some(tid()),
setting_key: "theme.primary_color".to_string(),
setting_value: serde_json::json!("#1890ff"),
created_at: chrono::Utc::now(),
updated_at: chrono::Utc::now(),
created_by: tid(),
updated_by: tid(),
deleted_at: None,
version: 3,
};
let resp = SettingService::model_to_resp(&m);
assert_eq!(resp.scope, "tenant");
assert_eq!(resp.setting_key, "theme.primary_color");
assert_eq!(resp.setting_value, serde_json::json!("#1890ff"));
assert_eq!(resp.version, 3);
}
#[test]
fn model_to_resp_null_scope_id() {
let m = setting::Model {
id: Uuid::parse_str("00000000-0000-0000-0000-000000000010").unwrap(),
tenant_id: tid(),
scope: "platform".to_string(),
scope_id: None,
setting_key: "language.default".to_string(),
setting_value: serde_json::json!("zh-CN"),
created_at: chrono::Utc::now(),
updated_at: chrono::Utc::now(),
created_by: tid(),
updated_by: tid(),
deleted_at: None,
version: 1,
};
let resp = SettingService::model_to_resp(&m);
assert_eq!(resp.scope_id, None);
}
}