compliance/test_correct_multi_key_logic.py
2025-08-07 22:44:57 +08:00

299 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
测试修正后的多主键删除逻辑
基于identityId列表长度而不是schema结构
"""
import sys
import json
from unittest.mock import Mock
from custom_stages.dms_crud_scenario_stage import DmsCrudScenarioStage
from ddms_compliance_suite.input_parser.parser import DMSEndpoint
def test_single_key_by_identity_id():
"""测试单主键删除基于identityId长度=1"""
print("🧪 测试单主键删除identityId长度=1")
print("=" * 60)
# 创建模拟的删除端点identityId只有一个元素
mock_delete_endpoint = Mock(spec=DMSEndpoint)
mock_delete_endpoint.identity_id_list = ["proppantId"] # 单主键
# 创建模拟的scenario
scenario = {"delete": mock_delete_endpoint}
# 创建CRUD Stage实例
crud_stage = DmsCrudScenarioStage(
api_group_metadata={"name": "测试"},
apis_in_group=[],
global_api_spec=Mock()
)
# 测试构建删除请求体
create_payload = {"proppantId": "proppant_001", "proppantName": "测试支撑剂"}
delete_body = crud_stage._build_delete_request_body(
scenario, "proppantId", "proppant_001", create_payload
)
print(f"单主键删除请求体: {json.dumps(delete_body, indent=2, ensure_ascii=False)}")
# 验证结果:应该是字符串数组格式
expected_structure = {"data": ["proppant_001"]}
if delete_body == expected_structure:
print("✅ 单主键删除请求体格式正确(字符串数组)")
return True
else:
print(f"❌ 单主键删除请求体格式错误,期望: {expected_structure}")
return False
def test_multi_key_by_identity_id():
"""测试多主键删除基于identityId长度>1"""
print("\n🧪 测试多主键删除identityId长度>1")
print("=" * 60)
# 创建模拟的删除端点identityId有多个元素
mock_delete_endpoint = Mock(spec=DMSEndpoint)
mock_delete_endpoint.identity_id_list = ["projectId", "surveyId"] # 多主键
# 创建模拟的scenario
scenario = {"delete": mock_delete_endpoint}
# 创建CRUD Stage实例
crud_stage = DmsCrudScenarioStage(
api_group_metadata={"name": "测试"},
apis_in_group=[],
global_api_spec=Mock()
)
# 测试构建删除请求体
create_payload = {
"projectId": "项目1_ID",
"surveyId": "工区1_ID",
"projectName": "测试项目",
"surveyName": "测试工区"
}
delete_body = crud_stage._build_delete_request_body(
scenario, "projectId", "项目1_ID", create_payload
)
print(f"多主键删除请求体: {json.dumps(delete_body, indent=2, ensure_ascii=False)}")
# 验证结果:应该是对象数组格式
if isinstance(delete_body, dict) and "data" in delete_body:
data_array = delete_body["data"]
if isinstance(data_array, list) and len(data_array) > 0:
first_item = data_array[0]
# 检查第一个对象是否包含正确的主键
if (isinstance(first_item, dict) and
first_item.get("projectId") == "项目1_ID" and
first_item.get("surveyId") == "工区1_ID"):
print("✅ 多主键删除请求体格式正确(对象数组)")
print(f"✅ 包含主键: projectId={first_item['projectId']}, surveyId={first_item['surveyId']}")
# 检查是否有版本号
if delete_body.get("version"):
print(f"✅ 包含版本号: {delete_body['version']}")
# 检查是否支持批量删除
if len(data_array) > 1:
print(f"✅ 支持批量删除,共{len(data_array)}个对象")
return True
else:
print(f"❌ 主键字段不正确: {first_item}")
return False
else:
print(f"❌ data数组格式错误: {data_array}")
return False
else:
print(f"❌ 删除请求体格式错误: {delete_body}")
return False
def test_three_key_scenario():
"""测试三主键删除场景"""
print("\n🧪 测试三主键删除场景")
print("=" * 60)
# 创建模拟的删除端点identityId有三个元素
mock_delete_endpoint = Mock(spec=DMSEndpoint)
mock_delete_endpoint.identity_id_list = ["wellId", "layerId", "sampleId"] # 三主键
scenario = {"delete": mock_delete_endpoint}
crud_stage = DmsCrudScenarioStage(
api_group_metadata={"name": "测试"},
apis_in_group=[],
global_api_spec=Mock()
)
# 创建负载只包含部分主键
create_payload = {
"wellId": "井001",
"layerId": "层001",
# 注意缺少sampleId
"wellName": "测试井",
"layerName": "测试层"
}
delete_body = crud_stage._build_delete_request_body(
scenario, "wellId", "井001", create_payload
)
print(f"三主键删除请求体: {json.dumps(delete_body, indent=2, ensure_ascii=False)}")
# 验证结果
if isinstance(delete_body, dict) and "data" in delete_body:
data_array = delete_body["data"]
if isinstance(data_array, list) and len(data_array) > 0:
first_item = data_array[0]
# 检查是否包含所有三个主键
required_keys = ["wellId", "layerId", "sampleId"]
missing_keys = [key for key in required_keys if key not in first_item]
if not missing_keys:
print("✅ 成功生成所有三个主键字段")
print(f"✅ wellId: {first_item['wellId']}")
print(f"✅ layerId: {first_item['layerId']}")
print(f"✅ sampleId: {first_item['sampleId']} (自动生成)")
return True
else:
print(f"❌ 缺失主键字段: {missing_keys}")
return False
else:
print(f"❌ data数组格式错误: {data_array}")
return False
else:
print(f"❌ 删除请求体格式错误: {delete_body}")
return False
def test_empty_identity_id_fallback():
"""测试identityId为空时的回退逻辑"""
print("\n🧪 测试identityId为空时的回退逻辑")
print("=" * 60)
# 创建模拟的删除端点identityId为空
mock_delete_endpoint = Mock(spec=DMSEndpoint)
mock_delete_endpoint.identity_id_list = [] # 空列表
scenario = {"delete": mock_delete_endpoint}
crud_stage = DmsCrudScenarioStage(
api_group_metadata={"name": "测试"},
apis_in_group=[],
global_api_spec=Mock()
)
create_payload = {"siteId": "test_site_001"}
delete_body = crud_stage._build_delete_request_body(
scenario, "siteId", "test_site_001", create_payload
)
print(f"回退删除请求体: {json.dumps(delete_body, indent=2, ensure_ascii=False)}")
# 验证回退结果
expected_fallback = {"data": ["test_site_001"]}
if delete_body == expected_fallback:
print("✅ identityId为空时正确回退到简单格式")
return True
else:
print("❌ identityId为空时回退失败")
return False
def test_logic_comparison():
"""对比新旧逻辑的差异"""
print("\n🧪 对比新旧逻辑的差异")
print("=" * 60)
print("📋 新逻辑基于identityId:")
print("- 单主键: identityId = ['proppantId'] → 字符串数组")
print("- 多主键: identityId = ['projectId', 'surveyId'] → 对象数组")
print("- 判断依据: len(identity_id_list)")
print("\n📋 旧逻辑基于schema:")
print("- 单主键: items.type = 'string' → 字符串数组")
print("- 多主键: items.type = 'object' → 对象数组")
print("- 判断依据: schema结构分析")
print("\n✅ 新逻辑的优势:")
print("- 直接基于业务配置identityId")
print("- 不依赖schema解析")
print("- 更准确反映业务意图")
print("- 支持任意数量的主键组合")
return True
def main():
"""主函数"""
print("🚀 修正后的多主键删除逻辑测试")
print("=" * 80)
success_count = 0
total_tests = 5
# 测试1: 单主键删除
if test_single_key_by_identity_id():
success_count += 1
# 测试2: 多主键删除
if test_multi_key_by_identity_id():
success_count += 1
# 测试3: 三主键删除
if test_three_key_scenario():
success_count += 1
# 测试4: 空identityId回退
if test_empty_identity_id_fallback():
success_count += 1
# 测试5: 逻辑对比
if test_logic_comparison():
success_count += 1
# 总结
print("\n" + "=" * 80)
print("📋 测试总结")
print("=" * 80)
print(f"通过测试: {success_count}/{total_tests}")
if success_count == total_tests:
print("🎉 修正后的多主键删除逻辑测试通过!")
print("\n✅ 修正内容:")
print("1. 判断依据改为identityId列表长度")
print(" - len(identity_id_list) == 1 → 单主键(字符串数组)")
print(" - len(identity_id_list) > 1 → 多主键(对象数组)")
print("\n2. DMSEndpoint增加identity_id_list属性")
print(" - 存储完整的identityId配置")
print(" - 在解析DMS API时自动设置")
print("\n3. 删除schema自动生成")
print(" - 单主键: {\"data\": [\"key1\", \"key2\"]}")
print(" - 多主键: {\"version\": \"1.0.0\", \"data\": [{\"key1\": \"val1\", \"key2\": \"val2\"}]}")
print("\n💡 配置示例:")
print("单主键: \"identityId\": [\"proppantId\"]")
print("多主键: \"identityId\": [\"projectId\", \"surveyId\"]")
print("三主键: \"identityId\": [\"wellId\", \"layerId\", \"sampleId\"]")
sys.exit(0)
else:
print("❌ 部分测试失败")
sys.exit(1)
if __name__ == "__main__":
main()