Files
smart-project-pricing/后端服务/tests/test_api/test_projects.py
2026-01-31 21:33:06 +08:00

153 lines
4.6 KiB
Python

"""服务项目接口测试"""
import pytest
from httpx import AsyncClient
from app.models import Project, Category, Material, Equipment, StaffLevel
from tests.conftest import assert_response_success
class TestProjectsAPI:
"""服务项目 API 测试"""
@pytest.mark.api
@pytest.mark.asyncio
async def test_create_project(
self,
client: AsyncClient,
sample_category: Category
):
"""测试创建项目"""
response = await client.post(
"/api/v1/projects",
json={
"project_code": "PRJ_TEST001",
"project_name": "测试项目",
"category_id": sample_category.id,
"description": "测试项目描述",
"duration_minutes": 45,
"is_active": True
}
)
data = assert_response_success(response)
assert data["project_code"] == "PRJ_TEST001"
assert data["project_name"] == "测试项目"
assert data["duration_minutes"] == 45
@pytest.mark.api
@pytest.mark.asyncio
async def test_get_projects_list(
self,
client: AsyncClient,
sample_project: Project
):
"""测试获取项目列表"""
response = await client.get("/api/v1/projects")
data = assert_response_success(response)
assert "items" in data
assert data["total"] >= 1
@pytest.mark.api
@pytest.mark.asyncio
async def test_get_project_detail(
self,
client: AsyncClient,
sample_project: Project
):
"""测试获取项目详情"""
response = await client.get(f"/api/v1/projects/{sample_project.id}")
data = assert_response_success(response)
assert data["id"] == sample_project.id
assert data["project_name"] == sample_project.project_name
@pytest.mark.api
@pytest.mark.asyncio
async def test_add_cost_item(
self,
client: AsyncClient,
sample_project: Project,
sample_material: Material
):
"""测试添加成本明细"""
response = await client.post(
f"/api/v1/projects/{sample_project.id}/cost-items",
json={
"item_type": "material",
"item_id": sample_material.id,
"quantity": 5,
"remark": "测试备注"
}
)
data = assert_response_success(response)
assert data["item_type"] == "material"
assert float(data["quantity"]) == 5.0
assert float(data["total_cost"]) == 10.0 # 5 * 2.00
@pytest.mark.api
@pytest.mark.asyncio
async def test_add_labor_cost(
self,
client: AsyncClient,
sample_project: Project,
sample_staff_level: StaffLevel
):
"""测试添加人工成本"""
response = await client.post(
f"/api/v1/projects/{sample_project.id}/labor-costs",
json={
"staff_level_id": sample_staff_level.id,
"duration_minutes": 30
}
)
data = assert_response_success(response)
assert data["duration_minutes"] == 30
assert float(data["labor_cost"]) == 25.0 # 30/60 * 50
@pytest.mark.api
@pytest.mark.asyncio
async def test_calculate_project_cost(
self,
client: AsyncClient,
sample_project_with_costs: Project
):
"""测试计算项目成本"""
response = await client.post(
f"/api/v1/projects/{sample_project_with_costs.id}/calculate-cost",
json={"allocation_method": "count"}
)
data = assert_response_success(response)
assert data["project_id"] == sample_project_with_costs.id
assert "cost_breakdown" in data
assert "total_cost" in data
assert data["total_cost"] > 0
@pytest.mark.api
@pytest.mark.asyncio
async def test_get_cost_summary(
self,
client: AsyncClient,
sample_project_with_costs: Project
):
"""测试获取成本汇总"""
# 先计算成本
await client.post(
f"/api/v1/projects/{sample_project_with_costs.id}/calculate-cost",
json={"allocation_method": "count"}
)
# 获取汇总
response = await client.get(
f"/api/v1/projects/{sample_project_with_costs.id}/cost-summary"
)
data = assert_response_success(response)
assert data["project_id"] == sample_project_with_costs.id
assert "material_cost" in data
assert "total_cost" in data