334 lines
9.9 KiB
Python
334 lines
9.9 KiB
Python
"""
|
||
业务表解析接口测试
|
||
"""
|
||
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"])
|