fix: isolate EventCard tests and clean compose refs hook

This commit is contained in:
2026-05-25 11:01:01 -04:00
parent 3c3ba7cb33
commit 1af9ee02df
2 changed files with 68 additions and 54 deletions

View File

@@ -54,9 +54,12 @@ function composeRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> {
* A custom hook that composes multiple refs * A custom hook that composes multiple refs
* Accepts callback refs and RefObject(s) * Accepts callback refs and RefObject(s)
*/ */
function useComposedRefs<T>(...refs: PossibleRef<T>[]): React.RefCallback<T> { function useComposedRefs<T>(
// biome-ignore lint/correctness/useExhaustiveDependencies: we want to memoize by all values ref1: PossibleRef<T>,
return React.useCallback(composeRefs(...refs), refs); ref2: PossibleRef<T>,
ref3?: PossibleRef<T>,
): React.RefCallback<T> {
return React.useMemo(() => composeRefs(ref1, ref2, ref3), [ref1, ref2, ref3]);
} }
export { composeRefs, useComposedRefs }; export { composeRefs, useComposedRefs };

View File

@@ -1,65 +1,76 @@
import { describe, expect, test } from "bun:test"; import { afterEach, beforeEach, describe, expect, test } from "bun:test";
import { renderToStaticMarkup } from "react-dom/server"; import { renderToStaticMarkup } from "react-dom/server";
import { EventCard } from "@/components/event-card"; import { EventCard } from "@/components/event-card";
import type { CalendarEvent } from "@/lib/types"; import type { CalendarEvent } from "@/lib/types";
const sampleEvent: CalendarEvent = { const sampleEvent: CalendarEvent = {
id: "evt_1", id: "evt_1",
title: "Design Review", title: "Design Review",
start: "2026-04-09T10:00:00+00:00", start: "2026-04-09T10:00:00+00:00",
end: "2026-04-09T11:00:00+00:00", end: "2026-04-09T11:00:00+00:00",
description: "Review the updated event list UI.", description: "Review the updated event list UI.",
location: "Studio A", location: "Studio A",
url: "https://example.com/event", url: "https://example.com/event",
allDay: false, allDay: false,
}; };
describe("EventCard actions trigger", () => { describe("EventCard actions trigger", () => {
test("shows the triple-dots trigger without requiring hover and exposes an aria-label for the icon-only button", () => { beforeEach(() => {
const markup = renderToStaticMarkup( globalThis.document = {
EventCard({ addEventListener: () => {},
event: sampleEvent, removeEventListener: () => {},
onEdit: () => {}, } as unknown as Document;
onDelete: () => {}, });
}),
);
expect(markup).toContain('aria-label="Event actions"'); afterEach(() => {
expect(markup).not.toContain("opacity-0"); delete (globalThis as { document?: Document }).document;
expect(markup).not.toContain("group-hover:opacity-100"); });
});
test("renders friendly shared date formatting instead of native locale strings", () => { test("shows the triple-dots trigger without requiring hover and exposes an aria-label for the icon-only button", () => {
const markup = renderToStaticMarkup( const markup = renderToStaticMarkup(
EventCard({ EventCard({
event: sampleEvent, event: sampleEvent,
onEdit: () => {}, onEdit: () => {},
onDelete: () => {}, onDelete: () => {},
}), }),
); );
expect(markup).toContain("10:0011:00"); expect(markup).toContain('aria-label="Event actions"');
expect(markup).not.toContain("AM"); expect(markup).not.toContain("opacity-0");
}); expect(markup).not.toContain("group-hover:opacity-100");
});
test("renders inline warning copy for invalid event ranges", () => { test("renders friendly shared date formatting instead of native locale strings", () => {
const markup = renderToStaticMarkup( const markup = renderToStaticMarkup(
EventCard({ EventCard({
event: { event: sampleEvent,
id: "evt_invalid", onEdit: () => {},
title: "Broken Event", onDelete: () => {},
start: "2026-04-09T11:00:00+00:00", }),
end: "2026-04-09T10:00:00+00:00", );
allDay: false,
},
onEdit: () => {},
onDelete: () => {},
}),
);
expect(markup).toContain("Warning:"); expect(markup).toContain("10:0011:00");
expect(markup).toContain("end time is before start time"); expect(markup).not.toContain("AM");
expect(markup).not.toContain("Preview"); });
expect(markup).not.toContain("Ship");
}); test("renders inline warning copy for invalid event ranges", () => {
const markup = renderToStaticMarkup(
EventCard({
event: {
id: "evt_invalid",
title: "Broken Event",
start: "2026-04-09T11:00:00+00:00",
end: "2026-04-09T10:00:00+00:00",
allDay: false,
},
onEdit: () => {},
onDelete: () => {},
}),
);
expect(markup).toContain("Warning:");
expect(markup).toContain("end time is before start time");
expect(markup).not.toContain("Preview");
expect(markup).not.toContain("Ship");
});
}); });