227 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			227 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Python
		
	
	
	
#!/usr/bin/env python3
 | 
						||
# -*- coding: utf-8 -*-
 | 
						||
"""
 | 
						||
WordPress REST API 测试脚本
 | 
						||
"""
 | 
						||
 | 
						||
import os
 | 
						||
import requests
 | 
						||
import json
 | 
						||
from requests.auth import HTTPBasicAuth
 | 
						||
from dotenv import load_dotenv
 | 
						||
 | 
						||
# 加载环境变量
 | 
						||
load_dotenv()
 | 
						||
 | 
						||
# WordPress 配置信息
 | 
						||
WP_URL = os.getenv('WORDPRESS_URL')
 | 
						||
WP_USER = os.getenv('WORDPRESS_USERNAME')
 | 
						||
WP_APP_PASSWORD = os.getenv('WORDPRESS_APP_PASSWORD')
 | 
						||
 | 
						||
# 移除密码中的空格
 | 
						||
if WP_APP_PASSWORD:
 | 
						||
    WP_APP_PASSWORD = WP_APP_PASSWORD.replace(" ", "")
 | 
						||
 | 
						||
# 检查必需的环境变量
 | 
						||
if not all([WP_URL, WP_USER, WP_APP_PASSWORD]):
 | 
						||
    print("❌ 错误: 请在 .env 文件中配置 WORDPRESS_URL, WORDPRESS_USERNAME, WORDPRESS_APP_PASSWORD")
 | 
						||
    exit(1)
 | 
						||
 | 
						||
class WordPressAPITester:
 | 
						||
    def __init__(self, url, username, app_password):
 | 
						||
        self.base_url = url.rstrip('/')
 | 
						||
        self.api_url = f"{self.base_url}/wp-json/wp/v2"
 | 
						||
        self.username = username
 | 
						||
        self.app_password = app_password
 | 
						||
        self.auth = HTTPBasicAuth(username, app_password)
 | 
						||
        
 | 
						||
    def test_connection(self):
 | 
						||
        """测试基本连接"""
 | 
						||
        print("🔍 测试 WordPress REST API 连接...")
 | 
						||
        try:
 | 
						||
            response = requests.get(f"{self.base_url}/wp-json", timeout=10)
 | 
						||
            if response.status_code == 200:
 | 
						||
                data = response.json()
 | 
						||
                print(f"✅ 连接成功!")
 | 
						||
                print(f"   站点名称: {data.get('name', 'N/A')}")
 | 
						||
                print(f"   描述: {data.get('description', 'N/A')}")
 | 
						||
                print(f"   URL: {data.get('url', 'N/A')}")
 | 
						||
                print(f"   WordPress版本: {data.get('gmt_offset', 'N/A')}")
 | 
						||
                return True
 | 
						||
            else:
 | 
						||
                print(f"❌ 连接失败: HTTP {response.status_code}")
 | 
						||
                return False
 | 
						||
        except requests.exceptions.RequestException as e:
 | 
						||
            print(f"❌ 连接错误: {e}")
 | 
						||
            return False
 | 
						||
    
 | 
						||
    def test_authentication(self):
 | 
						||
        """测试认证"""
 | 
						||
        print("\n🔐 测试用户认证...")
 | 
						||
        try:
 | 
						||
            response = requests.get(f"{self.api_url}/users/me", auth=self.auth, timeout=10)
 | 
						||
            if response.status_code == 200:
 | 
						||
                user_data = response.json()
 | 
						||
                print(f"✅ 认证成功!")
 | 
						||
                print(f"   用户ID: {user_data.get('id')}")
 | 
						||
                print(f"   用户名: {user_data.get('username')}")
 | 
						||
                print(f"   显示名称: {user_data.get('name')}")
 | 
						||
                print(f"   邮箱: {user_data.get('email')}")
 | 
						||
                print(f"   角色: {', '.join(user_data.get('roles', []))}")
 | 
						||
                return True
 | 
						||
            else:
 | 
						||
                print(f"❌ 认证失败: HTTP {response.status_code}")
 | 
						||
                if response.status_code == 401:
 | 
						||
                    print("   可能的原因: 用户名或应用密码错误")
 | 
						||
                elif response.status_code == 403:
 | 
						||
                    print("   可能的原因: 用户权限不足")
 | 
						||
                return False
 | 
						||
        except requests.exceptions.RequestException as e:
 | 
						||
            print(f"❌ 认证错误: {e}")
 | 
						||
            return False
 | 
						||
    
 | 
						||
    def test_posts_endpoint(self):
 | 
						||
        """测试文章端点"""
 | 
						||
        print("\n📝 测试文章端点...")
 | 
						||
        try:
 | 
						||
            # 获取文章列表
 | 
						||
            response = requests.get(f"{self.api_url}/posts?per_page=5", timeout=10)
 | 
						||
            if response.status_code == 200:
 | 
						||
                posts = response.json()
 | 
						||
                print(f"✅ 文章端点正常! 找到 {len(posts)} 篇文章")
 | 
						||
                for i, post in enumerate(posts[:3], 1):
 | 
						||
                    print(f"   {i}. {post.get('title', {}).get('rendered', 'N/A')} (ID: {post.get('id')})")
 | 
						||
                return True
 | 
						||
            else:
 | 
						||
                print(f"❌ 文章端点失败: HTTP {response.status_code}")
 | 
						||
                return False
 | 
						||
        except requests.exceptions.RequestException as e:
 | 
						||
            print(f"❌ 文章端点错误: {e}")
 | 
						||
            return False
 | 
						||
    
 | 
						||
    def test_categories_endpoint(self):
 | 
						||
        """测试分类端点"""
 | 
						||
        print("\n📂 测试分类端点...")
 | 
						||
        try:
 | 
						||
            response = requests.get(f"{self.api_url}/categories", timeout=10)
 | 
						||
            if response.status_code == 200:
 | 
						||
                categories = response.json()
 | 
						||
                print(f"✅ 分类端点正常! 找到 {len(categories)} 个分类")
 | 
						||
                for i, cat in enumerate(categories[:3], 1):
 | 
						||
                    print(f"   {i}. {cat.get('name')} (ID: {cat.get('id')}, 文章数: {cat.get('count')})")
 | 
						||
                return True
 | 
						||
            else:
 | 
						||
                print(f"❌ 分类端点失败: HTTP {response.status_code}")
 | 
						||
                return False
 | 
						||
        except requests.exceptions.RequestException as e:
 | 
						||
            print(f"❌ 分类端点错误: {e}")
 | 
						||
            return False
 | 
						||
    
 | 
						||
    def test_media_endpoint(self):
 | 
						||
        """测试媒体端点"""
 | 
						||
        print("\n🖼️ 测试媒体端点...")
 | 
						||
        try:
 | 
						||
            response = requests.get(f"{self.api_url}/media?per_page=5", timeout=10)
 | 
						||
            if response.status_code == 200:
 | 
						||
                media = response.json()
 | 
						||
                print(f"✅ 媒体端点正常! 找到 {len(media)} 个媒体文件")
 | 
						||
                for i, item in enumerate(media[:3], 1):
 | 
						||
                    print(f"   {i}. {item.get('title', {}).get('rendered', 'N/A')} (类型: {item.get('media_type')})")
 | 
						||
                return True
 | 
						||
            else:
 | 
						||
                print(f"❌ 媒体端点失败: HTTP {response.status_code}")
 | 
						||
                return False
 | 
						||
        except requests.exceptions.RequestException as e:
 | 
						||
            print(f"❌ 媒体端点错误: {e}")
 | 
						||
            return False
 | 
						||
    
 | 
						||
    def test_write_permissions(self):
 | 
						||
        """测试写入权限"""
 | 
						||
        print("\n✏️ 测试写入权限...")
 | 
						||
        try:
 | 
						||
            # 尝试创建一个测试文章草稿
 | 
						||
            test_post = {
 | 
						||
                'title': 'API测试文章 - 请删除',
 | 
						||
                'content': '这是一个API测试文章,可以安全删除。',
 | 
						||
                'status': 'draft'  # 草稿状态,不会公开发布
 | 
						||
            }
 | 
						||
            
 | 
						||
            response = requests.post(
 | 
						||
                f"{self.api_url}/posts",
 | 
						||
                json=test_post,
 | 
						||
                auth=self.auth,
 | 
						||
                timeout=10
 | 
						||
            )
 | 
						||
            
 | 
						||
            if response.status_code == 201:
 | 
						||
                created_post = response.json()
 | 
						||
                post_id = created_post.get('id')
 | 
						||
                print(f"✅ 写入权限正常! 创建了测试文章 (ID: {post_id})")
 | 
						||
                
 | 
						||
                # 立即删除测试文章
 | 
						||
                delete_response = requests.delete(
 | 
						||
                    f"{self.api_url}/posts/{post_id}?force=true",
 | 
						||
                    auth=self.auth,
 | 
						||
                    timeout=10
 | 
						||
                )
 | 
						||
                
 | 
						||
                if delete_response.status_code == 200:
 | 
						||
                    print(f"✅ 测试文章已清理 (ID: {post_id})")
 | 
						||
                else:
 | 
						||
                    print(f"⚠️ 测试文章创建成功但清理失败 (ID: {post_id}),请手动删除")
 | 
						||
                
 | 
						||
                return True
 | 
						||
            else:
 | 
						||
                print(f"❌ 写入权限测试失败: HTTP {response.status_code}")
 | 
						||
                if response.status_code == 401:
 | 
						||
                    print("   可能的原因: 认证失败")
 | 
						||
                elif response.status_code == 403:
 | 
						||
                    print("   可能的原因: 用户没有发布文章的权限")
 | 
						||
                return False
 | 
						||
                
 | 
						||
        except requests.exceptions.RequestException as e:
 | 
						||
            print(f"❌ 写入权限测试错误: {e}")
 | 
						||
            return False
 | 
						||
    
 | 
						||
    def run_all_tests(self):
 | 
						||
        """运行所有测试"""
 | 
						||
        print("🚀 开始 WordPress REST API 全面测试\n")
 | 
						||
        print(f"测试目标: {self.base_url}")
 | 
						||
        print(f"用户: {self.username}")
 | 
						||
        print("=" * 50)
 | 
						||
        
 | 
						||
        tests = [
 | 
						||
            self.test_connection,
 | 
						||
            self.test_authentication,
 | 
						||
            self.test_posts_endpoint,
 | 
						||
            self.test_categories_endpoint,
 | 
						||
            self.test_media_endpoint,
 | 
						||
            self.test_write_permissions
 | 
						||
        ]
 | 
						||
        
 | 
						||
        passed = 0
 | 
						||
        total = len(tests)
 | 
						||
        
 | 
						||
        for test in tests:
 | 
						||
            if test():
 | 
						||
                passed += 1
 | 
						||
        
 | 
						||
        print("\n" + "=" * 50)
 | 
						||
        print(f"📊 测试结果: {passed}/{total} 项测试通过")
 | 
						||
        
 | 
						||
        if passed == total:
 | 
						||
            print("🎉 所有测试通过! WordPress REST API 工作正常")
 | 
						||
        elif passed >= total * 0.8:
 | 
						||
            print("⚠️ 大部分测试通过,但有一些问题需要注意")
 | 
						||
        else:
 | 
						||
            print("❌ 多项测试失败,请检查配置和权限")
 | 
						||
        
 | 
						||
        return passed, total
 | 
						||
 | 
						||
def main():
 | 
						||
    """主函数"""
 | 
						||
    tester = WordPressAPITester(WP_URL, WP_USER, WP_APP_PASSWORD)
 | 
						||
    tester.run_all_tests()
 | 
						||
 | 
						||
if __name__ == "__main__":
 | 
						||
    main() |