import '@testing-library/jest-dom' import { render, fireEvent } from '@testing-library/react' import { parseISODateString } from 'shared-utils/date-utils' import { PktCalendar, IPktCalendar } from './Calendar' const createCalendar = (props: Partial = {}) => { return render() } describe('PktCalendar', () => { describe('Rendering and basic functionality', () => { test('renders without errors', () => { const { container } = createCalendar() const calendarElement = container.querySelector('.pkt-calendar') expect(calendarElement).toBeInTheDocument() }) test('renders with correct structure', () => { const { container } = createCalendar() const calendarElement = container.querySelector('.pkt-calendar') const calendarTable = container.querySelector('.pkt-cal-days') const monthNav = container.querySelector('.pkt-cal-month-nav') expect(calendarElement).toBeInTheDocument() expect(calendarTable).toBeInTheDocument() expect(monthNav).toBeInTheDocument() }) test('renders month picker when withcontrols is true', () => { const { container } = createCalendar({ withcontrols: true }) // Navigation buttons should always be present const prevButton = container.querySelector('.pkt-calendar__prev-month') const nextButton = container.querySelector('.pkt-calendar__next-month') expect(prevButton).toBeInTheDocument() expect(nextButton).toBeInTheDocument() // Should show month picker controls, not static title const monthPicker = container.querySelector('.pkt-cal-month-picker') const monthTitle = container.querySelector('.pkt-calendar__month-title') expect(monthPicker).toBeInTheDocument() expect(monthTitle).not.toBeInTheDocument() // Should have month and year inputs const monthSelect = monthPicker?.querySelector('select') const yearInput = monthPicker?.querySelector('input[type="number"]') expect(monthSelect).toBeInTheDocument() expect(yearInput).toBeInTheDocument() }) test('renders static month title when withcontrols is false', () => { const { container } = createCalendar() // Navigation buttons should always be present const prevButton = container.querySelector('.pkt-calendar__prev-month') const nextButton = container.querySelector('.pkt-calendar__next-month') expect(prevButton).toBeInTheDocument() expect(nextButton).toBeInTheDocument() // Should show static month title, not controls const monthTitle = container.querySelector('.pkt-calendar__month-title') const monthPicker = container.querySelector('.pkt-cal-month-picker') expect(monthTitle).toBeInTheDocument() expect(monthPicker).not.toBeInTheDocument() }) }) describe('Properties and attributes', () => { test('applies default properties correctly', () => { const { container } = createCalendar() // Verify defaults through DOM effects const grid = container.querySelector('[role="grid"]') expect(grid).not.toHaveAttribute('aria-multiselectable') // No week numbers by default const weekNumbers = container.querySelectorAll('.pkt-calendar__week-number') expect(weekNumbers.length).toBe(0) // No month picker by default const monthPicker = container.querySelector('.pkt-cal-month-picker') expect(monthPicker).not.toBeInTheDocument() // No selected dates const selectedDates = container.querySelectorAll('.pkt-calendar__date--selected') expect(selectedDates.length).toBe(0) }) test('handles multiple property correctly', () => { const { container } = createCalendar({ multiple: true }) const grid = container.querySelector('[role="grid"]') expect(grid).toHaveAttribute('aria-multiselectable', 'true') }) test('handles range property correctly', () => { const { container } = createCalendar({ range: true }) const grid = container.querySelector('[role="grid"]') expect(grid).toHaveAttribute('aria-multiselectable', 'true') }) test('handles weeknumbers property correctly', () => { const { container } = createCalendar({ weeknumbers: true }) const weekNumbers = container.querySelectorAll('.pkt-calendar__week-number') expect(weekNumbers.length).toBeGreaterThan(0) }) test('handles maxMultiple property correctly', () => { const { container } = createCalendar({ multiple: true, maxMultiple: 3 }) const grid = container.querySelector('[role="grid"]') expect(grid).toHaveAttribute('aria-multiselectable', 'true') // Select 3 dates - all should work const availableDates = container.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDates.length).toBeGreaterThan(3) fireEvent.click(availableDates[0]) fireEvent.click(availableDates[1]) fireEvent.click(availableDates[2]) const selectedDates = container.querySelectorAll('.pkt-calendar__date--selected') expect(selectedDates.length).toBe(3) }) test('handles currentmonth property correctly', () => { const { container } = createCalendar({ currentmonth: '2024-03-15' }) const monthTitle = container.querySelector('.pkt-calendar__month-title') expect(monthTitle?.textContent).toContain('Mars') expect(monthTitle?.textContent).toContain('2024') }) }) describe('Month navigation', () => { it('should navigate to previous month when clicking previous button', () => { const { container } = createCalendar({ currentmonth: '2024-06-15' }) const monthTitle = container.querySelector('.pkt-calendar__month-title') expect(monthTitle?.textContent).toContain('Juni') const prevButton = container.querySelector('.pkt-calendar__prev-month') fireEvent.click(prevButton!) expect(monthTitle?.textContent).toContain('Mai') }) it('should navigate to next month when clicking next button', () => { const { container } = createCalendar({ currentmonth: '2024-06-15' }) const monthTitle = container.querySelector('.pkt-calendar__month-title') expect(monthTitle?.textContent).toContain('Juni') const nextButton = container.querySelector('.pkt-calendar__next-month') fireEvent.click(nextButton!) expect(monthTitle?.textContent).toContain('Juli') }) test('navigates to next month with controls', () => { const { container } = createCalendar({ withcontrols: true, currentmonth: '2024-06-15' }) const nextButton = container.querySelector('.pkt-calendar__next-month') expect(nextButton).toBeInTheDocument() const monthSelect = container.querySelector( '.pkt-cal-month-picker select', ) as HTMLSelectElement const initialMonth = monthSelect?.value fireEvent.click(nextButton!) const newMonth = monthSelect?.value expect(newMonth).not.toBe(initialMonth) }) test('month navigation updates visible dates', () => { const { container } = createCalendar({ withcontrols: true, currentmonth: '2024-06-15' }) const initialDates = Array.from(container.querySelectorAll('.pkt-calendar__date')).map( (el) => el.textContent, ) const nextButton = container.querySelector('.pkt-calendar__next-month') fireEvent.click(nextButton!) const newDates = Array.from(container.querySelectorAll('.pkt-calendar__date')).map( (el) => el.textContent, ) expect(newDates).not.toEqual(initialDates) }) }) describe('Date formatting and localization', () => { test('displays day names correctly', () => { const { container } = createCalendar() const dayHeaders = container.querySelectorAll('.pkt-calendar__day-name') expect(dayHeaders.length).toBe(7) dayHeaders.forEach((header) => { expect(header.textContent).toBeTruthy() expect(header.textContent!.length).toBeGreaterThan(0) }) }) test('displays month names correctly', () => { const { container } = createCalendar({ currentmonth: '2024-06-15' }) const monthTitle = container.querySelector('.pkt-calendar__month-title') expect(monthTitle).toBeInTheDocument() expect(monthTitle?.textContent).toBeTruthy() }) test('handles custom day strings', () => { const { container } = createCalendar({ strings: { daysShort: ['S', 'M', 'T', 'W', 'T', 'F', 'S'] }, }) const dayHeaders = container.querySelectorAll('.pkt-calendar__day-name') expect(dayHeaders[0].textContent?.trim()).toBe('S') expect(dayHeaders[1].textContent?.trim()).toBe('M') }) test('handles custom month strings', () => { const { container } = createCalendar({ withcontrols: true, strings: { months: [ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', ], }, }) const monthSelect = container.querySelector('.pkt-cal-month-picker select') expect(monthSelect).toBeInTheDocument() const options = monthSelect?.querySelectorAll('option') expect(options?.[0]?.textContent).toContain('Jan') }) }) describe('Today highlighting', () => { test('highlights today date', () => { const { container } = createCalendar() const todayDate = container.querySelector('.pkt-calendar__date--today') expect(todayDate).toBeInTheDocument() }) test('today date is selectable unless excluded', () => { const { container } = createCalendar() const todayDate = container.querySelector('.pkt-calendar__date--today') if (todayDate && !todayDate.classList.contains('pkt-calendar__date--disabled')) { fireEvent.click(todayDate) expect(todayDate).toHaveClass('pkt-calendar__date--selected') } }) }) })