import { describe, expect, test } from "bun:test" import imageLexicon from "../../lexicons/pics/pixl/image.json" import { IMAGE_ENCODINGS, MAX_IMAGE_BYTES } from "../config" import { imageCid, imageDeletion, imageFile, imageUpload } from "./image-contract" describe("image action inputs", () => { test("accepts a non-empty image", () => { const file = new File(["image"], "image.png", { type: "image/png" }) expect(imageFile.parse(file)).toEqual({ file, encoding: "image/png" }) expect(imageUpload.parse({ image: file, alt: null })).toEqual({ image: { file, encoding: "image/png" }, alt: "", }) expect(imageUpload.safeParse({ image: file, alt: null }).success).toBeFalse() }) test.each([ [new File([], "empty.png", { type: "image/png" }), "Choose an image to upload"], [ new File(["image"], "image.tiff", { type: "image/tiff" }), "Images must be JPEG, PNG, WebP, GIF, or AVIF", ], [ new File(["text"], "notes.txt", { type: "text/plain" }), "Images must be JPEG, PNG, WebP, GIF, or AVIF", ], [ new File([new Uint8Array(MAX_IMAGE_BYTES + 1)], "large.png", { type: "image/png" }), "Images must be 50 MB or smaller", ], ])("rejects invalid files", (file, message) => { const result = imageFile.safeParse(file) expect(result.success).toBeFalse() if (!result.success) expect(result.error.issues[0]?.message).toBe(message) }) test("validates blob CIDs", () => { expect( imageCid.parse("bafkreibjfgx2gprinfvicegelk5kosd6y2frmqpqzwqkg7usac74l3t2v4"), ).toStartWith("bafk") const result = imageCid.safeParse("not-a-cid") expect(result.success).toBeFalse() if (!result.success) expect(result.error.issues[0]?.message).toBe("Invalid image CID") }) test("validates image deletion references", () => { const input = { rkey: "3jxf7z2k3q2aa", recordCid: "bafkreibjfgx2gprinfvicegelk5kosd6y2frmqpqzwqkg7usac74l3t2v4", } expect(imageDeletion.parse(input)).toEqual(input) expect(imageDeletion.safeParse({ ...input, rkey: "not-a-tid" }).success).toBeFalse() expect(imageDeletion.safeParse({ ...input, recordCid: "not-a-cid" }).success).toBeFalse() }) test("keeps the upload and record limits aligned", () => { expect(imageLexicon.defs.main.record.properties.image.maxSize).toBe(MAX_IMAGE_BYTES) expect(imageLexicon.defs.main.record.properties.image.accept).toEqual([...IMAGE_ENCODINGS]) expect(imageLexicon.defs.main.record.required).not.toContain("preview") }) })