mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix(pdf): stop page tools failing on short and encrypted PDFs (#594)
Empty the hardcoded page-range default in remove/split/extract PDF tools (remove-pages defaulted to "2,4-6", out of range for any PDF under 6 pages) and disable submit until a range is entered. Reject password-protected PDFs up front for PDF-only tools with guidance to unlock first, instead of failing cryptically in the qpdf worker. Adds integration + e2e coverage.
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
|
||||
const PDF = readFixture(fixtures.document.pdf3);
|
||||
const PDF_PATH = fixtures.document.pdf3;
|
||||
const ENCRYPTED_PDF = readFixture(fixtures.document.encrypted);
|
||||
|
||||
let testApp: TestApp;
|
||||
let adminToken: string;
|
||||
@@ -107,6 +108,30 @@ describe.skipIf(!qpdfAvailable())("remove-pages (requires qpdf)", () => {
|
||||
expect(body.details || body.error || body.message).toMatch(/out of range/i);
|
||||
}, 60_000);
|
||||
|
||||
it("rejects a password-protected PDF up front with a clear message", async () => {
|
||||
// A page tool cannot operate on an encrypted PDF without the password.
|
||||
// The factory must reject it at input validation (400) with guidance to
|
||||
// unlock first, instead of letting qpdf fail cryptically in the worker.
|
||||
const { body, contentType } = createMultipartPayload([
|
||||
{
|
||||
name: "file",
|
||||
filename: "encrypted.pdf",
|
||||
contentType: "application/pdf",
|
||||
content: ENCRYPTED_PDF,
|
||||
},
|
||||
{ name: "settings", content: JSON.stringify({ pages: "1" }) },
|
||||
]);
|
||||
const res = await testApp.app.inject({
|
||||
method: "POST",
|
||||
url: "/api/v1/tools/pdf/remove-pages",
|
||||
headers: { authorization: `Bearer ${adminToken}`, "content-type": contentType },
|
||||
body,
|
||||
});
|
||||
expect(res.statusCode).toBe(400);
|
||||
const parsed = JSON.parse(res.body);
|
||||
expect(parsed.error).toMatch(/password-protected|unlock/i);
|
||||
}, 60_000);
|
||||
|
||||
it("removes page 1 from a 96-page pdf (large keepSpec path)", async () => {
|
||||
// The keep-spec for 95 pages as a raw comma list would be ~280 chars,
|
||||
// exceeding the 200-char assertValidRange cap. compressPageRuns compresses
|
||||
|
||||
Reference in New Issue
Block a user