test(health): 补充 article/dialysis/lab_report 状态转换验证 + 83 单元测试
- validate_article_status (枚举白名单) + validate_article_status_transition (draft→pending_review→approved→published, rejected→pending_review, published→draft) - validate_dialysis_status + validate_dialysis_status_transition (draft→completed→reviewed) - validate_lab_report_status_transition (pending→reviewed) - 全部 83 个 validation 测试通过
This commit is contained in:
@@ -131,6 +131,85 @@ pub fn validate_online_status(value: &str) -> HealthResult<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// article.status 枚举白名单
|
||||
pub fn validate_article_status(value: &str) -> HealthResult<()> {
|
||||
validate_enum!(value, "article.status", [
|
||||
"draft", "pending_review", "approved", "rejected", "published",
|
||||
]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// article.status 状态转换
|
||||
/// draft → pending_review, rejected → pending_review
|
||||
/// pending_review → approved / rejected
|
||||
/// approved → published
|
||||
/// published → draft (下架)
|
||||
pub fn validate_article_status_transition(current: &str, new: &str) -> HealthResult<()> {
|
||||
if current == new {
|
||||
return Ok(());
|
||||
}
|
||||
let allowed = match current {
|
||||
"draft" => matches!(new, "pending_review"),
|
||||
"pending_review" => matches!(new, "approved" | "rejected"),
|
||||
"approved" => matches!(new, "published"),
|
||||
"rejected" => matches!(new, "pending_review"),
|
||||
"published" => matches!(new, "draft"),
|
||||
_ => false,
|
||||
};
|
||||
if allowed {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(HealthError::InvalidStatusTransition(format!(
|
||||
"article.status: 不允许从 '{}' 转换到 '{}'", current, new
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// dialysis_record.status 枚举白名单
|
||||
pub fn validate_dialysis_status(value: &str) -> HealthResult<()> {
|
||||
validate_enum!(value, "dialysis_record.status", ["draft", "completed", "reviewed"]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// dialysis_record.status 状态转换
|
||||
/// draft → completed → reviewed
|
||||
pub fn validate_dialysis_status_transition(current: &str, new: &str) -> HealthResult<()> {
|
||||
if current == new {
|
||||
return Ok(());
|
||||
}
|
||||
let allowed = match current {
|
||||
"draft" => matches!(new, "completed"),
|
||||
"completed" => matches!(new, "reviewed"),
|
||||
_ => false,
|
||||
};
|
||||
if allowed {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(HealthError::InvalidStatusTransition(format!(
|
||||
"dialysis_record.status: 不允许从 '{}' 转换到 '{}'", current, new
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// lab_report.status 状态转换
|
||||
/// pending → reviewed
|
||||
pub fn validate_lab_report_status_transition(current: &str, new: &str) -> HealthResult<()> {
|
||||
if current == new {
|
||||
return Ok(());
|
||||
}
|
||||
let allowed = match current {
|
||||
"pending" => matches!(new, "reviewed"),
|
||||
_ => false,
|
||||
};
|
||||
if allowed {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(HealthError::InvalidStatusTransition(format!(
|
||||
"lab_report.status: 不允许从 '{}' 转换到 '{}'", current, new
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// follow_up_task.status 状态转换(含 overdue 状态)
|
||||
pub fn validate_follow_up_status_transition(current: &str, new: &str) -> HealthResult<()> {
|
||||
if current == new {
|
||||
@@ -276,6 +355,68 @@ mod tests {
|
||||
#[test]
|
||||
fn online_invalid() { assert!(validate_online_status("away").is_err()); }
|
||||
|
||||
// --- article_status ---
|
||||
#[test]
|
||||
fn article_draft() { assert!(validate_article_status("draft").is_ok()); }
|
||||
#[test]
|
||||
fn article_published() { assert!(validate_article_status("published").is_ok()); }
|
||||
#[test]
|
||||
fn article_invalid() { assert!(validate_article_status("archived").is_err()); }
|
||||
|
||||
// --- article_status_transition ---
|
||||
#[test]
|
||||
fn art_draft_to_pending_review() { assert!(validate_article_status_transition("draft", "pending_review").is_ok()); }
|
||||
#[test]
|
||||
fn art_draft_to_published_fails() { assert!(validate_article_status_transition("draft", "published").is_err()); }
|
||||
#[test]
|
||||
fn art_pending_review_to_approved() { assert!(validate_article_status_transition("pending_review", "approved").is_ok()); }
|
||||
#[test]
|
||||
fn art_pending_review_to_rejected() { assert!(validate_article_status_transition("pending_review", "rejected").is_ok()); }
|
||||
#[test]
|
||||
fn art_pending_review_to_draft_fails() { assert!(validate_article_status_transition("pending_review", "draft").is_err()); }
|
||||
#[test]
|
||||
fn art_approved_to_published() { assert!(validate_article_status_transition("approved", "published").is_ok()); }
|
||||
#[test]
|
||||
fn art_rejected_to_pending_review() { assert!(validate_article_status_transition("rejected", "pending_review").is_ok()); }
|
||||
#[test]
|
||||
fn art_published_to_draft() { assert!(validate_article_status_transition("published", "draft").is_ok()); }
|
||||
#[test]
|
||||
fn art_published_to_approved_fails() { assert!(validate_article_status_transition("published", "approved").is_err()); }
|
||||
#[test]
|
||||
fn art_same_status_ok() { assert!(validate_article_status_transition("draft", "draft").is_ok()); }
|
||||
|
||||
// --- dialysis_status ---
|
||||
#[test]
|
||||
fn dialysis_draft() { assert!(validate_dialysis_status("draft").is_ok()); }
|
||||
#[test]
|
||||
fn dialysis_reviewed() { assert!(validate_dialysis_status("reviewed").is_ok()); }
|
||||
#[test]
|
||||
fn dialysis_invalid() { assert!(validate_dialysis_status("approved").is_err()); }
|
||||
|
||||
// --- dialysis_status_transition ---
|
||||
#[test]
|
||||
fn dial_draft_to_completed() { assert!(validate_dialysis_status_transition("draft", "completed").is_ok()); }
|
||||
#[test]
|
||||
fn dial_draft_to_reviewed_fails() { assert!(validate_dialysis_status_transition("draft", "reviewed").is_err()); }
|
||||
#[test]
|
||||
fn dial_completed_to_reviewed() { assert!(validate_dialysis_status_transition("completed", "reviewed").is_ok()); }
|
||||
#[test]
|
||||
fn dial_completed_to_draft_fails() { assert!(validate_dialysis_status_transition("completed", "draft").is_err()); }
|
||||
#[test]
|
||||
fn dial_reviewed_to_any_fails() { assert!(validate_dialysis_status_transition("reviewed", "draft").is_err()); }
|
||||
#[test]
|
||||
fn dial_same_status_ok() { assert!(validate_dialysis_status_transition("draft", "draft").is_ok()); }
|
||||
|
||||
// --- lab_report_status_transition ---
|
||||
#[test]
|
||||
fn lab_pending_to_reviewed() { assert!(validate_lab_report_status_transition("pending", "reviewed").is_ok()); }
|
||||
#[test]
|
||||
fn lab_pending_to_draft_fails() { assert!(validate_lab_report_status_transition("pending", "draft").is_err()); }
|
||||
#[test]
|
||||
fn lab_reviewed_to_any_fails() { assert!(validate_lab_report_status_transition("reviewed", "pending").is_err()); }
|
||||
#[test]
|
||||
fn lab_same_status_ok() { assert!(validate_lab_report_status_transition("pending", "pending").is_ok()); }
|
||||
|
||||
// --- follow_up_status_transition ---
|
||||
#[test]
|
||||
fn fu_pending_to_in_progress() { assert!(validate_follow_up_status_transition("pending", "in_progress").is_ok()); }
|
||||
|
||||
Reference in New Issue
Block a user