mirror of
https://github.com/byoungd/up.git
synced 2026-10-02 08:04:40 +08:00
Harden published book download checks
This commit is contained in:
@@ -71,17 +71,22 @@ jobs:
|
||||
fi
|
||||
done
|
||||
downloads=(
|
||||
$'/downloads/life-level-up-guide-zh.epub|application/epub+zip'
|
||||
$'/downloads/life-level-up-guide-en.epub|application/epub+zip'
|
||||
$'/downloads/life-level-up-guide-zh.pdf|application/pdf'
|
||||
$'/downloads/life-level-up-guide-en.pdf|application/pdf'
|
||||
$'/downloads/life-level-up-guide-zh.epub|application/epub+zip|0-3|504b0304'
|
||||
$'/downloads/life-level-up-guide-en.epub|application/epub+zip|0-3|504b0304'
|
||||
$'/downloads/life-level-up-guide-zh.pdf|application/pdf|0-4|255044462d'
|
||||
$'/downloads/life-level-up-guide-en.pdf|application/pdf|0-4|255044462d'
|
||||
)
|
||||
for entry in "${downloads[@]}"; do
|
||||
IFS='|' read -r path expected_type <<< "$entry"
|
||||
IFS='|' read -r path expected_type byte_range expected_signature <<< "$entry"
|
||||
url="${PAGE_URL%/}${path}"
|
||||
headers="$(curl --fail --head --location --retry 8 --retry-delay 5 --connect-timeout 15 --max-time 45 "$url")"
|
||||
if ! grep -Eiq "^content-type: *${expected_type}" <<< "$headers"; then
|
||||
if ! grep -Fiq "content-type: ${expected_type}" <<< "$headers"; then
|
||||
printf 'Unexpected content type for %s; expected %s\n' "$url" "$expected_type" >&2
|
||||
exit 1
|
||||
fi
|
||||
signature="$(curl --fail --silent --show-error --location --retry 8 --retry-delay 5 --connect-timeout 15 --max-time 45 --range "$byte_range" "$url" | od -An -tx1 | tr -d ' \n')"
|
||||
if [[ "$signature" != "$expected_signature" ]]; then
|
||||
printf 'Unexpected file signature for %s; expected %s, received %s\n' "$url" "$expected_signature" "$signature" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
+14
-2
@@ -357,12 +357,12 @@ test("home pages expose deterministic bilingual EPUB editions", async ({ page, r
|
||||
);
|
||||
});
|
||||
|
||||
test("home pages expose deterministic print-ready bilingual PDF editions", async ({ page, request }) => {
|
||||
test("home pages expose reproducible print-ready bilingual PDF editions", async ({ page, request }) => {
|
||||
const manifestResponse = await request.get("downloads/pdf-manifest.json");
|
||||
expect(manifestResponse.status()).toBe(200);
|
||||
expect(manifestResponse.headers()["content-type"]).toContain("application/json");
|
||||
const manifest = await manifestResponse.json();
|
||||
expect(manifest).toMatchObject({ version: 1, format: "PDF 1.7", pageSize: "6 × 9.6 in" });
|
||||
expect(manifest).toMatchObject({ version: 2, format: "PDF 1.7", pageSize: "6 × 9.6 in" });
|
||||
|
||||
const editions = [
|
||||
{ language: "zh-CN", label: "下载中文 PDF", href: "./downloads/life-level-up-guide-zh.pdf" },
|
||||
@@ -380,6 +380,18 @@ test("home pages expose deterministic print-ready bilingual PDF editions", async
|
||||
expect(output.pages).toBeGreaterThan(200);
|
||||
expect(output.bytes).toBeGreaterThan(500_000);
|
||||
expect(output.bytes).toBeLessThan(8_000_000);
|
||||
expect(output.semanticSha256).toMatch(/^[a-f0-9]{64}$/);
|
||||
expect(output.outlineEntries).toBeGreaterThan(500);
|
||||
expect(output.linkAnnotations).toBeGreaterThan(500);
|
||||
expect(output.images).toBeGreaterThan(10);
|
||||
if (edition.language === "zh-CN") {
|
||||
const embeddedNotoFonts = output.fonts.filter(
|
||||
(font) => font.name.startsWith("Noto") && font.embedded,
|
||||
);
|
||||
expect(embeddedNotoFonts.map((font) => font.name)).toEqual(
|
||||
expect.arrayContaining(["NotoSans-Regular", "NotoSerifSC-Bold", "NotoSerifSC-Regular"]),
|
||||
);
|
||||
}
|
||||
const response = await request.get(`downloads/${output.file}`);
|
||||
expect(response.status()).toBe(200);
|
||||
expect(response.headers()["content-type"]).toContain("application/pdf");
|
||||
|
||||
Reference in New Issue
Block a user