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": { "skuId": "SKU66", "spuCode": "SPU66", "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 payload = session.calls[0]["data"] assert payload["token"] == "tok" assert payload["userToken"] == "tok" assert str(payload["amount"]) == "7" assert payload["skuId"] == "SKU66" assert payload["spuCode"] == "SPU66" assert payload["sellerCode"] == "GD01" 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, "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 body = session.calls[0]["json"] assert body["skuId"] == "SKU48" assert body["skuNum"] == 3 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