package controller import ( "net/http" "net/http/httptest" "strconv" "testing" "time" "ezops/model" "github.com/gin-gonic/gin" "github.com/glebarez/sqlite" "gorm.io/gorm" ) func TestDeleteAgentCLISessionRetainsExecutionAudit(t *testing.T) { gin.SetMode(gin.TestMode) db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) if err != nil { t.Fatalf("打开测试数据库失败: %v", err) } if err := db.AutoMigrate(&model.AIRun{}, &model.AIRunMessage{}, &model.AIRunSpan{}, &model.OpsCommand{}); err != nil { t.Fatalf("创建测试表失败: %v", err) } run := model.AIRun{RunID: "run-delete-audit", UserID: 7, Feature: "agent_cli", StartedAt: time.Now()} if err := db.Create(&run).Error; err != nil { t.Fatalf("创建会话失败: %v", err) } db.Create(&model.AIRunMessage{RunID: run.RunID, Role: "tool", Type: "tool_result", Content: "ok"}) db.Create(&model.AIRunSpan{RunID: run.RunID, SpanID: "span-delete-audit", Kind: "tool", Name: "ssh_execute", StartedAt: time.Now()}) db.Create(&model.OpsCommand{RunID: run.RunID, CommandID: "cmd-delete-audit", UserID: 7, Command: "uptime", ExecutedAt: time.Now()}) router := gin.New() router.DELETE("/sessions/:id", func(c *gin.Context) { c.Set("userID", uint(7)) NewAgentCLIHandler(db).DeleteSession(c) }) recorder := httptest.NewRecorder() router.ServeHTTP(recorder, httptest.NewRequest(http.MethodDelete, "/sessions/"+strconv.FormatUint(uint64(run.ID), 10), nil)) if recorder.Code != http.StatusOK { t.Fatalf("删除响应状态=%d, body=%s", recorder.Code, recorder.Body.String()) } assertCount := func(name string, target interface{}, want int64) { t.Helper() var count int64 if err := db.Model(target).Where("run_id = ?", run.RunID).Count(&count).Error; err != nil { t.Fatalf("查询 %s 失败: %v", name, err) } if count != want { t.Fatalf("%s 数量=%d, want %d", name, count, want) } } assertCount("消息", &model.AIRunMessage{}, 0) assertCount("Span", &model.AIRunSpan{}, 1) assertCount("命令审计", &model.OpsCommand{}, 1) }