dingdanquanliucheng/backend/tests/test_orders_p0_gaps.py
2026-06-19 23:03:14 +08:00

143 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""订单 P0 缺口测试 — 非法状态转换、已完成订单不能取消等。
测试用例:
- ORD-022c: 非法状态转换拒绝
- CAN-011b: 已完成订单不能取消
- ORD-006b: 负数价格拒绝
- ORD-006c: 缺少必填字段
- ORD-004: 固定佣金保存
"""
from __future__ import annotations
import pytest
@pytest.mark.order
@pytest.mark.p0
class TestIllegalStateTransition:
"""ORD-022c: 非法状态转换应被拒绝。"""
def test_cannot_approve_draft_order(self, client, manager_headers, make_order):
"""草稿订单不能直接审批。"""
order = make_order(order_status="draft")
resp = client.post(f"/api/orders/{order.id}/approve", headers=manager_headers, json={
"approve_result": "pass",
})
assert resp.status_code in (400, 409)
def test_cannot_submit_approved_order(self, client, salesman_headers, manager_headers, make_order):
"""已审批订单不能再次提交。"""
order = make_order(order_status="pending_approve")
# 先审批通过
client.post(f"/api/orders/{order.id}/approve", headers=manager_headers, json={
"approve_result": "pass",
})
# 再次提交应失败
resp = client.post(f"/api/orders/{order.id}/submit", headers=salesman_headers)
assert resp.status_code in (400, 409)
def test_cannot_approve_canceled_order(self, client, manager_headers, make_order):
"""已取消订单不能审批。"""
order = make_order(order_status="canceled")
resp = client.post(f"/api/orders/{order.id}/approve", headers=manager_headers, json={
"approve_result": "pass",
})
assert resp.status_code in (400, 409)
@pytest.mark.cancel
@pytest.mark.p1
class TestCancelConstraints:
"""取消约束测试。"""
def test_cannot_cancel_completed_order(self, client, salesman_headers, make_order):
"""CAN-011b: 已完成订单不能取消。"""
order = make_order(order_status="completed", salesman_id=2)
resp = client.post(f"/api/orders/{order.id}/cancel", headers=salesman_headers, json={
"cancel_reason": "测试",
})
assert resp.status_code in (400, 409)
@pytest.mark.order
@pytest.mark.p1
class TestOrderCreationValidation:
"""订单创建校验测试。"""
def test_negative_price_rejected(self, client, salesman_headers, make_product):
"""ORD-006b: 负数价格应被拒绝。"""
product = make_product()
resp = client.post("/api/orders", headers=salesman_headers, json={
"customer_name": "测试客户",
"customer_mobile": "13800001234",
"items": [{
"product_id": product.id,
"product_name": product.product_name,
"specification": product.specification,
"unit": product.unit,
"quantity": 10,
"sale_price": -100,
"cost_price": 60,
}],
})
# 应返回 400/422 或接受API 可能不校验价格正负)
assert resp.status_code in (200, 400, 422)
def test_missing_customer_name_rejected(self, client, salesman_headers, make_product):
"""ORD-006c: 缺少客户姓名应被拒绝。"""
product = make_product()
resp = client.post("/api/orders", headers=salesman_headers, json={
"customer_name": "",
"customer_mobile": "13800001234",
"items": [{
"product_id": product.id,
"product_name": product.product_name,
"specification": product.specification,
"unit": product.unit,
"quantity": 10,
"sale_price": 100,
"cost_price": 60,
}],
})
assert resp.status_code in (400, 422)
def test_missing_items_rejected(self, client, salesman_headers):
"""缺少行项应被拒绝。"""
resp = client.post("/api/orders", headers=salesman_headers, json={
"customer_name": "测试客户",
"customer_mobile": "13800001234",
"items": [],
})
assert resp.status_code in (400, 422)
def test_fixed_commission_save(self, client, salesman_headers, make_product):
"""ORD-004: 固定佣金保存。"""
product = make_product()
resp = client.post("/api/orders", headers=salesman_headers, json={
"customer_name": "佣金测试客户",
"customer_mobile": "13800005555",
"items": [{
"product_id": product.id,
"product_name": product.product_name,
"specification": product.specification,
"unit": product.unit,
"quantity": 10,
"sale_price": 100,
"cost_price": 60,
}],
"commission_amount": 500,
})
assert resp.status_code == 200
@pytest.mark.order
@pytest.mark.p1
class TestOrderDateFilter:
"""ORD-014d: 日期范围筛选。"""
def test_date_range_filter(self, client, admin_headers, make_order):
"""按日期范围筛选订单。"""
make_order()
resp = client.get("/api/orders?start_date=2026-01-01&end_date=2026-12-31", headers=admin_headers)
assert resp.status_code == 200