68 lines
4.0 KiB
TypeScript
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);
|
|
});
|