""" 导航分类功能端到端探针 ====================== 不依赖浏览器 + ddddocr + 调试 header,直接用 Flask test_client 走完整流程: 1. 登录 admin 2. GET /system/nav-category/ (主页面 HTML) 3. GET /system/nav-category/data (table_api JSON) 4. POST /system/nav-category/save (新增) 5. PUT /system/nav-category/update (更新) 6. PUT /system/nav-category/enable (启用/禁用) 7. DELETE /system/nav-category/remove/ (删除) 8. 验证每个 API 的 {code, message, data} 协议 退出码:全部通过 → 0;任一失败 → 1 """ import json import sys import traceback sys.path.insert(0, r'D:\bwstudio\pear-admin-flask') from applications import create_app app = create_app() client = app.test_client() def _login(): """admin/123456 登录拿 cookie session。""" # 拿一张 captcha —— 通过 test_client 共享 session_transaction r = client.get('/system/passport/getCaptcha') assert r.status_code == 200, r.status_code with client.session_transaction() as sess: code = sess.get('code') or '' code = code.lower() assert code, 'captcha code missing' r = client.post('/system/passport/login', data={ 'username': 'admin', 'password': '123456', 'captcha': code, }, follow_redirects=False) assert r.status_code in (200, 302), r.status_code def _show(label, resp): body = resp.get_data(as_text=True) print(f' [{resp.status_code}] {label} -> {body[:200]}{"..." if len(body) > 200 else ""}') def main(): _login() print('=== 已登录,开始 E2E 探针 ===\n') # 1. 分类主页面 HTML r = client.get('/system/nav-category/') print(f'[HTML main] {r.status_code} content-type={r.content_type}') assert r.status_code == 200 assert b'nav-category/data' in r.data or b'\u5bfc\u822a\u5206\u7c7b' in r.data, 'main 页面未包含预期内容' print(' [OK] 分类主页面返回 200,含预期关键字\n') # 2. data 接口(table_api 协议:{code, data, count, msg, limit}) r = client.get('/system/nav-category/data') assert r.status_code == 200 payload = r.get_json() assert payload['code'] == 0, payload before_ids = {row['id'] for row in payload['data']} print(f' [OK] data 接口 code=0,count={payload["count"]},已有分类 {len(before_ids)} 条:{sorted(before_ids)}\n') # 3. 新增(success_api 协议:{success, msg}) unique_name = f'E2E临时分类{int(__import__("time").time())}' r = client.post('/system/nav-category/save', json={'name': unique_name, 'icon': 'layui-icon-test', 'description': 'e2e created', 'sort': 1, 'enable': 1}) payload = r.get_json() assert payload.get('success') is True, payload print(f' [OK] 新增成功:{unique_name}\n') # 4. 拿到 id r = client.get('/system/nav-category/data') payload = r.get_json() new_id = next((row['id'] for row in payload['data'] if row['name'] == unique_name), None) assert new_id is not None, '新增的分类查不到' print(f' [OK] 查回新增分类 id={new_id}\n') # 5. 更新 r = client.put('/system/nav-category/update', json={'catId': new_id, 'name': unique_name + '_改', 'icon': 'layui-icon-edit', 'description': 'e2e updated', 'sort': 99, 'enable': 1}) payload = r.get_json() assert payload.get('success') is True, payload print(f' [OK] 更新成功\n') # 6. 禁用 → 启用 r = client.put('/system/nav-category/disable', json={'catId': new_id}) assert r.get_json().get('success') is True r = client.put('/system/nav-category/enable', json={'catId': new_id}) assert r.get_json().get('success') is True print(f' [OK] 禁用→启用通过\n') # 7. 删除 r = client.delete(f'/system/nav-category/remove/{new_id}') assert r.get_json().get('success') is True, r.get_json() print(f' [OK] 删除成功\n') # 8. 查回 count 必须等于开始前 r = client.get('/system/nav-category/data') payload = r.get_json() after_ids = {row['id'] for row in payload['data']} assert before_ids == after_ids, f'分类集合变化:before={before_ids}, after={after_ids}' print(f' [OK] 删除后 count 还原,新增的 id 已不在集合中\n') # 9. 重名检测 existing_name = None if payload['data']: existing_name = payload['data'][0]['name'] if existing_name: r = client.post('/system/nav-category/save', json={'name': existing_name, 'icon': 'x', 'description': '', 'sort': 0, 'enable': 1}) body = r.get_json() assert body.get('success') is False, body print(f' [OK] 重名拦截正常:{body["msg"]}\n') print('=== ALL PASS ===') if __name__ == '__main__': try: main() sys.exit(0) except AssertionError as e: print(f'\n!!! ASSERT FAIL: {e}') traceback.print_exc() sys.exit(1) except Exception as e: print(f'\n!!! UNEXPECTED: {e}') traceback.print_exc() sys.exit(1)