""" 业务表解析接口测试 """ import pytest from fastapi.testclient import TestClient from unittest.mock import patch from app.main import app client = TestClient(app) @pytest.fixture def sample_request_data(): """示例请求数据""" return { "file_paths": [ "/tmp/business_table1.xlsx", "/tmp/business_table2.csv" ], "project_id": "project_001" } @pytest.fixture def mock_parse_result(): """模拟解析结果""" return { "tables": [ { "raw_name": "orders", "display_name": "订单流水明细表", "description": "从文件 business_table1.xlsx 解析", "source_file": "business_table1.xlsx", "fields": [ { "raw_name": "order_id", "display_name": "订单ID", "type": "string", "comment": None, "inferred_type": "varchar(64)" }, { "raw_name": "order_amount", "display_name": "订单金额", "type": "float64", "comment": None, "inferred_type": "decimal(10,2)" } ], "field_count": 2, "row_count": 10000 }, { "raw_name": "users", "display_name": "用户表", "description": "从文件 business_table2.csv 解析", "source_file": "business_table2.csv", "fields": [ { "raw_name": "user_id", "display_name": "用户ID", "type": "string", "comment": None, "inferred_type": "varchar(64)" } ], "field_count": 1, "row_count": 5000 } ], "total_tables": 2, "total_fields": 3, "total_files": 2, "success_files": 2, "failed_files": [], "parse_time": 1.5, "file_info": { "processed_files": [ { "file_name": "business_table1.xlsx", "file_size": 102400, "tables_extracted": 1, "status": "success" }, { "file_name": "business_table2.csv", "file_size": 51200, "tables_extracted": 1, "status": "success" } ] } } @pytest.mark.asyncio async def test_parse_business_tables_success(sample_request_data, mock_parse_result): """测试业务表解析成功""" with patch('app.services.parse_business_tables_service.ParseBusinessTablesService.parse') as mock_parse: # 模拟服务返回解析结果 mock_parse.return_value = mock_parse_result response = client.post( "/api/v1/inventory/parse-business-tables", json=sample_request_data ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["code"] == 200 assert "data" in data assert "tables" in data["data"] assert len(data["data"]["tables"]) > 0 assert data["data"]["total_tables"] == 2 assert data["data"]["total_files"] == 2 assert data["data"]["success_files"] == 2 assert len(data["data"]["failed_files"]) == 0 assert "file_info" in data["data"] def test_parse_business_tables_request_validation(): """测试请求验证""" # 测试缺少必需字段 invalid_request = { "file_paths": ["/tmp/test.xlsx"] # 缺少 project_id } response = client.post( "/api/v1/inventory/parse-business-tables", json=invalid_request ) assert response.status_code == 422 # 验证错误 def test_parse_business_tables_empty_file_paths(): """测试空文件路径列表""" request_data = { "file_paths": [], "project_id": "project_001" } response = client.post( "/api/v1/inventory/parse-business-tables", json=request_data ) assert response.status_code == 422 # 验证错误(min_items=1) def test_parse_business_tables_single_file(): """测试单文件解析""" request_data = { "file_paths": ["/tmp/single_file.xlsx"], "project_id": "project_001" } mock_result = { "tables": [ { "raw_name": "test_table", "display_name": "测试表", "description": "从文件 single_file.xlsx 解析", "source_file": "single_file.xlsx", "fields": [ { "raw_name": "id", "display_name": "ID", "type": "int64", "comment": None, "inferred_type": "bigint" } ], "field_count": 1, "row_count": 100 } ], "total_tables": 1, "total_fields": 1, "total_files": 1, "success_files": 1, "failed_files": [], "parse_time": 0.5, "file_info": { "processed_files": [ { "file_name": "single_file.xlsx", "file_size": 5120, "tables_extracted": 1, "status": "success" } ] } } with patch('app.services.parse_business_tables_service.ParseBusinessTablesService.parse') as mock_parse: mock_parse.return_value = mock_result response = client.post( "/api/v1/inventory/parse-business-tables", json=request_data ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["data"]["total_files"] == 1 assert data["data"]["success_files"] == 1 def test_parse_business_tables_with_failed_files(): """测试部分文件失败的情况""" request_data = { "file_paths": [ "/tmp/success_file.xlsx", "/tmp/failed_file.unknown", "/tmp/another_success.xlsx" ], "project_id": "project_001" } mock_result = { "tables": [ { "raw_name": "table1", "display_name": "表1", "description": "从文件 success_file.xlsx 解析", "source_file": "success_file.xlsx", "fields": [], "field_count": 0, "row_count": 0 }, { "raw_name": "table2", "display_name": "表2", "description": "从文件 another_success.xlsx 解析", "source_file": "another_success.xlsx", "fields": [], "field_count": 0, "row_count": 0 } ], "total_tables": 2, "total_fields": 0, "total_files": 3, "success_files": 2, "failed_files": [ { "file_name": "failed_file.unknown", "error": "不支持的文件类型: .unknown" } ], "parse_time": 0.8, "file_info": { "processed_files": [ { "file_name": "success_file.xlsx", "file_size": 5120, "tables_extracted": 1, "status": "success" }, { "file_name": "another_success.xlsx", "file_size": 6144, "tables_extracted": 1, "status": "success" } ] } } with patch('app.services.parse_business_tables_service.ParseBusinessTablesService.parse') as mock_parse: mock_parse.return_value = mock_result response = client.post( "/api/v1/inventory/parse-business-tables", json=request_data ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["data"]["total_files"] == 3 assert data["data"]["success_files"] == 2 assert len(data["data"]["failed_files"]) == 1 assert data["data"]["failed_files"][0]["file_name"] == "failed_file.unknown" def test_parse_business_tables_empty_result(): """测试空结果""" request_data = { "file_paths": ["/tmp/empty_file.xlsx"], "project_id": "project_001" } mock_result = { "tables": [], "total_tables": 0, "total_fields": 0, "total_files": 1, "success_files": 1, "failed_files": [], "parse_time": 0.2, "file_info": { "processed_files": [ { "file_name": "empty_file.xlsx", "file_size": 1024, "tables_extracted": 0, "status": "success" } ] } } with patch('app.services.parse_business_tables_service.ParseBusinessTablesService.parse') as mock_parse: mock_parse.return_value = mock_result response = client.post( "/api/v1/inventory/parse-business-tables", json=request_data ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["data"]["total_tables"] == 0 if __name__ == "__main__": pytest.main([__file__, "-v"])