v0.2.0: CRM/ERP 系统升级 - 清理 .gitignore 并移除误提交的 venv/env/db 文件
- 更新 .gitignore:全面覆盖环境变量、数据库、日志、缓存、上传文件 - 移除误跟踪的 server/venv/、crm_data.db、.env 文件 - 新增 server/.env.example 模板 - 新增合同管理、利润核算、AI教练等功能模块 - 新增 Playwright e2e 测试套件 - 前后端多项功能升级和 bug 修复
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
"""
|
||||
订单管理模块测试 —— /api/orders
|
||||
覆盖: 创建订单 / 列表 / 详情 / 动态定价 / 收款 / 订单发票关联
|
||||
"""
|
||||
import uuid
|
||||
import pytest
|
||||
from httpx import AsyncClient
|
||||
from tests.conftest import (
|
||||
make_auth_headers, ADMIN_USER_ID, SALES_USER_ID,
|
||||
COMPANY_ID, CUSTOMER_ID, SKU_ID,
|
||||
)
|
||||
|
||||
|
||||
class TestCreateOrder:
|
||||
"""POST /api/orders"""
|
||||
|
||||
async def test_create_order_success(self, client: AsyncClient, admin_headers):
|
||||
"""创建含 1 个明细行的订单 → 200"""
|
||||
resp = await client.post("/api/orders", headers=admin_headers, json={
|
||||
"customer_id": str(CUSTOMER_ID),
|
||||
"items": [
|
||||
{"sku_id": str(SKU_ID), "qty": 10, "unit_price": 280.00}
|
||||
],
|
||||
"remark": "测试订单",
|
||||
"order_date": "2026-03-30"
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()["data"]
|
||||
assert "order_no" in data
|
||||
assert float(data["total_amount"]) == 2800.00
|
||||
|
||||
async def test_create_order_no_items(self, client: AsyncClient, admin_headers):
|
||||
"""空明细 → 应失败(422 或 400)"""
|
||||
resp = await client.post("/api/orders", headers=admin_headers, json={
|
||||
"customer_id": str(CUSTOMER_ID),
|
||||
"items": []
|
||||
})
|
||||
assert resp.status_code in (400, 422)
|
||||
|
||||
async def test_create_order_no_company_header(self, client: AsyncClient, seed_data):
|
||||
"""缺少 X-Company-Id → 422"""
|
||||
headers = {"Authorization": f"Bearer {make_auth_headers(ADMIN_USER_ID)['Authorization'].split(' ')[1]}"}
|
||||
resp = await client.post("/api/orders", headers=headers, json={
|
||||
"customer_id": str(CUSTOMER_ID),
|
||||
"items": [{"sku_id": str(SKU_ID), "qty": 1, "unit_price": 280}]
|
||||
})
|
||||
assert resp.status_code == 422
|
||||
|
||||
|
||||
class TestListOrders:
|
||||
"""GET /api/orders"""
|
||||
|
||||
async def test_list_orders_empty(self, client: AsyncClient, admin_headers):
|
||||
"""无订单时 → 200 + total=0"""
|
||||
resp = await client.get("/api/orders", headers=admin_headers)
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()["data"]
|
||||
assert data["total"] >= 0
|
||||
|
||||
async def test_list_orders_with_filters(self, client: AsyncClient, admin_headers):
|
||||
"""带筛选条件 → 200"""
|
||||
resp = await client.get(
|
||||
"/api/orders?shipping_state=pending&payment_state=unpaid",
|
||||
headers=admin_headers
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
|
||||
|
||||
class TestOrderDetail:
|
||||
"""GET /api/orders/{id}"""
|
||||
|
||||
async def test_get_nonexistent_order(self, client: AsyncClient, admin_headers):
|
||||
"""不存在的订单 → 404"""
|
||||
fake_id = uuid.uuid4()
|
||||
resp = await client.get(f"/api/orders/{fake_id}", headers=admin_headers)
|
||||
assert resp.status_code == 404
|
||||
|
||||
|
||||
class TestCalculatePrice:
|
||||
"""GET /api/orders/price/calculate"""
|
||||
|
||||
async def test_calculate_price(self, client: AsyncClient, admin_headers):
|
||||
"""动态定价查询 → 200"""
|
||||
resp = await client.get(
|
||||
f"/api/orders/price/calculate?customer_id={CUSTOMER_ID}&sku_id={SKU_ID}",
|
||||
headers=admin_headers
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
data = resp.json()["data"]
|
||||
assert "price" in data or "standard_price" in data or "unit_price" in data
|
||||
|
||||
|
||||
class TestOrderPayment:
|
||||
"""PUT /api/orders/{id}/payment"""
|
||||
|
||||
async def test_update_payment_nonexistent(self, client: AsyncClient, admin_headers):
|
||||
"""不存在的订单更新收款 → 404"""
|
||||
fake_id = uuid.uuid4()
|
||||
resp = await client.put(
|
||||
f"/api/orders/{fake_id}/payment",
|
||||
headers=admin_headers,
|
||||
json={"paid_amount": 1000}
|
||||
)
|
||||
assert resp.status_code == 404
|
||||
Reference in New Issue
Block a user