123 lines
4.8 KiB
Go
123 lines
4.8 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestLiveHistoricalSortMetadata(t *testing.T) {
|
|
if os.Getenv("JUKU_LIVE_METADATA") != "1" {
|
|
t.Skip("set JUKU_LIVE_METADATA=1 for explicit text-metadata verification")
|
|
}
|
|
cfg := defaultConfig()
|
|
cfg.dataDir, cfg.OutputDir, cfg.Retries = t.TempDir(), t.TempDir(), 1
|
|
d := NewDownloader(cfg)
|
|
transport := d.client.Transport
|
|
d.client.Transport = rankingTransport(func(request *http.Request) (*http.Response, error) {
|
|
path := request.URL.Path
|
|
if !(strings.HasPrefix(path, "/search/") || path == "/detail" || strings.HasPrefix(path, "/detail/") || path == "/novel/player/video_detail/v1/" || path == "/api/drama/detail" || path == "/api/drama/list") {
|
|
t.Errorf("metadata verification refused a non-metadata path: %s", path)
|
|
return rankingHTTPResponse(request, 403, "blocked by test"), nil
|
|
}
|
|
return transport.RoundTrip(request)
|
|
})
|
|
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
|
|
defer cancel()
|
|
search, err := d.searchHongguoDramas(ctx, "聚宝仙盆")
|
|
if err != nil || len(search.Dramas) == 0 {
|
|
t.Fatalf("search: %v", err)
|
|
}
|
|
base := "聚宝仙盆之杂灵根才是真BOSS"
|
|
rows := []Drama{
|
|
{ID: "hongguo:7498612570866076734", Source: sourceHongguo, Title: "聚宝仙盆"},
|
|
{ID: "hongguo:7615465407347952664", Source: sourceHongguo, Title: base},
|
|
{ID: "hongguo:7629943873896188990", Source: sourceHongguo, Title: base + "第二季"},
|
|
{ID: "hongguo:7637096540321893400", Source: sourceHongguo, Title: base + "第三季"},
|
|
{ID: "hongguo:7642925668568665150", Source: sourceHongguo, Title: base + "第四季"},
|
|
{ID: "hongguo:7653639205888724030", Source: sourceHongguo, Title: base + "第五季"},
|
|
{ID: "hongguo:7654979763613731864", Source: sourceHongguo, Title: base + "第六季"},
|
|
{ID: "hongguo:7665257305725750297", Source: sourceHongguo, Title: base + "第七季"},
|
|
{ID: "hongguo:7671115782083841048", Source: sourceHongguo, Title: base + "第八季"},
|
|
{ID: "hongguo:7673807696302197784", Source: sourceHongguo, Title: base + "第九季"},
|
|
{ID: "hongguo:7677914379060251673", Source: sourceHongguo, Title: base + "第十季"},
|
|
{ID: "hongguo:7681903520873729048", Source: sourceHongguo, Title: base + "第十一季"},
|
|
{ID: "huangguoai:453", Source: sourceHuangguoAI, Title: "黄果样本"},
|
|
{ID: "huangdou:6a8928e0817f7dacc5972a24", Source: sourceHuangdou, Title: "黄豆样本"},
|
|
}
|
|
seen := map[string]bool{}
|
|
for _, row := range rows {
|
|
seen[row.ID] = true
|
|
}
|
|
var searchIDs []string
|
|
for _, row := range search.Dramas {
|
|
searchIDs = append(searchIDs, row.ID)
|
|
if !seen[row.ID] {
|
|
seen[row.ID] = true
|
|
rows = append(rows, Drama{ID: row.ID, Source: row.Source, Title: row.Title})
|
|
}
|
|
}
|
|
patches, failures := d.backfillSortMetadata(withKnownHongguoDramas(ctx, rows), "")
|
|
if len(failures) > 0 {
|
|
for source, err := range failures {
|
|
t.Errorf("%s: %v", source, err)
|
|
}
|
|
}
|
|
merged := mergeSourceDramas(rows, patches, nil, "")
|
|
type textRow struct {
|
|
ID string `json:"id"`
|
|
Source string `json:"source"`
|
|
Title string `json:"title"`
|
|
OnlineDate string `json:"onlineDate,omitempty"`
|
|
Heat string `json:"heat,omitempty"`
|
|
Views string `json:"views,omitempty"`
|
|
}
|
|
var report []textRow
|
|
counts := map[string]map[string]int{}
|
|
for _, row := range merged {
|
|
if counts[row.Source] == nil {
|
|
counts[row.Source] = map[string]int{}
|
|
}
|
|
count := counts[row.Source]
|
|
count["total"]++
|
|
if row.OnlineDate != "" {
|
|
count["dates"]++
|
|
}
|
|
if row.Heat != "" {
|
|
count["heat"]++
|
|
}
|
|
if row.Views != "" {
|
|
count["views"]++
|
|
}
|
|
if row.SortMetadata == nil || row.SortMetadata.Version != sortMetadataVersion {
|
|
t.Errorf("entry was not checked: %s", row.ID)
|
|
}
|
|
if address := bestDramaCover(row); address != "" && (row.Source != sourceHongguo || hongguoCoverAddress(address) != address) {
|
|
t.Fatal("metadata must retain only a validated cover address")
|
|
}
|
|
report = append(report, textRow{row.ID, row.Source, row.Title, row.OnlineDate, row.Heat, row.Views})
|
|
}
|
|
for source, count := range counts {
|
|
t.Logf("%s: %v", source, count)
|
|
}
|
|
if count := counts[sourceHongguo]; count["dates"] == 0 || count["heat"] == 0 || count["views"] == 0 {
|
|
t.Error("Hongguo live sorting metadata is missing")
|
|
}
|
|
if count := counts[sourceHuangguoAI]; count["dates"] == 0 || count["views"] == 0 {
|
|
t.Error("Huangguo live sorting metadata is missing")
|
|
}
|
|
if count := counts[sourceHuangdou]; count["heat"] == 0 || count["views"] == 0 {
|
|
t.Error("Huangdou live sorting metadata is missing")
|
|
}
|
|
if path := os.Getenv("JUKU_SORT_METADATA_REPORT"); path != "" {
|
|
data, _ := json.MarshalIndent(map[string]any{"query": "聚宝仙盆", "rows": report, "counts": counts, "searchIDs": searchIDs}, "", " ")
|
|
if err := os.WriteFile(path, data, 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|