236 lines
8.7 KiB
Go
236 lines
8.7 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"net/http"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
// API测试结构
|
||
type APITest struct {
|
||
Name string
|
||
Method string
|
||
URL string
|
||
Headers map[string]string
|
||
Body string
|
||
Expected int // 期望的HTTP状态码
|
||
}
|
||
|
||
// 响应结构
|
||
type Response struct {
|
||
Code int `json:"code"`
|
||
Message string `json:"message"`
|
||
Data interface{} `json:"data"`
|
||
}
|
||
|
||
func main() {
|
||
baseURL := "http://localhost:16001"
|
||
|
||
// 定义所有需要测试的API
|
||
tests := []APITest{
|
||
// 用户端API
|
||
{Name: "用户注册", Method: "POST", URL: "/api/v1/auth/auth/register", Expected: 200},
|
||
{Name: "用户登录", Method: "POST", URL: "/api/v1/auth/auth/login", Expected: 200},
|
||
{Name: "获取用户信息", Method: "GET", URL: "/api/v1/auth/auth/profile", Expected: 200},
|
||
{Name: "更新用户信息", Method: "POST", URL: "/api/v1/auth/auth/profile", Expected: 200},
|
||
{Name: "刷新令牌", Method: "POST", URL: "/api/v1/auth/auth/refresh", Expected: 200},
|
||
{Name: "用户退出", Method: "POST", URL: "/api/v1/auth/auth/logout", Expected: 200},
|
||
|
||
// 影片相关API
|
||
{Name: "获取影片列表", Method: "GET", URL: "/api/v1/movies", Expected: 200},
|
||
{Name: "获取影片详情", Method: "GET", URL: "/api/v1/movies/1", Expected: 200},
|
||
{Name: "搜索影片", Method: "GET", URL: "/api/v1/movies/search?keyword=test", Expected: 200},
|
||
{Name: "获取推荐影片", Method: "GET", URL: "/api/v1/movies/recommend", Expected: 200},
|
||
{Name: "获取热门影片", Method: "GET", URL: "/api/v1/movies/hot", Expected: 200},
|
||
{Name: "获取最新影片", Method: "GET", URL: "/api/v1/movies/new", Expected: 200},
|
||
{Name: "按分类获取影片", Method: "GET", URL: "/api/v1/movies/category/1", Expected: 200},
|
||
|
||
// 集数相关API
|
||
{Name: "获取影片集数", Method: "GET", URL: "/api/v1/episodes/movie/1", Expected: 200},
|
||
{Name: "获取集数详情", Method: "GET", URL: "/api/v1/episodes/1", Expected: 200},
|
||
{Name: "获取视频信息", Method: "GET", URL: "/api/v1/episodes/video/info", Expected: 200},
|
||
|
||
// 用户收藏API
|
||
{Name: "添加收藏", Method: "POST", URL: "/api/v1/user/collect/add", Expected: 200},
|
||
{Name: "取消收藏", Method: "POST", URL: "/api/v1/user/collect/remove", Expected: 200},
|
||
{Name: "获取收藏列表", Method: "GET", URL: "/api/v1/user/collect/list", Expected: 200},
|
||
{Name: "检查收藏状态", Method: "GET", URL: "/api/v1/user/collect/check", Expected: 200},
|
||
|
||
// 观看历史API
|
||
{Name: "添加观看记录", Method: "POST", URL: "/api/v1/user/history/add", Expected: 200},
|
||
{Name: "获取观看历史", Method: "GET", URL: "/api/v1/user/history/list", Expected: 200},
|
||
{Name: "获取观看记录", Method: "GET", URL: "/api/v1/user/history/get", Expected: 200},
|
||
{Name: "删除观看记录", Method: "POST", URL: "/api/v1/user/history/delete", Expected: 200},
|
||
{Name: "清空观看历史", Method: "POST", URL: "/api/v1/user/history/clear", Expected: 200},
|
||
|
||
// 轮播图API
|
||
{Name: "获取轮播图", Method: "GET", URL: "/api/v1/banner/list", Expected: 200},
|
||
|
||
// VIP相关API
|
||
{Name: "获取VIP等级", Method: "GET", URL: "/api/v1/vip/levels", Expected: 200},
|
||
{Name: "获取我的VIP", Method: "GET", URL: "/api/v1/vip/my", Expected: 200},
|
||
|
||
// 订单相关API
|
||
{Name: "创建订单", Method: "POST", URL: "/api/v1/payment/create", Expected: 200},
|
||
{Name: "获取订单列表", Method: "GET", URL: "/api/v1/payment/list", Expected: 200},
|
||
{Name: "获取订单详情", Method: "GET", URL: "/api/v1/payment/1", Expected: 200},
|
||
|
||
// 附件相关API
|
||
{Name: "上传附件", Method: "POST", URL: "/api/v1/attachment/upload", Expected: 200},
|
||
{Name: "获取附件列表", Method: "GET", URL: "/api/v1/attachment/list", Expected: 200},
|
||
|
||
// 配置相关API
|
||
{Name: "获取公共配置", Method: "GET", URL: "/api/v1/config/public", Expected: 200},
|
||
|
||
// 日志相关API
|
||
{Name: "获取我的日志", Method: "GET", URL: "/api/v1/log/my", Expected: 200},
|
||
|
||
// 管理员端API
|
||
{Name: "管理员注册", Method: "POST", URL: "/api/v1/admin/register", Expected: 200},
|
||
{Name: "管理员登录", Method: "POST", URL: "/api/v1/admin/login", Expected: 200},
|
||
{Name: "获取管理员信息", Method: "GET", URL: "/api/v1/admin/profile", Expected: 200},
|
||
{Name: "更新管理员信息", Method: "POST", URL: "/api/v1/admin/profile", Expected: 200},
|
||
{Name: "刷新管理员令牌", Method: "POST", URL: "/api/v1/admin/refresh", Expected: 200},
|
||
{Name: "管理员退出", Method: "POST", URL: "/api/v1/admin/logout", Expected: 200},
|
||
|
||
// 管理员-影片管理
|
||
{Name: "管理员创建影片", Method: "POST", URL: "/api/v1/movies", Expected: 200},
|
||
{Name: "管理员更新影片", Method: "POST", URL: "/api/v1/movies/update", Expected: 200},
|
||
{Name: "管理员批量更新影片", Method: "POST", URL: "/api/v1/movies/batch-update", Expected: 200},
|
||
{Name: "管理员删除影片", Method: "DELETE", URL: "/api/v1/movies/1", Expected: 200},
|
||
{Name: "管理员上传海报", Method: "POST", URL: "/api/v1/movies/upload/poster", Expected: 200},
|
||
{Name: "管理员上传视频", Method: "POST", URL: "/api/v1/movies/upload/video", Expected: 200},
|
||
|
||
// 管理员-集数管理
|
||
{Name: "管理员创建集数", Method: "POST", URL: "/api/v1/episodes", Expected: 200},
|
||
{Name: "管理员更新集数", Method: "POST", URL: "/api/v1/episodes/update", Expected: 200},
|
||
{Name: "管理员批量创建集数", Method: "POST", URL: "/api/v1/episodes/batch", Expected: 200},
|
||
{Name: "管理员批量更新状态", Method: "POST", URL: "/api/v1/episodes/batch-status", Expected: 200},
|
||
{Name: "管理员删除集数", Method: "DELETE", URL: "/api/v1/episodes/1", Expected: 200},
|
||
{Name: "管理员上传视频", Method: "POST", URL: "/api/v1/episodes/upload/video", Expected: 200},
|
||
{Name: "管理员生成缩略图", Method: "POST", URL: "/api/v1/episodes/thumbnail", Expected: 200},
|
||
}
|
||
|
||
fmt.Println("开始测试API接口...")
|
||
fmt.Println(strings.Repeat("=", 60))
|
||
|
||
successCount := 0
|
||
failCount := 0
|
||
|
||
for i, test := range tests {
|
||
fmt.Printf("[%d/%d] 测试: %s\n", i+1, len(tests), test.Name)
|
||
|
||
success := testAPI(baseURL+test.URL, test.Method, test.Headers, test.Body, test.Expected)
|
||
if success {
|
||
fmt.Printf("✅ 成功\n")
|
||
successCount++
|
||
} else {
|
||
fmt.Printf("❌ 失败\n")
|
||
failCount++
|
||
}
|
||
fmt.Println()
|
||
|
||
// 避免请求过快
|
||
time.Sleep(100 * time.Millisecond)
|
||
}
|
||
|
||
fmt.Println(strings.Repeat("=", 60))
|
||
fmt.Printf("测试完成!成功: %d, 失败: %d, 总计: %d\n", successCount, failCount, len(tests))
|
||
|
||
if failCount == 0 {
|
||
fmt.Println("🎉 所有API接口测试通过!")
|
||
} else {
|
||
fmt.Printf("⚠️ 有 %d 个接口测试失败,请检查相关代码\n", failCount)
|
||
}
|
||
}
|
||
|
||
func testAPI(url, method string, headers map[string]string, body string, expectedStatus int) bool {
|
||
client := &http.Client{
|
||
Timeout: 10 * time.Second,
|
||
}
|
||
|
||
var req *http.Request
|
||
var err error
|
||
|
||
if body != "" {
|
||
req, err = http.NewRequest(method, url, strings.NewReader(body))
|
||
} else {
|
||
req, err = http.NewRequest(method, url, nil)
|
||
}
|
||
|
||
if err != nil {
|
||
fmt.Printf("创建请求失败: %v\n", err)
|
||
return false
|
||
}
|
||
|
||
// 设置默认头部
|
||
req.Header.Set("Content-Type", "application/json")
|
||
req.Header.Set("User-Agent", "API-Test-Client/1.0")
|
||
|
||
// 设置自定义头部
|
||
for key, value := range headers {
|
||
req.Header.Set(key, value)
|
||
}
|
||
|
||
resp, err := client.Do(req)
|
||
if err != nil {
|
||
fmt.Printf("请求失败: %v\n", err)
|
||
return false
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
// 读取响应体
|
||
respBody, err := io.ReadAll(resp.Body)
|
||
if err != nil {
|
||
fmt.Printf("读取响应失败: %v\n", err)
|
||
return false
|
||
}
|
||
|
||
// 检查HTTP状态码
|
||
if resp.StatusCode != expectedStatus {
|
||
fmt.Printf("HTTP状态码不匹配: 期望 %d, 实际 %d\n", expectedStatus, resp.StatusCode)
|
||
fmt.Printf("响应内容: %s\n", string(respBody))
|
||
return false
|
||
}
|
||
|
||
// 尝试解析JSON响应
|
||
var response Response
|
||
if err := json.Unmarshal(respBody, &response); err != nil {
|
||
fmt.Printf("JSON解析失败: %v\n", err)
|
||
fmt.Printf("响应内容: %s\n", string(respBody))
|
||
return false
|
||
}
|
||
|
||
// 检查业务逻辑响应码
|
||
if response.Code != 0 && response.Code != 200 {
|
||
fmt.Printf("业务错误码: %d, 消息: %s\n", response.Code, response.Message)
|
||
// 对于某些预期的错误(如未登录、数据不存在等),不算作失败
|
||
if isExpectedError(response.Code) {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
fmt.Printf("✅ 响应正常: %s\n", response.Message)
|
||
return true
|
||
}
|
||
|
||
// 判断是否为预期的错误码
|
||
func isExpectedError(code int) bool {
|
||
expectedErrors := []int{
|
||
401, // 未登录
|
||
404, // 数据不存在
|
||
403, // 权限不足
|
||
400, // 参数错误
|
||
}
|
||
|
||
for _, expectedCode := range expectedErrors {
|
||
if code == expectedCode {
|
||
return true
|
||
}
|
||
}
|
||
return false
|
||
} |