diff --git a/frontend/src/components/dashboard/CalendarView.test.tsx b/frontend/src/components/dashboard/CalendarView.test.tsx new file mode 100644 index 00000000..bfd11d7a --- /dev/null +++ b/frontend/src/components/dashboard/CalendarView.test.tsx @@ -0,0 +1,81 @@ +import { describe, it, expect } from "vitest"; +import { render, screen, fireEvent } from "@testing-library/react"; +import { CalendarView } from "./CalendarView"; + +describe("CalendarView", () => { + it("disables the Today button when already viewing the current month and enables it when navigating away", () => { + render(); + + const todayButton = screen.getByRole("button", { name: "Today" }); + expect(todayButton).toBeDisabled(); + + const nextMonthButton = screen.getByRole("button", { name: "Next month" }); + fireEvent.click(nextMonthButton); + + expect(todayButton).not.toBeDisabled(); + }); + + it("resets the displayed month and year to the current system date when clicking Today", () => { + render(); + + const now = new Date(); + const expectedLabel = now.toLocaleString("default", { + month: "long", + year: "numeric", + }); + + const monthHeading = screen.getByTestId("calendar-current-month"); + expect(monthHeading).toHaveTextContent(expectedLabel); + + const nextMonthButton = screen.getByRole("button", { name: "Next month" }); + fireEvent.click(nextMonthButton); + fireEvent.click(nextMonthButton); + fireEvent.click(nextMonthButton); + + const todayButton = screen.getByRole("button", { name: "Today" }); + expect(todayButton).not.toBeDisabled(); + + fireEvent.click(todayButton); + + expect(monthHeading).toHaveTextContent(expectedLabel); + expect(todayButton).toBeDisabled(); + }); + + it("highlights the current day cell with an accent border ring and a Today pill badge", () => { + render(); + + const todayCell = screen.getByTestId("calendar-today-cell"); + expect(todayCell).toBeInTheDocument(); + expect(todayCell).toHaveAttribute("aria-current", "date"); + expect(todayCell.className).toContain("ring-2"); + expect(todayCell.className).toContain("ring-accent"); + + const todayBadge = screen.getByTestId("calendar-today-badge"); + expect(todayBadge).toBeInTheDocument(); + expect(todayBadge).toHaveTextContent("Today"); + }); + + it("navigates to previous month and returns to current month via Today button", () => { + render(); + + const now = new Date(); + const expectedLabel = now.toLocaleString("default", { + month: "long", + year: "numeric", + }); + + const prevMonthButton = screen.getByRole("button", { + name: "Previous month", + }); + fireEvent.click(prevMonthButton); + + const todayButton = screen.getByRole("button", { name: "Today" }); + expect(todayButton).not.toBeDisabled(); + + fireEvent.click(todayButton); + expect(screen.getByTestId("calendar-current-month")).toHaveTextContent( + expectedLabel, + ); + expect(todayButton).toBeDisabled(); + }); +}); diff --git a/frontend/src/components/dashboard/CalendarView.tsx b/frontend/src/components/dashboard/CalendarView.tsx index 46c96250..123e297d 100644 --- a/frontend/src/components/dashboard/CalendarView.tsx +++ b/frontend/src/components/dashboard/CalendarView.tsx @@ -145,6 +145,11 @@ export function CalendarView({ return days; }, [currentDate, filteredStreams]); + const now = new Date(); + const isViewingCurrentMonth = + currentDate.getFullYear() === now.getFullYear() && + currentDate.getMonth() === now.getMonth(); + const goToPrevMonth = () => { setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1)); }; @@ -194,24 +199,34 @@ export function CalendarView({ {/* Navigation */}
-

+

{currentDate.toLocaleString("default", { month: "long", year: "numeric" })}