feat(agent): 运行详情分页与增量读取契约 (#600)

Co-authored-by: ddcat666 <26564566+ddcat666@users.noreply.github.com>
This commit is contained in:
AetherNo2332
2026-09-24 11:31:09 +08:00
committed by ddcat666
parent c4b9a426ab
commit b701b3efd1
11 changed files with 761 additions and 25 deletions

View File

@@ -0,0 +1,63 @@
package handler
import (
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
// 运行详情分页参数(?sinceSeq= / ?eventLimit=)。合法值按原样进入视图选项,
// 非法或越界一律拒绝:静默夹取会让客户端以为拿到的是它请求的那一页,
// 从而把缺口当成"没有更多记录"。
func TestAgentRunViewOptionsParsesPaginationQuery(t *testing.T) {
gin.SetMode(gin.TestMode)
for _, testCase := range []struct {
query string
wantSinceSeq, wantEventLimit int
}{
{query: "", wantSinceSeq: 0, wantEventLimit: 0},
{query: "?sinceSeq=0", wantSinceSeq: 0, wantEventLimit: 0},
{query: "?sinceSeq=12", wantSinceSeq: 12, wantEventLimit: 0},
{query: "?eventLimit=1", wantSinceSeq: 0, wantEventLimit: 1},
{query: "?eventLimit=500", wantSinceSeq: 0, wantEventLimit: 500},
{query: "?sinceSeq=12&eventLimit=50", wantSinceSeq: 12, wantEventLimit: 50},
{query: "?sinceSeq=%203%20&eventLimit=%207%20", wantSinceSeq: 3, wantEventLimit: 7},
} {
t.Run(testCase.query, func(t *testing.T) {
request := httptest.NewRequest("GET", "/api/agent/runs/run-1"+testCase.query, nil)
context, _ := gin.CreateTestContext(httptest.NewRecorder())
context.Request = request
options, err := agentRunViewOptions(context)
if err != nil {
t.Fatalf("%s 被拒绝: %v", testCase.query, err)
}
if options.SinceSeq != testCase.wantSinceSeq || options.EventLimit != testCase.wantEventLimit {
t.Fatalf("%s 解析为 %+v,期望 sinceSeq=%d eventLimit=%d", testCase.query, options, testCase.wantSinceSeq, testCase.wantEventLimit)
}
})
}
}
func TestAgentRunViewOptionsRejectsInvalidPaginationQuery(t *testing.T) {
gin.SetMode(gin.TestMode)
for _, query := range []string{
"?sinceSeq=abc",
"?sinceSeq=-1",
"?sinceSeq=1.5",
"?sinceSeq=99999999999999999999",
"?eventLimit=0",
"?eventLimit=501",
"?eventLimit=-5",
"?eventLimit=abc",
} {
t.Run(query, func(t *testing.T) {
request := httptest.NewRequest("GET", "/api/agent/runs/run-1"+query, nil)
context, _ := gin.CreateTestContext(httptest.NewRecorder())
context.Request = request
if options, err := agentRunViewOptions(context); err == nil {
t.Fatalf("%s 未被拒绝,解析为 %+v", query, options)
}
})
}
}