Files
HealthLog/src/components/documents/__tests__/document-bulk-bar.test.tsx
T
Marc-André Bombeck aef2003d4c feat(documents): multi-select bulk actions on the vault timeline
Selection grows file-manager gestures — shift-click ranges (additive,
anchored on the last plain toggle) and press-and-hold on touch — and a
floating toolbar appears with the selected count and the bulk verbs:
change type, link condition, delete, clear. All verbs drive the bulk
endpoint in <=100-id chunks with merged per-id results; partial failures
surface as one counted toast, and a bulk delete gets one aggregate undo
that bulk-restores the succeeded rows (both sides no-op-safe by
contract). Escape clears the selection unless a dialog owns the key.

Refs: document-vault plan W3-T2
2026-07-07 13:21:16 +02:00

47 lines
1.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { renderToStaticMarkup } from "react-dom/server";
/**
* The floating bulk bar, pinned via single-pass static renders: a labelled
* toolbar carrying the selected count and the four bulk verbs. The
* link-condition menu only renders when the account actually has episodes
* to link — no dead affordance on an episode-free account.
*/
import { I18nProvider } from "@/lib/i18n/context";
import { DocumentBulkBar } from "../document-bulk-bar";
function render(episodes: { id: string; label: string }[]) {
return renderToStaticMarkup(
<I18nProvider initialLocale="en">
<DocumentBulkBar
selectedCount={3}
episodes={episodes}
busy={false}
onSetKind={() => {}}
onLinkEpisode={() => {}}
onDelete={() => {}}
onClear={() => {}}
/>
</I18nProvider>,
);
}
describe("<DocumentBulkBar>", () => {
it("renders a labelled toolbar with count and the bulk verbs", () => {
const html = render([{ id: "ep1", label: "Knee" }]);
expect(html).toContain('data-slot="document-bulk-bar"');
expect(html).toContain('role="toolbar"');
expect(html).toContain("3 selected");
expect(html).toContain("Change type");
expect(html).toContain("Link condition");
expect(html).toContain("Delete");
expect(html).toContain("Clear selection");
});
it("omits the link-condition verb when the account has no episodes", () => {
const html = render([]);
expect(html).not.toContain("Link condition");
expect(html).toContain("Change type");
});
});