test(admin-tags): pin merge/delete previews to the direct count (#698)

Characterization tests for AC#8: the merge preview and the delete-impact
warning describe direct-document operations, so they must report the tag's
direct documentCount, never a subtree rollup. Both tests pass a stray
subtreeDocumentCount and assert it does not leak into the preview, so a future
change can't silently desync a destructive-action preview.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-31 12:26:42 +02:00
committed by marcel
parent 1fc74f8892
commit 6d4aa8bd5c
2 changed files with 41 additions and 0 deletions

View File

@@ -68,6 +68,21 @@ describe('TagDeleteGuard', () => {
renderWithConfirm();
await expect.element(page.getByText(/3 Dokument/)).toBeInTheDocument();
});
// Characterization (#698): the delete-impact warning describes a destructive single-tag delete,
// which removes only the tag's DIRECT document_tags rows — so it must show documentCount, never
// a subtree rollup. Pinned so a future change can't silently desync this warning.
it('shows the direct documentCount in the impact summary, not a subtree rollup', async () => {
const tagWithStraySubtree = {
id: 't1',
name: 'Familie',
documentCount: 3,
subtreeDocumentCount: 99
};
renderWithConfirm({ tag: tagWithStraySubtree, allTags });
await expect.element(page.getByText(/3 Dokument/)).toBeInTheDocument();
expect(document.body.textContent).not.toContain('99');
});
});
describe('TagDeleteGuard confirmation dialog', () => {

View File

@@ -66,6 +66,32 @@ describe('TagMergeZone step flow', () => {
});
});
describe('TagMergeZone preview uses the direct document count (characterization, #698)', () => {
it('shows the tag direct documentCount in the merge preview, not a subtree rollup', async () => {
vi.stubGlobal(
'fetch',
vi.fn().mockResolvedValue({
ok: true,
json: vi.fn().mockResolvedValue([{ id: 't2', name: 'Reise' }])
})
);
// documentCount (direct) = 3; a stray subtree rollup of 99 must NOT leak into the preview —
// merge re-tags only direct documents, so the preview has to stay the direct count.
const mergeTag = { id: 't1', name: 'Familie', documentCount: 3, subtreeDocumentCount: 99 };
render(TagMergeZone, { tag: mergeTag, allTags, form: null });
const input = page.getByRole('combobox');
await input.fill('R');
await vi.advanceTimersByTimeAsync(300);
await page.getByRole('option', { name: 'Reise' }).click();
await vi.advanceTimersByTimeAsync(0);
await expect.element(page.getByTestId('merge-step2')).toBeInTheDocument();
expect(document.body.textContent).toContain('3 Dokumente');
expect(document.body.textContent).not.toContain('99');
});
});
describe('TagMergeZone stale state reset', () => {
it('resets target selection when tag prop changes', async () => {
vi.stubGlobal(