/** * The complete email that each of the site's own templates sends. * * Every other check here reads for a fragment, so a render that kept the * opening and lost the ticket link, a row, or a whole conditional block would * still pass. These read the whole email, so nothing can go missing quietly. * * One booking of one ticket on a free listing, with nothing owed, which is the * shape that leaves every conditional block out. The blocks themselves have * their own checks in `render-content.test.ts`. */ import { assertStringIncludes } from "@std/assert"; import { expect } from "@std/expect"; import { describe, it as test } from "@std/testing/bdd"; import { renderEmailContent } from "#shared/email-renderer.ts"; import type { EmailContent } from "#templates/email/shared.ts"; import { makeTestEntry as makeEntry } from "#test-utils/factories.ts"; import type { EmailTemplateType } from "#types"; import { buildTestData, describeEmailRenderer } from "./test-helpers.ts"; const WHOLE_EMAIL = { admin: { html: `

New registration

ListingQtyPrice
Test Listing1
`, subject: "New registration: Jane Doe for Test Listing", text: `New registration Name: Jane Doe Email: jane@example.com Phone: 555-1234 Test Listing: 1 ticket`, }, confirmation: { html: `

Thanks for registering!

You're confirmed for Test Listing.

ListingQtyPrice
Test Listing1

View your tickets

Or copy this link: https://example.com/t/ABC

`, subject: "Your tickets for Test Listing", text: `Thanks for registering! You're confirmed for Test Listing. Test Listing: 1 ticket View your tickets: https://example.com/t/ABC`, }, } as const satisfies Record; const EVERY_PART = ["subject", "html", "text"] as const; describeEmailRenderer(() => { describe("the whole email the site's own wording sends", () => { for (const [which, whole] of Object.entries(WHOLE_EMAIL)) { for (const part of EVERY_PART) { test(`the ${which} email's ${part}, whole`, async () => { const data = await buildTestData([makeEntry()]); const sent = await renderEmailContent( which as EmailTemplateType, data, ); expect(sent[part]).toBe(whole[part]); }); } } }); }); describe("the whole email the site's own wording sends with answers", () => { describeEmailRenderer(() => { const data = () => buildTestData([makeEntry()], { answerLines: new Map([ [ 42, new Map([ [ 1, [ { question: "Any allergies?", text: "Peanuts and nuts", }, ], ], ]), ], ]), }); test("the confirmation prints each answer", async () => { const sent = await renderEmailContent("confirmation", await data()); assertStringIncludes( sent.text, "Any allergies?: Peanuts and nuts", ); assertStringIncludes( sent.html, "Any allergies?: Peanuts <b>and</b> nuts", ); }); test("the admin notification prints each answer with its listing", async () => { const sent = await renderEmailContent("admin", await data()); assertStringIncludes( sent.text, "Any allergies? (Test Listing): Peanuts and nuts", ); assertStringIncludes( sent.html, "Any allergies? (Test Listing): Peanuts <b>and</b> nuts", ); }); }); });