Test coverage increased from ~34 to 183 tests (zero failures): - erp-core (21): version check, pagination, API response, error mapping - erp-auth (39): org tree building, DTO validation, error conversion, password hashing, user model mapping - erp-config (57): DTO validation, numbering reset logic, menu tree building, error conversion. Fixed BatchSaveMenusReq nested validation - erp-message (50): DTO validation, template rendering, query defaults, error conversion - erp-workflow (16): unchanged (parser + expression tests) All tests are pure unit tests requiring no database.
121 lines
3.9 KiB
Rust
121 lines
3.9 KiB
Rust
use erp_core::error::AppError;
|
|
|
|
/// 消息中心模块错误类型。
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum MessageError {
|
|
#[error("验证失败: {0}")]
|
|
Validation(String),
|
|
|
|
#[error("未找到: {0}")]
|
|
NotFound(String),
|
|
|
|
#[error("模板编码已存在: {0}")]
|
|
DuplicateTemplateCode(String),
|
|
|
|
#[error("渲染失败: {0}")]
|
|
TemplateRenderError(String),
|
|
|
|
#[error("版本冲突: 数据已被其他操作修改,请刷新后重试")]
|
|
VersionMismatch,
|
|
}
|
|
|
|
impl From<MessageError> for AppError {
|
|
fn from(err: MessageError) -> Self {
|
|
match err {
|
|
MessageError::Validation(msg) => AppError::Validation(msg),
|
|
MessageError::NotFound(msg) => AppError::NotFound(msg),
|
|
MessageError::DuplicateTemplateCode(msg) => AppError::Conflict(msg),
|
|
MessageError::TemplateRenderError(msg) => AppError::Internal(msg),
|
|
MessageError::VersionMismatch => AppError::VersionMismatch,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<sea_orm::TransactionError<MessageError>> for MessageError {
|
|
fn from(err: sea_orm::TransactionError<MessageError>) -> Self {
|
|
match err {
|
|
sea_orm::TransactionError::Connection(db_err) => {
|
|
MessageError::Validation(db_err.to_string())
|
|
}
|
|
sea_orm::TransactionError::Transaction(msg_err) => msg_err,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub type MessageResult<T> = Result<T, MessageError>;
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use erp_core::error::AppError;
|
|
|
|
#[test]
|
|
fn validation_maps_to_app_validation() {
|
|
let app: AppError = MessageError::Validation("标题不能为空".to_string()).into();
|
|
match app {
|
|
AppError::Validation(msg) => assert_eq!(msg, "标题不能为空"),
|
|
other => panic!("Expected AppError::Validation, got {:?}", other),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn not_found_maps_to_app_not_found() {
|
|
let app: AppError = MessageError::NotFound("消息不存在".to_string()).into();
|
|
match app {
|
|
AppError::NotFound(msg) => assert_eq!(msg, "消息不存在"),
|
|
other => panic!("Expected AppError::NotFound, got {:?}", other),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn duplicate_template_code_maps_to_app_conflict() {
|
|
let app: AppError = MessageError::DuplicateTemplateCode("WELCOME".to_string()).into();
|
|
match app {
|
|
AppError::Conflict(msg) => assert_eq!(msg, "WELCOME"),
|
|
other => panic!("Expected AppError::Conflict, got {:?}", other),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn template_render_error_maps_to_app_internal() {
|
|
let app: AppError = MessageError::TemplateRenderError("变量缺失".to_string()).into();
|
|
match app {
|
|
AppError::Internal(msg) => assert_eq!(msg, "变量缺失"),
|
|
other => panic!("Expected AppError::Internal, got {:?}", other),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn version_mismatch_maps_to_app_version_mismatch() {
|
|
let app: AppError = MessageError::VersionMismatch.into();
|
|
match app {
|
|
AppError::VersionMismatch => {}
|
|
other => panic!("Expected AppError::VersionMismatch, got {:?}", other),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn error_display_format() {
|
|
assert_eq!(
|
|
MessageError::Validation("字段为空".to_string()).to_string(),
|
|
"验证失败: 字段为空"
|
|
);
|
|
assert_eq!(
|
|
MessageError::NotFound("id=123".to_string()).to_string(),
|
|
"未找到: id=123"
|
|
);
|
|
assert_eq!(
|
|
MessageError::DuplicateTemplateCode("CODE".to_string()).to_string(),
|
|
"模板编码已存在: CODE"
|
|
);
|
|
assert_eq!(
|
|
MessageError::TemplateRenderError("解析失败".to_string()).to_string(),
|
|
"渲染失败: 解析失败"
|
|
);
|
|
assert_eq!(
|
|
MessageError::VersionMismatch.to_string(),
|
|
"版本冲突: 数据已被其他操作修改,请刷新后重试"
|
|
);
|
|
}
|
|
}
|