package main import ( "bytes" "encoding/json" "io" "net/http" "testing" "git.x2erp.com/qdy/go-base/model/request/configreq" ) const ( testProjectID = "test-project-001" testDescription = "测试项目描述" testMcpURL = "http://localhost:8080/mcp" baseURL = "http://localhost:8080" ) // TestProjectCRUD 测试项目的增删改查 func TestProjectCRUD(t *testing.T) { // 1. 创建项目 t.Run("CreateProject", testCreateProject) // 2. 查询单个项目 t.Run("GetProject", testGetProject) // 3. 查询项目列表 t.Run("ListProjects", testListProjects) // 4. 更新项目 t.Run("UpdateProject", testUpdateProject) // 5. 查询更新后的项目 t.Run("GetUpdatedProject", testGetUpdatedProject) // 6. 删除项目 t.Run("DeleteProject", testDeleteProject) // 7. 验证项目已删除 t.Run("VerifyProjectDeleted", testVerifyProjectDeleted) } func testCreateProject(t *testing.T) { httpClient := &http.Client{} url := baseURL + "/api/create/config/project" reqBody := configreq.ProjectRequest{ ProjectID: testProjectID, Description: testDescription, McpURL: testMcpURL, } jsonData, err := json.Marshal(reqBody) if err != nil { t.Fatalf("JSON序列化失败: %v", err) } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { t.Fatalf("创建请求失败: %v", err) } // 使用Basic认证 req.SetBasicAuth("admin", "123") req.Header.Set("Content-Type", "application/json") resp, err := httpClient.Do(req) if err != nil { t.Fatalf("请求失败: %v", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("读取响应失败: %v", err) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { t.Fatalf("JSON解析失败: %v", err) } if success, ok := result["success"].(bool); !ok || !success { t.Errorf("创建项目失败: %v", result) } t.Logf("创建项目成功: %s", string(body)) } func testGetProject(t *testing.T) { httpClient := &http.Client{} url := baseURL + "/api/query/config/project/" + testProjectID req, err := http.NewRequest("POST", url, nil) if err != nil { t.Fatalf("创建请求失败: %v", err) } req.SetBasicAuth("admin", "123") req.Header.Set("Content-Type", "application/json") resp, err := httpClient.Do(req) if err != nil { t.Fatalf("请求失败: %v", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("读取响应失败: %v", err) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { t.Fatalf("JSON解析失败: %v", err) } if success, ok := result["success"].(bool); !ok || !success { t.Errorf("查询项目失败: %v", result) } // 验证项目信息 if data, ok := result["data"].(map[string]interface{}); ok { if projectID, ok := data["ProjectID"].(string); !ok || projectID != testProjectID { t.Errorf("项目ID不匹配: 期望 %s, 实际 %v", testProjectID, data["ProjectID"]) } if description, ok := data["Description"].(string); !ok || description != testDescription { t.Errorf("项目描述不匹配: 期望 %s, 实际 %v", testDescription, data["Description"]) } if mcpURL, ok := data["McpURL"].(string); !ok || mcpURL != testMcpURL { t.Errorf("MCP URL不匹配: 期望 %s, 实际 %v", testMcpURL, data["McpURL"]) } } t.Logf("查询项目成功: %s", string(body)) } func testListProjects(t *testing.T) { httpClient := &http.Client{} url := baseURL + "/api/query/config/projects" req, err := http.NewRequest("POST", url, nil) if err != nil { t.Fatalf("创建请求失败: %v", err) } req.SetBasicAuth("admin", "123") req.Header.Set("Content-Type", "application/json") resp, err := httpClient.Do(req) if err != nil { t.Fatalf("请求失败: %v", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("读取响应失败: %v", err) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { t.Fatalf("JSON解析失败: %v", err) } if success, ok := result["success"].(bool); !ok || !success { t.Errorf("查询项目列表失败: %v", result) } // 验证返回的项目列表包含测试项目 if count, ok := result["count"].(float64); !ok || count < 1 { t.Errorf("项目列表为空或计数错误: %v", result) } t.Logf("查询项目列表成功: %s", string(body)) } func testUpdateProject(t *testing.T) { httpClient := &http.Client{} url := baseURL + "/api/update/config/project/" + testProjectID updatedReq := configreq.ProjectRequest{ ProjectID: testProjectID, Description: "更新后的描述", McpURL: "http://localhost:9090/mcp", } jsonData, err := json.Marshal(updatedReq) if err != nil { t.Fatalf("JSON序列化失败: %v", err) } req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData)) if err != nil { t.Fatalf("创建请求失败: %v", err) } req.SetBasicAuth("admin", "123") req.Header.Set("Content-Type", "application/json") resp, err := httpClient.Do(req) if err != nil { t.Fatalf("请求失败: %v", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("读取响应失败: %v", err) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { t.Fatalf("JSON解析失败: %v", err) } if success, ok := result["success"].(bool); !ok || !success { t.Errorf("更新项目失败: %v", result) } t.Logf("更新项目成功: %s", string(body)) } func testGetUpdatedProject(t *testing.T) { httpClient := &http.Client{} url := baseURL + "/api/query/config/project/" + testProjectID req, err := http.NewRequest("POST", url, nil) if err != nil { t.Fatalf("创建请求失败: %v", err) } req.SetBasicAuth("admin", "123") req.Header.Set("Content-Type", "application/json") resp, err := httpClient.Do(req) if err != nil { t.Fatalf("请求失败: %v", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("读取响应失败: %v", err) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { t.Fatalf("JSON解析失败: %v", err) } if success, ok := result["success"].(bool); !ok || !success { t.Errorf("查询更新后的项目失败: %v", result) } // 验证更新后的信息 if data, ok := result["data"].(map[string]interface{}); ok { if description, ok := data["Description"].(string); !ok || description != "更新后的描述" { t.Errorf("项目描述未更新: 期望 '更新后的描述', 实际 %v", data["Description"]) } if mcpURL, ok := data["McpURL"].(string); !ok || mcpURL != "http://localhost:9090/mcp" { t.Errorf("MCP URL未更新: 期望 'http://localhost:9090/mcp', 实际 %v", data["McpURL"]) } } t.Logf("查询更新后的项目成功: %s", string(body)) } func testDeleteProject(t *testing.T) { httpClient := &http.Client{} url := baseURL + "/api/delete/config/project/" + testProjectID req, err := http.NewRequest("POST", url, nil) if err != nil { t.Fatalf("创建请求失败: %v", err) } // 删除操作使用Basic认证 req.Header.Set("Authorization", "Basic YWRtaW46MTIz") // test:test req.Header.Set("Content-Type", "application/json") resp, err := httpClient.Do(req) if err != nil { t.Fatalf("请求失败: %v", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("读取响应失败: %v", err) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { t.Fatalf("JSON解析失败: %v", err) } if success, ok := result["success"].(bool); !ok || !success { t.Errorf("删除项目失败: %v", result) } t.Logf("删除项目成功: %s", string(body)) } func testVerifyProjectDeleted(t *testing.T) { httpClient := &http.Client{} url := baseURL + "/api/query/config/project/" + testProjectID req, err := http.NewRequest("POST", url, nil) if err != nil { t.Fatalf("创建请求失败: %v", err) } req.SetBasicAuth("admin", "123") req.Header.Set("Content-Type", "application/json") resp, err := httpClient.Do(req) if err != nil { t.Fatalf("请求失败: %v", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { t.Fatalf("读取响应失败: %v", err) } var result map[string]interface{} if err := json.Unmarshal(body, &result); err != nil { t.Fatalf("JSON解析失败: %v", err) } // 期望查询失败,因为项目已删除 if success, ok := result["success"].(bool); ok && success { t.Errorf("项目删除验证失败: 项目仍存在") } t.Logf("项目删除验证成功: 项目已不存在") }