巴青农资商城

test_full_chain.py 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. # ============================================================
  2. # 全链路串联测试 — 跨角色业务流程
  3. # 模拟真实的业务协作场景
  4. # ============================================================
  5. import pytest
  6. import json
  7. from config import SELLER_SHOP_ID, KEEP_TEST_DATA
  8. class TestFullChain:
  9. def test_chain_01_admin_entry_review(self, client, admin_token):
  10. """管理员查看并审核入驻申请"""
  11. resp = client.get("/agri/merchantEntryApply/list", params={
  12. "pageSize": 5, "pageNum": 1
  13. })
  14. client.assert_ok()
  15. data = client.extract_data() or {}
  16. total = data.get("total", 0)
  17. rows = data.get("rows", [])
  18. print(f" [INFO] 入驻申请共 {total} 条")
  19. pending = [r for r in rows if r.get("applyStatus") == "PENDING"]
  20. if pending:
  21. apply = pending[0]
  22. aid = apply.get("applyId")
  23. resp = client.put(f"/agri/merchantEntryApply/approve/{aid}", json={})
  24. client.assert_ok("审核通过失败")
  25. print(f" [OK] 审核通过 applyId={aid}")
  26. else:
  27. print(f" [SKIP] 无待审核申请")
  28. def test_chain_02_admin_audit_goods(self, client, admin_token):
  29. """管理员审核待上架商品"""
  30. resp = client.get("/agri/goodsAudit/list", params={
  31. "pageSize": 5, "pageNum": 1
  32. })
  33. client.assert_ok()
  34. data = client.extract_data() or {}
  35. total = data.get("total", 0)
  36. rows = data.get("rows", [])
  37. print(f" [INFO] 待审核商品共 {total} 条")
  38. pending = [r for r in rows if r.get("goodsStatus") in ("SUBMITTED", "PENDING")]
  39. if pending:
  40. g = pending[0]
  41. gid = g.get("goodsId")
  42. resp = client.put("/agri/goodsAudit/audit", json={
  43. "goodsIds": [gid],
  44. "auditStatus": "APPROVED",
  45. "auditRemark": "E2E测试自动审核通过"
  46. })
  47. data = client.assert_ok("审核失败")
  48. print(f" [OK] 审核通过 goodsId={gid}")
  49. else:
  50. print(f" [SKIP] 无待审核商品")
  51. def test_chain_03_seller_switch_shop(self, client, seller_token):
  52. """商家切换店铺上下文"""
  53. resp = client.put("/agri/seller/context/shop", json={
  54. "shopId": SELLER_SHOP_ID
  55. })
  56. client.assert_ok("切换店铺失败")
  57. print(f" [OK] 店铺已切换 shopId={SELLER_SHOP_ID}")
  58. def test_chain_04_seller_view_goods(self, client, seller_token):
  59. """商家查看商品并检查待提交商品"""
  60. resp = client.get("/agri/seller/goods/list")
  61. client.assert_ok()
  62. data = client.extract_data() or {}
  63. total = data.get("total", 0)
  64. rows = data.get("rows", [])
  65. print(f" [INFO] 商家商品共 {total} 条")
  66. draft = [r for r in rows if r.get("goodsStatus") in ("DRAFT",)]
  67. submitted = [r for r in rows if r.get("goodsStatus") in ("SUBMITTED", "PENDING")]
  68. on_shelf = [r for r in rows if r.get("goodsStatus") == "ON_SHELF"]
  69. if draft:
  70. g = draft[0]
  71. gid = g.get("goodsId")
  72. resp = client.put(f"/agri/seller/goods/{gid}/submit")
  73. client.assert_ok("提交上架失败")
  74. print(f" [OK] 提交上架 goodsId={gid}")
  75. else:
  76. print(f" [SKIP] 无草稿商品需提交")
  77. if on_shelf:
  78. print(f" [INFO] 在售商品 {len(on_shelf)} 个")
  79. def test_chain_05_seller_view_orders(self, client, seller_token):
  80. """商家查看订单并发货"""
  81. resp = client.get("/agri/seller/order/list")
  82. client.assert_ok()
  83. data = client.extract_data() or {}
  84. total = data.get("total", 0)
  85. rows = data.get("rows", [])
  86. print(f" [INFO] 商家订单共 {total} 条")
  87. unpaid = [r for r in rows if r.get("orderStatus") in ("WAIT_PAY", "UNPAID")]
  88. shipped = [r for r in rows if r.get("orderStatus") in ("WAIT_SHIP", "UNSHIPPED")]
  89. print(f" [INFO] 待付款 {len(unpaid)}, 待发货 {len(shipped)}")
  90. def test_chain_06_seller_view_stock(self, client, seller_token):
  91. """商家查看库存"""
  92. resp = client.get("/agri/seller/stock/query/list")
  93. client.assert_ok()
  94. data = client.extract_data() or {}
  95. total = data.get("total", 0)
  96. rows = data.get("rows", [])
  97. low_stock = [r for r in rows if (r.get("stock") or 0) < 10]
  98. print(f" [INFO] 库存商品 {total} 个, 低库存 {len(low_stock)} 个")
  99. if low_stock:
  100. g = low_stock[0]
  101. gid = g.get("goodsId")
  102. print(f" [INFO] 需补货: goodsId={gid} stock={g.get('stock','?')}")
  103. def test_chain_07_consumer_register_browse(self, client, member_token):
  104. """消费者注册后浏览首页"""
  105. resp = client.get("/api/home/banners")
  106. client.assert_ok()
  107. banners = client.extract_data() or []
  108. resp = client.get("/api/home/categories")
  109. client.assert_ok()
  110. cats = client.extract_data() or []
  111. resp = client.get("/api/home/hot-goods")
  112. client.assert_ok()
  113. goods = client.extract_data() or []
  114. print(f" [OK] 首页浏览: Banner={len(banners)} 分类={len(cats)} 热销={len(goods)}")
  115. if goods:
  116. client._test_goods_id = goods[0].get("goodsId") or goods[0].get("id")
  117. resp = client.get(f"/api/goods/{client._test_goods_id}")
  118. client.assert_ok()
  119. detail = client.extract_data() or {}
  120. print(f" [OK] 商品详情: {detail.get('goodsName','')[:20]}")
  121. def test_chain_08_consumer_add_to_cart(self, client, member_token):
  122. """消费者加购并下单"""
  123. gid = getattr(client, '_test_goods_id', None)
  124. resp = client.get("/api/home/hot-goods")
  125. data = client.assert_ok()
  126. goods = data.get("data", [])
  127. if not goods:
  128. pytest.skip("无在售商品")
  129. gid = goods[0].get("goodsId") or goods[0].get("id")
  130. # 加购
  131. resp = client.post("/api/cart/items", json={"goodsId": gid, "quantity": 1})
  132. client.assert_ok("加购失败")
  133. print(f" [OK] 加购 goodsId={gid}")
  134. # 需要地址才能下单
  135. resp = client.post("/api/member/address", json={
  136. "receiverName": "测试用户",
  137. "receiverMobile": "13800138000",
  138. "province": "北京市", "city": "北京市", "district": "朝阳区",
  139. "detailAddress": "E2E测试地址100号",
  140. "fullAddress": "北京市北京市朝阳区E2E测试地址100号",
  141. "isDefault": True,
  142. })
  143. data = client.assert_ok()
  144. addr_id = data.get("data")
  145. # 预览订单
  146. resp = client.post("/api/checkout/preview", json={
  147. "source": "BUY_NOW",
  148. "items": [{"goodsId": gid, "quantity": 1}],
  149. })
  150. client.assert_ok("预览订单失败")
  151. print(f" [OK] 订单预览通过")
  152. # 提交订单
  153. resp = client.post("/api/checkout/submit", json={
  154. "source": "BUY_NOW",
  155. "addressId": addr_id,
  156. "payType": "WEIXIN",
  157. "items": [{"goodsId": gid, "quantity": 1}],
  158. })
  159. data = client.assert_ok("提交订单失败")
  160. order_data = data.get("data", {}) if isinstance(data.get("data"), dict) else data
  161. order_id = order_data.get("orderId")
  162. if not order_id:
  163. order_ids = order_data.get("orderIds", [])
  164. order_id = order_ids[0] if order_ids else None
  165. if order_id:
  166. print(f" [OK] 订单已提交 orderId={order_id}")
  167. def test_chain_09_consumer_view_after_sale(self, client, member_token):
  168. """消费者查看售后入口"""
  169. resp = client.get("/api/order/list")
  170. client.assert_ok()
  171. data = client.extract_data() or {}
  172. total = data.get("total", 0)
  173. print(f" [INFO] 我的订单共 {total} 条")
  174. # 售后列表
  175. resp = client.get("/api/order/aftersale/list")
  176. client.assert_ok()
  177. data = client.extract_data() or {}
  178. total_as = data.get("total", 0) if isinstance(data, dict) else 0
  179. print(f" [INFO] 售后单共 {total_as} 条")
  180. def test_chain_10_admin_stats_overview(self, client, admin_token):
  181. """平台端统一数据概览"""
  182. modules = [
  183. ("商品待审", "/agri/goodsAudit/pendingCount", "pendingCount"),
  184. ("入驻待审", "/agri/merchantEntryApply/pendingCount", "pendingCount"),
  185. ("提现待审", "/agri/finance/withdrawAudit/pendingCount", "pendingCount"),
  186. ]
  187. for label, path, field in modules:
  188. resp = client.get(path)
  189. client.assert_ok()
  190. val = (client.extract_data() or {}).get(field, "?")
  191. print(f" [INFO] {label}: {val}")