Detect misclassified video attachments

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dotta 2026-06-01 19:12:53 +00:00
parent e86d000c7b
commit 8af359b656
4 changed files with 89 additions and 3 deletions

View file

@ -155,6 +155,33 @@ describe("IssueAttachmentsSection", () => {
expect(fetchSpy).not.toHaveBeenCalled();
});
it("treats mp4 filenames as playable videos even with a generic binary content type", async () => {
const attachment = makeAttachment({
id: "misclassified-mp4",
originalFilename: "demo.mp4",
contentType: "application/octet-stream",
contentPath: "/api/attachments/misclassified-mp4/content",
});
await act(async () => {
root.render(
<QueryClientProvider client={queryClient}>
<IssueAttachmentsSection
attachments={[attachment]}
onDelete={vi.fn()}
onImageClick={vi.fn()}
/>
</QueryClientProvider>,
);
});
await flushReact();
const video = container.querySelector("video");
expect(video?.getAttribute("src")).toBe("/api/attachments/misclassified-mp4/content");
expect(container.textContent).toContain("application/octet-stream");
expect(fetchSpy).not.toHaveBeenCalled();
});
it("keeps generic attachments as compact file rows with open and download actions", async () => {
const attachment = makeAttachment({
id: "pdf-attachment",

View file

@ -25,8 +25,20 @@ export function isImageAttachment(attachment: Pick<IssueAttachment, "contentType
return normalizedContentType(attachment).startsWith("image/");
}
export function isVideoAttachment(attachment: Pick<IssueAttachment, "contentType">) {
return isVideoContentType(normalizedContentType(attachment));
export function isVideoAttachment(
attachment: Pick<IssueAttachment, "contentType" | "originalFilename">,
) {
if (isVideoContentType(normalizedContentType(attachment))) return true;
const filename = (attachment.originalFilename ?? "").toLowerCase();
return (
filename.endsWith(".mp4") ||
filename.endsWith(".m4v") ||
filename.endsWith(".webm") ||
filename.endsWith(".mov") ||
filename.endsWith(".qt") ||
filename.endsWith(".quicktime")
);
}
export function isMarkdownAttachment(