巴青农资商城

test_admin_flow.py 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. # ============================================================
  2. # 平台管理员端 — 全量端到端测试
  3. # 覆盖 20 个 Controller,约 70 个 API 端点
  4. # ============================================================
  5. import pytest
  6. import json
  7. from config import KEEP_TEST_DATA
  8. from api_client import ApiClient
  9. # ============================================================
  10. # 平台端 — 账号管理 (AccountManageController)
  11. # ============================================================
  12. class TestAdminAccountManage:
  13. def test_01_account_list(self, client, admin_token):
  14. """平台端账号列表查询"""
  15. resp = client.get("/agri/accountManage/list")
  16. client.assert_ok("查询账号列表失败")
  17. data = client.extract_data() or {}
  18. print(f" [OK] 账号列表 total={data.get('total','?')}")
  19. def test_02_account_detail(self, client, admin_token):
  20. """平台端账号详情"""
  21. # 从列表取第一个
  22. resp = client.get("/agri/accountManage/list", params={"pageSize": 1, "pageNum": 1})
  23. data = client.assert_ok()
  24. rows = (data.get("data") or {}).get("rows") or []
  25. if not rows:
  26. pytest.skip("无账号数据")
  27. uid = rows[0].get("userId")
  28. resp = client.get(f"/agri/accountManage/{uid}")
  29. client.assert_ok("查询账号详情失败")
  30. print(f" [OK] 账号详情 userId={uid}")
  31. # ============================================================
  32. # 平台端 — 管理员管理 (PlatformAdminController)
  33. # ============================================================
  34. class TestAdminPlatformAdmin:
  35. def test_03_admin_list(self, client, admin_token):
  36. """平台管理员列表"""
  37. resp = client.get("/agri/platformAdmin/list")
  38. client.assert_ok("查询管理员列表失败")
  39. data = client.extract_data() or {}
  40. print(f" [OK] 管理员列表 total={data.get('total','?')}")
  41. def test_04_admin_role_options(self, client, admin_token):
  42. """平台管理员角色选项"""
  43. resp = client.get("/agri/platformAdmin/roleOptions")
  44. client.assert_ok("查询角色选项失败")
  45. roles = client.extract_data() or []
  46. print(f" [OK] 角色选项 count={len(roles)}")
  47. def test_05_admin_detail(self, client, admin_token):
  48. """平台管理员详情"""
  49. resp = client.get("/agri/platformAdmin/list", params={"pageSize": 1})
  50. data = client.assert_ok()
  51. rows = (data.get("data") or {}).get("rows") or []
  52. if not rows:
  53. pytest.skip("无管理员数据")
  54. uid = rows[0].get("userId")
  55. resp = client.get(f"/agri/platformAdmin/{uid}")
  56. client.assert_ok("查询管理员详情失败")
  57. print(f" [OK] 管理员详情 userId={uid}")
  58. # ============================================================
  59. # 平台端 — 会员管理 (MemberController)
  60. # ============================================================
  61. class TestAdminMember:
  62. def test_06_member_list(self, client, admin_token):
  63. """平台端会员列表"""
  64. resp = client.get("/agri/member/list")
  65. client.assert_ok("查询会员列表失败")
  66. data = client.extract_data() or {}
  67. print(f" [OK] 会员列表 total={data.get('total','?')}")
  68. def test_07_member_levels(self, client, admin_token):
  69. """平台端会员等级列表"""
  70. resp = client.get("/agri/member/levels")
  71. client.assert_ok("查询会员等级失败")
  72. data = client.extract_data() or []
  73. if isinstance(data, list):
  74. print(f" [OK] 会员等级 count={len(data)}")
  75. else:
  76. print(f" [OK] 会员等级正常")
  77. def test_08_member_detail(self, client, admin_token):
  78. """平台端会员详情"""
  79. resp = client.get("/agri/member/list", params={"pageSize": 1})
  80. data = client.assert_ok()
  81. rows = (data.get("data") or {}).get("rows") or []
  82. if not rows:
  83. pytest.skip("无会员数据")
  84. mid = rows[0].get("memberId")
  85. resp = client.get(f"/agri/member/{mid}")
  86. client.assert_ok("查询会员详情失败")
  87. print(f" [OK] 会员详情 memberId={mid}")
  88. # ============================================================
  89. # 平台端 — 商家管理 (MerchantController)
  90. # ============================================================
  91. class TestAdminMerchant:
  92. def test_09_merchant_list(self, client, admin_token):
  93. """平台端商家列表"""
  94. resp = client.get("/agri/merchant/list")
  95. client.assert_ok("查询商家列表失败")
  96. data = client.extract_data() or {}
  97. print(f" [OK] 商家列表 total={data.get('total','?')}")
  98. def test_10_merchant_detail(self, client, admin_token):
  99. """平台端商家详情"""
  100. resp = client.get("/agri/merchant/list", params={"pageSize": 1})
  101. data = client.assert_ok()
  102. rows = (data.get("data") or {}).get("rows") or []
  103. if not rows:
  104. pytest.skip("无商家数据")
  105. mid = rows[0].get("merchantId")
  106. resp = client.get(f"/agri/merchant/{mid}")
  107. client.assert_ok("查询商家详情失败")
  108. print(f" [OK] 商家详情 merchantId={mid}")
  109. # ============================================================
  110. # 平台端 — 入驻审核 (MerchantEntryApplyController)
  111. # ============================================================
  112. class TestAdminEntryAudit:
  113. def test_11_entry_apply_list(self, client, admin_token):
  114. """入驻申请列表"""
  115. resp = client.get("/agri/merchantEntryApply/list")
  116. client.assert_ok("查询入驻申请失败")
  117. data = client.extract_data() or {}
  118. total = data.get("total", 0) if isinstance(data, dict) else 0
  119. print(f" [OK] 入驻申请 total={total}")
  120. def test_12_entry_pending_count(self, client, admin_token):
  121. """待审核入驻数量"""
  122. resp = client.get("/agri/merchantEntryApply/pendingCount")
  123. data = client.assert_ok("查询待审核入驻数量失败")
  124. cnt = (data.get("data") or {}).get("pendingCount", 0)
  125. print(f" [OK] 待审核入驻 count={cnt}")
  126. def test_13_entry_apply_detail(self, client, admin_token):
  127. """入驻申请详情"""
  128. resp = client.get("/agri/merchantEntryApply/list", params={"pageSize": 1})
  129. data = client.assert_ok()
  130. rows = (data.get("data") or {}).get("rows") or []
  131. if not rows:
  132. pytest.skip("无入驻申请")
  133. aid = rows[0].get("applyId")
  134. resp = client.get(f"/agri/merchantEntryApply/{aid}")
  135. client.assert_ok("查询入驻申请详情失败")
  136. print(f" [OK] 入驻申请详情 applyId={aid}")
  137. def test_14_entry_approve_flow(self, client, admin_token):
  138. """入驻审核通过流程(需有待审核数据)"""
  139. resp = client.get("/agri/merchantEntryApply/list", params={
  140. "pageSize": 1, "pageNum": 1
  141. })
  142. data = client.assert_ok()
  143. rows = (data.get("data") or {}).get("rows") or []
  144. if not rows:
  145. pytest.skip("无入驻申请")
  146. apply = rows[0]
  147. aid = apply.get("applyId")
  148. status = apply.get("applyStatus", "")
  149. print(f" [INFO] 入驻申请 applyId={aid} status={status}")
  150. if status == "PENDING":
  151. resp = client.put(f"/agri/merchantEntryApply/approve/{aid}", json={})
  152. client.assert_ok("入驻审核通过失败")
  153. print(f" [OK] 入驻申请 {aid} 审核通过")
  154. elif status == "APPROVED":
  155. resp = client.put(f"/agri/merchantEntryApply/completePublicity/{aid}")
  156. client.assert_ok("完成公示失败")
  157. print(f" [OK] 入驻申请 {aid} 完成公示")
  158. else:
  159. print(f" [SKIP] 当前状态 {status},跳过")
  160. # ============================================================
  161. # 平台端 — 商品管理 (GoodsController + GoodsAuditController)
  162. # ============================================================
  163. class TestAdminGoods:
  164. def test_15_goods_list(self, client, admin_token):
  165. """平台端商品列表"""
  166. resp = client.get("/agri/goods/list")
  167. client.assert_ok("查询商品列表失败")
  168. data = client.extract_data() or {}
  169. print(f" [OK] 商品列表 total={data.get('total','?')}")
  170. def test_16_goods_pending_count(self, client, admin_token):
  171. """待审核商品数量"""
  172. resp = client.get("/agri/goods/pendingCount")
  173. data = client.assert_ok("查询待审核商品数量失败")
  174. cnt = (data.get("data") or {}).get("pendingCount", 0)
  175. print(f" [OK] 待审核商品 count={cnt}")
  176. def test_17_goods_detail(self, client, admin_token):
  177. """平台端商品详情"""
  178. resp = client.get("/agri/goods/list", params={"pageSize": 1})
  179. data = client.assert_ok()
  180. rows = (data.get("data") or {}).get("rows") or []
  181. if not rows:
  182. resp = client.get("/agri/goodsAudit/list", params={"pageSize": 1})
  183. data = client.assert_ok()
  184. rows = (data.get("data") or {}).get("rows") or []
  185. if not rows:
  186. pytest.skip("无商品数据")
  187. gid = rows[0].get("goodsId")
  188. resp = client.get(f"/agri/goods/{gid}")
  189. client.assert_ok("查询商品详情失败")
  190. print(f" [OK] 商品详情 goodsId={gid}")
  191. def test_18_goods_audit_list(self, client, admin_token):
  192. """商品审核列表"""
  193. resp = client.get("/agri/goodsAudit/list")
  194. client.assert_ok("查询商品审核列表失败")
  195. data = client.extract_data() or {}
  196. print(f" [OK] 商品审核列表 total={data.get('total','?')}")
  197. def test_19_goods_audit_pending_count(self, client, admin_token):
  198. """商品审核待审数量"""
  199. resp = client.get("/agri/goodsAudit/pendingCount")
  200. data = client.assert_ok("查询审核待审数量失败")
  201. cnt = (data.get("data") or {}).get("pendingCount", 0)
  202. print(f" [OK] 审核待审商品 count={cnt}")
  203. def test_20_goods_audit_detail(self, client, admin_token):
  204. """商品审核详情"""
  205. resp = client.get("/agri/goodsAudit/list", params={"pageSize": 1})
  206. data = client.assert_ok()
  207. rows = (data.get("data") or {}).get("rows") or []
  208. if not rows:
  209. pytest.skip("无待审商品")
  210. gid = rows[0].get("goodsId")
  211. resp = client.get(f"/agri/goodsAudit/{gid}")
  212. client.assert_ok("查询审核商品详情失败")
  213. print(f" [OK] 审核商品详情 goodsId={gid}")
  214. # ============================================================
  215. # 平台端 — 分类管理 (PlatformCategoryController)
  216. # ============================================================
  217. class TestAdminCategory:
  218. def test_21_category_list(self, client, admin_token):
  219. """平台分类列表"""
  220. resp = client.get("/agri/category/list")
  221. client.assert_ok("查询分类列表失败")
  222. data = client.extract_data() or {}
  223. print(f" [OK] 分类列表 total={data.get('total','?')}")
  224. def test_22_category_tree(self, client, admin_token):
  225. """平台分类树"""
  226. resp = client.get("/agri/category/tree")
  227. client.assert_ok("查询分类树失败")
  228. tree = client.extract_data() or []
  229. print(f" [OK] 分类树 nodes={len(tree)}")
  230. def test_23_category_detail(self, client, admin_token):
  231. """平台分类详情"""
  232. resp = client.get("/agri/category/list", params={"pageSize": 1})
  233. data = client.assert_ok()
  234. rows = (data.get("data") or {}).get("rows") or []
  235. if not rows:
  236. pytest.skip("无分类数据")
  237. cid = rows[0].get("categoryId")
  238. resp = client.get(f"/agri/category/{cid}")
  239. client.assert_ok("查询分类详情失败")
  240. print(f" [OK] 分类详情 categoryId={cid}")
  241. # ============================================================
  242. # 平台端 — Banner管理 (BannerController)
  243. # ============================================================
  244. class TestAdminBanner:
  245. def test_24_banner_list(self, client, admin_token):
  246. """Banner列表"""
  247. resp = client.get("/agri/banner/list")
  248. client.assert_ok("查询Banner列表失败")
  249. data = client.extract_data() or {}
  250. print(f" [OK] Banner列表 total={data.get('total','?')}")
  251. def test_25_banner_detail(self, client, admin_token):
  252. """Banner详情"""
  253. resp = client.get("/agri/banner/list", params={"pageSize": 1})
  254. data = client.assert_ok()
  255. rows = (data.get("data") or {}).get("rows") or []
  256. if not rows:
  257. pytest.skip("无Banner数据")
  258. bid = rows[0].get("bannerId")
  259. resp = client.get(f"/agri/banner/{bid}")
  260. client.assert_ok("查询Banner详情失败")
  261. print(f" [OK] Banner详情 bannerId={bid}")
  262. # ============================================================
  263. # 平台端 — 商城设置 (MallSettingController)
  264. # ============================================================
  265. class TestAdminMallSetting:
  266. def test_26_mall_setting_get(self, client, admin_token):
  267. """商城设置查询"""
  268. resp = client.get("/agri/mallSetting")
  269. client.assert_ok("查询商城设置失败")
  270. setting = client.extract_data() or {}
  271. print(f" [OK] 商城设置: {json.dumps(setting, ensure_ascii=False)[:100]}")
  272. # ============================================================
  273. # 平台端 — 服务协议 (MallServiceAgreementController)
  274. # ============================================================
  275. class TestAdminAgreement:
  276. def test_27_service_agreement_get(self, client, admin_token):
  277. """商城服务协议查询"""
  278. resp = client.get("/agri/mallServiceAgreement")
  279. client.assert_ok("查询服务协议失败")
  280. agmt = client.extract_data() or {}
  281. print(f" [OK] 服务协议: {str(agmt.get('agreementType',''))[:80]}")
  282. def test_28_entry_agreement_get(self, client, admin_token):
  283. """入驻协议查询"""
  284. resp = client.get("/agri/merchantEntryAgreement")
  285. client.assert_ok("查询入驻协议失败")
  286. agmt = client.extract_data() or {}
  287. print(f" [OK] 入驻协议: {str(agmt.get('agreementType',''))[:80]}")
  288. client._test_has_agreement = True
  289. # ============================================================
  290. # 平台端 — 地区管理 (RegionController)
  291. # ============================================================
  292. class TestAdminRegion:
  293. def test_29_region_tree(self, client, admin_token):
  294. """地区树查询"""
  295. resp = client.get("/agri/region/tree")
  296. client.assert_ok("查询地区树失败")
  297. tree = client.extract_data() or []
  298. print(f" [OK] 地区树 nodes={len(tree) if isinstance(tree, list) else 'ok'}")
  299. # ============================================================
  300. # 平台端 — 店铺管理 (ShopController)
  301. # ============================================================
  302. class TestAdminShop:
  303. def test_30_shop_list(self, client, admin_token):
  304. """平台端店铺列表"""
  305. resp = client.get("/agri/shop/list")
  306. client.assert_ok("查询店铺列表失败")
  307. data = client.extract_data() or {}
  308. total = data.get("total", 0) if isinstance(data, dict) else 0
  309. print(f" [OK] 店铺列表 total={total}")
  310. def test_31_shop_detail(self, client, admin_token):
  311. """平台端店铺详情"""
  312. resp = client.get("/agri/shop/list", params={"pageSize": 1})
  313. data = client.assert_ok()
  314. rows = (data.get("data") or {}).get("rows") or []
  315. if not rows:
  316. pytest.skip("无店铺数据")
  317. sid = rows[0].get("shopId")
  318. resp = client.get(f"/agri/shop/{sid}")
  319. client.assert_ok("查询店铺详情失败")
  320. print(f" [OK] 店铺详情 shopId={sid}")
  321. # ============================================================
  322. # 平台端 — 商品服务 (GoodsServiceController)
  323. # ============================================================
  324. class TestAdminGoodsService:
  325. def test_32_goods_service_list(self, client, admin_token):
  326. """商品服务列表"""
  327. resp = client.get("/agri/goodsService/list")
  328. client.assert_ok("查询商品服务列表失败")
  329. data = client.extract_data() or {}
  330. print(f" [OK] 商品服务列表 total={data.get('total','?') if isinstance(data, dict) else 'ok'}")
  331. def test_33_goods_service_detail(self, client, admin_token):
  332. """商品服务详情"""
  333. resp = client.get("/agri/goodsService/list", params={"pageSize": 1})
  334. data = client.assert_ok()
  335. # 可能返回 list 或 {rows, total}
  336. rows = []
  337. if isinstance(data.get("data"), dict):
  338. rows = data["data"].get("rows", [])
  339. elif isinstance(data.get("data"), list):
  340. rows = data["data"]
  341. if not rows:
  342. pytest.skip("无商品服务数据")
  343. sid = rows[0].get("serviceId")
  344. resp = client.get(f"/agri/goodsService/{sid}")
  345. client.assert_ok("查询商品服务详情失败")
  346. print(f" [OK] 商品服务详情 serviceId={sid}")
  347. # ============================================================
  348. # 平台端 — 财务管理 (FundOverview / WithdrawAudit / WithdrawSummary)
  349. # ============================================================
  350. class TestAdminFinance:
  351. def test_34_fund_summary(self, client, admin_token):
  352. """资金概览"""
  353. resp = client.get("/agri/finance/fundOverview/summary")
  354. client.assert_ok("查询资金概览失败")
  355. summary = client.extract_data() or {}
  356. print(f" [OK] 资金概览: {json.dumps(summary, ensure_ascii=False)[:120]}")
  357. def test_35_fund_shops(self, client, admin_token):
  358. """资金概览-店铺列表"""
  359. resp = client.get("/agri/finance/fundOverview/shops")
  360. client.assert_ok("查询资金店铺列表失败")
  361. data = client.extract_data() or {}
  362. print(f" [OK] 资金店铺列表: {json.dumps(data, ensure_ascii=False)[:120]}")
  363. def test_36_fund_details(self, client, admin_token):
  364. """资金概览-明细"""
  365. resp = client.get("/agri/finance/fundOverview/details", params={"pageSize": 1})
  366. client.assert_ok("查询资金明细失败")
  367. data = client.extract_data() or {}
  368. print(f" [OK] 资金明细正常")
  369. def test_37_withdraw_audit_list(self, client, admin_token):
  370. """提现审核列表"""
  371. resp = client.get("/agri/finance/withdrawAudit/list")
  372. client.assert_ok("查询提现列表失败")
  373. data = client.extract_data() or {}
  374. total = data.get("total", 0) if isinstance(data, dict) else 0
  375. print(f" [OK] 提现审核列表 total={total}")
  376. def test_38_withdraw_pending_count(self, client, admin_token):
  377. """提现待审数量"""
  378. resp = client.get("/agri/finance/withdrawAudit/pendingCount")
  379. client.assert_ok("查询提现待审数量失败")
  380. cnt = (client.extract_data() or {}).get("pendingCount", 0)
  381. print(f" [OK] 提现待审 count={cnt}")
  382. def test_39_withdraw_summary_shops(self, client, admin_token):
  383. """提现汇总-店铺"""
  384. resp = client.get("/agri/finance/withdrawSummary/shops")
  385. client.assert_ok("查询提现汇总店铺失败")
  386. data = client.extract_data() or {}
  387. print(f" [OK] 提现汇总-店铺正常")
  388. def test_40_withdraw_summary_details(self, client, admin_token):
  389. """提现汇总-明细"""
  390. resp = client.get("/agri/finance/withdrawSummary/details", params={"pageSize": 1})
  391. client.assert_ok("查询提现汇总明细失败")
  392. data = client.extract_data() or {}
  393. print(f" [OK] 提现汇总-明细正常")
  394. # ============================================================
  395. # 平台端 — 微信支付配置 (PlatformShopWechatPayController)
  396. # ============================================================
  397. class TestAdminWechatPay:
  398. def test_41_wechat_pay_list(self, client, admin_token):
  399. """微信支付配置列表"""
  400. resp = client.get("/agri/shop/wechat-pay/list")
  401. client.assert_ok("查询支付配置列表失败")
  402. data = client.extract_data() or {}
  403. total = data.get("total", 0) if isinstance(data, dict) else 0
  404. print(f" [OK] 支付配置列表 total={total}")
  405. def test_42_wechat_pay_pending_count(self, client, admin_token):
  406. """微信支付待审数量"""
  407. resp = client.get("/agri/shop/wechat-pay/pendingCount")
  408. client.assert_ok("查询支付待审数量失败")
  409. cnt = (client.extract_data() or {}).get("pendingCount", 0)
  410. print(f" [OK] 支付待审 count={cnt}")
  411. def test_43_wechat_pay_detail(self, client, admin_token):
  412. """微信支付配置详情"""
  413. resp = client.get("/agri/shop/wechat-pay/list", params={"pageSize": 1})
  414. data = client.assert_ok()
  415. rows = (data.get("data") or {}).get("rows") or []
  416. if not rows:
  417. pytest.skip("无支付配置数据")
  418. sid = rows[0].get("shopId")
  419. resp = client.get(f"/agri/shop/wechat-pay/{sid}")
  420. client.assert_ok("查询支付配置详情失败")
  421. print(f" [OK] 支付配置详情 shopId={sid}")
  422. # ============================================================
  423. # 平台端 — 全局设置 (ShopGlobalSettingController)
  424. # ============================================================
  425. class TestAdminGlobalSetting:
  426. def test_44_global_setting_get(self, client, admin_token):
  427. """全局设置查询"""
  428. resp = client.get("/agri/shopSetting")
  429. client.assert_ok("查询全局设置失败")
  430. setting = client.extract_data() or {}
  431. print(f" [OK] 全局设置: {json.dumps(setting, ensure_ascii=False)[:100]}")