Files
mangabaka-seeder/test/webtoons-parse.test.ts
T

55 lines
3.3 KiB
TypeScript

import { expect, test } from "bun:test";
import { parseSeriesPage } from "../src/core/sources/webtoons/parse";
import { fixtureText } from "./helpers/fixtures";
// Expected URLs are what the fixtures captured on 2026-10-14. If Webtoons changed since and you
// re-captured, the fixture is the truth: update these strings to what it now contains.
const P = "https://swebtoon-phinf.pstatic.net";
test("official series: poster, square, banner, foreground; title, canonical, flags", async () => {
const page = parseSeriesPage(await fixtureText("webtoons/tower-of-god.html"),
new URL("https://www.webtoons.com/en/fantasy/tower-of-god/list?title_no=95"));
expect(page.title).toBe("Tower of God");
expect(page.canonicalUrl).toBe("https://www.webtoons.com/en/fantasy/tower-of-god/list?title_no=95");
expect(page.canvas).toBe(false);
expect(page.mature).toBe(false);
expect(page.covers.map((c) => [c.role, c.url])).toEqual([
["poster", `${P}/20250204_46/17386458444547o1b2_JPEG/95.jpg`],
["square", `${P}/20230324_171/1679612128056zKhRj_JPEG/1TowerOfGod_thumbnail_mobile.jpg`],
["banner", `${P}/20230408_147/1680918244853P9prU_JPEG/0TowerOfGod_landingpage_desktop_bg.jpg`],
["foreground", `${P}/20230324_64/1679612177711Smf0u_PNG/6TowerOfGod_landingpage_desktop_fg.png`],
]);
expect(page.covers[0]!.originalUrl).toContain("?type=crop540_540");
expect(page.covers.every((c) => c.current === false)).toBe(true);
});
test("canvas series: squares only, hero image deduplicated by URL", async () => {
const page = parseSeriesPage(await fixtureText("webtoons/crow-time-canvas.html"),
new URL("https://www.webtoons.com/en/canvas/crow-time/list?title_no=693372"));
expect(page.canvas).toBe(true);
expect(page.covers.map((c) => c.role)).toEqual(["square", "square"]);
expect(page.covers[0]!.url).toBe(`${P}/20240408_279/1712548929813q5cnb_JPEG/thumbnail.jpg`);
});
test("mature series is flagged", async () => {
const page = parseSeriesPage(await fixtureText("webtoons/zombie-revelation-mature.html"),
new URL("https://www.webtoons.com/en/action/zombie-revelation-82-08/list?title_no=6065"));
expect(page.mature).toBe(true);
expect(page.covers.length).toBeGreaterThan(0);
});
test("2015 Wayback snapshot: unquoted url(), old naver.net hosts", async () => {
const page = parseSeriesPage(await fixtureText("wayback/tower-of-god-2015.html"),
new URL("http://www.webtoons.com:80/en/fantasy/tower-of-god/list?title_no=95"));
const byRole = Object.fromEntries(page.covers.map((c) => [c.role, c]));
expect(byRole.poster!.url).toBe(`${P}/20140710_28/1404979632969uKBA8_JPEG/01_EC8BA0EC9D98ED8391.jpg`);
expect(byRole.poster!.originalUrl).toBe("http://swebtoon.phinf.naver.net/20140710_28/1404979632969uKBA8_JPEG/01_EC8BA0EC9D98ED8391.jpg");
expect(byRole.banner!.url).toBe(`${P}/20140915_195/1410759727783HvB4R_JPEG/11_EC8BA0EC9D98ED8391_bg.jpg`);
expect(byRole.foreground!.url).toBe(`${P}/20140915_275/1410759723052oa5KP_PNG/11_EC8BA0EC9D98ED8391.png`);
});
test("pages without the markup give no covers, not an error", () => {
const page = parseSeriesPage("<html><head><title>x</title></head></html>", new URL("https://www.webtoons.com/en/x/list?title_no=1"));
expect(page).toEqual({ title: null, canonicalUrl: null, canvas: false, mature: false, covers: [] });
});