56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { renderEmailPreview } from "../src/browser.ts";
|
|
import { renderEmail } from "../src/email.ts";
|
|
import type { BlockDocument } from "@wrnexus/blocks";
|
|
|
|
const document: BlockDocument = {
|
|
schemaVersion: 1,
|
|
kind: "email",
|
|
meta: { subject: "Local preview", lang: "en" },
|
|
theme: { tokens: {} },
|
|
root: {
|
|
id: "root",
|
|
type: "layout.email-document",
|
|
version: 1,
|
|
props: { width: "600" },
|
|
styles: {},
|
|
slots: {
|
|
content: [
|
|
{
|
|
id: "text",
|
|
type: "content.text",
|
|
version: 1,
|
|
props: { text: "Hello {{recipientName|friend}}" },
|
|
styles: {},
|
|
slots: {},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
};
|
|
|
|
test("browser preview matches production HTML/text without server validators", async () => {
|
|
const before = structuredClone(document);
|
|
for (const direction of ["ltr", "rtl"] as const) {
|
|
const options = { direction, variables: { recipientName: "<script>unsafe</script>" } };
|
|
const preview = await renderEmailPreview(document, options);
|
|
const production = await renderEmail(document, options);
|
|
expect(preview.ok).toBe(true);
|
|
expect(production.ok).toBe(true);
|
|
if (preview.ok && production.ok) {
|
|
expect(preview.value.html).toBe(production.value.parts.html.content);
|
|
expect(preview.value.text).toBe(production.value.parts.text.content);
|
|
expect(preview.value.html).toContain("<script>");
|
|
}
|
|
}
|
|
expect(document).toEqual(before);
|
|
});
|
|
|
|
test("browser preview rejects unknown blocks without mutating them", async () => {
|
|
const invalid = structuredClone(document);
|
|
invalid.root.slots.content[0].type = "unknown.block";
|
|
const before = structuredClone(invalid);
|
|
expect((await renderEmailPreview(invalid)).ok).toBe(false);
|
|
expect(invalid).toEqual(before);
|
|
});
|