208 lines
6.1 KiB
Python
208 lines
6.1 KiB
Python
from fastapi.testclient import TestClient
|
||
|
||
|
||
# --- GET /box/info 测试 ---
|
||
|
||
|
||
def test_box_info_success(client: TestClient):
|
||
"""查询真实存在的总排号 → 200"""
|
||
resp = client.get(
|
||
"/CargoTrace/box/info", params={"zongpai_no": "26BW0011"}
|
||
)
|
||
assert resp.status_code == 200
|
||
data = resp.json()
|
||
assert data["zongpai_no"] == "26BW0011"
|
||
assert data["paichan_no"] == "W00009"
|
||
assert "work_order_no" in data
|
||
assert data["work_order_no"] is None or isinstance(data["work_order_no"], str)
|
||
assert data["quantity"] == 80
|
||
assert "current_zongpai_boxes" in data
|
||
assert "existing_boxes" in data
|
||
for box in data["existing_boxes"]:
|
||
for item in box["items"]:
|
||
assert "box_item_id" in item
|
||
assert "max_box_no" in data
|
||
assert data["suggested_box_no"] == data["max_box_no"] + 1
|
||
|
||
|
||
def test_box_info_invalid_zongpai(client: TestClient):
|
||
"""无效总排号格式 → 400"""
|
||
resp = client.get(
|
||
"/CargoTrace/box/info", params={"zongpai_no": "INVALID"}
|
||
)
|
||
assert resp.status_code == 400
|
||
assert resp.json()["error_code"] == "INVALID_ZONGPAI"
|
||
|
||
|
||
def test_box_info_not_found(client: TestClient):
|
||
"""格式合法但 ERP 中不存在 → 404"""
|
||
resp = client.get(
|
||
"/CargoTrace/box/info", params={"zongpai_no": "26B99999"}
|
||
)
|
||
assert resp.status_code == 404
|
||
assert resp.json()["error_code"] == "ZONGPAI_NOT_FOUND"
|
||
|
||
|
||
# --- POST /box 测试 ---
|
||
|
||
|
||
def test_box_save_invalid_zongpai(client: TestClient):
|
||
"""无效总排号 → 400"""
|
||
resp = client.post(
|
||
"/CargoTrace/box",
|
||
json={"zongpai_no": "INVALID", "box_no": 1, "quantity": 10},
|
||
)
|
||
assert resp.status_code == 400
|
||
assert resp.json()["error_code"] == "INVALID_ZONGPAI"
|
||
|
||
|
||
def test_box_save_invalid_box_no(client: TestClient):
|
||
"""箱号 <= 0 → 400"""
|
||
resp = client.post(
|
||
"/CargoTrace/box",
|
||
json={"zongpai_no": "26BW0011", "box_no": 0, "quantity": 10},
|
||
)
|
||
assert resp.status_code == 400
|
||
|
||
|
||
def test_box_save_invalid_quantity(client: TestClient):
|
||
"""数量 <= 0 → 400"""
|
||
resp = client.post(
|
||
"/CargoTrace/box",
|
||
json={"zongpai_no": "26BW0011", "box_no": 1, "quantity": 0},
|
||
)
|
||
assert resp.status_code == 400
|
||
|
||
|
||
def test_box_save_zongpai_not_found(client: TestClient):
|
||
"""ERP 中不存在的总排号 → 404"""
|
||
resp = client.post(
|
||
"/CargoTrace/box",
|
||
json={"zongpai_no": "26B99999", "box_no": 1, "quantity": 10},
|
||
)
|
||
assert resp.status_code == 404
|
||
assert resp.json()["error_code"] == "ZONGPAI_NOT_FOUND"
|
||
|
||
|
||
def test_box_save_many_to_one_appends_different_zongpais(client: TestClient):
|
||
"""多码一箱:同一排产号同一箱号可追加不同总排号。"""
|
||
box_no = 901
|
||
first = client.post(
|
||
"/CargoTrace/box",
|
||
json={
|
||
"zongpai_no": "26BW0011",
|
||
"box_no": box_no,
|
||
"quantity": 10,
|
||
"box_mode": "many-to-one",
|
||
},
|
||
)
|
||
assert first.status_code == 200
|
||
assert first.json()["box_item_id"] is not None
|
||
|
||
second = client.post(
|
||
"/CargoTrace/box",
|
||
json={
|
||
"zongpai_no": "26BW0012",
|
||
"box_no": box_no,
|
||
"quantity": 8,
|
||
"box_mode": "many-to-one",
|
||
},
|
||
)
|
||
assert second.status_code == 200
|
||
assert second.json()["box_no"] == box_no
|
||
assert second.json()["zongpai_no"] == "26BW0012"
|
||
|
||
info = client.get("/CargoTrace/box/info", params={"zongpai_no": "26BW0011"})
|
||
assert info.status_code == 200
|
||
target_box = next(
|
||
box for box in info.json()["existing_boxes"] if box["box_no"] == box_no
|
||
)
|
||
assert {item["zongpai_no"] for item in target_box["items"]} == {
|
||
"26BW0011",
|
||
"26BW0012",
|
||
}
|
||
for item in target_box["items"]:
|
||
assert "work_order_no" in item
|
||
assert isinstance(item["total_quantity"], int)
|
||
|
||
|
||
def test_box_save_many_to_one_duplicate_same_zongpai(client: TestClient):
|
||
"""多码一箱:同箱同总排重复录入返回 DUPLICATE_BOX_NO。"""
|
||
box_no = 902
|
||
first = client.post(
|
||
"/CargoTrace/box",
|
||
json={
|
||
"zongpai_no": "26BW0011",
|
||
"box_no": box_no,
|
||
"quantity": 10,
|
||
"box_mode": "many-to-one",
|
||
},
|
||
)
|
||
assert first.status_code == 200
|
||
|
||
duplicate = client.post(
|
||
"/CargoTrace/box",
|
||
json={
|
||
"zongpai_no": "26BW0011",
|
||
"box_no": box_no,
|
||
"quantity": 5,
|
||
"box_mode": "many-to-one",
|
||
},
|
||
)
|
||
assert duplicate.status_code == 409
|
||
assert duplicate.json()["error_code"] == "DUPLICATE_BOX_NO"
|
||
|
||
|
||
def test_box_update_same_box_no_does_not_conflict(client: TestClient):
|
||
"""PATCH 原箱号未变时,应排除当前 box_item_id,避免误判重复。"""
|
||
box_no = 903
|
||
created = client.post(
|
||
"/CargoTrace/box",
|
||
json={
|
||
"zongpai_no": "26BW0011",
|
||
"box_no": box_no,
|
||
"quantity": 10,
|
||
"box_mode": "one-to-many",
|
||
},
|
||
)
|
||
assert created.status_code == 200
|
||
box_item_id = created.json()["box_item_id"]
|
||
|
||
updated = client.patch(
|
||
f"/CargoTrace/box/{box_item_id}",
|
||
json={"box_no": box_no, "quantity": 7, "box_mode": "one-to-many"},
|
||
)
|
||
assert updated.status_code == 200
|
||
assert updated.json()["quantity"] == 7
|
||
|
||
|
||
def test_box_delete_removes_empty_box(client: TestClient):
|
||
"""DELETE 删除最后一条明细后,同步清理空箱号。"""
|
||
box_no = 904
|
||
created = client.post(
|
||
"/CargoTrace/box",
|
||
json={
|
||
"zongpai_no": "26BW0011",
|
||
"box_no": box_no,
|
||
"quantity": 10,
|
||
"box_mode": "many-to-one",
|
||
},
|
||
)
|
||
assert created.status_code == 200
|
||
box_item_id = created.json()["box_item_id"]
|
||
|
||
deleted = client.delete(f"/CargoTrace/box/{box_item_id}")
|
||
assert deleted.status_code == 200
|
||
assert deleted.json() == {"box_item_id": box_item_id, "deleted": True}
|
||
|
||
recreated = client.post(
|
||
"/CargoTrace/box",
|
||
json={
|
||
"zongpai_no": "26BW0012",
|
||
"box_no": box_no,
|
||
"quantity": 8,
|
||
"box_mode": "one-to-many",
|
||
},
|
||
)
|
||
assert recreated.status_code == 200
|