/// import { describe, expect, it } from "bun:test"; import { Hono } from "hono"; import { getFileFromContext, isFile, isReadableStream } from "../../src/core/utils"; import { MediaApi } from "../../src/media/api/MediaApi"; import { assetsPath, assetsTmpPath } from "../helper"; const mockedBackend = new Hono() .basePath("/api/media") .post("/upload/:name", async (c) => { const { name } = c.req.param(); const body = await getFileFromContext(c); return c.json({ name, is_file: isFile(body), size: body.size }); }) .get("/file/:name", async (c) => { const { name } = c.req.param(); const file = Bun.file(`${assetsPath}/${name}`); return new Response(file, { headers: { "Content-Type": file.type, "Content-Length": file.size.toString(), }, }); }); describe("MediaApi", () => { it("should give correct file upload url", () => { const host = "http://localhost"; const basepath = "/api/media"; // @ts-ignore tests const api = new MediaApi({ host, basepath, }); expect(api.getFileUploadUrl({ path: "path" } as any)).toBe(`${host}${basepath}/upload/path`); }); it("should have correct upload headers", () => { // @ts-ignore tests const api = new MediaApi({ token: "token", }); expect(api.getUploadHeaders().get("Authorization")).toBe("Bearer token"); }); it("should get file: native", async () => { const name = "image.png"; const path = `${assetsTmpPath}/${name}`; const res = await mockedBackend.request("/api/media/file/" + name); await Bun.write(path, res); const file = await Bun.file(path); expect(file.size).toBeGreaterThan(0); expect(file.type).toBe("image/png"); await file.delete(); }); it("download", async () => { // @ts-ignore tests const api = new MediaApi({}, mockedBackend.request); const name = "image.png"; const file = await api.download(name); expect(isFile(file)).toBe(true); expect(file.size).toBeGreaterThan(0); expect(file.type).toBe("image/png"); expect(file.name).toContain(name); }); it("getFile", async () => { // @ts-ignore tests const api = new MediaApi({}, mockedBackend.request); const name = "image.png"; const res = await api.getFile(name); expect(res.ok).toBe(true); // make sure it's a normal api request as usual expect(res.res.ok).toBe(true); expect(isReadableStream(res)).toBe(true); expect(isReadableStream(res.body)).toBe(true); expect(isReadableStream(res.res.body)).toBe(true); const blob = await res.res.blob(); expect(isFile(blob)).toBe(true); expect(blob.size).toBeGreaterThan(0); expect(blob.type).toBe("image/png"); expect(blob.name).toContain(name); }); it("getFileStream", async () => { // @ts-ignore tests const api = new MediaApi({}, mockedBackend.request); const name = "image.png"; const res = await api.getFileStream(name); expect(isReadableStream(res)).toBe(true); const blob = await new Response(res).blob(); expect(isFile(blob)).toBe(true); expect(blob.size).toBeGreaterThan(0); expect(blob.type).toBe("image/png"); expect(blob.name).toContain(name); }); it("should upload file in various ways", async () => { // @ts-ignore tests const api = new MediaApi({}, mockedBackend.request); const file = Bun.file(`${assetsPath}/image.png`); async function matches(req: Promise, filename: string) { const res: any = await req; expect(res.name).toBe(filename); expect(res.is_file).toBe(true); expect(res.size).toBe(file.size); } const url = "http://localhost/api/media/file/image.png"; // upload bun file await matches(api.upload(file as any, { filename: "bunfile.png" }), "bunfile.png"); // upload via request await matches(api.upload(new Request(url), { filename: "request.png" }), "request.png"); // upload via url await matches(api.upload(url, { filename: "url.png" }), "url.png"); // upload via response { const response = await mockedBackend.request(url); await matches(api.upload(response, { filename: "response.png" }), "response.png"); } // upload via readable from bun await matches(await api.upload(file.stream(), { filename: "readable.png" }), "readable.png"); // upload via readable from response { const response = (await mockedBackend.request(url)) as Response; await matches( await api.upload(response.body!, { filename: "readable.png" }), "readable.png", ); } }); });