162 lines
5.1 KiB
Python
162 lines
5.1 KiB
Python
import json
|
||
|
||
from cart_add import KIND_BUSINESS, KIND_OK, KIND_SYSTEM, classify_mall_message
|
||
from cart_match import CartOffer
|
||
from cart_yaoex import YAOEX_ADD_URL, add_yaoex_cart
|
||
from cart_ybm import YBM_ADD_URL, add_ybm_cart
|
||
|
||
|
||
class FakeAuth:
|
||
token = "tok"
|
||
user_id = "u1"
|
||
buyer_code = "b1"
|
||
|
||
|
||
class FakeResponse:
|
||
def __init__(self, json_data=None, status_code=200, text=""):
|
||
self._json = json_data
|
||
self.status_code = status_code
|
||
self.text = text or str(json_data)
|
||
self.headers = {"content-type": "application/json"}
|
||
|
||
def raise_for_status(self):
|
||
if self.status_code >= 400:
|
||
raise RuntimeError(f"HTTP {self.status_code}")
|
||
|
||
def json(self):
|
||
if self._json is None:
|
||
raise ValueError("not json")
|
||
return self._json
|
||
|
||
|
||
class FakeSession:
|
||
def __init__(self, response: FakeResponse):
|
||
self.response = response
|
||
self.calls: list[dict] = []
|
||
|
||
def post(self, url, data=None, json=None, headers=None, timeout=None, verify=None, params=None):
|
||
self.calls.append(
|
||
{
|
||
"url": url,
|
||
"data": data,
|
||
"json": json,
|
||
"headers": headers,
|
||
"params": params,
|
||
}
|
||
)
|
||
return self.response
|
||
|
||
def close(self):
|
||
return None
|
||
|
||
|
||
def _offer(**overrides) -> CartOffer:
|
||
extra = overrides.pop(
|
||
"extra",
|
||
{
|
||
"raw": {
|
||
"spuCode": "SPU66",
|
||
"frontSellerCode": 8353,
|
||
"sellerCode": "GD01",
|
||
}
|
||
},
|
||
)
|
||
data = dict(
|
||
sku_id="SPU66",
|
||
vendor_raw="广东壹号药业有限公司",
|
||
vendor_norm="广东壹号药业有限公司",
|
||
stock=20.0,
|
||
price=90.0,
|
||
extra=extra,
|
||
)
|
||
data.update(overrides)
|
||
return CartOffer(**data)
|
||
|
||
|
||
def test_classify_pack_and_stock_and_ok():
|
||
pack = classify_mall_message("加入失败,数量须为中包装倍数")
|
||
assert pack.kind == KIND_BUSINESS
|
||
assert "中包装" in pack.reason
|
||
stock = classify_mall_message("库存不足")
|
||
assert stock.kind == KIND_BUSINESS
|
||
assert stock.reason == "库存不足"
|
||
ok = classify_mall_message("加入购物车成功")
|
||
assert ok.kind == KIND_OK
|
||
|
||
|
||
def test_yaoex_add_posts_token_and_qty():
|
||
session = FakeSession(FakeResponse({"code": 0, "msg": "成功"}))
|
||
outcome = add_yaoex_cart(FakeAuth(), _offer(), 7, session=session)
|
||
assert outcome.kind == KIND_OK
|
||
assert session.calls[0]["url"] == YAOEX_ADD_URL
|
||
assert session.calls[0]["params"]["token"] == "tok"
|
||
payload = session.calls[0]["data"]
|
||
assert payload["token"] == "tok"
|
||
assert payload["userToken"] == "tok"
|
||
assert payload["addType"] == "1"
|
||
assert payload["sourceType"] == 17052
|
||
items = json.loads(payload["itemList"])
|
||
assert items[0]["productNum"] == 7
|
||
assert items[0]["spuCode"] == "SPU66"
|
||
assert items[0]["supplyId"] == 8353
|
||
|
||
|
||
# 网关按 cartResponseList 回库存不足时记业务失败。
|
||
def test_yaoex_add_stock_message_from_cart_list():
|
||
session = FakeSession(
|
||
FakeResponse(
|
||
{
|
||
"rtn_code": "0",
|
||
"data": {
|
||
"statusCode": 1,
|
||
"cartResponseList": [{"message": "库存不足", "spuCode": "SPU66"}],
|
||
},
|
||
}
|
||
)
|
||
)
|
||
outcome = add_yaoex_cart(FakeAuth(), _offer(), 1, session=session)
|
||
assert outcome.kind == KIND_BUSINESS
|
||
assert outcome.reason == "库存不足"
|
||
|
||
|
||
def test_yaoex_add_classifies_pack_error():
|
||
session = FakeSession(FakeResponse({"code": 1, "msg": "数量必须是中包装的倍数"}))
|
||
outcome = add_yaoex_cart(FakeAuth(), _offer(), 7, session=session)
|
||
assert outcome.kind == KIND_BUSINESS
|
||
assert "中包装" in outcome.reason
|
||
|
||
|
||
def test_ybm_add_posts_sku_and_qty():
|
||
session = FakeSession(FakeResponse({"success": True, "code": 200, "msg": "操作成功"}))
|
||
offer = _offer(sku_id="SKU48", extra={"raw": {"skuId": "SKU48"}})
|
||
outcome = add_ybm_cart({"SESSION": "c1"}, offer, 3, session=session)
|
||
assert outcome.kind == KIND_OK
|
||
assert session.calls[0]["url"] == YBM_ADD_URL
|
||
assert YBM_ADD_URL.endswith("/new-front/cart/change-cart")
|
||
body = session.calls[0]["json"]
|
||
assert body["skuId"] == "SKU48"
|
||
assert body["amount"] == 3
|
||
assert body["direct"] == 1
|
||
|
||
|
||
# 现行口成功时 data.message 可能带中包装提示,仍按加车成功。
|
||
def test_ybm_success_keeps_pack_hint_as_ok():
|
||
session = FakeSession(
|
||
FakeResponse(
|
||
{
|
||
"success": True,
|
||
"code": 200,
|
||
"msg": "操作成功",
|
||
"data": {"message": "中包装验证:只能按照500的倍数购买", "qty": 500},
|
||
}
|
||
)
|
||
)
|
||
outcome = add_ybm_cart({}, _offer(extra={"raw": {"skuId": "X"}}), 5, session=session)
|
||
assert outcome.kind == KIND_OK
|
||
|
||
|
||
def test_ybm_http_error_is_system_fail():
|
||
session = FakeSession(FakeResponse(json_data=None, status_code=500, text="bad"))
|
||
outcome = add_ybm_cart({}, _offer(extra={"raw": {"skuId": "X"}}), 1, session=session)
|
||
assert outcome.kind == KIND_SYSTEM
|