新增 doctor(7)、diagnosis(7)、consent(6)、medication(8)、 dialysis_prescription(7)、follow_up_template(7)、daily_monitoring(7) 覆盖 CRUD、状态流、列表过滤、软删除、租户隔离、乐观锁。
223 lines
7.8 KiB
Rust
223 lines
7.8 KiB
Rust
//! erp-health 用药记录集成测试
|
|
//!
|
|
//! 验证用药记录 CRUD、列表按患者过滤、租户隔离、乐观锁。
|
|
|
|
use erp_health::dto::medication_record_dto::*;
|
|
use erp_health::service::medication_record_service;
|
|
|
|
use super::test_fixture::TestApp;
|
|
|
|
fn default_create_medication_req(patient_id: uuid::Uuid) -> CreateMedicationRecordReq {
|
|
CreateMedicationRecordReq {
|
|
patient_id,
|
|
medication_name: "缬沙坦".to_string(),
|
|
generic_name: Some("Valsartan".to_string()),
|
|
dosage: Some("80mg".to_string()),
|
|
unit: Some("mg".to_string()),
|
|
frequency: Some("daily".to_string()),
|
|
route: Some("oral".to_string()),
|
|
start_date: chrono::NaiveDate::from_ymd_opt(2026, 1, 1),
|
|
end_date: None,
|
|
is_current: Some(true),
|
|
prescribed_by: None,
|
|
notes: None,
|
|
}
|
|
}
|
|
|
|
async fn seed_medication(app: &TestApp, patient_id: uuid::Uuid) -> MedicationRecordResp {
|
|
medication_record_service::create_medication(
|
|
app.health_state(), app.tenant_id(), Some(app.operator_id()),
|
|
default_create_medication_req(patient_id),
|
|
)
|
|
.await
|
|
.expect("创建用药记录应成功")
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 1: 创建用药记录
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_medication_create() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("用药患者").await;
|
|
|
|
let med = seed_medication(&app, patient_id).await;
|
|
|
|
assert_eq!(med.patient_id, patient_id);
|
|
assert_eq!(med.medication_name, "缬沙坦");
|
|
assert_eq!(med.frequency, Some("daily".to_string()));
|
|
assert!(med.is_current);
|
|
assert_eq!(med.version, 1);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 2: 查询用药记录
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_medication_get() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("用药查询患者").await;
|
|
let med = seed_medication(&app, patient_id).await;
|
|
|
|
let fetched = medication_record_service::get_medication(
|
|
app.health_state(), app.tenant_id(), med.id,
|
|
)
|
|
.await
|
|
.expect("查询应成功");
|
|
assert_eq!(fetched.id, med.id);
|
|
assert_eq!(fetched.medication_name, "缬沙坦");
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 3: 更新用药记录
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_medication_update() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("用药更新患者").await;
|
|
let med = seed_medication(&app, patient_id).await;
|
|
|
|
let updated = medication_record_service::update_medication(
|
|
app.health_state(), app.tenant_id(), med.id,
|
|
Some(app.operator_id()),
|
|
UpdateMedicationRecordReq {
|
|
dosage: Some("160mg".to_string()),
|
|
is_current: Some(false),
|
|
medication_name: None, generic_name: None, unit: None,
|
|
frequency: None, route: None, start_date: None,
|
|
end_date: None, prescribed_by: None, notes: None,
|
|
},
|
|
med.version,
|
|
)
|
|
.await
|
|
.expect("更新应成功");
|
|
|
|
assert_eq!(updated.dosage, Some("160mg".to_string()));
|
|
assert!(!updated.is_current);
|
|
assert_eq!(updated.version, 2);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 4: 列表按患者过滤
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_medication_list_by_patient() {
|
|
let app = TestApp::new().await;
|
|
let patient_a = app.create_patient("用药列表A").await;
|
|
let patient_b = app.create_patient("用药列表B").await;
|
|
|
|
seed_medication(&app, patient_a).await;
|
|
seed_medication(&app, patient_b).await;
|
|
|
|
let list_a = medication_record_service::list_medications(
|
|
app.health_state(), app.tenant_id(), patient_a, 1, 20,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(list_a.total, 1);
|
|
|
|
let list_b = medication_record_service::list_medications(
|
|
app.health_state(), app.tenant_id(), patient_b, 1, 20,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(list_b.total, 1);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 5: 软删除
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_medication_soft_delete() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("用药删除患者").await;
|
|
let med = seed_medication(&app, patient_id).await;
|
|
|
|
medication_record_service::delete_medication(
|
|
app.health_state(), app.tenant_id(), med.id,
|
|
Some(app.operator_id()), med.version,
|
|
)
|
|
.await
|
|
.expect("删除应成功");
|
|
|
|
let result = medication_record_service::get_medication(
|
|
app.health_state(), app.tenant_id(), med.id,
|
|
)
|
|
.await;
|
|
assert!(result.is_err(), "软删除后查询应失败");
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 6: 租户隔离
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_medication_tenant_isolation() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("用药隔离患者").await;
|
|
seed_medication(&app, patient_id).await;
|
|
|
|
let other_tenant = uuid::Uuid::new_v4();
|
|
let list = medication_record_service::list_medications(
|
|
app.health_state(), other_tenant, patient_id, 1, 20,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(list.total, 0, "不同租户不应看到用药记录");
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 7: 乐观锁冲突
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_medication_version_conflict() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("用药锁患者").await;
|
|
let med = seed_medication(&app, patient_id).await;
|
|
|
|
// 先更新一次
|
|
medication_record_service::update_medication(
|
|
app.health_state(), app.tenant_id(), med.id,
|
|
Some(app.operator_id()),
|
|
UpdateMedicationRecordReq {
|
|
dosage: Some("160mg".to_string()),
|
|
medication_name: None, generic_name: None, unit: None,
|
|
frequency: None, route: None, start_date: None,
|
|
end_date: None, is_current: None, prescribed_by: None, notes: None,
|
|
},
|
|
med.version,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
// 用旧 version 再更新应失败
|
|
let result = medication_record_service::update_medication(
|
|
app.health_state(), app.tenant_id(), med.id,
|
|
Some(app.operator_id()),
|
|
UpdateMedicationRecordReq {
|
|
dosage: Some("320mg".to_string()),
|
|
medication_name: None, generic_name: None, unit: None,
|
|
frequency: None, route: None, start_date: None,
|
|
end_date: None, is_current: None, prescribed_by: None, notes: None,
|
|
},
|
|
med.version,
|
|
)
|
|
.await;
|
|
assert!(result.is_err(), "乐观锁冲突应返回错误");
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 8: 无效患者创建用药记录返回错误
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_medication_invalid_patient() {
|
|
let app = TestApp::new().await;
|
|
let fake_patient = uuid::Uuid::new_v4();
|
|
|
|
let result = medication_record_service::create_medication(
|
|
app.health_state(), app.tenant_id(), None,
|
|
default_create_medication_req(fake_patient),
|
|
)
|
|
.await;
|
|
assert!(result.is_err(), "无效患者应返回错误");
|
|
}
|