2021-03-16 01:48:27 +01:00
|
|
|
|
import { jest, test, expect } from "@jest/globals";
|
2021-03-13 11:45:13 +01:00
|
|
|
|
import os from "os";
|
|
|
|
|
import path from "path";
|
|
|
|
|
import fs from "fs";
|
|
|
|
|
import * as got from "got";
|
2020-03-19 15:48:31 +01:00
|
|
|
|
import nodemailer from "nodemailer";
|
2021-03-13 12:07:56 +01:00
|
|
|
|
import html from "@leafac/html";
|
2021-03-13 11:45:13 +01:00
|
|
|
|
import killTheNewsletter from ".";
|
|
|
|
|
|
2021-03-16 01:48:27 +01:00
|
|
|
|
jest.setTimeout(300_000);
|
|
|
|
|
|
2021-03-13 23:35:02 +01:00
|
|
|
|
test("Kill the Newsletter!", async () => {
|
|
|
|
|
// Start servers
|
2021-03-13 11:45:13 +01:00
|
|
|
|
const rootDirectory = fs.mkdtempSync(
|
|
|
|
|
path.join(os.tmpdir(), "kill-the-newsletter--test--")
|
|
|
|
|
);
|
|
|
|
|
const { webApplication, emailApplication } = killTheNewsletter(rootDirectory);
|
2021-03-13 23:35:02 +01:00
|
|
|
|
const webServer = webApplication.listen(
|
|
|
|
|
new URL(webApplication.get("url")).port
|
|
|
|
|
);
|
|
|
|
|
const emailServer = emailApplication.listen(
|
2021-03-13 11:45:13 +01:00
|
|
|
|
new URL(webApplication.get("email")).port
|
|
|
|
|
);
|
2021-03-13 23:35:02 +01:00
|
|
|
|
const webClient = got.default.extend({
|
|
|
|
|
prefixUrl: webApplication.get("url"),
|
|
|
|
|
});
|
|
|
|
|
const emailClient = nodemailer.createTransport(webApplication.get("email"));
|
2021-03-15 00:09:27 +01:00
|
|
|
|
const emailHostname = new URL(webApplication.get("url")).hostname;
|
2020-03-18 20:21:44 +01:00
|
|
|
|
|
2021-03-13 23:35:02 +01:00
|
|
|
|
// 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
|
2021-03-14 00:13:35 +01:00
|
|
|
|
const feedOriginal = await webClient.get(`feeds/${feedReference}.xml`);
|
2021-03-13 23:35:02 +01:00
|
|
|
|
expect(feedOriginal.headers["content-type"]).toMatch("application/atom+xml");
|
|
|
|
|
expect(feedOriginal.headers["x-robots-tag"]).toBe("noindex");
|
|
|
|
|
expect(feedOriginal.body).toMatch(html`<title>A newsletter</title>`);
|
|
|
|
|
|
|
|
|
|
// Test alternate
|
|
|
|
|
const alternateReference = feedOriginal.body.match(
|
2021-03-13 12:07:56 +01:00
|
|
|
|
/\/alternates\/([a-z0-9]{16})\.html/
|
|
|
|
|
)![1];
|
2021-03-13 23:35:02 +01:00
|
|
|
|
const alternate = await webClient.get(
|
2021-03-13 12:07:56 +01:00
|
|
|
|
`alternates/${alternateReference}.html`
|
2020-07-23 17:11:41 +02:00
|
|
|
|
);
|
2021-03-13 23:35:02 +01:00
|
|
|
|
expect(alternate.headers["content-type"]).toMatch("text/html");
|
|
|
|
|
expect(alternate.headers["x-robots-tag"]).toBe("noindex");
|
|
|
|
|
expect(alternate.body).toMatch(`Enjoy your readings!`);
|
2020-03-19 01:16:00 +01:00
|
|
|
|
|
2021-03-13 23:35:02 +01:00
|
|
|
|
// Test email with HTML
|
|
|
|
|
await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait for a second to test that the ‘<updated>’ field will be updated
|
|
|
|
|
await emailClient.sendMail({
|
|
|
|
|
from: "publisher@example.com",
|
2021-03-15 00:09:27 +01:00
|
|
|
|
to: `${feedReference}@${emailHostname}`,
|
2021-03-14 00:01:59 +01:00
|
|
|
|
subject: "Test email with HTML",
|
|
|
|
|
html: html`<p>Some HTML</p>`,
|
2021-03-13 12:23:02 +01:00
|
|
|
|
});
|
2021-03-15 00:09:27 +01:00
|
|
|
|
const feedWithHTMLEntry = (await webClient.get(`feeds/${feedReference}.xml`))
|
|
|
|
|
.body;
|
|
|
|
|
expect(feedWithHTMLEntry.match(/<updated>(.+?)<\/updated>/)![1]).not.toBe(
|
2021-03-13 23:35:02 +01:00
|
|
|
|
feedOriginal.body.match(/<updated>(.+?)<\/updated>/)![1]
|
|
|
|
|
);
|
2021-03-15 00:09:27 +01:00
|
|
|
|
expect(feedWithHTMLEntry).toMatch(
|
2021-03-13 23:35:02 +01:00
|
|
|
|
html`<author><name>publisher@example.com</name></author>`
|
|
|
|
|
);
|
2021-03-15 00:09:27 +01:00
|
|
|
|
expect(feedWithHTMLEntry).toMatch(html`<title>Test email with HTML</title>`);
|
|
|
|
|
expect(feedWithHTMLEntry).toMatch(
|
2021-03-13 23:35:02 +01:00
|
|
|
|
// prettier-ignore
|
2021-03-14 00:01:59 +01:00
|
|
|
|
html`<content type="html">${`<p>Some HTML</p>`}\n</content>`
|
|
|
|
|
);
|
|
|
|
|
|
2021-03-14 00:13:35 +01:00
|
|
|
|
// Test email with text
|
2021-03-14 00:01:59 +01:00
|
|
|
|
await emailClient.sendMail({
|
|
|
|
|
from: "publisher@example.com",
|
2021-03-15 00:09:27 +01:00
|
|
|
|
to: `${feedReference}@${emailHostname}`,
|
2021-03-14 00:13:35 +01:00
|
|
|
|
subject: "Test email with text",
|
2021-03-14 00:01:59 +01:00
|
|
|
|
text: "A link: https://kill-the-newsletter.com",
|
|
|
|
|
});
|
2021-03-14 00:13:35 +01:00
|
|
|
|
expect((await webClient.get(`feeds/${feedReference}.xml`)).body).toMatch(
|
2021-03-14 00:01:59 +01:00
|
|
|
|
// prettier-ignore
|
|
|
|
|
html`<content type="html">${`<p>A link: <a href="https://kill-the-newsletter.com">https://kill-the-newsletter.com</a></p>`}</content>`
|
2021-03-13 23:35:02 +01:00
|
|
|
|
);
|
|
|
|
|
|
2021-03-15 00:09:27 +01:00
|
|
|
|
// Test email missing fields
|
2021-03-14 00:21:30 +01:00
|
|
|
|
await emailClient.sendMail({
|
2021-03-15 00:09:27 +01:00
|
|
|
|
to: `${feedReference}@${emailHostname}`,
|
2020-07-23 17:11:41 +02:00
|
|
|
|
});
|
2021-03-15 00:09:27 +01:00
|
|
|
|
const feedMissingFields = (await webClient.get(`feeds/${feedReference}.xml`))
|
|
|
|
|
.body;
|
|
|
|
|
expect(feedMissingFields).toMatch(html`<author><name></name></author>`);
|
|
|
|
|
expect(feedMissingFields).toMatch(html`<title></title>`);
|
|
|
|
|
expect(feedMissingFields).toMatch(html`<content type="html"></content>`);
|
2020-07-23 17:11:41 +02:00
|
|
|
|
|
2021-03-14 00:21:30 +01:00
|
|
|
|
// Test email to nonexistent ‘to’ (gets ignored)
|
|
|
|
|
await emailClient.sendMail({
|
|
|
|
|
from: "publisher@example.com",
|
2021-03-15 00:09:27 +01:00
|
|
|
|
to: `nonexistent@${emailHostname}`,
|
2021-03-14 00:21:30 +01:00
|
|
|
|
subject: "Test email to nonexistent ‘to’ (gets ignored)",
|
|
|
|
|
text: "A link: https://kill-the-newsletter.com",
|
2020-03-23 16:08:57 +01:00
|
|
|
|
});
|
2021-03-14 00:21:30 +01:00
|
|
|
|
expect((await webClient.get(`feeds/${feedReference}.xml`)).body).not.toMatch(
|
|
|
|
|
"Test email to nonexistent ‘to’ (gets ignored)"
|
|
|
|
|
);
|
2020-03-23 16:08:57 +01:00
|
|
|
|
|
2021-03-14 00:30:37 +01:00
|
|
|
|
// Test truncation
|
|
|
|
|
for (let index = 1; index <= 5; index++)
|
2020-05-05 08:12:57 +02:00
|
|
|
|
await emailClient.sendMail({
|
|
|
|
|
from: "publisher@example.com",
|
2021-03-15 00:09:27 +01:00
|
|
|
|
to: `${feedReference}@${emailHostname}`,
|
2021-03-14 00:30:37 +01:00
|
|
|
|
subject: `Test truncation: ${index}`,
|
|
|
|
|
text: `TRUNCATION ${index} `.repeat(10_000),
|
2020-05-05 08:12:57 +02:00
|
|
|
|
});
|
2021-03-14 00:30:37 +01:00
|
|
|
|
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",
|
2021-03-15 00:09:27 +01:00
|
|
|
|
to: `${feedReference}@${emailHostname}`,
|
2021-03-14 00:30:37 +01:00
|
|
|
|
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",
|
2021-03-15 00:09:27 +01:00
|
|
|
|
to: `${feedReference}@${emailHostname}`,
|
2021-03-14 00:30:37 +01:00
|
|
|
|
subject: "Test email after truncation",
|
|
|
|
|
text: "A link: https://kill-the-newsletter.com",
|
2020-03-23 16:24:14 +01:00
|
|
|
|
});
|
2021-03-14 00:30:37 +01:00
|
|
|
|
expect((await webClient.get(`feeds/${feedReference}.xml`)).body).toMatch(
|
|
|
|
|
// prettier-ignore
|
|
|
|
|
html`<title>Test email after truncation</title>`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Stop servers
|
|
|
|
|
webServer.close();
|
|
|
|
|
emailServer.close();
|
2020-03-19 05:20:28 +01:00
|
|
|
|
});
|