Fix Invalid PDF structure after reload for uploaded documents.
Stop inventing /fixtures/pdfs/<title> URLs when blob bytes are missing; rely on IndexedDB-hydrated byte store. Seeded tests set an explicit fixture uri. Session metadata already survived; PDF bytes now survive too.
This commit is contained in:
parent
9dbe806487
commit
a73d45bfac
3 changed files with 26 additions and 8 deletions
|
|
@ -38,11 +38,16 @@ describe("resolvePdfViewerUrl", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("falls back to fixture path when only a stale blob uri is stored", () => {
|
||||
it("returns null for stale blob uri without live bytes (no fixture guess)", () => {
|
||||
const store = createPdfByteStore();
|
||||
expect(
|
||||
resolvePdfViewerUrl(doc({ uri: "blob:revoked", title: "a.pdf" }), store),
|
||||
).toBe("/fixtures/pdfs/a.pdf");
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
it("returns null when uri was stripped on persist and bytes are gone", () => {
|
||||
const store = createPdfByteStore();
|
||||
expect(resolvePdfViewerUrl(doc({ uri: undefined, title: "upload.pdf" }), store)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -51,4 +56,4 @@ describe("isEphemeralBlobUri", () => {
|
|||
expect(isEphemeralBlobUri("blob:http://localhost/x")).toBe(true);
|
||||
expect(isEphemeralBlobUri("/fixtures/pdfs/x.pdf")).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
* Uploaded PDFs are served via ephemeral `blob:` URLs owned by
|
||||
* `PdfByteStore`. Those URLs must not be persisted (see persistence
|
||||
* sanitization) and must be re-resolved from live bytes on every render.
|
||||
*
|
||||
* After a reload, bytes come back via IndexedDB hydrate into the byte store.
|
||||
* Never invent a `/fixtures/pdfs/<title>` URL for arbitrary uploads — that
|
||||
* path 404s (or returns HTML) and PDF.js reports "Invalid PDF structure".
|
||||
*/
|
||||
|
||||
import type { Document } from "@shared/document";
|
||||
|
|
@ -20,7 +24,8 @@ export function isEphemeralBlobUri(uri: string | undefined): boolean {
|
|||
|
||||
/**
|
||||
* Prefer the byte store's live blob URL for uploaded documents; fall back
|
||||
* to a stable HTTP fixture path or a non-blob `document.uri`.
|
||||
* to a stable non-blob `document.uri` (e.g. fixture HTTP path). Returns
|
||||
* `null` when bytes are not available — ViewerShell shows re-upload copy.
|
||||
*/
|
||||
export function resolvePdfViewerUrl(
|
||||
document: Document,
|
||||
|
|
@ -33,8 +38,8 @@ export function resolvePdfViewerUrl(
|
|||
return document.uri;
|
||||
}
|
||||
|
||||
const titleOrId = document.title ?? document.id;
|
||||
return `/fixtures/pdfs/${encodeURIComponent(titleOrId)}`;
|
||||
// Stale blob URI and no in-memory/IDB bytes: do not guess a fixture path.
|
||||
return null;
|
||||
}
|
||||
|
||||
/** True when bytes exist in the store but the document record lacks a URI. */
|
||||
|
|
@ -43,4 +48,4 @@ export function documentHasUploadedBytes(
|
|||
byteStore: PdfByteStore,
|
||||
): boolean {
|
||||
return byteStore.has(documentId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,10 +49,18 @@ export function seedSessionWithDoc(opts: SeedOptions): SeedResult {
|
|||
lastOpenedAt: now,
|
||||
};
|
||||
|
||||
// Stable HTTP fixture URI so the viewer mounts without IndexedDB bytes.
|
||||
// (resolvePdfViewerUrl no longer invents /fixtures paths from title alone —
|
||||
// that produced "Invalid PDF structure" for arbitrary uploads after reload.)
|
||||
const document: Document = {
|
||||
id: documentId,
|
||||
mediaType: "application/pdf",
|
||||
...(opts.documentTitle ? { title: opts.documentTitle } : {}),
|
||||
...(opts.documentTitle
|
||||
? {
|
||||
title: opts.documentTitle,
|
||||
uri: `/fixtures/pdfs/${encodeURIComponent(opts.documentTitle)}`,
|
||||
}
|
||||
: {}),
|
||||
fingerprint: "seed-fingerprint",
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue