### Photography Portfolio API 综合测试套件 ### 包含所有接口的完整测试用例 @baseUrl = http://localhost:8080/api/v1 @token = ### =============================================== ### 健康检查接口测试 ### =============================================== ### 1. 健康检查 - 基础测试 GET {{baseUrl}}/health Content-Type: application/json ### =============================================== ### 认证接口测试 ### =============================================== ### 2. 用户注册 - 正常场景 POST {{baseUrl}}/auth/register Content-Type: application/json { "username": "testuser_{{$timestamp}}", "email": "test{{$timestamp}}@example.com", "password": "testpass123" } ### 3. 用户注册 - 重复用户名 POST {{baseUrl}}/auth/register Content-Type: application/json { "username": "admin", "email": "admin2@example.com", "password": "testpass123" } ### 4. 用户注册 - 无效邮箱 POST {{baseUrl}}/auth/register Content-Type: application/json { "username": "testuser2", "email": "invalid-email", "password": "testpass123" } ### 5. 用户注册 - 密码过短 POST {{baseUrl}}/auth/register Content-Type: application/json { "username": "testuser3", "email": "test3@example.com", "password": "123" } ### 6. 用户登录 - 正常场景 POST {{baseUrl}}/auth/login Content-Type: application/json { "username": "admin", "password": "admin123" } ### 7. 用户登录 - 使用邮箱 POST {{baseUrl}}/auth/login Content-Type: application/json { "username": "admin@photography.com", "password": "admin123" } ### 8. 用户登录 - 错误密码 POST {{baseUrl}}/auth/login Content-Type: application/json { "username": "admin", "password": "wrongpassword" } ### 9. 用户登录 - 不存在的用户 POST {{baseUrl}}/auth/login Content-Type: application/json { "username": "nonexistent", "password": "password123" } ### =============================================== ### 用户管理接口测试 (需要认证) ### =============================================== ### 10. 获取用户列表 - 无认证 GET {{baseUrl}}/users Content-Type: application/json ### 11. 获取用户列表 - 有认证 GET {{baseUrl}}/users Content-Type: application/json Authorization: Bearer {{token}} ### 12. 获取用户列表 - 分页参数 GET {{baseUrl}}/users?page=1&limit=5&status=1 Content-Type: application/json Authorization: Bearer {{token}} ### 13. 获取用户列表 - 搜索关键词 GET {{baseUrl}}/users?keyword=admin Content-Type: application/json Authorization: Bearer {{token}} ### 14. 获取用户详情 - 存在的用户 GET {{baseUrl}}/users/1 Content-Type: application/json Authorization: Bearer {{token}} ### 15. 获取用户详情 - 不存在的用户 GET {{baseUrl}}/users/99999 Content-Type: application/json Authorization: Bearer {{token}} ### 16. 创建用户 - 正常场景 POST {{baseUrl}}/users Content-Type: application/json Authorization: Bearer {{token}} { "username": "newuser_{{$timestamp}}", "email": "newuser{{$timestamp}}@example.com", "password": "newpass123", "status": 1 } ### 17. 创建用户 - 重复用户名 POST {{baseUrl}}/users Content-Type: application/json Authorization: Bearer {{token}} { "username": "admin", "email": "admin3@example.com", "password": "newpass123" } ### 18. 创建用户 - 缺少必填字段 POST {{baseUrl}}/users Content-Type: application/json Authorization: Bearer {{token}} { "username": "incompleteuser", "password": "newpass123" } ### 19. 更新用户 - 正常场景 PUT {{baseUrl}}/users/1 Content-Type: application/json Authorization: Bearer {{token}} { "username": "admin_updated", "email": "admin_updated@photography.com" } ### 20. 更新用户 - 不存在的用户 PUT {{baseUrl}}/users/99999 Content-Type: application/json Authorization: Bearer {{token}} { "username": "nonexistent_user", "email": "nonexistent@example.com" } ### 21. 删除用户 - 存在的用户 DELETE {{baseUrl}}/users/2 Content-Type: application/json Authorization: Bearer {{token}} ### 22. 删除用户 - 不存在的用户 DELETE {{baseUrl}}/users/99999 Content-Type: application/json Authorization: Bearer {{token}} ### 23. 用户头像上传 - 正常场景 POST {{baseUrl}}/users/1/avatar Authorization: Bearer {{token}} Content-Type: multipart/form-data; boundary=boundary --boundary Content-Disposition: form-data; name="file"; filename="avatar.jpg" Content-Type: image/jpeg < ./test_images/avatar.jpg --boundary-- ### 24. 用户头像上传 - 无文件 POST {{baseUrl}}/users/1/avatar Authorization: Bearer {{token}} Content-Type: multipart/form-data; boundary=boundary --boundary Content-Disposition: form-data; name="title" Test Avatar --boundary-- ### 25. 用户头像上传 - 非图片文件 POST {{baseUrl}}/users/1/avatar Authorization: Bearer {{token}} Content-Type: multipart/form-data; boundary=boundary --boundary Content-Disposition: form-data; name="file"; filename="document.txt" Content-Type: text/plain This is not an image file --boundary-- ### =============================================== ### 分类管理接口测试 ### =============================================== ### 26. 获取分类列表 - 基础查询 GET {{baseUrl}}/categories Content-Type: application/json ### 27. 获取分类列表 - 包含统计 GET {{baseUrl}}/categories?with_count=true Content-Type: application/json ### 28. 获取分类列表 - 按状态筛选 GET {{baseUrl}}/categories?is_active=1 Content-Type: application/json ### 29. 获取分类详情 - 存在的分类 GET {{baseUrl}}/categories/1 Content-Type: application/json ### 30. 获取分类详情 - 不存在的分类 GET {{baseUrl}}/categories/99999 Content-Type: application/json ### 31. 创建分类 - 正常场景 POST {{baseUrl}}/categories Content-Type: application/json Authorization: Bearer {{token}} { "name": "测试分类_{{$timestamp}}", "description": "这是一个测试分类", "sort_order": 1, "is_active": 1 } ### 32. 创建分类 - 缺少名称 POST {{baseUrl}}/categories Content-Type: application/json Authorization: Bearer {{token}} { "description": "没有名称的分类", "sort_order": 1 } ### 33. 创建子分类 - 正常场景 POST {{baseUrl}}/categories Content-Type: application/json Authorization: Bearer {{token}} { "name": "子分类_{{$timestamp}}", "description": "这是一个子分类", "parent_id": 1, "sort_order": 1, "is_active": 1 } ### 34. 创建子分类 - 父分类不存在 POST {{baseUrl}}/categories Content-Type: application/json Authorization: Bearer {{token}} { "name": "子分类2", "description": "父分类不存在的子分类", "parent_id": 99999, "sort_order": 1 } ### 35. 更新分类 - 正常场景 PUT {{baseUrl}}/categories/1 Content-Type: application/json Authorization: Bearer {{token}} { "name": "更新的风景分类", "description": "更新后的自然风光和城市景观", "sort_order": 2 } ### 36. 更新分类 - 不存在的分类 PUT {{baseUrl}}/categories/99999 Content-Type: application/json Authorization: Bearer {{token}} { "name": "不存在的分类", "description": "这个分类不存在" } ### 37. 删除分类 - 存在的分类 DELETE {{baseUrl}}/categories/3 Content-Type: application/json Authorization: Bearer {{token}} ### 38. 删除分类 - 不存在的分类 DELETE {{baseUrl}}/categories/99999 Content-Type: application/json Authorization: Bearer {{token}} ### =============================================== ### 照片管理接口测试 ### =============================================== ### 39. 获取照片列表 - 基础查询 GET {{baseUrl}}/photos Content-Type: application/json ### 40. 获取照片列表 - 分页参数 GET {{baseUrl}}/photos?page=1&limit=5 Content-Type: application/json ### 41. 获取照片列表 - 按分类筛选 GET {{baseUrl}}/photos?category_id=1 Content-Type: application/json ### 42. 获取照片列表 - 按用户筛选 GET {{baseUrl}}/photos?user_id=1 Content-Type: application/json ### 43. 获取照片列表 - 按状态筛选 GET {{baseUrl}}/photos?status=1 Content-Type: application/json ### 44. 获取照片列表 - 关键词搜索 GET {{baseUrl}}/photos?keyword=日落 Content-Type: application/json ### 45. 获取照片列表 - 排序 GET {{baseUrl}}/photos?sort=created_at_desc Content-Type: application/json ### 46. 获取照片列表 - 复合条件 GET {{baseUrl}}/photos?category_id=1&status=1&sort=title_asc&page=1&limit=10 Content-Type: application/json ### 47. 获取照片详情 - 存在的照片 GET {{baseUrl}}/photos/1 Content-Type: application/json ### 48. 获取照片详情 - 不存在的照片 GET {{baseUrl}}/photos/99999 Content-Type: application/json ### 49. 上传照片 - 正常场景 POST {{baseUrl}}/photos Authorization: Bearer {{token}} Content-Type: multipart/form-data; boundary=boundary --boundary Content-Disposition: form-data; name="file"; filename="test_photo.jpg" Content-Type: image/jpeg < ./test_images/test_photo.jpg --boundary Content-Disposition: form-data; name="title" 测试照片_{{$timestamp}} --boundary Content-Disposition: form-data; name="description" 这是一个测试照片的描述 --boundary Content-Disposition: form-data; name="category_id" 1 --boundary-- ### 50. 上传照片 - 无文件 POST {{baseUrl}}/photos Authorization: Bearer {{token}} Content-Type: multipart/form-data; boundary=boundary --boundary Content-Disposition: form-data; name="title" 无文件的照片 --boundary Content-Disposition: form-data; name="description" 这个请求没有文件 --boundary-- ### 51. 上传照片 - 非图片文件 POST {{baseUrl}}/photos Authorization: Bearer {{token}} Content-Type: multipart/form-data; boundary=boundary --boundary Content-Disposition: form-data; name="file"; filename="document.pdf" Content-Type: application/pdf This is not an image --boundary Content-Disposition: form-data; name="title" PDF文件测试 --boundary-- ### 52. 上传照片 - 文件过大 POST {{baseUrl}}/photos Authorization: Bearer {{token}} Content-Type: multipart/form-data; boundary=boundary --boundary Content-Disposition: form-data; name="file"; filename="large_image.jpg" Content-Type: image/jpeg < ./test_images/large_image.jpg --boundary Content-Disposition: form-data; name="title" 大文件测试 --boundary-- ### 53. 更新照片 - 正常场景 PUT {{baseUrl}}/photos/1 Content-Type: application/json Authorization: Bearer {{token}} { "title": "更新的照片标题", "description": "更新的照片描述", "category_id": 2, "status": 1 } ### 54. 更新照片 - 不存在的照片 PUT {{baseUrl}}/photos/99999 Content-Type: application/json Authorization: Bearer {{token}} { "title": "不存在的照片", "description": "这个照片不存在" } ### 55. 更新照片 - 权限不足(尝试更新其他用户的照片) PUT {{baseUrl}}/photos/2 Content-Type: application/json Authorization: Bearer {{token}} { "title": "试图更新他人照片", "description": "应该被拒绝" } ### 56. 删除照片 - 存在的照片 DELETE {{baseUrl}}/photos/1 Content-Type: application/json Authorization: Bearer {{token}} ### 57. 删除照片 - 不存在的照片 DELETE {{baseUrl}}/photos/99999 Content-Type: application/json Authorization: Bearer {{token}} ### 58. 删除照片 - 权限不足 DELETE {{baseUrl}}/photos/3 Content-Type: application/json Authorization: Bearer {{token}} ### =============================================== ### 静态文件访问测试 ### =============================================== ### 59. 访问照片原图 GET {{baseUrl}}/../../uploads/photos/test_image_1752197561_34895178.jpg ### 60. 访问照片缩略图 GET {{baseUrl}}/../../uploads/photos/thumbs/test_image_1752197561_34895178_thumb.jpg ### 61. 访问用户头像 GET {{baseUrl}}/../../uploads/avatars/1.jpg ### 62. 访问不存在的文件 GET {{baseUrl}}/../../uploads/photos/nonexistent.jpg ### =============================================== ### 错误处理测试 ### =============================================== ### 63. 访问不存在的端点 GET {{baseUrl}}/nonexistent Content-Type: application/json ### 64. 使用错误的HTTP方法 POST {{baseUrl}}/health Content-Type: application/json ### 65. 发送无效JSON POST {{baseUrl}}/auth/login Content-Type: application/json { "username": "test", "password": "test" // 这是无效的JSON注释 } ### 66. 发送超大请求体 POST {{baseUrl}}/auth/login Content-Type: application/json { "username": "test", "password": "{{$randomWords}}{{$randomWords}}{{$randomWords}}{{$randomWords}}{{$randomWords}}{{$randomWords}}{{$randomWords}}{{$randomWords}}{{$randomWords}}{{$randomWords}}" } ### 67. 使用无效Token GET {{baseUrl}}/users Content-Type: application/json Authorization: Bearer invalid_token_here ### 68. 使用过期Token GET {{baseUrl}}/users Content-Type: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c ### =============================================== ### 性能测试 ### =============================================== ### 69. 大量数据查询 GET {{baseUrl}}/photos?limit=1000 Content-Type: application/json ### 70. 并发请求测试 (运行多次) GET {{baseUrl}}/health Content-Type: application/json ### 71. 复杂查询 GET {{baseUrl}}/photos?category_id=1&status=1&keyword=测试&sort=created_at_desc&page=1&limit=50 Content-Type: application/json ### =============================================== ### 中间件测试 ### =============================================== ### 72. CORS预检请求 OPTIONS {{baseUrl}}/photos Origin: http://localhost:3000 Access-Control-Request-Method: POST Access-Control-Request-Headers: Content-Type, Authorization ### 73. CORS实际请求 GET {{baseUrl}}/photos Origin: http://localhost:3000 ### 74. 非法来源CORS GET {{baseUrl}}/photos Origin: http://malicious-site.com ### 75. 请求ID跟踪 GET {{baseUrl}}/health X-Request-ID: test-request-123 ### =============================================== ### 边界条件测试 ### =============================================== ### 76. 空字符串参数 GET {{baseUrl}}/photos?keyword= Content-Type: application/json ### 77. 负数页码 GET {{baseUrl}}/photos?page=-1 Content-Type: application/json ### 78. 零页码 GET {{baseUrl}}/photos?page=0 Content-Type: application/json ### 79. 超大页码 GET {{baseUrl}}/photos?page=999999 Content-Type: application/json ### 80. 超大limit GET {{baseUrl}}/photos?limit=10000 Content-Type: application/json ### 81. SQL注入尝试 GET {{baseUrl}}/photos?keyword=' OR 1=1 -- Content-Type: application/json ### 82. XSS尝试 POST {{baseUrl}}/categories Content-Type: application/json Authorization: Bearer {{token}} { "name": "", "description": "XSS测试分类" } ### =============================================== ### 综合业务流程测试 ### =============================================== ### 83. 完整用户注册登录流程 POST {{baseUrl}}/auth/register Content-Type: application/json { "username": "workflow_user", "email": "workflow@example.com", "password": "workflow123" } ### 84. 登录获取Token POST {{baseUrl}}/auth/login Content-Type: application/json { "username": "workflow_user", "password": "workflow123" } ### 85. 创建分类 POST {{baseUrl}}/categories Content-Type: application/json Authorization: Bearer {{token}} { "name": "工作流测试分类", "description": "用于测试完整工作流的分类" } ### 86. 上传照片到分类 POST {{baseUrl}}/photos Authorization: Bearer {{token}} Content-Type: multipart/form-data; boundary=boundary --boundary Content-Disposition: form-data; name="file"; filename="workflow_photo.jpg" Content-Type: image/jpeg < ./test_images/workflow_photo.jpg --boundary Content-Disposition: form-data; name="title" 工作流测试照片 --boundary Content-Disposition: form-data; name="description" 这是工作流测试上传的照片 --boundary Content-Disposition: form-data; name="category_id" 1 --boundary-- ### 87. 查看上传的照片 GET {{baseUrl}}/photos?user_id=1&keyword=工作流 Content-Type: application/json ### 88. 更新照片信息 PUT {{baseUrl}}/photos/1 Content-Type: application/json Authorization: Bearer {{token}} { "title": "更新的工作流测试照片", "description": "已更新的照片描述" } ### 89. 最终验证 GET {{baseUrl}}/photos/1 Content-Type: application/json ### =============================================== ### 清理测试数据 (可选) ### =============================================== ### 90. 删除测试照片 DELETE {{baseUrl}}/photos/1 Content-Type: application/json Authorization: Bearer {{token}} ### 91. 删除测试分类 DELETE {{baseUrl}}/categories/1 Content-Type: application/json Authorization: Bearer {{token}} ### 92. 删除测试用户 DELETE {{baseUrl}}/users/2 Content-Type: application/json Authorization: Bearer {{token}} ### =============================================== ### 测试完成 ### =============================================== ### 测试完成 - 健康检查 GET {{baseUrl}}/health Content-Type: application/json