import { describe, expect, it } from "vitest"; import { changeFields, formData, kindOf, moveRow, noteEditor, shapeOf } from "../src/editor.ts"; const form = (pairs: [string, string][]) => new URLSearchParams(pairs); describe("note editor fields", () => { it("knows every field of every kind of page it edits", () => { const p = shapeOf("page").properties; expect(kindOf(p.portrait!)).toBe("image"); expect(kindOf(p.cover!)).toBe("image"); expect(kindOf(p.photos!)).toBe("rows"); expect(kindOf(p.links!)).toBe("links"); expect(kindOf(p.tags!)).toBe("lines"); expect(kindOf(shapeOf("make").properties.photos!)).toBe("images"); expect(kindOf(shapeOf("make").properties.date!)).toBe("date"); expect(kindOf(shapeOf("experience").properties.start!)).toBe("month"); expect(kindOf(shapeOf("product-line").properties.slots!)).toBe("group"); expect(kindOf(shapeOf("craft").properties.status!)).toBe("enum"); }); it("reads a Page text form back into note values", () => { const v = formData( "page", form([ ["page", "/about"], ["lede", " Maker of things "], ["portrait", "greg.jpg"], ["photos.0.file", "kashi.jpg"], ["photos.0.alt", "Kashi asleep"], ["photos.0.caption", "Kashi"], ["photos.1.file", "tea.jpg"], ["photos.1.alt", "Tea"], ["photos.1.remove", "1"], ["photos.2.file", ""], ["photos.2.alt", ""], ["has.publish", "1"], ["publish", "1"], ["has.favorite", "1"], ["links", "Resin\n[[Galaxy dice]]\n"], ]), new Map([["cover", ["new-cover.jpg"]]]), ); expect(v).toMatchObject({ page: "/about", lede: "Maker of things", portrait: "[[greg.jpg]]", cover: "[[new-cover.jpg]]", photos: [{ file: "[[kashi.jpg]]", alt: "Kashi asleep", caption: "Kashi" }], publish: true, links: ["[[Resin]]", "[[Galaxy dice]]"], }); expect(v.quickFacts).toBeUndefined(); expect(v.favorite).toBeUndefined(); }); it("adds uploaded photos to an image list and keeps https images", () => { const v = formData( "make", form([ ["photos.0", "https://example.com/a.jpg"], ["photos.1", "b.jpg"], ["photos.1.remove", "1"], ]), new Map([["photos", ["c.jpg", "d.jpg"]]]), ); expect(v.photos).toEqual(["https://example.com/a.jpg", "[[c.jpg]]", "[[d.jpg]]"]); }); it("clears emptied fields on an update and leaves them out on a create", () => { const v = { lede: "Hi", portrait: undefined, photos: undefined }; expect(changeFields(v, true)).toEqual({ lede: "Hi", portrait: null, photos: null }); expect(changeFields(v, false)).toEqual({ lede: "Hi" }); }); it("moves a row up or down", () => { const v = { photos: ["a", "b", "c"] }; expect(moveRow(v, "photos:2:up").photos).toEqual(["a", "c", "b"]); expect(moveRow(v, "photos:0:down").photos).toEqual(["b", "a", "c"]); expect(moveRow(v, "photos:0:up").photos).toEqual(["a", "b", "c"]); }); it("renders a picker with a thumbnail for each image", () => { const page = String( noteEditor( { type: "page", path: "Pages/About.md", title: "About", publish: true, data: { page: "/about", portrait: "[[greg.jpg]]", photos: [{ file: "[[kashi.jpg]]", alt: "Kashi" }] }, body: "Hello" }, { images: [{ name: "greg.jpg", folder: "Pages", size: 1, modified: "", usedBy: [] }], notes: [] }, ), ); expect(page).toContain('Hello"); }); });