mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import { Readable } from "node:stream";
|
|
import { afterAll, describe, expect, it } from "vitest";
|
|
import {
|
|
deleteObject,
|
|
getObjectSize,
|
|
getObjectStream,
|
|
listObjects,
|
|
objectExists,
|
|
putObject,
|
|
putObjectStream,
|
|
} from "../../../apps/api/src/lib/object-storage.js";
|
|
|
|
describe("object-storage (local backend)", () => {
|
|
const key = `outputs/test-${process.pid}/hello.txt`;
|
|
|
|
afterAll(async () => {
|
|
await deleteObject(key).catch(() => {});
|
|
});
|
|
|
|
it("round-trips buffers and streams with size and listing", async () => {
|
|
await putObject(key, Buffer.from("hello world"));
|
|
expect(await objectExists(key)).toBe(true);
|
|
expect(await getObjectSize(key)).toBe(11);
|
|
const chunks: Buffer[] = [];
|
|
for await (const c of await getObjectStream(key)) chunks.push(c as Buffer);
|
|
expect(Buffer.concat(chunks).toString()).toBe("hello world");
|
|
const ranged: Buffer[] = [];
|
|
for await (const c of await getObjectStream(key, { start: 6, end: 10 }))
|
|
ranged.push(c as Buffer);
|
|
expect(Buffer.concat(ranged).toString()).toBe("world");
|
|
const listed = await listObjects(`outputs/test-${process.pid}/`);
|
|
expect(listed.some((o) => o.key === key)).toBe(true);
|
|
const streamKey = `outputs/test-${process.pid}/streamed.bin`;
|
|
const written = await putObjectStream(streamKey, Readable.from([Buffer.alloc(1024, 1)]), {
|
|
maxBytes: 2048,
|
|
});
|
|
expect(written).toBe(1024);
|
|
await expect(
|
|
putObjectStream(
|
|
`outputs/test-${process.pid}/too-big.bin`,
|
|
Readable.from([Buffer.alloc(4096, 1)]),
|
|
{
|
|
maxBytes: 2048,
|
|
},
|
|
),
|
|
).rejects.toThrow(/exceeds/i);
|
|
await deleteObject(streamKey);
|
|
});
|
|
|
|
it("rejects path traversal in keys", async () => {
|
|
await expect(putObject("outputs/../../etc/passwd", Buffer.from("x"))).rejects.toThrow(
|
|
/invalid/i,
|
|
);
|
|
});
|
|
});
|