| 1 | const dir = vi.hoisted(() => { |
| 2 | const fs = process.getBuiltinModule("node:fs"); |
| 3 | const os = process.getBuiltinModule("node:os"); |
| 4 | const dir = fs.mkdtempSync(os.tmpdir() + "/clover-sot-test-"); |
| 5 | fs.mkdirSync(dir + "/raw"); |
| 6 | fs.mkdirSync(dir + "/derived"); |
| 7 | Object.assign(process.env, { |
| 8 | CLOVER_DB: dir + "/db", |
| 9 | CLOVER_FILE_RAW: dir + "/raw", |
| 10 | CLOVER_FILE_DERIVED: dir + "/derived", |
| 11 | CLOVER_SOT_KEY: "test", |
| 12 | }); |
| 13 | return dir; |
| 14 | }); |
| 15 | afterAll(() => fs.rmSync(dir, { recursive: true, force: true })); |
| 16 | |
| 17 | const data = crypto.randomBytes(1_000_000); |
| 18 | const url = "http://localhost/file/new%20home%20[rev%203].mp3"; |
| 19 | fs.writeFileSync(dir + "/raw/new home [rev 3].mp3", data); |
| 20 | mediaFiles.createFile({ |
| 21 | path: "/new home [rev 3].mp3", |
| 22 | date: new Date(0), |
| 23 | hash: crypto.createHash("sha1").update(data).digest("hex"), |
| 24 | size: data.length, |
| 25 | duration: 0, |
| 26 | dimensions: "", |
| 27 | contents: "", |
| 28 | }); |
| 29 | |
| 30 | test("requests for the same file do not share a file offset", async () => { |
| 31 | // the second request arrives once the first holds the descriptor |
| 32 | const first = await app.fetch(new Request(url)); |
| 33 | const second = await app.fetch(new Request(url)); |
| 34 | const bodies = await Promise.all([first.arrayBuffer(), second.arrayBuffer()]); |
| 35 | for (const body of bodies) assert.ok(data.equals(Buffer.from(body))); |
| 36 | }); |
| 37 | |
| 38 | test("a range is served as partial content", async () => { |
| 39 | const response = await app.fetch(new Request(url, { headers: { Range: "bytes=70000-" } })); |
| 40 | assert.equal(response.status, 206); |
| 41 | assert.equal(response.headers.get("Content-Range"), `bytes 70000-999999/1000000`); |
| 42 | assert.equal(response.headers.get("Content-Length"), "930000"); |
| 43 | assert.ok(data.subarray(70000).equals(Buffer.from(await response.arrayBuffer()))); |
| 44 | }); |
| 45 | |
| 46 | import { strict as assert } from "node:assert"; |
| 47 | import * as crypto from "node:crypto"; |
| 48 | import * as fs from "node:fs"; |
| 49 | import { afterAll, test, vi } from "vitest"; |
| 50 | import * as mediaFiles from "./file-viewer/models/media-files.ts"; |
| 51 | import app from "./source-of-truth.ts"; |