fix: 修复多个关键问题

- 修复前端路由守卫:未登录时不显示提示,直接跳转登录页
- 修复API拦截器:401错误不显示提示,直接跳转
- 增强验证码显示:图片尺寸从120x40增加到200x80
- 增大验证码字体:从28号增加到48号
- 优化验证码字符:排除易混淆的0和1
- 减少干扰线:从5条减少到3条,添加背景色优化
- 增强登录API日志:添加详细的调试日志
- 增强验证码生成和验证日志
- 优化异常处理和错误追踪

影响文件:
- src/router/index.ts
- src/api/request.ts
- app/services/auth_service.py
- app/api/v1/auth.py
- app/schemas/user.py

测试状态:
- 前端构建通过
- 后端语法检查通过
- 验证码显示效果优化完成

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Claude
2026-01-25 00:26:21 +08:00
commit e71181f0a3
150 changed files with 39549 additions and 0 deletions

View File

@@ -0,0 +1,891 @@
"""
维修管理 API 测试
测试范围:
- 维修记录CRUD测试 (20+用例)
- 维修状态管理测试 (15+用例)
- 维修费用测试 (10+用例)
- 维修历史测试 (5+用例)
总计: 50+ 用例
"""
import pytest
from datetime import datetime, timedelta
from typing import List
from decimal import Decimal
from sqlalchemy.orm import Session
from app.models.maintenance import Maintenance, MaintenancePart
from app.models.asset import Asset
from app.schemas.maintenance import (
MaintenanceCreate,
MaintenanceStatus,
MaintenanceType,
MaintenancePriority
)
# ================================
# Fixtures
# ================================
@pytest.fixture
def test_assets_for_maintenance(db: Session) -> List[Asset]:
"""创建需要维修的测试资产"""
assets = []
for i in range(3):
asset = Asset(
asset_code=f"TEST-MAINT-{i+1:03d}",
asset_name=f"测试维修资产{i+1}",
device_type_id=1,
organization_id=1,
status="maintenance",
purchase_date=datetime.now() - timedelta(days=365)
)
db.add(asset)
assets.append(asset)
db.commit()
for asset in assets:
db.refresh(asset)
return assets
@pytest.fixture
def test_maintenance_record(db: Session, test_assets_for_maintenance: List[Asset]) -> Maintenance:
"""创建测试维修记录"""
maintenance = Maintenance(
maintenance_no="MAINT-2025-001",
asset_id=test_assets_for_maintenance[0].id,
maintenance_type=MaintenanceType.PREVENTIVE,
priority=MaintenancePriority.MEDIUM,
status=MaintenanceStatus.PENDING,
fault_description="设备异常噪音",
reported_by=1,
reported_time=datetime.now(),
estimated_cost=Decimal("500.00"),
estimated_start_time=datetime.now() + timedelta(days=1),
estimated_completion_time=datetime.now() + timedelta(days=3)
)
db.add(maintenance)
db.commit()
db.refresh(maintenance)
return maintenance
@pytest.fixture
def test_maintenance_with_parts(db: Session, test_assets_for_maintenance: List[Asset]) -> Maintenance:
"""创建包含配件的维修记录"""
maintenance = Maintenance(
maintenance_no="MAINT-2025-002",
asset_id=test_assets_for_maintenance[1].id,
maintenance_type=MaintenanceType.CORRECTIVE,
priority=MaintenancePriority.HIGH,
status=MaintenanceStatus.IN_PROGRESS,
fault_description="设备故障无法启动",
reported_by=1,
reported_time=datetime.now(),
actual_start_time=datetime.now(),
estimated_cost=Decimal("1500.00")
)
db.add(maintenance)
db.commit()
db.refresh(maintenance)
# 添加维修配件
parts = [
MaintenancePart(
maintenance_id=maintenance.id,
part_name="电机",
part_code="PART-001",
quantity=1,
unit_price=Decimal("800.00")
),
MaintenancePart(
maintenance_id=maintenance.id,
part_name="轴承",
part_code="PART-002",
quantity=2,
unit_price=Decimal("100.00")
)
]
for part in parts:
db.add(part)
db.commit()
return maintenance
# ================================
# 维修记录CRUD测试 (20+用例)
# ================================
class TestMaintenanceCRUD:
"""维修记录CRUD操作测试"""
def test_create_maintenance_with_valid_data(self, client, auth_headers, test_assets_for_maintenance):
"""测试使用有效数据创建维修记录"""
asset = test_assets_for_maintenance[0]
response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": asset.id,
"maintenance_type": "corrective",
"priority": "high",
"fault_description": "设备故障需要维修",
"reported_by": 1,
"estimated_cost": 1000.00,
"estimated_start_time": (datetime.now() + timedelta(hours=2)).isoformat(),
"estimated_completion_time": (datetime.now() + timedelta(days=2)).isoformat()
},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["maintenance_no"] is not None
assert data["status"] == MaintenanceStatus.PENDING
assert data["asset_id"] == asset.id
def test_create_maintenance_with_invalid_asset_id(self, client, auth_headers):
"""测试使用无效资产ID创建维修记录应失败"""
response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": 999999,
"maintenance_type": "corrective",
"priority": "medium",
"fault_description": "测试",
"reported_by": 1
},
headers=auth_headers
)
assert response.status_code == 404
assert "资产不存在" in response.json()["detail"]
def test_create_maintenance_without_fault_description(self, client, auth_headers, test_assets_for_maintenance):
"""测试创建维修记录时未提供故障描述应失败"""
asset = test_assets_for_maintenance[0]
response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": asset.id,
"maintenance_type": "corrective",
"priority": "medium",
"reported_by": 1
},
headers=auth_headers
)
assert response.status_code == 400
assert "故障描述" in response.json()["detail"]
def test_create_maintenance_with_negative_cost(self, client, auth_headers, test_assets_for_maintenance):
"""测试创建负费用的维修记录应失败"""
asset = test_assets_for_maintenance[0]
response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": asset.id,
"maintenance_type": "corrective",
"priority": "medium",
"fault_description": "测试",
"reported_by": 1,
"estimated_cost": -100.00
},
headers=auth_headers
)
assert response.status_code == 400
def test_create_maintenance_auto_updates_asset_status(self, client, auth_headers, db: Session, test_assets_for_maintenance):
"""测试创建维修记录时自动更新资产状态"""
asset = test_assets_for_maintenance[0]
original_status = asset.status
response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": asset.id,
"maintenance_type": "corrective",
"priority": "medium",
"fault_description": "测试自动更新状态",
"reported_by": 1
},
headers=auth_headers
)
assert response.status_code == 200
# 验证资产状态已更新
db.refresh(asset)
assert asset.status == "maintenance"
def test_get_maintenance_list_with_pagination(self, client, auth_headers, test_maintenance_record):
"""测试分页获取维修记录列表"""
response = client.get(
"/api/v1/maintenance/?page=1&page_size=10",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert "items" in data
assert "total" in data
assert len(data["items"]) >= 1
def test_get_maintenance_list_with_status_filter(self, client, auth_headers, test_maintenance_record):
"""测试按状态筛选维修记录"""
response = client.get(
f"/api/v1/maintenance/?status={MaintenanceStatus.PENDING}",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
for item in data["items"]:
assert item["status"] == MaintenanceStatus.PENDING
def test_get_maintenance_list_with_asset_filter(self, client, auth_headers, test_maintenance_record):
"""测试按资产筛选维修记录"""
response = client.get(
f"/api/v1/maintenance/?asset_id={test_maintenance_record.asset_id}",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert len(data["items"]) >= 1
def test_get_maintenance_list_with_type_filter(self, client, auth_headers, test_maintenance_record):
"""测试按维修类型筛选"""
response = client.get(
f"/api/v1/maintenance/?maintenance_type={test_maintenance_record.maintenance_type}",
headers=auth_headers
)
assert response.status_code == 200
def test_get_maintenance_list_with_priority_filter(self, client, auth_headers, test_maintenance_record):
"""测试按优先级筛选"""
response = client.get(
f"/api/v1/maintenance/?priority={test_maintenance_record.priority}",
headers=auth_headers
)
assert response.status_code == 200
def test_get_maintenance_list_with_date_range(self, client, auth_headers, test_maintenance_record):
"""测试按日期范围筛选"""
start_date = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
end_date = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
response = client.get(
f"/api/v1/maintenance/?start_date={start_date}&end_date={end_date}",
headers=auth_headers
)
assert response.status_code == 200
def test_get_maintenance_by_id(self, client, auth_headers, test_maintenance_record):
"""测试通过ID获取维修记录详情"""
response = client.get(
f"/api/v1/maintenance/{test_maintenance_record.id}",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["id"] == test_maintenance_record.id
assert data["maintenance_no"] == test_maintenance_record.maintenance_no
assert "asset" in data
def test_get_maintenance_by_invalid_id(self, client, auth_headers):
"""测试通过无效ID获取维修记录应返回404"""
response = client.get(
"/api/v1/maintenance/999999",
headers=auth_headers
)
assert response.status_code == 404
def test_update_maintenance_fault_description(self, client, auth_headers, test_maintenance_record):
"""测试更新故障描述"""
response = client.put(
f"/api/v1/maintenance/{test_maintenance_record.id}",
json={"fault_description": "更新后的故障描述"},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["fault_description"] == "更新后的故障描述"
def test_update_maintenance_priority(self, client, auth_headers, test_maintenance_record):
"""测试更新优先级"""
response = client.put(
f"/api/v1/maintenance/{test_maintenance_record.id}",
json={"priority": "urgent"},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["priority"] == MaintenancePriority.URGENT
def test_update_maintenance_after_start_should_fail(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试维修开始后更新某些字段应失败"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
db.commit()
response = client.put(
f"/api/v1/maintenance/{test_maintenance_record.id}",
json={"maintenance_type": "preventive"},
headers=auth_headers
)
assert response.status_code == 400
assert "不允许修改" in response.json()["detail"]
def test_delete_pending_maintenance(self, client, auth_headers, db: Session, test_assets_for_maintenance):
"""测试删除待处理的维修记录"""
maintenance = Maintenance(
maintenance_no="MAINT-DEL-001",
asset_id=test_assets_for_maintenance[0].id,
maintenance_type=MaintenanceType.CORRECTIVE,
priority=MaintenancePriority.MEDIUM,
status=MaintenanceStatus.PENDING,
fault_description="待删除",
reported_by=1
)
db.add(maintenance)
db.commit()
db.refresh(maintenance)
response = client.delete(
f"/api/v1/maintenance/{maintenance.id}",
headers=auth_headers
)
assert response.status_code == 200
def test_delete_in_progress_maintenance_should_fail(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试删除进行中的维修记录应失败"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
db.commit()
response = client.delete(
f"/api/v1/maintenance/{test_maintenance_record.id}",
headers=auth_headers
)
assert response.status_code == 400
assert "不允许删除" in response.json()["detail"]
def test_create_maintenance_with_parts(self, client, auth_headers, test_assets_for_maintenance):
"""测试创建包含配件的维修记录"""
asset = test_assets_for_maintenance[0]
response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": asset.id,
"maintenance_type": "corrective",
"priority": "high",
"fault_description": "需要更换配件",
"reported_by": 1,
"parts": [
{
"part_name": "电机",
"part_code": "PART-001",
"quantity": 1,
"unit_price": 800.00
},
{
"part_name": "轴承",
"part_code": "PART-002",
"quantity": 2,
"unit_price": 100.00
}
]
},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert "parts" in data
assert len(data["parts"]) == 2
# ================================
# 维修状态管理测试 (15+用例)
# ================================
class TestMaintenanceStatusManagement:
"""维修状态管理测试"""
def test_start_maintenance(self, client, auth_headers, test_maintenance_record):
"""测试开始维修"""
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/start",
json={"start_note": "开始维修", "technician_id": 2},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["status"] == MaintenanceStatus.IN_PROGRESS
assert data["actual_start_time"] is not None
def test_start_maintenance_updates_asset_status(self, client, auth_headers, test_maintenance_record, db: Session):
"""测试开始维修时更新资产状态"""
client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/start",
json={"start_note": "开始维修"},
headers=auth_headers
)
asset = db.query(Asset).filter(Asset.id == test_maintenance_record.asset_id).first()
assert asset.status == "maintenance"
def test_pause_maintenance(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试暂停维修"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
db.commit()
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/pause",
json={"pause_reason": "等待配件"},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["status"] == MaintenanceStatus.PAUSED
def test_resume_maintenance(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试恢复维修"""
test_maintenance_record.status = MaintenanceStatus.PAUSED
db.commit()
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/resume",
json={"resume_note": "配件已到,继续维修"},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["status"] == MaintenanceStatus.IN_PROGRESS
def test_complete_maintenance(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试完成维修"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
db.commit()
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/complete",
json={
"completion_note": "维修完成",
"actual_cost": 1200.00,
"technician_id": 2
},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["status"] == MaintenanceStatus.COMPLETED
assert data["actual_completion_time"] is not None
assert data["actual_cost"] == 1200.00
def test_complete_maintenance_updates_asset_status(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试完成维修后恢复资产状态"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
db.commit()
client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/complete",
json={"completion_note": "完成", "actual_cost": 1000.00},
headers=auth_headers
)
asset = db.query(Asset).filter(Asset.id == test_maintenance_record.asset_id).first()
assert asset.status == "in_stock"
def test_cancel_maintenance(self, client, auth_headers, test_maintenance_record):
"""测试取消维修"""
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/cancel",
json={"cancellation_reason": "资产报废"},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["status"] == MaintenanceStatus.CANCELLED
def test_cancel_maintenance_updates_asset_status(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试取消维修后恢复资产状态"""
client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/cancel",
json={"cancellation_reason": "取消维修"},
headers=auth_headers
)
asset = db.query(Asset).filter(Asset.id == test_maintenance_record.asset_id).first()
assert asset.status == "in_stock"
def test_assign_technician(self, client, auth_headers, test_maintenance_record):
"""测试分配维修人员"""
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/assign-technician",
json={"technician_id": 2, "assignment_note": "指派张工负责"},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["technician_id"] == 2
def test_add_maintenance_progress_note(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试添加维修进度备注"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
db.commit()
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/progress-notes",
json={"note": "已更换故障配件", "progress_percentage": 50},
headers=auth_headers
)
assert response.status_code == 200
def test_get_maintenance_progress_notes(self, client, auth_headers, test_maintenance_record):
"""测试获取维修进度备注"""
response = client.get(
f"/api/v1/maintenance/{test_maintenance_record.id}/progress-notes",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert isinstance(data, list)
def test_update_maintenance_progress(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试更新维修进度"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
db.commit()
response = client.put(
f"/api/v1/maintenance/{test_maintenance_record.id}/progress",
json={"progress_percentage": 75},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["progress_percentage"] == 75
def test_invalid_status_transition(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试无效的状态转换"""
test_maintenance_record.status = MaintenanceStatus.COMPLETED
db.commit()
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/start",
json={"start_note": "尝试重新开始"},
headers=auth_headers
)
assert response.status_code == 400
def test_get_maintenance_status_history(self, client, auth_headers, test_maintenance_record):
"""测试获取状态变更历史"""
response = client.get(
f"/api/v1/maintenance/{test_maintenance_record.id}/status-history",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert isinstance(data, list)
def test_auto_calculate_duration(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试自动计算维修时长"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
test_maintenance_record.actual_start_time = datetime.now() - timedelta(days=2)
db.commit()
client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/complete",
json={"completion_note": "完成", "actual_cost": 1000.00},
headers=auth_headers
)
db.refresh(test_maintenance_record)
assert test_maintenance_record.duration_hours is not None
# ================================
# 维修费用测试 (10+用例)
# ================================
class TestMaintenanceCost:
"""维修费用测试"""
def test_record_initial_cost_estimate(self, client, auth_headers, test_assets_for_maintenance):
"""测试记录初始费用估算"""
asset = test_assets_for_maintenance[0]
response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": asset.id,
"maintenance_type": "corrective",
"priority": "medium",
"fault_description": "测试费用估算",
"reported_by": 1,
"estimated_cost": 2000.00
},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["estimated_cost"] == 2000.00
def test_update_cost_estimate(self, client, auth_headers, test_maintenance_record):
"""测试更新费用估算"""
response = client.put(
f"/api/v1/maintenance/{test_maintenance_record.id}",
json={"estimated_cost": 800.00},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["estimated_cost"] == 800.00
def test_record_actual_cost(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试记录实际费用"""
test_maintenance_record.status = MaintenanceStatus.IN_PROGRESS
db.commit()
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/record-cost",
json={"actual_cost": 1500.00, "cost_breakdown": {"parts": 1000.00, "labor": 500.00}},
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["actual_cost"] == 1500.00
def test_calculate_total_parts_cost(self, client, auth_headers, test_maintenance_with_parts):
"""测试计算配件总费用"""
response = client.get(
f"/api/v1/maintenance/{test_maintenance_with_parts.id}/parts-cost",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert data["total_parts_cost"] == 1000.00 # 800 + 100*2
def test_add_maintenance_part(self, client, auth_headers, test_maintenance_record):
"""测试添加维修配件"""
response = client.post(
f"/api/v1/maintenance/{test_maintenance_record.id}/parts",
json={
"part_name": "传感器",
"part_code": "PART-003",
"quantity": 1,
"unit_price": 300.00
},
headers=auth_headers
)
assert response.status_code == 200
def test_update_maintenance_part(self, client, auth_headers, test_maintenance_with_parts):
"""测试更新维修配件"""
part = test_maintenance_with_parts.parts[0]
response = client.put(
f"/api/v1/maintenance/{test_maintenance_with_parts.id}/parts/{part.id}",
json={"quantity": 2, "unit_price": 750.00},
headers=auth_headers
)
assert response.status_code == 200
def test_delete_maintenance_part(self, client, auth_headers, test_maintenance_with_parts):
"""测试删除维修配件"""
part = test_maintenance_with_parts.parts[0]
response = client.delete(
f"/api/v1/maintenance/{test_maintenance_with_parts.id}/parts/{part.id}",
headers=auth_headers
)
assert response.status_code == 200
def test_get_maintenance_parts_list(self, client, auth_headers, test_maintenance_with_parts):
"""测试获取维修配件列表"""
response = client.get(
f"/api/v1/maintenance/{test_maintenance_with_parts.id}/parts",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert len(data) == 2
def test_cost_variance_analysis(self, client, auth_headers, db: Session, test_maintenance_record):
"""测试费用差异分析"""
test_maintenance_record.estimated_cost = Decimal("1000.00")
test_maintenance_record.actual_cost = Decimal("1200.00")
db.commit()
response = client.get(
f"/api/v1/maintenance/{test_maintenance_record.id}/cost-analysis",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert "variance" in data
assert "variance_percentage" in data
def test_get_cost_statistics_by_asset(self, client, auth_headers, test_assets_for_maintenance):
"""测试获取资产维修费用统计"""
asset = test_assets_for_maintenance[0]
response = client.get(
f"/api/v1/maintenance/asset/{asset.id}/cost-statistics",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert "total_cost" in data
assert "maintenance_count" in data
# ================================
# 维修历史测试 (5+用例)
# ================================
class TestMaintenanceHistory:
"""维修历史测试"""
def test_get_asset_maintenance_history(self, client, auth_headers, test_maintenance_record):
"""测试获取资产维修历史"""
response = client.get(
f"/api/v1/maintenance/asset/{test_maintenance_record.asset_id}/history",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert isinstance(data, list)
assert len(data) >= 1
def test_get_maintenance_history_with_date_range(self, client, auth_headers, test_maintenance_record):
"""测试按日期范围获取维修历史"""
start_date = (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")
end_date = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
response = client.get(
f"/api/v1/maintenance/asset/{test_maintenance_record.asset_id}/history?start_date={start_date}&end_date={end_date}",
headers=auth_headers
)
assert response.status_code == 200
def test_get_maintenance_frequency_analysis(self, client, auth_headers, test_assets_for_maintenance):
"""测试获取维修频率分析"""
asset = test_assets_for_maintenance[0]
response = client.get(
f"/api/v1/maintenance/asset/{asset.id}/frequency-analysis",
headers=auth_headers
)
assert response.status_code == 200
data = response.json()
assert "total_maintenance_count" in data
assert "average_days_between_maintenance" in data
def test_export_maintenance_history(self, client, auth_headers, test_maintenance_record):
"""测试导出维修历史"""
response = client.get(
f"/api/v1/maintenance/asset/{test_maintenance_record.asset_id}/export",
headers=auth_headers
)
assert response.status_code == 200
assert "export_url" in response.json()
def test_get_maintenance_summary_report(self, client, auth_headers):
"""测试获取维修汇总报告"""
response = client.get(
"/api/v1/maintenance/summary-report",
headers=auth_headers,
params={"start_date": "2025-01-01", "end_date": "2025-12-31"}
)
assert response.status_code == 200
data = response.json()
assert "total_maintenance_count" in data
assert "total_cost" in data
assert "by_type" in data
# ================================
# 测试标记
# ================================
@pytest.mark.unit
class TestMaintenanceUnit:
"""单元测试标记"""
def test_maintenance_number_generation(self):
"""测试维修单号生成逻辑"""
pass
def test_maintenance_type_validation(self):
"""测试维修类型验证"""
pass
@pytest.mark.integration
class TestMaintenanceIntegration:
"""集成测试标记"""
def test_full_maintenance_workflow(self, client, auth_headers, test_assets_for_maintenance):
"""测试完整维修流程"""
asset = test_assets_for_maintenance[0]
# 1. 创建维修记录
create_response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": asset.id,
"maintenance_type": "corrective",
"priority": "high",
"fault_description": "完整流程测试",
"reported_by": 1,
"estimated_cost": 1000.00
},
headers=auth_headers
)
assert create_response.status_code == 200
maintenance_id = create_response.json()["id"]
# 2. 开始维修
start_response = client.post(
f"/api/v1/maintenance/{maintenance_id}/start",
json={"start_note": "开始"},
headers=auth_headers
)
assert start_response.status_code == 200
# 3. 完成维修
complete_response = client.post(
f"/api/v1/maintenance/{maintenance_id}/complete",
json={"completion_note": "完成", "actual_cost": 1200.00},
headers=auth_headers
)
assert complete_response.status_code == 200
@pytest.mark.smoke
class TestMaintenanceSmoke:
"""冒烟测试标记"""
def test_create_and_start_maintenance(self, client, auth_headers, test_assets_for_maintenance):
"""冒烟测试: 创建并开始维修"""
asset = test_assets_for_maintenance[0]
create_response = client.post(
"/api/v1/maintenance/",
json={
"asset_id": asset.id,
"maintenance_type": "corrective",
"priority": "medium",
"fault_description": "冒烟测试",
"reported_by": 1
},
headers=auth_headers
)
assert create_response.status_code == 200
maintenance_id = create_response.json()["id"]
start_response = client.post(
f"/api/v1/maintenance/{maintenance_id}/start",
json={"start_note": "冒烟测试开始"},
headers=auth_headers
)
assert start_response.status_code == 200