From 1bf571736fca7f196f940713777632eba213fecd Mon Sep 17 00:00:00 2001 From: Sulthan Zaki Date: Tue, 11 Aug 2026 20:23:51 +0700 Subject: [PATCH] Pin the lnw scan removal with computeLatestChapter tests (#91) The new export is the seam the suite addresses behaviour through: for lightnovelworld no anchor set yields a Latest Chapter, comment-shaped anchors included, and for novelfull the scan still returns the maximum and ignores other series. The old lnw scan test asserted the deleted behaviour. --- userscript/test/novel-logic.test.js | 30 ++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/userscript/test/novel-logic.test.js b/userscript/test/novel-logic.test.js index 61380b1..5471694 100644 --- a/userscript/test/novel-logic.test.js +++ b/userscript/test/novel-logic.test.js @@ -45,6 +45,7 @@ globalThis.document = { const { novelfull, lightnovelworld, + computeLatestChapter, kindOf, maxChapter, repairLnwStaleRow, @@ -314,17 +315,40 @@ test("lightnovelworld.detect returns other for non-series paths", () => { assert.equal(lightnovelworld.detect(loc("https://lightnovelworld.net/az-lists/")).type, "other"); }); -test("lightnovelworld.latestChapterFromAnchors takes the max and ignores other series", () => { - const best = lightnovelworld.latestChapterFromAnchors( +test("computeLatestChapter yields nothing for lightnovelworld, comment anchors included", () => { + // A realistic Series-page anchor set: current-slug chapters, a second + // Chapter Slug's chapters, and a wpdiscuz comment pasting a high-numbered + // chapter of another novel (the poisoning vector). The client never scans + // this Site — the Poll's cooldown dominates the client throttle and the + // comment thread is a public write surface — so this must fail the moment + // a scan is reintroduced, scoped or not. + const latest = computeLatestChapter( + "lightnovelworld", [ { href: "https://lightnovelworld.net/a-will-eternal-chapter-1/", text: "Chapter 1" }, { href: "https://lightnovelworld.net/a-will-eternal-chapter-1317/", text: "Chapter 1317" }, { href: "https://lightnovelworld.net/a-will-eternal-chapter-1298/", text: "Chapter 1298" }, + // a divergent novel's second Chapter Slug + { href: "https://lightnovelworld.net/my-longevity-simulation-chapter-400/", text: "Chapter 400" }, + // a wpdiscuz comment anchor { href: "https://lightnovelworld.net/overgeared-chapter-9999/", text: "Chapter 9999" }, ], "a-will-eternal" ); - assert.deepEqual(best, { num: 1317, label: "Chapter 1317" }); + assert.equal(latest, null); +}); + +test("computeLatestChapter still scans novelfull and ignores other series", () => { + const best = computeLatestChapter( + "novelfull", + [ + { href: "/reverend-insanity/chapter-2334-fang-yuan.html", text: "Chapter 2334" }, + { href: "/reverend-insanity/chapter-1.html", text: "Chapter 1" }, + { href: "/release-that-witch/chapter-9999.html", text: "Chapter 9999" }, + ], + "reverend-insanity" + ); + assert.deepEqual(best, { num: 2334, label: "Chapter 2334" }); }); test("latestChapterFromAnchors returns null when nothing matches", () => {