#!/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()