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(())
|
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 状态)
|
/// follow_up_task.status 状态转换(含 overdue 状态)
|
||||||
pub fn validate_follow_up_status_transition(current: &str, new: &str) -> HealthResult<()> {
|
pub fn validate_follow_up_status_transition(current: &str, new: &str) -> HealthResult<()> {
|
||||||
if current == new {
|
if current == new {
|
||||||
@@ -276,6 +355,68 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn online_invalid() { assert!(validate_online_status("away").is_err()); }
|
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 ---
|
// --- follow_up_status_transition ---
|
||||||
#[test]
|
#[test]
|
||||||
fn fu_pending_to_in_progress() { assert!(validate_follow_up_status_transition("pending", "in_progress").is_ok()); }
|
fn fu_pending_to_in_progress() { assert!(validate_follow_up_status_transition("pending", "in_progress").is_ok()); }
|
||||||
|
|||||||
Reference in New Issue
Block a user