""" 测试 API 返回格式 验证登录 API 是否正确返回 cookies 和 cookies_full """ import json def test_api_response_format(): """测试 API 响应格式""" # 模拟 API 返回的数据 mock_response = { "code": 0, "message": "登录成功", "data": { "user_info": {}, "cookies": { "a1": "xxx", "webId": "yyy", "web_session": "zzz" }, "cookies_full": [ { "name": "a1", "value": "xxx", "domain": ".xiaohongshu.com", "path": "/", "expires": 1797066496, "httpOnly": False, "secure": False, "sameSite": "Lax" }, { "name": "webId", "value": "yyy", "domain": ".xiaohongshu.com", "path": "/", "expires": 1797066496, "httpOnly": False, "secure": False, "sameSite": "Lax" }, { "name": "web_session", "value": "zzz", "domain": ".xiaohongshu.com", "path": "/", "expires": 1797066497, "httpOnly": True, "secure": True, "sameSite": "Lax" } ], "login_time": "2025-12-12T23:30:00" } } print("="*60) print("API 响应格式测试") print("="*60) print() # 检查响应结构 assert "code" in mock_response, "缺少 code 字段" assert "message" in mock_response, "缺少 message 字段" assert "data" in mock_response, "缺少 data 字段" data = mock_response["data"] # 检查 cookies 字段(键值对格式) print("✅ 检查 cookies 字段(键值对格式):") assert "cookies" in data, "缺少 cookies 字段" assert isinstance(data["cookies"], dict), "cookies 应该是字典类型" print(f" 类型: {type(data['cookies']).__name__}") print(f" 示例: {json.dumps(data['cookies'], ensure_ascii=False, indent=2)}") print() # 检查 cookies_full 字段(Playwright 完整格式) print("✅ 检查 cookies_full 字段(Playwright 完整格式):") assert "cookies_full" in data, "缺少 cookies_full 字段" assert isinstance(data["cookies_full"], list), "cookies_full 应该是列表类型" print(f" 类型: {type(data['cookies_full']).__name__}") print(f" 数量: {len(data['cookies_full'])} 个 Cookie") print(f" 示例(第一个):") print(f"{json.dumps(data['cookies_full'][0], ensure_ascii=False, indent=6)}") print() # 检查 cookies_full 的每个元素 print("✅ 检查 cookies_full 的结构:") for i, cookie in enumerate(data["cookies_full"]): assert "name" in cookie, f"Cookie[{i}] 缺少 name 字段" assert "value" in cookie, f"Cookie[{i}] 缺少 value 字段" assert "domain" in cookie, f"Cookie[{i}] 缺少 domain 字段" assert "path" in cookie, f"Cookie[{i}] 缺少 path 字段" assert "expires" in cookie, f"Cookie[{i}] 缺少 expires 字段" assert "httpOnly" in cookie, f"Cookie[{i}] 缺少 httpOnly 字段" assert "secure" in cookie, f"Cookie[{i}] 缺少 secure 字段" assert "sameSite" in cookie, f"Cookie[{i}] 缺少 sameSite 字段" print(f" Cookie[{i}] ({cookie['name']}): ✅ 所有字段完整") print() print("="*60) print("🎉 所有检查通过!API 返回格式正确") print("="*60) print() # 使用场景说明 print("📝 使用场景:") print() print("1. 前端展示 - 使用 cookies(键值对格式):") print(" const cookies = response.data.cookies;") print(" console.log(cookies.a1, cookies.webId);") print() print("2. 数据库存储 - 使用 cookies_full(完整格式):") print(" const cookiesFull = response.data.cookies_full;") print(" await db.saveCookies(userId, JSON.stringify(cookiesFull));") print() print("3. Python 脚本使用 - 使用 cookies_full:") print(" cookies_full = response['data']['cookies_full']") print(" publisher = XHSPublishService(cookies_full)") print() def compare_formats(): """对比两种格式""" print("="*60) print("格式对比分析") print("="*60) print() # 键值对格式 cookies_dict = { "a1": "xxx", "webId": "yyy", "web_session": "zzz" } # Playwright 完整格式 cookies_full = [ { "name": "a1", "value": "xxx", "domain": ".xiaohongshu.com", "path": "/", "expires": 1797066496, "httpOnly": False, "secure": False, "sameSite": "Lax" } ] print("📊 键值对格式:") dict_str = json.dumps(cookies_dict, ensure_ascii=False, indent=2) print(dict_str) print(f" 大小: {len(dict_str)} 字符") print() print("📊 Playwright 完整格式:") full_str = json.dumps(cookies_full, ensure_ascii=False, indent=2) print(full_str) print(f" 大小: {len(full_str)} 字符") print() print("📊 对比结果:") print(f" 完整格式 vs 键值对格式: {len(full_str)} / {len(dict_str)} = {len(full_str)/len(dict_str):.1f}x") print(f" 每个 Cookie 完整格式约增加: {(len(full_str) - len(dict_str)) // len(cookies_dict)} 字符") print() print("✅ 结论:") print(" - 完整格式虽然较大,但包含所有必要属性") print(" - 对于数据库存储,建议使用完整格式") print(" - 对于前端展示,可以使用键值对格式") print() if __name__ == "__main__": # 测试 API 响应格式 test_api_response_format() # 对比两种格式 compare_formats() print("="*60) print("✅ 测试完成!") print("="*60)