77 lines
2.2 KiB
TypeScript
77 lines
2.2 KiB
TypeScript
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");
|
||
});
|
||
});
|