package handler import ( "bytes" "strings" "testing" "fashionapi/internal/model" "fashionapi/internal/pkg/pagination" "github.com/gin-gonic/gin" ) // TestCrawlPageRendersProgress 守住抓取列表页的「进度」列。 // // 这一列由模板 + 前端轮询共同驱动,出错时不会编译失败、只会在打开页面时 500 或空白, // 所以用一个渲染测试把「运行中 + 卡住 + 有进度文案」这几种情况固定下来。 func TestCrawlPageRendersProgress(t *testing.T) { tpl, ok := pageTemplates["crawl"] if !ok { t.Fatal("crawl 模板未注册") } data := gin.H{ "NavKey": "crawl", "PendingReviews": 0, "Rows": []crawlRowView{{ ID: 7, BrandUID: "abc123", BrandName: "Celine", Status: model.CrawlRunning, StatusLabel: "执行中", Shows: 3, Worker: "vm-1-100-0", UpdatedAt: "2026-10-25 21:00", ProgressLabel: "3/13 场 · Fall 2021 Menswear(24/38 张)", Stale: true, CanCancel: true, }}, "Total": 1, "Queued": 0, "Running": 1, "Done": 0, "Failed": 0, "Added": 0, "Pager": pagination.Pager{Label: "第 1 / 1 页"}, } var buf bytes.Buffer if err := tpl.ExecuteTemplate(&buf, "layout", data); err != nil { t.Fatalf("渲染抓取列表页失败: %v", err) } out := buf.String() for _, want := range []string{ `data-live-progress="7"`, // 轮询锚点:JS 靠它定位单元格 `data-live-status="7"`, // 状态徽标也要能刷新 "3/13 场 · Fall 2021 Menswear(24/38 张)", // 进度文案原样输出 "progress stale", // 心跳停了要有警示样式 "/admin/crawl/live", // 轮询地址 } { if !strings.Contains(out, want) { t.Errorf("页面缺少 %q", want) } } }