import { jest, test, expect } from "@jest/globals"; import os from "os"; import path from "path"; import fs from "fs"; import * as got from "got"; import nodemailer from "nodemailer"; import html from "@leafac/html"; import killTheNewsletter from "."; jest.setTimeout(300_000); test("Kill the Newsletter!", async () => { // Start servers const rootDirectory = fs.mkdtempSync( path.join(os.tmpdir(), "kill-the-newsletter--test--") ); const { webApplication, emailApplication } = killTheNewsletter(rootDirectory); const webServer = webApplication.listen( new URL(webApplication.get("url")).port ); const emailServer = emailApplication.listen( new URL(webApplication.get("email")).port ); const webClient = got.default.extend({ prefixUrl: webApplication.get("url"), }); const emailClient = nodemailer.createTransport(webApplication.get("email")); const emailHostname = new URL(webApplication.get("url")).hostname; // Create feed const create = (await webClient.post("", { form: { name: "A newsletter" } })) .body; expect(create).toMatch(`“A newsletter” inbox created`); const feedReference = create.match(/\/feeds\/([a-z0-9]{16})\.xml/)![1]; // Test feed properties const feedOriginal = await webClient.get(`feeds/${feedReference}.xml`); expect(feedOriginal.headers["content-type"]).toMatch("application/atom+xml"); expect(feedOriginal.headers["x-robots-tag"]).toBe("noindex"); expect(feedOriginal.body).toMatch(html`A newsletter`); // Test alternate const alternateReference = feedOriginal.body.match( /\/alternates\/([a-z0-9]{16})\.html/ )![1]; const alternate = await webClient.get( `alternates/${alternateReference}.html` ); expect(alternate.headers["content-type"]).toMatch("text/html"); expect(alternate.headers["x-robots-tag"]).toBe("noindex"); expect(alternate.body).toMatch(`Enjoy your readings!`); // Test email with HTML await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for a second to test that the ‘’ field will be updated await emailClient.sendMail({ from: "publisher@example.com", to: `${feedReference}@${emailHostname}`, subject: "Test email with HTML", html: html`

Some HTML

`, }); const feedWithHTMLEntry = (await webClient.get(`feeds/${feedReference}.xml`)) .body; expect(feedWithHTMLEntry.match(/(.+?)<\/updated>/)![1]).not.toBe( feedOriginal.body.match(/(.+?)<\/updated>/)![1] ); expect(feedWithHTMLEntry).toMatch( html`publisher@example.com` ); expect(feedWithHTMLEntry).toMatch(html`Test email with HTML`); expect(feedWithHTMLEntry).toMatch( // prettier-ignore html`${`

Some HTML

`}\n
` ); // Test email with text await emailClient.sendMail({ from: "publisher@example.com", to: `${feedReference}@${emailHostname}`, subject: "Test email with text", text: "A link: https://kill-the-newsletter.com", }); expect((await webClient.get(`feeds/${feedReference}.xml`)).body).toMatch( // prettier-ignore html`${`

A link: https://kill-the-newsletter.com

`}
` ); // Test email missing fields await emailClient.sendMail({ to: `${feedReference}@${emailHostname}`, }); const feedMissingFields = (await webClient.get(`feeds/${feedReference}.xml`)) .body; expect(feedMissingFields).toMatch(html``); expect(feedMissingFields).toMatch(html``); expect(feedMissingFields).toMatch(html``); // Test email to nonexistent ‘to’ (gets ignored) await emailClient.sendMail({ from: "publisher@example.com", to: `nonexistent@${emailHostname}`, subject: "Test email to nonexistent ‘to’ (gets ignored)", text: "A link: https://kill-the-newsletter.com", }); expect((await webClient.get(`feeds/${feedReference}.xml`)).body).not.toMatch( "Test email to nonexistent ‘to’ (gets ignored)" ); // Test truncation for (let index = 1; index <= 5; index++) await emailClient.sendMail({ from: "publisher@example.com", to: `${feedReference}@${emailHostname}`, subject: `Test truncation: ${index}`, text: `TRUNCATION ${index} `.repeat(10_000), }); const feedTruncated = (await webClient.get(`feeds/${feedReference}.xml`)) .body; expect(feedTruncated).toMatch("TRUNCATION 5"); expect(feedTruncated).not.toMatch("TRUNCATION 1"); // Test email that’s too long await emailClient.sendMail({ from: "publisher@example.com", to: `${feedReference}@${emailHostname}`, subject: "Test email that’s too long", text: `TOO LONG `.repeat(100_000), }); const feedEvenMoreTruncated = ( await webClient.get(`feeds/${feedReference}.xml`) ).body; expect(feedEvenMoreTruncated).not.toMatch("TOO LONG"); expect(feedEvenMoreTruncated).not.toMatch("TRUNCATION 5"); // Test email after truncation await emailClient.sendMail({ from: "publisher@example.com", to: `${feedReference}@${emailHostname}`, subject: "Test email after truncation", text: "A link: https://kill-the-newsletter.com", }); expect((await webClient.get(`feeds/${feedReference}.xml`)).body).toMatch( // prettier-ignore html`Test email after truncation` ); // Stop servers webServer.close(); emailServer.close(); });