Files
mangabaka-seeder/test/download.test.ts
T
2026-10-15 11:29:56 +02:00

68 lines
4.0 KiB
TypeScript

import { expect, test } from "bun:test";
import { coverFileName, downloadBundle, slug, type BundleInput } from "../src/core/download";
import type { SourceSeries } from "../src/core/model";
import type { ReviewCard } from "../src/core/session";
import { inspected } from "./helpers/covers";
const series: SourceSeries = {
source: "webtoons", externalId: "95", title: "Tower of God", language: "en",
canonicalUrl: "https://www.webtoons.com/en/fantasy/tower-of-god/list?title_no=95", archiveUrls: [], mature: false, flags: {},
};
const card = (cover = inspected(), over: Partial<ReviewCard> = {}): ReviewCard =>
({ cover, selected: true, type: cover.type, note: "WEBTOON poster (current)", contentRating: "safe", hostedUrl: null, error: null, ...over });
test("file names: position, role, language, first-seen year, size", () => {
expect(coverFileName(1, 4, card(), "en")).toBe("01_poster_en_480x623.jpg");
const old = inspected({ candidate: { role: "poster", current: false, seenAt: "20190414075103" }, ext: "png" });
expect(coverFileName(3, 4, card(old), "zh-Hant")).toBe("03_poster_zh-Hant_2019_480x623.png");
const banner = inspected({ candidate: { role: "banner" }, width: 1920, height: 321 });
expect(coverFileName(2, 4, card(banner), "en")).toBe("02_banner_en_1920x321.jpg");
});
test("file numbers pad to the count's width", () => {
expect(coverFileName(7, 120, card(), "en")).toMatch(/^007_/);
expect(coverFileName(7, 9, card(), "en")).toMatch(/^07_/);
});
test("slug: ASCII words joined by dashes; falls back when the title has none", () => {
expect(slug("Tower of God")).toBe("tower-of-god");
expect(slug(" Solo Leveling: Ragnarök!! ")).toBe("solo-leveling-ragnar-k");
expect(slug("나 혼자만 레벨업")).toBe("series");
});
function input(over: Partial<BundleInput> = {}): BundleInput {
const main = inspected({ fetchedFrom: "https://swebtoon-phinf.pstatic.net/a/95.jpg", candidate: { url: "https://swebtoon-phinf.pstatic.net/a/95.jpg" } });
const archived = inspected({
candidate: { url: "https://swebtoon-phinf.pstatic.net/b/old.jpg", role: "poster", current: false, seenAt: "20190414075103" },
fetchedFrom: "https://web.archive.org/web/20190414075103id_/https://swebtoon-phinf.pstatic.net/b/old.jpg",
live: false,
});
return {
seriesId: 9999, mbTitle: "Tower of God", mbLink: "https://mangabaka.org/manhwa/9999/Tower-of-God", sourceName: "WEBTOON", series,
cards: [card(main), card(archived, { type: "other", note: "WEBTOON poster, seen 2019-04", contentRating: "suggestive" })],
mainSha256: main.sha256, now: new Date("2026-10-15T12:00:00Z"), ...over,
};
}
test("the bundle: covers with their bytes, then covers.txt", () => {
const b = downloadBundle(input());
expect(b.zipName).toBe("tower-of-god-9999-covers.zip");
expect(b.files.map((f) => f.name)).toEqual(["01_poster_en_480x623.jpg", "02_poster_en_2019_480x623.jpg", "covers.txt"]);
const txt = new TextDecoder().decode(b.files[2]!.bytes);
expect(txt).toContain("Tower of God (MangaBaka #9999): https://mangabaka.org/manhwa/9999/Tower-of-God");
expect(txt).toContain("WEBTOON “Tower of God”: https://www.webtoons.com/en/fantasy/tower-of-god/list?title_no=95");
expect(txt).toContain("Cover form: https://mangabaka.org/data/submissions/series/9999/images");
expect(txt).toContain("01_poster_en_480x623.jpg\n type: volume · language: en · rating: safe · MAIN COVER\n note: WEBTOON poster (current)\n source: https://swebtoon-phinf.pstatic.net/a/95.jpg");
expect(txt).toContain("02_poster_en_2019_480x623.jpg\n type: other · language: en · rating: suggestive\n note: WEBTOON poster, seen 2019-04\n" +
" source: https://web.archive.org/web/20190414075103id_/https://swebtoon-phinf.pstatic.net/b/old.jpg\n" +
" original: https://swebtoon-phinf.pstatic.net/b/old.jpg");
expect(txt.match(/MAIN COVER/g)).toHaveLength(1);
});
test("the cover bytes go into the ZIP untouched", () => {
const i = input();
const b = downloadBundle(i);
expect(b.files[0]!.bytes).toBe(i.cards[0]!.cover.bytes);
expect(b.files[0]!.modified).toEqual(i.now);
});