test(ai): erp-ai 从零增至 34 个单元测试 — 覆盖 DTO/error/prompt/sanitization
- dto.rs: 8 个测试(AnalysisType 映射、serde round-trip、SSE 事件、默认值) - error.rs: 10 个测试(AiError 全部 10 个变体 → AppError 映射) - prompt: 8 个测试(变量替换、嵌套对象、数组迭代、条件、严格模式缺失变量) - sanitization: 8 个测试(4 种 DTO 脱敏通过、PII 字段检测、空数据边界)
This commit is contained in:
@@ -57,3 +57,108 @@ impl From<sea_orm::DbErr> for AiError {
|
||||
}
|
||||
|
||||
pub type AiResult<T> = Result<T, AiError>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn validation_maps_to_app_error_validation() {
|
||||
let err = AiError::Validation("字段缺失".to_string());
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::Validation(msg) => assert!(msg.contains("字段缺失")),
|
||||
other => panic!("期望 AppError::Validation,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn analysis_not_found_maps_to_not_found() {
|
||||
let err = AiError::AnalysisNotFound("abc-123".to_string());
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::NotFound(msg) => assert!(msg.contains("分析结果")),
|
||||
other => panic!("期望 AppError::NotFound,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prompt_not_found_maps_to_not_found() {
|
||||
let err = AiError::PromptNotFound("lab_report_interpretation".to_string());
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::NotFound(msg) => assert!(msg.contains("Prompt 模板")),
|
||||
other => panic!("期望 AppError::NotFound,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn provider_unavailable_maps_to_internal() {
|
||||
let err = AiError::ProviderUnavailable("Claude".to_string());
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::Internal(msg) => assert!(msg.contains("Claude")),
|
||||
other => panic!("期望 AppError::Internal,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn provider_error_maps_to_internal() {
|
||||
let err = AiError::ProviderError("超时".to_string());
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::Internal(msg) => assert!(msg.contains("超时")),
|
||||
other => panic!("期望 AppError::Internal,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sanitization_error_maps_to_internal() {
|
||||
let err = AiError::SanitizationError("PII 泄漏".to_string());
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::Internal(msg) => assert!(msg.contains("PII 泄漏")),
|
||||
other => panic!("期望 AppError::Internal,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn template_error_maps_to_internal() {
|
||||
let err = AiError::TemplateError("语法错误".to_string());
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::Internal(msg) => assert!(msg.contains("语法错误")),
|
||||
other => panic!("期望 AppError::Internal,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rate_limit_maps_to_too_many_requests() {
|
||||
let err = AiError::RateLimitExceeded;
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::TooManyRequests => {},
|
||||
other => panic!("期望 AppError::TooManyRequests,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn version_mismatch_maps_directly() {
|
||||
let err = AiError::VersionMismatch;
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::VersionMismatch => {},
|
||||
other => panic!("期望 AppError::VersionMismatch,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn db_error_maps_to_internal() {
|
||||
let err = AiError::DbError("连接失败".to_string());
|
||||
let app: AppError = err.into();
|
||||
match app {
|
||||
AppError::Internal(msg) => assert!(msg.contains("连接失败")),
|
||||
other => panic!("期望 AppError::Internal,得到 {:?}", other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user