Files
WRNexusJS/packages/uploader/test/resumable.test.ts
T
Clintchiz 586a6db8ff
Quality / quality (ubuntu-latest) (push) Failing after 21s
Quality / quality (windows-latest) (push) Canceled after 0s
release: WRNexusJS 0.8.0
2026-08-02 23:18:51 +05:30

74 lines
2.7 KiB
TypeScript

import { expect, test } from "bun:test";
import { createResumableUploadManager, memoryResumableSessionStore } from "../src/index.ts";
import type { StorageDriver } from "../src/index.ts";
function driver() {
const objects = new Map<string, Uint8Array>();
const storage: StorageDriver = {
async put(key, data) {
objects.set(key, data.slice());
},
async get(key) {
const body = objects.get(key);
return body ? { body, contentType: "application/octet-stream", size: body.length } : null;
},
async delete(key) {
objects.delete(key);
},
publicUrl: () => null,
};
return { storage, objects };
}
test("resumable uploads accept out-of-order idempotent chunks and assemble once", async () => {
const { storage, objects } = driver();
const manager = createResumableUploadManager({
driver: storage,
chunkSize: 3,
maxBytes: 20,
accept: ["text/plain"],
});
const session = await manager.create({ name: "hello.txt", type: "text/plain", size: 8 });
expect(session.totalChunks).toBe(3);
expect((await manager.uploadChunk(session.id, 1, new TextEncoder().encode("lo "))).complete).toBe(
false,
);
await manager.uploadChunk(session.id, 0, new TextEncoder().encode("hel"));
await manager.uploadChunk(session.id, 0, new TextEncoder().encode("hel"));
const result = await manager.uploadChunk(session.id, 2, new TextEncoder().encode("!!"));
expect(result.complete).toBe(true);
expect(new TextDecoder().decode(objects.get(result.file!.key))).toBe("hello !!");
expect(await manager.status(session.id)).toBeNull();
});
test("resumable uploads enforce checksums, conflicts, limits, expiry, and cancellation", async () => {
let now = 0;
const { storage } = driver();
const sessions = memoryResumableSessionStore();
const manager = createResumableUploadManager({
driver: storage,
sessions,
chunkSize: 2,
maxBytes: 4,
maxSessions: 1,
ttlMs: 10,
now: () => now,
});
const session = await manager.create({ name: "data.bin", size: 4 });
await expect(manager.create({ name: "other.bin", size: 1 })).rejects.toThrow("too many");
await expect(manager.uploadChunk(session.id, 0, new Uint8Array([1, 2]), "bad")).rejects.toThrow(
"checksum",
);
await manager.uploadChunk(session.id, 0, new Uint8Array([1, 2]));
await expect(manager.uploadChunk(session.id, 0, new Uint8Array([2, 1]))).rejects.toThrow(
"different content",
);
expect(await manager.cancel(session.id)).toBe(true);
const expiring = await manager.create({ name: "expire.bin", size: 2 });
now = 11;
expect(await manager.prune()).toBe(1);
await expect(manager.uploadChunk(expiring.id, 0, new Uint8Array([1, 2]))).rejects.toThrow(
"expired",
);
});