新增 doctor(7)、diagnosis(7)、consent(6)、medication(8)、 dialysis_prescription(7)、follow_up_template(7)、daily_monitoring(7) 覆盖 CRUD、状态流、列表过滤、软删除、租户隔离、乐观锁。
163 lines
5.4 KiB
Rust
163 lines
5.4 KiB
Rust
//! erp-health 知情同意集成测试
|
|
//!
|
|
//! 验证同意授权、撤销、列表按患者过滤、租户隔离。
|
|
|
|
use erp_health::dto::consent_dto::*;
|
|
use erp_health::service::consent_service;
|
|
|
|
use super::test_fixture::TestApp;
|
|
|
|
fn default_create_consent_req(patient_id: uuid::Uuid) -> CreateConsentReq {
|
|
CreateConsentReq {
|
|
patient_id,
|
|
consent_type: "data_processing".to_string(),
|
|
consent_scope: "健康数据采集与处理".to_string(),
|
|
expiry_date: None,
|
|
consent_method: Some("电子签名".to_string()),
|
|
witness_name: None,
|
|
notes: None,
|
|
}
|
|
}
|
|
|
|
async fn seed_consent(app: &TestApp, patient_id: uuid::Uuid) -> ConsentResp {
|
|
consent_service::grant_consent(
|
|
app.health_state(), app.tenant_id(), Some(app.operator_id()),
|
|
default_create_consent_req(patient_id),
|
|
)
|
|
.await
|
|
.expect("授权应成功")
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 1: 授权同意
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_consent_grant() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("同意患者").await;
|
|
|
|
let consent = seed_consent(&app, patient_id).await;
|
|
|
|
assert_eq!(consent.patient_id, patient_id);
|
|
assert_eq!(consent.consent_type, "data_processing");
|
|
assert_eq!(consent.status, "granted");
|
|
assert!(consent.granted_at.is_some());
|
|
assert_eq!(consent.version, 1);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 2: 撤销同意
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_consent_revoke() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("撤销患者").await;
|
|
let consent = seed_consent(&app, patient_id).await;
|
|
assert_eq!(consent.status, "granted");
|
|
|
|
let revoked = consent_service::revoke_consent(
|
|
app.health_state(), app.tenant_id(), consent.id,
|
|
Some(app.operator_id()),
|
|
RevokeConsentReq {
|
|
notes: Some("患者要求撤销".to_string()),
|
|
version: consent.version,
|
|
},
|
|
)
|
|
.await
|
|
.expect("撤销应成功");
|
|
|
|
assert_eq!(revoked.status, "revoked");
|
|
assert!(revoked.revoked_at.is_some());
|
|
assert_eq!(revoked.version, 2);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 3: 列表按患者过滤
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_consent_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_consent(&app, patient_a).await;
|
|
seed_consent(&app, patient_a).await;
|
|
seed_consent(&app, patient_b).await;
|
|
|
|
let list_a = consent_service::list_consents(
|
|
app.health_state(), app.tenant_id(), patient_a, 1, 20,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(list_a.total, 2);
|
|
|
|
let list_b = consent_service::list_consents(
|
|
app.health_state(), app.tenant_id(), patient_b, 1, 20,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(list_b.total, 1);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 4: 租户隔离
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_consent_tenant_isolation() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("同意隔离患者").await;
|
|
seed_consent(&app, patient_id).await;
|
|
|
|
let other_tenant = uuid::Uuid::new_v4();
|
|
let list = consent_service::list_consents(
|
|
app.health_state(), other_tenant, patient_id, 1, 20,
|
|
)
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(list.total, 0, "不同租户不应看到同意记录");
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 5: 无效患者授权返回错误
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_consent_invalid_patient() {
|
|
let app = TestApp::new().await;
|
|
let fake_patient = uuid::Uuid::new_v4();
|
|
|
|
let result = consent_service::grant_consent(
|
|
app.health_state(), app.tenant_id(), None,
|
|
default_create_consent_req(fake_patient),
|
|
)
|
|
.await;
|
|
assert!(result.is_err(), "无效患者应返回错误");
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// 测试 6: 撤销版本冲突
|
|
// ---------------------------------------------------------------------------
|
|
#[tokio::test]
|
|
async fn test_consent_revoke_version_conflict() {
|
|
let app = TestApp::new().await;
|
|
let patient_id = app.create_patient("同意锁患者").await;
|
|
let consent = seed_consent(&app, patient_id).await;
|
|
|
|
// 先撤销一次
|
|
consent_service::revoke_consent(
|
|
app.health_state(), app.tenant_id(), consent.id,
|
|
Some(app.operator_id()),
|
|
RevokeConsentReq { notes: None, version: consent.version },
|
|
)
|
|
.await
|
|
.unwrap();
|
|
|
|
// 用旧 version 再撤销应失败
|
|
let result = consent_service::revoke_consent(
|
|
app.health_state(), app.tenant_id(), consent.id,
|
|
Some(app.operator_id()),
|
|
RevokeConsentReq { notes: None, version: consent.version },
|
|
)
|
|
.await;
|
|
assert!(result.is_err(), "乐观锁冲突应返回错误");
|
|
}
|