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