Something went wrong. Try again.
Mirror of https://github.com/improsocial/improAn extensible Bluesky client for web
Something went wrong. Try again.
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260import { describe, it } from "node:test";import assert from "node:assert/strict";import { PluginCustomImages } from "/js/plugins/pluginCustomImages.js";
// A minimal in-memory stand-in for IndexedDbCustomImageStore, since// indexedDB isn't available in this project's node-based unit test// environment. PluginCustomImages only ever talks to its store through// list/put/remove, so this is a faithful substitute.function makeFakeStore() { const records = new Map(); // "pluginId::name" -> record return { records, async list(pluginId) { return [...records.values()].filter((r) => r.pluginId === pluginId); }, async put(pluginId, name, record) { records.set(`${pluginId}::${name}`, record); }, async remove(pluginId, name) { records.delete(`${pluginId}::${name}`); }, };}
function makeFakeValidator({ blobSize } = {}) { const calls = []; const validateImage = async (bytes, geometry, label) => { calls.push({ bytes, geometry, label }); return { size: blobSize ?? bytes.byteLength, _fakeBlob: true }; }; return { validateImage, calls };}
function bytesOfLength(n) { return new ArrayBuffer(n);}
describe("PluginCustomImages.register", () => { it("validates and stores a new image, returning the full record", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); const record = await images.register( "buddy", { name: "my_dance", frameWidth: 64, frameHeight: 64, frameCount: 8 }, bytesOfLength(1000), ); assert.deepEqual(record.name, "my_dance"); assert.deepEqual(record.frameWidth, 64); assert.deepEqual(record.size, 1000); assert.deepEqual(store.records.size, 1); });
it("rejects an invalid name", async () => { const images = new PluginCustomImages({ store: makeFakeStore(), validateImage: makeFakeValidator().validateImage, }); await assert.rejects( images.register( "buddy", { name: "has a space", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(10), ), /1-64 characters/, ); await assert.rejects( images.register( "buddy", { name: "", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(10), ), /1-64 characters/, ); });
it("allows a name that collides with a bundled manifest image, to override it", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); const record = await images.register( "buddy", { name: "idle_breathe", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(10), ); assert.deepEqual(record.name, "idle_breathe"); });
it("rejects non-positive-integer geometry", async () => { const images = new PluginCustomImages({ store: makeFakeStore(), validateImage: makeFakeValidator().validateImage, }); for (const bad of [ { frameWidth: 0, frameHeight: 1, frameCount: 1 }, { frameWidth: 1, frameHeight: -1, frameCount: 1 }, { frameWidth: 1, frameHeight: 1, frameCount: 1.5 }, { frameWidth: 1, frameHeight: 1, frameCount: "3" }, ]) { await assert.rejects( images.register("buddy", { name: "x", ...bad }, bytesOfLength(10)), /positive integers/, ); } });
it("enforces the per-plugin image count cap", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); for (let i = 0; i < 20; i++) { await images.register( "buddy", { name: `img_${i}`, frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(1), ); } await assert.rejects( images.register( "buddy", { name: "one_too_many", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(1), ), /maximum of 20/, ); });
it("does not count replacing an existing name against the count cap", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); for (let i = 0; i < 20; i++) { await images.register( "buddy", { name: `img_${i}`, frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(1), ); } // Re-registering an existing name (replacing it) must not trip the cap. const record = await images.register( "buddy", { name: "img_0", frameWidth: 2, frameHeight: 2, frameCount: 2 }, bytesOfLength(1), ); assert.deepEqual(record.frameWidth, 2); });
it("enforces the per-plugin total byte cap", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator({ blobSize: 15 * 1024 * 1024, }); const images = new PluginCustomImages({ store, validateImage }); await images.register( "buddy", { name: "big_one", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(15 * 1024 * 1024), ); await assert.rejects( images.register( "buddy", { name: "big_two", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(10 * 1024 * 1024), ), /byte limit/, ); });
it("scopes quota checks per plugin", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); for (let i = 0; i < 20; i++) { await images.register( "buddy", { name: `img_${i}`, frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(1), ); } // A different plugin's quota is untouched by buddy's 20 images. const record = await images.register( "other-plugin", { name: "img_0", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(1), ); assert.deepEqual(record.name, "img_0"); });});
describe("PluginCustomImages.list/delete/loadDescriptorsForMount", () => { it("list returns public summaries without blobs, sorted by name", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); await images.register( "buddy", { name: "zebra", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(5), ); await images.register( "buddy", { name: "apple", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(5), ); const list = await images.list("buddy"); assert.deepEqual( list.map((entry) => entry.name), ["apple", "zebra"], ); assert.deepEqual(list[0].blob, undefined); });
it("delete removes an image so it no longer counts against quota", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); await images.register( "buddy", { name: "temp", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(1), ); await images.delete("buddy", "temp"); assert.deepEqual(await images.list("buddy"), []); });
it("loadDescriptorsForMount includes the blob for PluginAssetsLoader", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); await images.register( "buddy", { name: "dance", frameWidth: 32, frameHeight: 32, frameCount: 4 }, bytesOfLength(5), ); const descriptors = await images.loadDescriptorsForMount("buddy"); assert.deepEqual(descriptors.length, 1); assert.deepEqual(descriptors[0].name, "dance"); assert(descriptors[0].blob); });
it("purgeForPlugin removes every image for that plugin only", async () => { const store = makeFakeStore(); const { validateImage } = makeFakeValidator(); const images = new PluginCustomImages({ store, validateImage }); await images.register( "buddy", { name: "a", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(1), ); await images.register( "other-plugin", { name: "b", frameWidth: 1, frameHeight: 1, frameCount: 1 }, bytesOfLength(1), ); await images.purgeForPlugin("buddy"); assert.deepEqual(await images.list("buddy"), []); assert.deepEqual((await images.list("other-plugin")).length, 1); });});