| … | … | @@ -78,7 +78,10 @@ test('tables render as tables', (t) => { |
| 78 | 78 | |
| 79 | 79 | test('images render, with escaped alt and an http-only src', (t) => { |
| 80 | 80 | t.ok(render('').includes('<img src="https://x/i.png" alt="a "b"">')) |
| 81 | | t.is(render(')'), '<p></p>', 'a non-http src drops the image entirely') |
| 81 | // ⚠ '' rather than '<p></p>'. The intent — "drops the image entirely" — is unchanged and now |
| 82 | // fully met: an empty paragraph is not nothing, it is a blank line in every consumer that renders |
| 83 | // it, which a live feed showed on every picture post. |
| 84 | t.is(render(')'), '', 'a non-http src drops the image entirely') |
| 82 | 85 | }) |
| 83 | 86 | |
| 84 | 87 | test('render is TOTAL — it never throws', (t) => { |
| … | … | @@ -216,3 +219,31 @@ test('a video or an unresolved embed breaks the run rather than leaving a hole', |
| 216 | 219 | const withUnknown = render('\n\n', o) |
| 217 | 220 | t.absent(withUnknown.includes('lighttable'), 'an embed that renders as nothing would leave a hole') |
| 218 | 221 | }) |
| 222 | |
| 223 | // ⛔ A PARAGRAPH THAT RENDERS TO NOTHING IS NOTHING. |
| 224 | // |
| 225 | // `image()` drops a `favela://blob/…` embed entirely when no resolver is supplied — correctly: an |
| 226 | // <img> with no usable src is noise. But the paragraph around it still rendered, so a post whose |
| 227 | // only content was a picture produced `<p>text</p><p></p>`. |
| 228 | // |
| 229 | // MEASURED on ashatron 2026-09-07: a bridge lifting embeds into AS2 attachments got exactly that, |
| 230 | // and a blank line would have shown in every receiving client. It is not specific to that consumer |
| 231 | // — the surface hits the same shape whenever a blob fails to resolve. |
| 232 | test('an empty paragraph is omitted, not emitted', (t) => { |
| 233 | const oid = 'a1'.repeat(16) |
| 234 | const html = render('look\n\n') |
| 235 | t.absent(html.includes('<p></p>'), 'no empty paragraph: ' + html) |
| 236 | t.ok(html.includes('look'), 'and the real text survives') |
| 237 | }) |
| 238 | |
| 239 | test('⚠ a paragraph with only whitespace is also nothing', (t) => { |
| 240 | t.absent(render('a\n\n \n\nb').includes('<p></p>')) |
| 241 | }) |
| 242 | |
| 243 | test('⛔ a resolved image still renders — this must not drop real content', (t) => { |
| 244 | const oid = 'b2'.repeat(16) |
| 245 | const html = render('', { |
| 246 | resolveBlob: () => ({ src: '/blob/' + oid, mimeType: 'image/webp' }) |
| 247 | }) |
| 248 | t.ok(html.includes('<img'), 'the picture is there: ' + html.slice(0, 80)) |
| 249 | }) |