package main import ( "net/http" "net/http/httptest" "strings" "testing" "cmautobuy/admin/repository" ) // 五个主页面都走一次真实路由和模板渲染。 // 这样模板字段写错或新增列漏接时,测试阶段就会失败,不必等人工点页面。 func TestMainPagesReturnOK(t *testing.T) { db, err := repository.Open(t.TempDir()) if err != nil { t.Fatalf("打开测试数据库失败: %v", err) } defer db.Close() if err := repository.Migrate(db); err != nil { t.Fatalf("迁移测试数据库失败: %v", err) } router, err := newRouter(db) if err != nil { t.Fatalf("组装路由失败: %v", err) } for _, path := range []string{"/shopee", "/pdd", "/syb", "/tasks", "/clients"} { t.Run(path, func(t *testing.T) { request := httptest.NewRequest(http.MethodGet, path, nil) response := httptest.NewRecorder() router.ServeHTTP(response, request) if response.Code != http.StatusOK { t.Fatalf("GET %s = %d,期望 200,响应:%s", path, response.Code, response.Body.String()) } }) } pdd, err := repository.EnsurePddProduct( db, "737116531267", "https://mobile.yangkeduo.com/goods.html?goods_id=737116531267") if err != nil { t.Fatalf("准备 PDD 商品失败: %v", err) } resultJSON := `{ "price_granularity":"color", "dimensions":[{"key":"color","name":"颜色分类"},{"key":"size","name":"尺码"}], "skus":[ {"options":{"color":"黑色","size":"M"},"price_cent":470, "price_observed_at":{"color":"黑色","size":"M"},"available":true}, {"options":{"color":"黑色","size":"L"},"price_cent":470, "price_observed_at":{"color":"黑色","size":"M"},"available":true} ] }` if err := repository.SetCollectResult( db, pdd.GoodsID, "测试商品", "测试旗舰店", resultJSON); err != nil { t.Fatalf("准备采集结果失败: %v", err) } request := httptest.NewRequest(http.MethodGet, "/pdd/detail?id=1", nil) response := httptest.NewRecorder() router.ServeHTTP(response, request) if response.Code != http.StatusOK { t.Fatalf("GET /pdd/detail = %d,响应:%s", response.Code, response.Body.String()) } body := response.Body.String() for _, want := range []string{ "测试旗舰店", "价格按颜色采样", "✓ 实测", "推断", } { if !strings.Contains(body, want) { t.Errorf("PDD 详情缺少 %q,响应:%s", want, body) } } }