${comment.replies.map((reply) => renderComment(reply, depth + 1))}
diff --git a/test/markdown.test.ts b/test/markdown.test.ts
index be2e2b6..ae7baa2 100644
--- a/test/markdown.test.ts
+++ b/test/markdown.test.ts
@@ -1,9 +1,16 @@
import assert from 'node:assert/strict';
import { test } from 'node:test';
+import { escapeHtml } from '../src/render/html.ts';
import { renderMarkdown } from '../src/render/markdown.ts';
const md = (text: string): string => String(renderMarkdown(text));
+/** Stands in for the real one, which proxies. Escapes the way that one does:
+ * placing the image is the renderer's job, and so is making it safe. */
+const img = (url: string, alt: string): string =>
+ `
})
`;
+const mdi = (text: string): string => String(renderMarkdown(text, img));
+
test('markup a commenter typed is text, not markup', () => {
const out = md(' & "quoted"');
assert.ok(!out.includes(''));
assert.ok(!html_.includes('
);)
{
+ const page = renderPost(redditPost({
+ comments: [{
+ author: 'u/a',
+ text: '\n\nhttps://i.redd.it/y.png',
+ replies: [],
+ }],
+ }));
+
+ assert.ok(!page.includes('https://preview.redd.it/x.jpeg'), 'upstream URLs must not reach the page');
+ assert.ok(!page.includes('https://i.redd.it/y.png'), 'a pasted address is proxied too');
+ assert.equal((page.match(/
 ?? []).length, 2);
+ // The payload survives as text inside the attribute, which is the point:
+ // its quotes are neutered, so it cannot close `alt=)