Something went wrong. Try again.
a tool for shared writing and social publishing
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315import { describe, expect, it } from "vitest";import { processBlocksToPages } from "./factsToPagesRecord";import type { Fact } from "src/replicache";import type { Attribute } from "src/replicache/attributes";
let n = 0;const fact = (f: Omit<Fact<Attribute>, "id">) => ({ id: `f${n++}`, ...f }) as Fact<Attribute>;const block = (entity: string, value: string) => fact({ entity, attribute: "block/type", data: { type: "block-type-union", value }, } as Omit<Fact<"block/type">, "id">);const child = (parent: string, value: string, position: string) => fact({ entity: parent, attribute: "card/block", data: { type: "ordered-reference", value, position }, });
describe("processBlocksToPages", () => { it("publishes only the theme colors a page overrides", async () => { let facts = [ fact({ entity: "root", attribute: "root/page", data: { type: "ordered-reference", value: "page", position: "a0" }, }), fact({ entity: "page", attribute: "theme/card-background", data: { type: "color", value: "0, 0%, 100%, 0.5" }, }), fact({ entity: "page", attribute: "theme/accent-background", data: { type: "color", value: "0, 100%, 100%, 1" }, }), ]; let { pages } = await processBlocksToPages({ facts, root_entity: "root", hooks: { uploadImage: async () => undefined, uploadPoll: null }, }); expect(pages[0].theme).toEqual({ $type: "pub.leaflet.theme.page", pageBackground: { $type: "pub.leaflet.theme.color#rgba", r: 255, g: 255, b: 255, a: 50, }, accentBackground: { $type: "pub.leaflet.theme.color#rgb", r: 255, g: 0, b: 0, }, }); });
it("omits the page theme when a page overrides nothing", async () => { let facts = [ fact({ entity: "root", attribute: "root/page", data: { type: "ordered-reference", value: "page", position: "a0" }, }), ]; let { pages } = await processBlocksToPages({ facts, root_entity: "root", hooks: { uploadImage: async () => undefined, uploadPoll: null }, }); expect(pages[0]).not.toHaveProperty("theme"); });
it("publishes a canvas page's background image and pattern", async () => { let facts = [ fact({ entity: "root", attribute: "root/page", data: { type: "ordered-reference", value: "page", position: "a0" }, }), fact({ entity: "page", attribute: "page/type", data: { type: "page-type-union", value: "canvas" }, }), fact({ entity: "page", attribute: "canvas/background-pattern", data: { type: "canvas-pattern-union", value: "plain" }, }), fact({ entity: "page", attribute: "theme/card-background-image", data: { type: "image", src: "https://example.com/bg.png", fallback: "", width: 1200, height: 1200, }, }), fact({ entity: "page", attribute: "theme/card-background-image-repeat", data: { type: "number", value: 320.7 }, }), fact({ entity: "page", attribute: "theme/card-background-image-opacity", data: { type: "number", value: 0.5 }, }), ]; let uploaded: string[] = []; let { pages } = await processBlocksToPages({ facts, root_entity: "root", hooks: { uploadImage: async (src) => { uploaded.push(src); return { ref: { $link: src } } as any; }, uploadPoll: null, }, }); expect(uploaded).toEqual(["https://example.com/bg.png"]); expect(pages[0]).toMatchObject({ $type: "pub.leaflet.pages.canvas", pattern: "plain", background: { $type: "pub.leaflet.pages.canvas#background", image: { ref: { $link: "https://example.com/bg.png" } }, width: 320, opacity: 50, }, }); });
it("publishes an embedded canvas as a block referencing its sized canvas page", async () => { let facts = [ fact({ entity: "root", attribute: "root/page", data: { type: "ordered-reference", value: "page", position: "a0" }, }), child("page", "embedded-canvas", "a0"), block("embedded-canvas", "embedded-canvas"), fact({ entity: "embedded-canvas", attribute: "block/card", data: { type: "reference", value: "canvasPage" }, }), fact({ entity: "embedded-canvas", attribute: "image/alt", data: { type: "string", value: "A sketch of a cat" }, }), fact({ entity: "canvasPage", attribute: "page/type", data: { type: "page-type-union", value: "canvas" }, }), fact({ entity: "canvasPage", attribute: "canvas/fixed-width", data: { type: "number", value: 624 }, }), fact({ entity: "canvasPage", attribute: "canvas/fixed-height", data: { type: "number", value: 240.5 }, }), ]; let { pages } = await processBlocksToPages({ facts, root_entity: "root", hooks: { uploadImage: async () => undefined, uploadPoll: null }, }); expect(pages.map((p) => p.id)).toEqual(["page", "canvasPage"]); expect(pages[0].blocks[0].block).toEqual({ $type: "pub.leaflet.blocks.embeddedCanvas", id: "canvasPage", alt: "A sketch of a cat", }); expect(pages[1]).toMatchObject({ $type: "pub.leaflet.pages.canvas", width: 624, height: 240, blocks: [], }); });
it("publishes a canvas group as a linear document canvas block", async () => { let facts = [ fact({ entity: "root", attribute: "root/page", data: { type: "ordered-reference", value: "page", position: "a0" }, }), fact({ entity: "page", attribute: "page/type", data: { type: "page-type-union", value: "canvas" }, }), fact({ entity: "page", attribute: "canvas/block", data: { type: "spatial-reference", value: "group", position: { x: 10.4, y: 20.6 }, }, }), block("group", "group"), fact({ entity: "group", attribute: "canvas/block/width", data: { type: "number", value: 400 }, }), child("group", "second", "a1"), child("group", "first", "a0"), block("first", "heading"), block("second", "horizontal-rule"), fact({ entity: "page", attribute: "canvas/block", data: { type: "spatial-reference", value: "empty", position: { x: 0, y: 0 }, }, }), block("empty", "group"), ]; let { pages } = await processBlocksToPages({ facts, root_entity: "root", hooks: { uploadImage: async () => undefined, uploadPoll: null }, }); expect(pages).toHaveLength(1); expect(pages[0].$type).toBe("pub.leaflet.pages.canvas"); expect(pages[0].blocks).toEqual([ { $type: "pub.leaflet.pages.canvas#block", x: 10, y: 20, width: 400, block: { $type: "pub.leaflet.pages.linearDocument", blocks: [ expect.objectContaining({ block: expect.objectContaining({ $type: "pub.leaflet.blocks.header", }), }), expect.objectContaining({ block: { $type: "pub.leaflet.blocks.horizontalRule" }, }), ], }, }, ]); });
it("publishes the alignment of a lone canvas text block", async () => { let canvasBlock = (value: string, x: number) => fact({ entity: "page", attribute: "canvas/block", data: { type: "spatial-reference", value, position: { x, y: 0 } }, }); let aligned = (entity: string) => fact({ entity, attribute: "block/text-alignment", data: { type: "text-alignment-type-union", value: "center" }, }); let facts = [ fact({ entity: "root", attribute: "root/page", data: { type: "ordered-reference", value: "page", position: "a0" }, }), fact({ entity: "page", attribute: "page/type", data: { type: "page-type-union", value: "canvas" }, }), canvasBlock("heading", 0), block("heading", "heading"), aligned("heading"), canvasBlock("rule", 100), block("rule", "horizontal-rule"), aligned("rule"), ]; let { pages } = await processBlocksToPages({ facts, root_entity: "root", hooks: { uploadImage: async () => undefined, uploadPoll: null }, }); expect(pages[0].blocks).toEqual([ expect.objectContaining({ block: expect.objectContaining({ $type: "pub.leaflet.blocks.header" }), alignment: "lex:pub.leaflet.pages.linearDocument#textAlignCenter", }), expect.not.objectContaining({ alignment: expect.anything() }), ]); });});