163 lines
5.2 KiB
JavaScript
163 lines
5.2 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { mkdtemp, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import test from "node:test";
|
|
|
|
import { convertTemplate } from "./convert-template.mjs";
|
|
|
|
test("converts an exported template to the bundled default-template shape", async () => {
|
|
const root = await mkdtemp(path.join(os.tmpdir(), "template-converter-"));
|
|
const appData = path.join(root, "app_data");
|
|
const inputDirectory = path.join(root, "templates", "modern");
|
|
const input = path.join(inputDirectory, "source.json");
|
|
const output = path.join(inputDirectory, "template.json");
|
|
const decorativeImage = path.join(
|
|
appData,
|
|
"pptx-to-json",
|
|
"session",
|
|
"images",
|
|
"decoration.png",
|
|
);
|
|
const preview = path.join(appData, "uploads", "template-previews", "id", "slide_1.png");
|
|
const staticDirectory = path.join(inputDirectory, "static");
|
|
await mkdir(path.dirname(decorativeImage), { recursive: true });
|
|
await mkdir(path.dirname(preview), { recursive: true });
|
|
await mkdir(staticDirectory, { recursive: true });
|
|
await writeFile(decorativeImage, "decorative image bytes");
|
|
await writeFile(preview, "preview bytes");
|
|
await writeFile(path.join(staticDirectory, "stale.png"), "stale bytes");
|
|
await writeFile(
|
|
input,
|
|
JSON.stringify({
|
|
id: "modern",
|
|
name: "Modern",
|
|
description: null,
|
|
created_at: "remove only this top-level key",
|
|
merged_components: {
|
|
components: [{ id: "merged", metadata: { created_at: "keep nested" } }],
|
|
},
|
|
layouts: {
|
|
layouts: [
|
|
{
|
|
id: "cover",
|
|
custom_key: "keep me",
|
|
components: [
|
|
{
|
|
elements: [
|
|
{
|
|
type: "image",
|
|
data: "/app_data/pptx-to-json/session/images/editable.png",
|
|
decorative: false,
|
|
is_icon: false,
|
|
custom_image_key: true,
|
|
},
|
|
{
|
|
type: "image",
|
|
data: "/app_data/pptx-to-json/session/images/icon.svg",
|
|
decorative: true,
|
|
is_icon: true,
|
|
},
|
|
{
|
|
type: "image",
|
|
data: "/app_data/pptx-to-json/session/images/decoration.png",
|
|
decorative: true,
|
|
is_icon: false,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
assets: {
|
|
fonts: { Montserrat: "https://fonts.example/montserrat.css" },
|
|
images: ["/app_data/unused.png"],
|
|
slide_image_urls: [
|
|
"http://127.0.0.1:8000/app_data/uploads/template-previews/id/slide_1.png",
|
|
],
|
|
},
|
|
}),
|
|
);
|
|
|
|
const result = await convertTemplate({ input, output, appData });
|
|
const converted = JSON.parse(await readFile(output, "utf8"));
|
|
|
|
assert.deepEqual(Object.keys(converted), [
|
|
"id",
|
|
"name",
|
|
"description",
|
|
"thumbnail",
|
|
"merged_components",
|
|
"layouts",
|
|
"fonts",
|
|
]);
|
|
assert.equal(converted.description, "");
|
|
assert.equal(converted.thumbnail, "static/thumbnail.png");
|
|
assert.equal(converted.merged_components[0].metadata.created_at, "keep nested");
|
|
assert.equal(converted.layouts[0].custom_key, "keep me");
|
|
assert.equal(converted.layouts[0].components[0].elements[0].custom_image_key, true);
|
|
assert.equal(
|
|
converted.layouts[0].components[0].elements[0].data,
|
|
"/static/images/replaceable_template_image.png",
|
|
);
|
|
assert.equal(
|
|
converted.layouts[0].components[0].elements[1].data,
|
|
"/static/icons/placeholder.svg",
|
|
);
|
|
assert.equal(
|
|
converted.layouts[0].components[0].elements[2].data,
|
|
"static/decoration.png",
|
|
);
|
|
assert.deepEqual(converted.fonts, {
|
|
Montserrat: "https://fonts.example/montserrat.css",
|
|
});
|
|
assert.equal(
|
|
await readFile(path.join(staticDirectory, "decoration.png"), "utf8"),
|
|
"decorative image bytes",
|
|
);
|
|
assert.equal(
|
|
await readFile(path.join(staticDirectory, "thumbnail.png"), "utf8"),
|
|
"preview bytes",
|
|
);
|
|
await assert.rejects(readFile(path.join(staticDirectory, "stale.png")), /ENOENT/);
|
|
assert.equal(result.assetCount, 2);
|
|
});
|
|
|
|
test("fails before writing output when a retained asset is missing", async () => {
|
|
const root = await mkdtemp(path.join(os.tmpdir(), "template-converter-missing-"));
|
|
const input = path.join(root, "source.json");
|
|
const output = path.join(root, "output", "template.json");
|
|
await writeFile(
|
|
input,
|
|
JSON.stringify({
|
|
id: "missing",
|
|
name: "Missing",
|
|
layouts: [
|
|
{
|
|
components: [
|
|
{
|
|
elements: [
|
|
{
|
|
type: "image",
|
|
data: "/app_data/no.png",
|
|
decorative: true,
|
|
is_icon: false,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
merged_components: [],
|
|
assets: { fonts: {} },
|
|
}),
|
|
);
|
|
|
|
await assert.rejects(
|
|
convertTemplate({ input, output, appData: path.join(root, "app_data") }),
|
|
/Referenced asset does not exist/,
|
|
);
|
|
await assert.rejects(readFile(output), /ENOENT/);
|
|
});
|