/** * CalendarWidget Component Tests * Following TDD principles */ import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, waitFor } from "@testing-library/react"; import { CalendarWidget } from "../CalendarWidget"; global.fetch = vi.fn() as typeof global.fetch; describe("CalendarWidget", (): void => { beforeEach((): void => { vi.clearAllMocks(); }); it("should render loading state initially", (): void => { vi.mocked(global.fetch).mockImplementation( () => new Promise(() => { // Intentionally never resolves to keep loading state }) ); render(); expect(screen.getByText(/loading/i)).toBeInTheDocument(); }); // TODO: Re-enable when CalendarWidget uses fetch API instead of setTimeout mock data it.skip("should render upcoming events", async (): Promise => { const mockEvents = [ { id: "1", title: "Team Meeting", startTime: new Date(Date.now() + 3600000).toISOString(), endTime: new Date(Date.now() + 7200000).toISOString(), }, { id: "2", title: "Project Review", startTime: new Date(Date.now() + 86400000).toISOString(), endTime: new Date(Date.now() + 90000000).toISOString(), }, ]; vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: () => Promise.resolve(mockEvents), } as unknown as Response); render(); await waitFor(() => { expect(screen.getByText("Team Meeting")).toBeInTheDocument(); expect(screen.getByText("Project Review")).toBeInTheDocument(); }); }); // TODO: Re-enable when CalendarWidget uses fetch API instead of setTimeout mock data it.skip("should handle empty event list", async (): Promise => { vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: () => Promise.resolve([]), } as unknown as Response); render(); await waitFor(() => { expect(screen.getByText(/no upcoming events/i)).toBeInTheDocument(); }); }); // TODO: Re-enable when CalendarWidget uses fetch API instead of setTimeout mock data it.skip("should handle API errors gracefully", async (): Promise => { vi.mocked(global.fetch).mockRejectedValueOnce(new Error("API Error")); render(); await waitFor(() => { expect(screen.getByText(/error/i)).toBeInTheDocument(); }); }); // TODO: Re-enable when CalendarWidget uses fetch API instead of setTimeout mock data it.skip("should format event times correctly", async (): Promise => { const now = new Date(); const startTime = new Date(now.getTime() + 3600000); // 1 hour from now const mockEvents = [ { id: "1", title: "Meeting", startTime: startTime.toISOString(), endTime: new Date(startTime.getTime() + 3600000).toISOString(), }, ]; vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: () => Promise.resolve(mockEvents), } as unknown as Response); render(); await waitFor(() => { expect(screen.getByText("Meeting")).toBeInTheDocument(); // Should show time in readable format }); }); // TODO: Re-enable when CalendarWidget uses fetch API and adds calendar-header test id it.skip("should display current date", async (): Promise => { vi.mocked(global.fetch).mockResolvedValueOnce({ ok: true, json: () => Promise.resolve([]), } as unknown as Response); render(); await waitFor(() => { // Widget should display current date or month expect(screen.getByTestId("calendar-header")).toBeInTheDocument(); }); }); });