124 lines
4.5 KiB
Python
124 lines
4.5 KiB
Python
"""CUS-001 ~ CUS-010: 客户管理测试。
|
||
|
||
覆盖功能点:
|
||
- 新增客户成功与重复校验
|
||
- 客户列表筛选
|
||
- 客户详情
|
||
- 业务员客户范围隔离
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
import pytest
|
||
|
||
|
||
@pytest.mark.customer
|
||
@pytest.mark.p0
|
||
class TestCustomerCreation:
|
||
"""CUS-001 ~ CUS-003: 客户创建测试。"""
|
||
|
||
def test_create_customer_success(self, client, admin_headers):
|
||
"""CUS-001: 新增客户成功。"""
|
||
resp = client.post("/api/customers", headers=admin_headers, json={
|
||
"customer_name": "新客户测试",
|
||
"mobile": "13800001001",
|
||
"settlement_type": "immediate",
|
||
})
|
||
assert resp.status_code == 200
|
||
data = resp.json()
|
||
assert data["code"] == 0
|
||
|
||
def test_duplicate_customer_name_mobile(self, client, admin_headers, make_customer):
|
||
"""CUS-002: 姓名+手机号重复应返回 40006。"""
|
||
make_customer(customer_name="重复客户", mobile="13800009999")
|
||
resp = client.post("/api/customers", headers=admin_headers, json={
|
||
"customer_name": "重复客户",
|
||
"mobile": "13800009999",
|
||
})
|
||
assert resp.status_code in (400, 409)
|
||
data = resp.json()
|
||
assert data["code"] == 40006
|
||
|
||
def test_customer_mobile_required(self, client, admin_headers):
|
||
"""CUS-003: 手机号为空应返回验证错误。
|
||
|
||
注意: FastAPI 默认返回 422 Unprocessable Entity (Pydantic 校验),
|
||
而非 400 Bad Request。
|
||
"""
|
||
resp = client.post("/api/customers", headers=admin_headers, json={
|
||
"customer_name": "无手机号客户",
|
||
})
|
||
# FastAPI Pydantic 校验返回 422,自定义校验返回 400
|
||
assert resp.status_code in (400, 422)
|
||
|
||
|
||
@pytest.mark.customer
|
||
@pytest.mark.p0
|
||
class TestCustomerList:
|
||
"""CUS-004: 客户列表筛选测试。"""
|
||
|
||
def test_list_customers(self, client, admin_headers, make_customer):
|
||
"""客户列表查询成功。"""
|
||
make_customer()
|
||
make_customer()
|
||
resp = client.get("/api/customers", headers=admin_headers)
|
||
assert resp.status_code == 200
|
||
data = resp.json()
|
||
assert "list" in data["data"]
|
||
assert data["data"]["total"] >= 2
|
||
|
||
def test_filter_customers_by_name(self, client, admin_headers, make_customer):
|
||
"""按姓名筛选客户。"""
|
||
make_customer(customer_name="特殊客户A")
|
||
make_customer(customer_name="普通客户B")
|
||
resp = client.get("/api/customers?keyword=特殊", headers=admin_headers)
|
||
assert resp.status_code == 200
|
||
|
||
|
||
@pytest.mark.customer
|
||
@pytest.mark.p0
|
||
class TestCustomerIsolation:
|
||
"""CUS-008: 业务员客户范围隔离测试。"""
|
||
|
||
def test_salesman_only_see_own_customers(self, client, salesman_headers, salesman2_headers, make_customer):
|
||
"""业务员只能看到自己的客户。"""
|
||
make_customer(customer_name="业务员A客户", salesman_id=2)
|
||
make_customer(customer_name="业务员B客户", salesman_id=3)
|
||
|
||
# 业务员A查看客户列表
|
||
resp = client.get("/api/customers", headers=salesman_headers)
|
||
data = resp.json()
|
||
# 应该只能看到自己的客户
|
||
for c in data["data"]["list"]:
|
||
assert c["salesman_id"] in (2, None)
|
||
|
||
def test_admin_see_all_customers(self, client, admin_headers, make_customer):
|
||
"""管理员可以看到所有客户。"""
|
||
make_customer(customer_name="客户1", salesman_id=2)
|
||
make_customer(customer_name="客户2", salesman_id=3)
|
||
|
||
resp = client.get("/api/customers", headers=admin_headers)
|
||
data = resp.json()
|
||
assert data["data"]["total"] >= 2
|
||
|
||
|
||
@pytest.mark.customer
|
||
@pytest.mark.p1
|
||
class TestCustomerDetail:
|
||
"""CUS-005, CUS-009 ~ CUS-010: 客户详情测试。"""
|
||
|
||
def test_customer_detail(self, client, admin_headers, make_customer):
|
||
"""CUS-005: 客户详情返回完整信息。"""
|
||
customer = make_customer()
|
||
resp = client.get(f"/api/customers/{customer.id}", headers=admin_headers)
|
||
assert resp.status_code == 200
|
||
data = resp.json()["data"]
|
||
assert data["customer_name"] is not None
|
||
|
||
def test_monthly_customer_flag(self, client, admin_headers, make_customer):
|
||
"""CUS-009: 月结客户标识。"""
|
||
customer = make_customer(settlement_type="monthly", settlement_days=30)
|
||
resp = client.get(f"/api/customers/{customer.id}", headers=admin_headers)
|
||
assert resp.status_code == 200
|
||
data = resp.json()["data"]
|
||
assert data["settlement_type"] == "monthly"
|