test(05-04): add failing tests for calendar widget
- Three test cases: event rendering with color dots, no-events empty state, no-sources empty state - Mocks calendar-api and next-intl following existing test patterns Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
import { cleanup, render, screen, waitFor } from '@testing-library/react';
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
// Mock next-intl
|
||||
vi.mock('next-intl', () => ({
|
||||
useTranslations: (ns: string) => (key: string) => {
|
||||
const map: Record<string, Record<string, string>> = {
|
||||
widgets: {
|
||||
'calendar.name': 'Calendar',
|
||||
'calendar.description': 'Upcoming events',
|
||||
'calendar.emptyNoSources': 'No calendar sources configured',
|
||||
'calendar.emptyNoEvents': 'No upcoming events',
|
||||
'calendar.loading': 'Loading...',
|
||||
},
|
||||
};
|
||||
return map[ns]?.[key] ?? key;
|
||||
},
|
||||
}));
|
||||
|
||||
// Mock calendar-api
|
||||
const mockFetchEvents = vi.fn();
|
||||
const mockFetchSources = vi.fn();
|
||||
vi.mock('@/lib/calendar-api', () => ({
|
||||
fetchEvents: (...args: unknown[]) => mockFetchEvents(...args),
|
||||
fetchSources: (...args: unknown[]) => mockFetchSources(...args),
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe('CalendarWidget', () => {
|
||||
beforeEach(() => {
|
||||
// Default: sources exist so we get past the source check
|
||||
mockFetchSources.mockResolvedValue([
|
||||
{ id: 's1', name: 'Work', type: 'caldav', isVisible: true, color: '#ff0000' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('renders event titles, times, and source color dots for two events', async () => {
|
||||
mockFetchEvents.mockResolvedValue([
|
||||
{
|
||||
id: 'e1',
|
||||
sourceId: 's1',
|
||||
title: 'Team Meeting',
|
||||
start: '2026-06-24T10:00:00Z',
|
||||
end: '2026-06-24T11:00:00Z',
|
||||
allDay: false,
|
||||
color: '#ff0000',
|
||||
},
|
||||
{
|
||||
id: 'e2',
|
||||
sourceId: 's1',
|
||||
title: 'Lunch Break',
|
||||
start: '2026-06-24T12:00:00Z',
|
||||
end: '2026-06-24T13:00:00Z',
|
||||
allDay: false,
|
||||
color: '#00ff00',
|
||||
},
|
||||
]);
|
||||
|
||||
const { CalendarWidget } = await import('./calendar-widget');
|
||||
render(
|
||||
<CalendarWidget
|
||||
instanceId="cal-1"
|
||||
config={{}}
|
||||
isEditMode={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
// Wait for events to load
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Team Meeting')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(screen.getByText('Lunch Break')).toBeInTheDocument();
|
||||
|
||||
// Source color dots should be rendered (8px circles)
|
||||
const colorDots = screen.getAllByTestId('event-color-dot');
|
||||
expect(colorDots).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('renders no-events message when sources exist but no events returned', async () => {
|
||||
mockFetchEvents.mockResolvedValue([]);
|
||||
|
||||
const { CalendarWidget } = await import('./calendar-widget');
|
||||
render(
|
||||
<CalendarWidget
|
||||
instanceId="cal-2"
|
||||
config={{}}
|
||||
isEditMode={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('No upcoming events')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders no-sources message when no sources configured', async () => {
|
||||
mockFetchSources.mockResolvedValue([]);
|
||||
mockFetchEvents.mockResolvedValue([]);
|
||||
|
||||
const { CalendarWidget } = await import('./calendar-widget');
|
||||
render(
|
||||
<CalendarWidget
|
||||
instanceId="cal-3"
|
||||
config={{}}
|
||||
isEditMode={false}
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.getByText('No calendar sources configured'),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user