package mineru_test import ( "context" "os" "strings" "testing" "time" "chat-agent-system/internal/mineru" ) // Live smoke: prefer Agent lightweight API (no token) so acceptance works // even when MINERU_API_KEY is expired. Set MINERU_LIVE=1. func TestLive_ParseTinyPDF(t *testing.T) { if os.Getenv("MINERU_LIVE") != "1" { t.Skip("set MINERU_LIVE=1 to run") } pdfPath := strings.TrimSpace(os.Getenv("MINERU_LIVE_PDF")) var pdf []byte var name string if pdfPath != "" { b, err := os.ReadFile(pdfPath) if err != nil { t.Fatalf("read pdf: %v", err) } pdf = b name = pdfPath } else { pdf = []byte("%PDF-1.4\n1 0 obj<<>>endobj\ntrailer<<>>\n%%EOF\n") name = "live-smoke.pdf" } client := mineru.NewClient(mineru.Config{ Endpoint: getenv("MINERU_ENDPOINT_URL", "https://mineru.net"), APIKey: strings.TrimSpace(os.Getenv("MINERU_API_KEY")), // may be expired; Agent fallback applies HTTPTimeout: 5 * time.Minute, }) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() res, err := client.ParseFile(ctx, name, pdf) if err != nil { // Synthetic tiny PDF may fail agent page/type checks; real PDF must succeed. if pdfPath == "" { t.Logf("synthetic pdf parse err (ok if using real PDF next): %v", err) return } t.Fatalf("parse failed: %v", err) } if strings.TrimSpace(res.Markdown) == "" { t.Fatal("empty markdown") } t.Logf("mode=%s pages=%d md_len=%d batch=%s", res.EngineMode, res.TotalPages, len(res.Markdown), res.BatchID) if pdfPath != "" && res.EngineMode == "" { t.Fatal("missing engine mode") } // Dump a content sample so the report can prove real text was extracted. if os.Getenv("MINERU_LIVE_DUMP") != "" { _ = os.WriteFile(os.Getenv("MINERU_LIVE_DUMP"), []byte(res.Markdown), 0o644) t.Logf("wrote %d bytes to %s; contains 冲击波=%v", len(res.Markdown), os.Getenv("MINERU_LIVE_DUMP"), strings.Contains(res.Markdown, "冲击波")) } } func getenv(k, def string) string { if v := strings.TrimSpace(os.Getenv(k)); v != "" { return v } return def }