package reader import ( "context" "net/http" "net/http/httptest" "strings" "testing" "github.com/truewhile/MeBox/internal/model" ) // 本文件:「更新目录」的结果分档回归测试。 // // 背景:书架提示曾经把「抓到了目录但没有新章节」也算成失败。完结书每次检查都没有新章节, // 于是书架天天报「N 本失败」,看起来像书源坏了。现在必须区分三档: // 抓到新章节 / 抓到但没变(已是最新)/ 抓取或写入失败。 // refreshTocForTest 跑一次「更新目录」并返回汇总。 func refreshTocForTest(t *testing.T, svc *ReaderService, ctx context.Context) *TocRefreshResult { t.Helper() res, err := svc.RefreshBooksToc(ctx, "u1") if err != nil { t.Fatalf("更新目录失败: %v", err) } return res } // newRefreshTocServer 建一个目录页内容可切换的测试源站点。 func newRefreshTocServer(tocHandler *http.HandlerFunc) *httptest.Server { return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") switch { case strings.HasPrefix(r.URL.Path, "/book/1/toc"): (*tocHandler)(w, r) case strings.HasPrefix(r.URL.Path, "/book/"): _, _ = w.Write([]byte(e2eBookInfoHTML)) default: http.NotFound(w, r) } })) } func TestRefreshBooksTocSeparatesUnchangedFromFailed(t *testing.T) { tocHandler := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte(e2eTocHTML)) }) srv := newRefreshTocServer(&tocHandler) defer srv.Close() svc, _ := newLoginTestService(t) ctx := t.Context() importTestSource(t, svc, e2eSourceJSON(srv.URL), srv.URL) book := &model.ReaderBook{ UserID: "u1", Origin: srv.URL, OriginName: "测试源", BookURL: srv.URL + "/book/1", TocURL: srv.URL + "/book/1/toc.html", Name: "斗破苍穹", } if err := svc.repo.CreateBook(ctx, book); err != nil { t.Fatalf("创建书籍失败: %v", err) } // 1) 首次刷新:抓到 2 章并落库。书架原先没有目录缓存,没有可比基准,算「已是最新」。 res := refreshTocForTest(t, svc, ctx) if res.Total != 1 || res.Updated != 0 || res.Unchanged != 1 || res.Failed != 0 { t.Fatalf("首次刷新 = %+v,期望 total 1 / updated 0 / unchanged 1 / failed 0", res) } chapters, err := svc.ListChapters(ctx, book.ID) if err != nil { t.Fatal(err) } if len(chapters) != 2 { t.Fatalf("目录缓存 = %d 章,期望 2", len(chapters)) } // 2) 站点多出一章:这才算「有新章节」。 tocHandler = func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte(strings.Replace( e2eTocHTML, "", `