Files

55 lines
2.3 KiB
TypeScript

import { expect, test } from "bun:test"
import { rm } from "node:fs/promises"
import { basename, dirname } from "node:path"
import { Effect } from "effect"
import { Browser } from "../src/rpc.js"
import { BrowserFiles } from "../src/files.js"
import { BrowserTools } from "../src/tools.js"
const tabID = Browser.TabID.make(`tab_${crypto.randomUUID()}`)
const navigate = (url: string) => BrowserTools.normalizeAction({ type: "navigate", tabID, url })
test("URL normalization rejects filesystem paths instead of treating them as hostnames", () => {
for (const path of ["/tmp/page.html", "./page.html", "../page.html", "C:\\Users\\me\\page.html", "D:/page.html"])
expect(() => navigate(path)).toThrow("Unsupported browser URL")
expect(navigate("example.com/docs")).toEqual({ type: "navigate", tabID, url: "https://example.com/docs" })
expect(navigate("localhost:8000")).toEqual({ type: "navigate", tabID, url: "http://localhost:8000/" })
expect(BrowserTools.normalizeAction({ type: "tabs.open" })).toEqual({ type: "tabs.open" })
expect(BrowserTools.normalizeAction({ type: "tabs.open", url: " " })).toEqual({
type: "tabs.open",
url: "about:blank",
})
})
test("URL normalization fails fast when percent-encoding exceeds the command bound", () => {
const input = `https://example.com/${"é".repeat(400)}`
expect(input.length).toBeLessThan(2_048)
expect(new URL(input).href.length).toBeGreaterThan(2_048)
expect(() => navigate(input)).toThrow()
})
test("saved capture names never escape their directory or name a Windows device", async () => {
const file = (name: string) => ({
id: Browser.FileID.make(`file_${crypto.randomUUID()}`),
name,
mime: "text/plain",
data: new TextEncoder().encode(name),
})
const saved = await Effect.runPromise(
BrowserFiles.save([file(".."), file("."), file("CON.txt"), file("lpt1"), file("report.html")]),
)
try {
expect(saved.map((entry) => basename(entry.path))).toEqual([
"capture",
"capture",
"capture",
"capture",
"report.html",
])
expect(saved.map((entry) => entry.name)).toEqual(["..", ".", "CON.txt", "lpt1", "report.html"])
expect(await Bun.file(saved[0]!.path).text()).toBe("..")
} finally {
await rm(dirname(dirname(saved[0]!.path)), { recursive: true, force: true })
}
})