test(health): 扩展预约集成测试 +3 — 状态流转/取消/乐观锁冲突
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
//! 预约创建依赖患者 + 医护档案 + 排班三条前置数据。
|
||||
|
||||
use erp_core::events::EventBus;
|
||||
use erp_health::dto::appointment_dto::CreateAppointmentReq;
|
||||
use erp_health::dto::appointment_dto::{CreateAppointmentReq, UpdateAppointmentStatusReq};
|
||||
use erp_health::dto::doctor_dto::CreateDoctorReq;
|
||||
use erp_health::dto::patient_dto::CreatePatientReq;
|
||||
use erp_health::service::{
|
||||
@@ -246,3 +246,149 @@ async fn test_appointment_tenant_isolation() {
|
||||
"跨租户查询预约应返回错误"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 测试 4: 预约状态流转 — pending → confirmed → completed
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_appointment_status_flow() {
|
||||
let test_db = TestDb::new().await;
|
||||
let state = make_state(test_db.db());
|
||||
let tenant_id = uuid::Uuid::new_v4();
|
||||
let operator_id = uuid::Uuid::new_v4();
|
||||
|
||||
let patient_id = seed_patient(&state, tenant_id, "状态患者").await;
|
||||
let doctor_id = seed_doctor(&state, tenant_id, "状态医生").await;
|
||||
let date = chrono::NaiveDate::from_ymd_opt(2026, 5, 15).unwrap();
|
||||
seed_schedule(&state, tenant_id, doctor_id, date).await;
|
||||
|
||||
let appt = appointment_service::create_appointment(
|
||||
&state, tenant_id, Some(operator_id),
|
||||
CreateAppointmentReq {
|
||||
patient_id,
|
||||
doctor_id: Some(doctor_id),
|
||||
appointment_type: None,
|
||||
appointment_date: date,
|
||||
start_time: chrono::NaiveTime::from_hms_opt(9, 0, 0).unwrap(),
|
||||
end_time: chrono::NaiveTime::from_hms_opt(9, 30, 0).unwrap(),
|
||||
notes: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("创建预约应成功");
|
||||
assert_eq!(appt.status, "pending");
|
||||
|
||||
// pending → confirmed
|
||||
let confirmed = appointment_service::update_appointment_status(
|
||||
&state, tenant_id, appt.id, Some(operator_id),
|
||||
UpdateAppointmentStatusReq { status: "confirmed".to_string(), cancel_reason: None },
|
||||
appt.version,
|
||||
)
|
||||
.await
|
||||
.expect("确认应成功");
|
||||
assert_eq!(confirmed.status, "confirmed");
|
||||
|
||||
// confirmed → completed
|
||||
let completed = appointment_service::update_appointment_status(
|
||||
&state, tenant_id, appt.id, Some(operator_id),
|
||||
UpdateAppointmentStatusReq { status: "completed".to_string(), cancel_reason: None },
|
||||
confirmed.version,
|
||||
)
|
||||
.await
|
||||
.expect("完成应成功");
|
||||
assert_eq!(completed.status, "completed");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 测试 5: 预约取消 — pending → cancelled
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_appointment_cancel() {
|
||||
let test_db = TestDb::new().await;
|
||||
let state = make_state(test_db.db());
|
||||
let tenant_id = uuid::Uuid::new_v4();
|
||||
|
||||
let patient_id = seed_patient(&state, tenant_id, "取消患者").await;
|
||||
let doctor_id = seed_doctor(&state, tenant_id, "取消医生").await;
|
||||
let date = chrono::NaiveDate::from_ymd_opt(2026, 5, 16).unwrap();
|
||||
seed_schedule(&state, tenant_id, doctor_id, date).await;
|
||||
|
||||
let appt = appointment_service::create_appointment(
|
||||
&state, tenant_id, None,
|
||||
CreateAppointmentReq {
|
||||
patient_id,
|
||||
doctor_id: Some(doctor_id),
|
||||
appointment_type: None,
|
||||
appointment_date: date,
|
||||
start_time: chrono::NaiveTime::from_hms_opt(9, 0, 0).unwrap(),
|
||||
end_time: chrono::NaiveTime::from_hms_opt(9, 30, 0).unwrap(),
|
||||
notes: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("创建应成功");
|
||||
|
||||
let cancelled = appointment_service::update_appointment_status(
|
||||
&state, tenant_id, appt.id, None,
|
||||
UpdateAppointmentStatusReq {
|
||||
status: "cancelled".to_string(),
|
||||
cancel_reason: Some("患者临时有事".to_string()),
|
||||
},
|
||||
appt.version,
|
||||
)
|
||||
.await
|
||||
.expect("取消应成功");
|
||||
assert_eq!(cancelled.status, "cancelled");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 测试 6: 预约乐观锁 — 旧版本更新拒绝
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_appointment_version_conflict() {
|
||||
let test_db = TestDb::new().await;
|
||||
let state = make_state(test_db.db());
|
||||
let tenant_id = uuid::Uuid::new_v4();
|
||||
let operator_id = uuid::Uuid::new_v4();
|
||||
|
||||
let patient_id = seed_patient(&state, tenant_id, "乐观锁患者").await;
|
||||
let doctor_id = seed_doctor(&state, tenant_id, "乐观锁医生").await;
|
||||
let date = chrono::NaiveDate::from_ymd_opt(2026, 5, 17).unwrap();
|
||||
seed_schedule(&state, tenant_id, doctor_id, date).await;
|
||||
|
||||
let appt = appointment_service::create_appointment(
|
||||
&state, tenant_id, Some(operator_id),
|
||||
CreateAppointmentReq {
|
||||
patient_id,
|
||||
doctor_id: Some(doctor_id),
|
||||
appointment_type: None,
|
||||
appointment_date: date,
|
||||
start_time: chrono::NaiveTime::from_hms_opt(9, 0, 0).unwrap(),
|
||||
end_time: chrono::NaiveTime::from_hms_opt(9, 30, 0).unwrap(),
|
||||
notes: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.expect("创建应成功");
|
||||
|
||||
// 正确版本确认
|
||||
let _confirmed = appointment_service::update_appointment_status(
|
||||
&state, tenant_id, appt.id, Some(operator_id),
|
||||
UpdateAppointmentStatusReq { status: "confirmed".to_string(), cancel_reason: None },
|
||||
appt.version,
|
||||
)
|
||||
.await
|
||||
.expect("确认应成功");
|
||||
|
||||
// 用旧版本再更新应失败
|
||||
let result = appointment_service::update_appointment_status(
|
||||
&state, tenant_id, appt.id, Some(operator_id),
|
||||
UpdateAppointmentStatusReq { status: "cancelled".to_string(), cancel_reason: None },
|
||||
appt.version, // 旧版本
|
||||
)
|
||||
.await;
|
||||
assert!(result.is_err(), "旧版本更新应失败");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user