diff --git a/tests/embeds.test.ts b/tests/embeds.test.ts
index 819e4d1..d784c7f 100644
--- a/tests/embeds.test.ts
+++ b/tests/embeds.test.ts
@@ -118,3 +118,58 @@ test('the editor corpus embed entries expand after sanitizing', () => {
assert.equal(expandEmbeds(clean), clean, entry.name)
}
})
+
+test('expansion is last: sanitizing the expanded output would strip the iframe', () => {
+ // Why the order matters: the sanitizer never keeps an iframe, so a sink that
+ // sanitized after expanding would lose every video.
+ const again = sanitizeJournalHtml(IFRAME)
+ assert.equal(iframeCount(again), 0)
+ assert.doesNotMatch(again, /youtube-nocookie/)
+})
+
+test('the sinks expand after sanitizing and the payload transforms never expand', () => {
+ const read = (path: string) => readFileSync(new URL(path, import.meta.url), 'utf8')
+ for (const sink of ['../app/components/Journal/PostBody.vue', '../app/components/Journal/CategoryHeader.vue']) {
+ const source = read(sink)
+ assert.match(source, /expandEmbeds\(sanitizeJournalHtml\(/, `${sink} must render expandEmbeds(sanitizeJournalHtml(...))`)
+ assert.equal((source.match(/expandEmbeds\(/g) ?? []).length, 1, `${sink} expands once`)
+ }
+ for (const transform of ['../app/utils/postView.ts', '../app/journal-pages/CategoryPage.vue']) {
+ assert.doesNotMatch(read(transform), /expandEmbeds/, `${transform} must not expand`)
+ }
+})
+
+test('only the exact serialization expands: case, spacing and entities stay inert', () => {
+ const inert = [
+ `
a
${PLACEHOLDER}b
${PLACEHOLDER}` + const first = expandEmbeds(body) + assert.equal(expandEmbeds(body), first) + assert.equal(EMBED_PLACEHOLDER.lastIndex, 0) + assert.equal(iframeCount(first), 2) +}) + +test('the iframe src is a fixed host plus the validated id, never stored text', () => { + const out = sink(`