Files

71 lines
3.8 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import { setupDom, teardownDom } from "../../composer/tests/_dom.js";
import { offer, _reset } from "../../shell/mounts.js";
import { loadFeatures } from "../../shell/features.js";
import { problem, request, resize } from "./sheet.js";
let hub;
test.before(async () => { setupDom(); hub = (await import("./index.js")).default; });
test.after(() => teardownDom());
const slot = (picture = "", label = "") => ({ picture, label });
test("resizing keeps what is in place (reading order) and the request leaves trailing empty slots out", () => {
const two = [slot("a", "front"), slot("", "back")];
const six = resize(two, 2, 3);
assert.equal(six.length, 6);
assert.deepEqual(six.slice(0, 2), two);
assert.deepEqual(resize(six, 1, 2), two);
const r = request({ title: " Mara ", rows: 2, cols: 3, format: "4:3", width: 512, slots: six });
assert.equal(r.title, "Mara");
assert.deepEqual(r.slots, [{ picture: "a", label: "front" }, { picture: undefined, label: "back" }]);
});
test("a sheet needs one picture and no more than 36 slots", () => {
assert.match(problem({ rows: 2, cols: 2, slots: [slot("", "x")] }), /at least one picture/);
assert.equal(problem({ rows: 2, cols: 2, slots: [slot("a")] }), "");
assert.match(problem({ rows: 12, cols: 12, slots: [slot("a")] }), /36/);
});
test("it is hidden when the server has no refsheet module, and the button opens a dialog that sends the grid and leaves nothing behind", async () => {
_reset();
const host = document.createElement("div");
offer("assets.actions", host);
let sent;
const said = [];
const api = { media: async () => ({ media: [{ id: "a", name: "front.png", kind: "image" }, { id: "v", name: "clip.mp4", kind: "video" }] }), uploadMedia: async () => ({ media: [], problems: [] }),
refsheetMake: async (b) => { sent = b; return { media: { id: "n", name: "Sheet.png" }, missing: [] }; } };
const app = { api, dom: { pickFile: async () => null }, say: (w) => said.push(w), hasModule: () => false };
const none = await loadFeatures(["x"], { load: async () => ({ default: hub }), app, has: (n) => n in app });
assert.equal(none.mounted.length, 0);
_reset();
offer("assets.actions", host);
app.hasModule = () => true;
const { mounted } = await loadFeatures(["x"], { load: async () => ({ default: hub }), app, has: (n) => n in app });
assert.equal(mounted.length, 1);
const button = host.querySelector("button");
assert.match(button.textContent, /Reference sheet/);
button.click();
await new Promise((r) => setTimeout(r, 20));
const buttons = (text) => [...document.querySelectorAll("button")].filter((b) => b.textContent.includes(text));
assert.equal(buttons("Choose picture…").length, 6);
assert.ok(document.body.textContent.includes("Rows") && document.body.textContent.includes("Columns") && document.body.textContent.includes("Slot format")); // every control has a visible label
buttons("Choose picture…")[0].click();
await new Promise((r) => setTimeout(r, 20));
const tiles = [...document.querySelectorAll("[role=option]")];
assert.deepEqual(tiles.map((t) => t.textContent), ["front.png"]); // the bin's pictures only: a video is not offered
assert.ok(tiles[0].querySelector("img").getAttribute("src").endsWith("/a/thumb"));
tiles[0].click();
await new Promise((r) => setTimeout(r, 20));
assert.equal(buttons("Change: front.png").length, 1);
const make = [...document.querySelectorAll("button")].find((b) => b.textContent === "Make sheet");
make.click();
await new Promise((r) => setTimeout(r, 20));
assert.deepEqual(sent, { title: "", rows: 2, cols: 3, format: "1:1", width: 512, slots: [{ picture: "a", label: undefined }] });
assert.ok(said.includes("media")); // the media bin redraws on "media"
mounted[0].teardown();
assert.equal(host.textContent, "");
});