import { describe, it, expect } from "vitest"; import { BINARY_FILE_EXTENSIONS, getFileExtension, getFileTypeIcon, isBinaryFilePath, linkifyFilePaths, } from "./filePaths"; describe("getFileExtension", () => { it("returns the lowercase extension of a simple path", () => { expect(getFileExtension("/tmp/report.pdf")).toBe("pdf"); }); it("returns the lowercase extension for uppercase file names", () => { expect(getFileExtension("/tmp/AUDIO.MP3")).toBe("mp3"); }); it("returns the extension for a path with multiple dots", () => { expect(getFileExtension("/tmp/my.file.docx")).toBe("docx"); }); it("returns an empty string when there is no extension", () => { expect(getFileExtension("/tmp/noextension")).toBe(""); }); it("returns an empty string for an empty string input", () => { expect(getFileExtension("")).toBe(""); }); it("returns the extension for a home-relative path", () => { expect(getFileExtension("~/downloads/track.wav")).toBe("wav"); }); }); describe("getFileTypeIcon", () => { it("returns the PDF icon for .pdf files", () => { expect(getFileTypeIcon("/tmp/doc.pdf")).toBe("📄"); }); it("returns the Word icon for .docx files", () => { expect(getFileTypeIcon("/tmp/report.docx")).toBe("📝"); }); it("returns the Word icon for .doc files", () => { expect(getFileTypeIcon("/tmp/old.doc")).toBe("📝"); }); it("returns the spreadsheet icon for .xlsx files", () => { expect(getFileTypeIcon("/tmp/data.xlsx")).toBe("📊"); }); it("returns the spreadsheet icon for .xls files", () => { expect(getFileTypeIcon("/tmp/data.xls")).toBe("📊"); }); it("returns the presentation icon for .pptx files", () => { expect(getFileTypeIcon("/tmp/slides.pptx")).toBe("📽️"); }); it("returns the presentation icon for .ppt files", () => { expect(getFileTypeIcon("/tmp/slides.ppt")).toBe("📽️"); }); it("returns the audio icon for .mp3 files", () => { expect(getFileTypeIcon("/tmp/song.mp3")).toBe("🎵"); }); it("returns the audio icon for .wav files", () => { expect(getFileTypeIcon("/tmp/sound.wav")).toBe("🎵"); }); it("returns the audio icon for .ogg files", () => { expect(getFileTypeIcon("/tmp/audio.ogg")).toBe("🎵"); }); it("returns the audio icon for .flac files", () => { expect(getFileTypeIcon("/tmp/lossless.flac")).toBe("🎵"); }); it("returns the audio icon for .aac files", () => { expect(getFileTypeIcon("/tmp/compressed.aac")).toBe("🎵"); }); it("returns the audio icon for .m4a files", () => { expect(getFileTypeIcon("/tmp/itunes.m4a")).toBe("🎵"); }); it("returns the video icon for .mp4 files", () => { expect(getFileTypeIcon("/tmp/video.mp4")).toBe("🎬"); }); it("returns the video icon for .avi files", () => { expect(getFileTypeIcon("/tmp/old.avi")).toBe("🎬"); }); it("returns the video icon for .mov files", () => { expect(getFileTypeIcon("/tmp/clip.mov")).toBe("🎬"); }); it("returns the video icon for .mkv files", () => { expect(getFileTypeIcon("/tmp/film.mkv")).toBe("🎬"); }); it("returns the video icon for .webm files", () => { expect(getFileTypeIcon("/tmp/stream.webm")).toBe("🎬"); }); it("returns the archive icon for .zip files", () => { expect(getFileTypeIcon("/tmp/bundle.zip")).toBe("📦"); }); it("returns the archive icon for .tar files", () => { expect(getFileTypeIcon("/tmp/archive.tar")).toBe("📦"); }); it("returns the archive icon for .gz files", () => { expect(getFileTypeIcon("/tmp/compressed.gz")).toBe("📦"); }); it("returns the disk icon for .bin files", () => { expect(getFileTypeIcon("/tmp/firmware.bin")).toBe("💿"); }); it("returns the disk icon for .iso files", () => { expect(getFileTypeIcon("/tmp/image.iso")).toBe("💿"); }); it("returns the generic folder icon for an unknown extension", () => { expect(getFileTypeIcon("/tmp/file.unknown")).toBe("📁"); }); it("returns the generic folder icon for a file with no extension", () => { expect(getFileTypeIcon("/tmp/noext")).toBe("📁"); }); }); describe("isBinaryFilePath", () => { it("returns true for a PDF path", () => { expect(isBinaryFilePath("/tmp/report.pdf")).toBe(true); }); it("returns true for an audio path", () => { expect(isBinaryFilePath("/tmp/song.mp3")).toBe(true); }); it("returns true for a video path", () => { expect(isBinaryFilePath("/tmp/clip.mp4")).toBe(true); }); it("returns true for a document path", () => { expect(isBinaryFilePath("/tmp/doc.docx")).toBe(true); }); it("returns false for a TypeScript file", () => { expect(isBinaryFilePath("/src/index.ts")).toBe(false); }); it("returns false for a text file", () => { expect(isBinaryFilePath("/tmp/output.txt")).toBe(false); }); it("returns false for a path with no extension", () => { expect(isBinaryFilePath("/tmp/file")).toBe(false); }); }); describe("BINARY_FILE_EXTENSIONS", () => { it("includes pdf", () => { expect(BINARY_FILE_EXTENSIONS).toContain("pdf"); }); it("includes common audio extensions", () => { expect(BINARY_FILE_EXTENSIONS).toContain("mp3"); expect(BINARY_FILE_EXTENSIONS).toContain("wav"); }); it("includes common video extensions", () => { expect(BINARY_FILE_EXTENSIONS).toContain("mp4"); }); it("includes common document extensions", () => { expect(BINARY_FILE_EXTENSIONS).toContain("docx"); expect(BINARY_FILE_EXTENSIONS).toContain("xlsx"); }); }); describe("linkifyFilePaths", () => { it("converts a PDF path in plain text to a file link", () => { const html = "

Saved to /tmp/report.pdf successfully.

"; const result = linkifyFilePaths(html); expect(result).toContain('data-filepath="/tmp/report.pdf"'); expect(result).toContain("📄"); expect(result).toContain('class="file-link"'); }); it("converts an audio path to a file link", () => { const html = "

Audio saved to /tmp/output.mp3

"; const result = linkifyFilePaths(html); expect(result).toContain('data-filepath="/tmp/output.mp3"'); expect(result).toContain("🎵"); }); it("does not linkify paths inside code blocks", () => { const html = "

Example:

/tmp/file.pdf
"; const result = linkifyFilePaths(html); expect(result).not.toContain('data-filepath="/tmp/file.pdf"'); expect(result).toContain("/tmp/file.pdf"); }); it("does not linkify paths inside inline code", () => { const html = "

Use /tmp/file.pdf to open it.

"; const result = linkifyFilePaths(html); expect(result).not.toContain('data-filepath="/tmp/file.pdf"'); expect(result).toContain("/tmp/file.pdf"); }); it("does not modify HTML that has no binary file paths", () => { const html = "

Hello, this is regular text with /tmp/script.sh

"; const result = linkifyFilePaths(html); expect(result).toBe(html); }); it("does not linkify text file paths", () => { const html = "

Saved to /tmp/output.txt

"; const result = linkifyFilePaths(html); expect(result).not.toContain("data-filepath"); }); it("handles a home-relative path", () => { const html = "

Saved to ~/downloads/audio.flac

"; const result = linkifyFilePaths(html); expect(result).toContain('data-filepath="~/downloads/audio.flac"'); expect(result).toContain("🎵"); }); it("handles multiple file paths in the same HTML", () => { const html = "

Files: /tmp/a.pdf and /tmp/b.mp3

"; const result = linkifyFilePaths(html); expect(result).toContain('data-filepath="/tmp/a.pdf"'); expect(result).toContain('data-filepath="/tmp/b.mp3"'); }); it("does not linkify paths that contain double quotes (invalid path character)", () => { // Double quotes are excluded from path chars so the path is not matched const html = `

Saved to /tmp/my"file.pdf

`; const result = linkifyFilePaths(html); expect(result).not.toContain("data-filepath"); }); it("preserves existing HTML tags and attributes", () => { const html = '

Saved to /tmp/report.pdf

'; const result = linkifyFilePaths(html); expect(result).toContain('class="foo"'); expect(result).toContain('data-filepath="/tmp/report.pdf"'); }); it("does not double-linkify a path already inside an anchor tag", () => { const html = '/tmp/file.pdf'; const result = linkifyFilePaths(html); // The href is inside a tag (placeholder), the text content IS linkified // but the href itself should not be modified const hrefMatches = result.match(/href="[^"]*\/tmp\/file\.pdf[^"]*"/g) ?? []; expect(hrefMatches.length).toBe(1); }); it("returns the input unchanged when html is empty", () => { expect(linkifyFilePaths("")).toBe(""); }); });