Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
eyeseast committed Apr 15, 2024
2 parents 41ebbfd + 1189565 commit dd26d02
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 51 deletions.
20 changes: 6 additions & 14 deletions src/lib/components/forms/DocumentUpload.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@
import * as documents from "$lib/api/documents";
import { DOCUMENT_TYPES } from "@/config/config.js";
import { isSupported } from "@/lib/utils/validateFiles";
import {
filenameToTitle,
getFileExtension,
isSupported,
} from "@/lib/utils/files";
let files: File[] = [];
let projects: Project[] = [];
Expand Down Expand Up @@ -167,18 +171,6 @@
files = files.filter((f, i) => i !== index);
}
function formatFileType(filetype: string) {
if (filetype && filetype.includes("/")) {
return filetype.split("/")[1];
}
return "unknown";
}
function filenameToTitle(filename: string): string {
const [name, ...ext] = filename.split(".");
return name.replace(/_+/g, " ").replace(/\s+/, " ").trim();
}
// handle uploads client side instead of going through the server
async function onSubmit(e: SubmitEvent) {
loading = true;
Expand Down Expand Up @@ -224,7 +216,7 @@
{#each files as file, index}
<Flex align="center" gap={1}>
<p class="fileInfo">
{formatFileType(file.type)} / {filesize(file.size)}
{getFileExtension(file)} / {filesize(file.size)}
</p>
<div class="title">
<Text name="title" value={filenameToTitle(file.name)} required />
Expand Down
100 changes: 100 additions & 0 deletions src/lib/utils/files.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { describe, test, it, expect } from "vitest";
import * as files from "./files";

describe("files.getFileExtensionFromType", () => {
it("returns the second half of a Mimetype", () => {
expect(files.getFileExtensionFromType("application/pdf")).toEqual("pdf");
expect(files.getFileExtensionFromType("image/jpeg")).toEqual("jpeg");
});
it("returns the provided input if not a Mimetype", () => {
expect(files.getFileExtensionFromType("")).toEqual("");
expect(files.getFileExtensionFromType("pdf")).toEqual("pdf");
expect(files.getFileExtensionFromType(undefined)).toEqual(undefined);
});
});

describe("files.getFileExtension", () => {
it("returns the extension from the end of the filename", () => {
const file1 = new File([], "document.pdf");
const file2 = new File([], "image.jpg");
expect(files.getFileExtension(file1)).toEqual("pdf");
expect(files.getFileExtension(file2)).toEqual("jpg");
});

it("returns the last extension", () => {
const file = new File([], "period.delimited.filename.pdf");
expect(files.getFileExtension(file)).toEqual("pdf");
});

it("checks the file type if it's provided", () => {
const file = new File([], "filename", { type: "application/pdf" });
expect(files.getFileExtension(file)).toEqual("pdf");
});

it("returns undefined if neither filename extension nor file type", () => {
const file = new File([], "filename");
expect(files.getFileExtension(file)).toBeUndefined();
});
});

test("files.isSupported", () => {
const file1 = new File([], "document.pdf");
const file2 = new File([], "invalid.zip");
expect(files.isSupported(file1)).toBe(true);
expect(files.isSupported(file2)).toBe(false);
});

describe("files.removeUnsupportedTypes", () => {
it("evaluates the filename for the type", () => {
const file1 = new File([], "document.pdf");
const file2 = new File([], "invalid.zip");
expect(files.removeUnsupportedTypes([file1, file2])).toEqual([file1]);
});
it("ignores files missing an extension", () => {
const file1 = new File([], "document.pdf");
const file2 = new File([], "pdf");
expect(files.removeUnsupportedTypes([file1, file2])).toEqual([file1]);
});
it("normalizes filenames to lowercase", () => {
const file1 = new File([], "document.pdf");
const file2 = new File([], "valid.PDF");
expect(files.removeUnsupportedTypes([file1, file2])).toEqual([
file1,
file2,
]);
});
});

describe("files.isWithinSizeLimit", () => {
it("enforces a 500MB max size for PDF files", () => {
let file = new File([new ArrayBuffer(128000)], "document.pdf");
expect(files.isWithinSizeLimit(file)).toBe(true);
file = new File([new ArrayBuffer(525336576)], "document.pdf");
expect(files.isWithinSizeLimit(file)).toBe(true);
file = new File([new ArrayBuffer(525336576)], "document");
expect(files.isWithinSizeLimit(file)).toBe(false);
file = new File([new ArrayBuffer(525336577)], "document", {
type: "application/pdf",
});
expect(files.isWithinSizeLimit(file)).toBe(false);
});
it("enforces a 25MB max size for other file types", () => {
let file = new File([new ArrayBuffer(128000)], "image.png");
expect(files.isWithinSizeLimit(file)).toBe(true);
file = new File([new ArrayBuffer(27262976)], "image", {
type: "image/png",
});
expect(files.isWithinSizeLimit(file)).toBe(true);
file = new File([new ArrayBuffer(27262977)], "image");
expect(files.isWithinSizeLimit(file)).toBe(false);
});
});

test("files.filenameToTitle", () => {
expect(files.filenameToTitle("foobar.zip")).toEqual("foobar");
expect(files.filenameToTitle("foo.bar.baz.zip")).toEqual("foo");
expect(files.filenameToTitle("BIP bim_bAp")).toEqual("BIP bim bAp");
expect(files.filenameToTitle("PDF_FINAL_FINAL 2")).toEqual(
"PDF FINAL FINAL 2",
);
});
47 changes: 47 additions & 0 deletions src/lib/utils/files.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {
DOCUMENT_TYPES,
PDF_SIZE_LIMIT,
DOCUMENT_SIZE_LIMIT,
} from "@/config/config.js";

const types = new Set(DOCUMENT_TYPES);

export function getFileExtensionFromType(filetype?: string) {
if (filetype?.includes("/")) {
return filetype.split("/")[1];
}
return filetype;
}

export function getFileExtension(file: File) {
if (file.name.includes(".")) {
return file.name.toLowerCase().trim().split(".").pop();
} else if (file.type) {
return getFileExtensionFromType(file.type);
}
}

export function isSupported(file: File) {
const extension = getFileExtension(file);
return types.has(extension);
}

/** Returns an array of only files with supported types */
export function removeUnsupportedTypes(files: File[]) {
return files.filter(isSupported);
}

export function isWithinSizeLimit(file: File) {
const { size } = file;
const extension = getFileExtension(file);
if (extension === "pdf") {
return size <= PDF_SIZE_LIMIT;
} else {
return size <= DOCUMENT_SIZE_LIMIT;
}
}

export function filenameToTitle(filename: string): string {
const [name, ...ext] = filename.split(".");
return name.replace(/_/g, " ");
}
20 changes: 0 additions & 20 deletions src/lib/utils/validateFiles.test.ts

This file was deleted.

17 changes: 0 additions & 17 deletions src/lib/utils/validateFiles.ts

This file was deleted.

0 comments on commit dd26d02

Please sign in to comment.