test(#248 F3): make empty-over-empty test actually reach the store empty-guard

The "does not block an empty store over an already-empty page" test set the
stored page.content to TiptapTransformer.fromYdoc(document,'default') — exactly
the value tiptapJson is computed from — so isDeepStrictEqual(tiptapJson,
page.content) was TRUE and onStoreDocument RETURNED at the unchanged short-circuit
before ever reaching the empty-guard. It exercised the old short-circuit, not the
new guard's `!isEmptyParagraphDoc(page.content)` branch (the only NEW branch
protecting empty existing pages from over-blocking); the condition could be
removed and the test would still pass (false coverage).

Set stored content to an empty paragraph with `content: []` — empty per
isEmptyParagraphDoc but NOT deep-equal to the live doc (which normalizes to a
paragraph with `attrs: { indent: 0 }` and no content key). Execution now skips
the short-circuit and enters the guard; reorient the assertion to "the write is
NOT blocked" (updatePage IS called). Verified the test now FAILS if the
`!isEmptyParagraphDoc(page.content)` condition is removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
claude code agent 227
2026-06-29 01:56:00 +03:00
parent 04fda0c0b2
commit 90a3fa012d

View File

@@ -229,21 +229,36 @@ describe('PersistenceExtension.onStoreDocument — Approach-A boundary snapshot'
expect(historyQueue.add).not.toHaveBeenCalled();
});
// persist-6 — a brand-new / already-empty page is unaffected: an empty store
// over empty stored content is not blocked (it short-circuits as unchanged).
// persist-6 — a legitimately-empty existing page must still be writable when
// the empty live doc actually DIFFERS from the stored content (so the
// unchanged short-circuit does NOT fire and execution reaches the empty-guard).
// This exercises the guard's third condition `!isEmptyParagraphDoc(page.content)`:
// because the stored page is ALSO empty, the guard must NOT block the write.
// The live doc normalizes to a paragraph carrying `attrs: { indent: 0 }` and no
// `content` key; the stored page is an empty paragraph with `content: []` —
// both empty per `isEmptyParagraphDoc`, but NOT `isDeepStrictEqual`, so the
// store passes the short-circuit (~line 208) and genuinely enters the guard
// (~line 229). If the `!isEmptyParagraphDoc(page.content)` condition were
// removed, the guard would block this write and updatePage would never run,
// failing this test.
it('does not block an empty store over an already-empty page (persist-6)', async () => {
const emptyDoc = { type: 'doc', content: [{ type: 'paragraph' }] };
const document = ydocFor(emptyDoc);
const normalized = TiptapTransformer.fromYdoc(document, 'default');
const liveEmptyDoc = { type: 'doc', content: [{ type: 'paragraph' }] };
const document = ydocFor(liveEmptyDoc);
// Stored content is empty per isEmptyParagraphDoc (paragraph with content:[])
// but structurally NOT deep-equal to the normalized live doc — so execution
// skips the unchanged short-circuit and reaches the empty-guard.
const storedEmptyDoc = { type: 'doc', content: [{ type: 'paragraph', content: [] }] };
pageRepo.findById.mockResolvedValue({
...persistedHumanPage('IGNORED'),
content: normalized,
content: storedEmptyDoc,
});
await ext.onStoreDocument(buildData(document, 'user') as any);
// Unchanged empty-over-empty: short-circuits, no spurious write, no error.
expect(pageRepo.updatePage).not.toHaveBeenCalled();
// Empty-over-empty reaches the guard, which must let the write through
// (the stored page is empty, so the empty-overwrite protection does not
// apply). updatePage IS called — proving `!isEmptyParagraphDoc(page.content)`.
expect(pageRepo.updatePage).toHaveBeenCalledTimes(1);
});
// persist-1 — when every attempt fails the hook must NOT report a phantom