diff --git a/backend/internal/latest/poller_test.go b/backend/internal/latest/poller_test.go index ae496b2..59b3cf8 100644 --- a/backend/internal/latest/poller_test.go +++ b/backend/internal/latest/poller_test.go @@ -1010,10 +1010,10 @@ func TestRunOnceFillsBlankCoverFromSeriesPage(t *testing.T) { }, { name: "lightnovelworld novel", - key: "lightnovelworld:a-will-eternal", site: "lightnovelworld", - seriesID: "a-will-eternal", seriesURL: "https://lightnovelworld.net/novel/a-will-eternal/", + key: "lightnovelworld:all-jobs-and-classes-i-just-wanted-one-skill-not-them-all", site: "lightnovelworld", + seriesID: "all-jobs-and-classes-i-just-wanted-one-skill-not-them-all", seriesURL: "https://lightnovelworld.net/novel/all-jobs-and-classes-i-just-wanted-one-skill-not-them-all/", kind: store.KindNovel, body: lnwSeriesFixture + lnwCoverFixture, - wantCover: "https://lightnovelworld.net/wp-content/uploads/2026/03/a-will-eternal-1.webp", + wantCover: "https://i1.wp.com/lightnovelworld.net/wp-content/uploads/2025/10/all-jobs-and-classes-i-just-wanted-one-skill-not-them-all.jpg", }, { name: "kagane manga", diff --git a/backend/internal/latest/sites_test.go b/backend/internal/latest/sites_test.go index 16cbab0..f1c4876 100644 --- a/backend/internal/latest/sites_test.go +++ b/backend/internal/latest/sites_test.go @@ -69,14 +69,113 @@ const novelfullSeriesFixture = ` Chapter 9999 ` -// Trimmed from https://lightnovelworld.net/novel/a-will-eternal/ fetched -// 2026-08-05. Its chapter anchors are absolute and flat — /-chapter-/ -// at the site root, not under /novel/. The last anchor is another series'. +// Trimmed from +// https://lightnovelworld.net/novel/all-jobs-and-classes-i-just-wanted-one-skill-not-them-all/ +// fetched 2026-08-11, whole document (~307 KB decoded; the wire body is ~32 KB +// zstd-compressed). This +// novel publishes its chapters under two Chapter Slugs: 1–99 at +// …-not-chapter-/ and 100–423 at …-not-them-all-chapter-/, and the page +// lists them newest-first, so the …-not-them-all anchors precede the …-not +// anchors. Every anchor through the comment-thread marker is verbatim page +// text (the site renders this novel's chapter titles as "[ ... words ]"). The +// comment block after the marker is the real wpdiscuz comment #wpd-comm-358_0 +// from https://lightnovelworld.net/novel/the-sword-illuminates-the-great-wilderness/ +// — the pinned page serves zero comments — with its share/link/vote/reply +// boilerplate trimmed. The comment's body carried no link, so the bare to https://lightnovelworld.net/overgeared-chapter-2059/ inside +// wpd-comment-text is the one composed element; that URL is a real chapter of +// a real different novel (overgeared; fetched, HTTP 200). const lnwSeriesFixture = ` -Chapter 1 -Chapter 1317 -Chapter 1298 -Chapter 9999 +
  • + +
    Vol. 1 Ch. 404
    +
    [ ... words ]
    +
    April 12, 2026
    +
    +
  • +
  • + +
    Vol. 1 Ch. 423
    +
    [ ... words ]
    +
    April 7, 2026
    +
    +
  • +
  • + +
    Vol. 1 Ch. 300
    +
    [ ... words ]
    +
    April 4, 2026
    +
    +
  • +
  • + +
    Vol. 1 Ch. 200
    +
    [ ... words ]
    +
    March 29, 2026
    +
    +
  • +
  • + +
    Vol. 1 Ch. 100
    +
    [ ... words ]
    +
    March 22, 2026
    +
    +
  • +
  • + +
    Vol. 1 Ch. 99
    +
    Chapter 99
    +
    November 5, 2025
    +
    +
  • +
  • + +
    Vol. 1 Ch. 50
    +
    Chapter 50
    +
    October 29, 2025
    +
    +
  • +
  • + +
    Vol. 1 Ch. 1
    +
    Chapter 01
    +
    October 11, 2025
    +
    +
  • +
    +
    +
    +
    +
    + hasbi asy +
    +
    + Member +
    + +
    +
    +
    +
    + hasbi asy +
    +
    + + 1 month ago +
    + +
    + + +
    +
    +
    +
    +
    ` // Trimmed from https://asurascans.com/comics/chronicles-of-the-demon-faction-f886a8af @@ -98,8 +197,10 @@ const kaganeCoverFixture = `{"series_covers":[{"cover_id":"019fe11a-84d1-714b-9c // Trimmed from https://novelfull.com/reverend-insanity.html on 2026-08-10. const novelfullCoverFixture = `` -// Trimmed from https://lightnovelworld.net/novel/a-will-eternal/ on 2026-08-10. -const lnwCoverFixture = `` +// Trimmed from +// https://lightnovelworld.net/novel/all-jobs-and-classes-i-just-wanted-one-skill-not-them-all/ +// on 2026-08-11. +const lnwCoverFixture = `` func TestCoverFrom(t *testing.T) { const comixURL = "https://comix.to/title/n8we-dungeons-and-crayons" @@ -139,7 +240,7 @@ func TestCoverFrom(t *testing.T) { { name: "lightnovelworld reads og image", site: "lightnovelworld", body: lnwCoverFixture, wantOK: true, - wantCover: "https://lightnovelworld.net/wp-content/uploads/2026/03/a-will-eternal-1.webp", + wantCover: "https://i1.wp.com/lightnovelworld.net/wp-content/uploads/2025/10/all-jobs-and-classes-i-just-wanted-one-skill-not-them-all.jpg", }, { name: "later metadata cover survives empty match", @@ -308,23 +409,23 @@ func TestLatestChapterFrom(t *testing.T) { wantOK: false, }, { - name: "lightnovelworld takes the max and ignores another series", + name: "lightnovelworld takes the max on a split-slug novel", site: "lightnovelworld", - seriesURL: "https://lightnovelworld.net/novel/a-will-eternal/", + seriesURL: "https://lightnovelworld.net/novel/all-jobs-and-classes-i-just-wanted-one-skill-not-them-all/", body: lnwSeriesFixture, - wantOK: true, wantNum: 1317, wantLabel: "Chapter 1317", + wantOK: true, wantNum: 423, wantLabel: "Chapter 423", }, { name: "lightnovelworld tolerates a series url with no trailing slash", site: "lightnovelworld", - seriesURL: "https://lightnovelworld.net/novel/a-will-eternal", + seriesURL: "https://lightnovelworld.net/novel/all-jobs-and-classes-i-just-wanted-one-skill-not-them-all", body: lnwSeriesFixture, - wantOK: true, wantNum: 1317, wantLabel: "Chapter 1317", + wantOK: true, wantNum: 423, wantLabel: "Chapter 423", }, { name: "lightnovelworld yields nothing on a challenge page", site: "lightnovelworld", - seriesURL: "https://lightnovelworld.net/novel/a-will-eternal/", + seriesURL: "https://lightnovelworld.net/novel/all-jobs-and-classes-i-just-wanted-one-skill-not-them-all/", body: challengeFixture, wantOK: false, },