import '@testing-library/jest-dom' import { render, fireEvent, act } from '@testing-library/react' import { createRef } from 'react' import { parseISODateString } from 'shared-utils/date-utils' import { PktCalendar, IPktCalendar, PktCalendarHandle } from './Calendar' const createCalendar = (props: Partial = {}) => { return render() } describe('PktCalendar', () => { describe('Date selection functionality', () => { test('selects single date correctly', () => { const { container } = createCalendar() // Find and click on a date const availableDate = container.querySelector( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDate).toBeInTheDocument() fireEvent.click(availableDate!) expect(availableDate).toHaveClass('pkt-calendar__date--selected') }) test('handles multiple date selection', () => { const { container } = createCalendar({ multiple: true }) // Find and click on multiple dates const availableDates = container.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDates.length).toBeGreaterThan(1) fireEvent.click(availableDates[0]) fireEvent.click(availableDates[1]) expect(availableDates[0]).toHaveClass('pkt-calendar__date--selected') expect(availableDates[1]).toHaveClass('pkt-calendar__date--selected') }) test('respects maxMultiple limit', () => { const { container } = createCalendar({ multiple: true, maxMultiple: 2 }) // Try to select more than maxMultiple dates const availableDates = container.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDates.length).toBeGreaterThan(2) // Select 3 dates but only 2 should be selected fireEvent.click(availableDates[0]) fireEvent.click(availableDates[1]) fireEvent.click(availableDates[2]) const selectedDates = container.querySelectorAll('.pkt-calendar__date--selected') expect(selectedDates.length).toBeLessThanOrEqual(2) }) test('handles pre-selected dates', () => { const preSelectedDates = ['2024-06-15', '2024-06-20'] const { container } = createCalendar({ selected: preSelectedDates, currentmonth: '2024-06-01', }) const selectedDates = container.querySelectorAll('.pkt-calendar__date--selected') expect(selectedDates.length).toBe(2) }) test('toggles date selection when clicking same date twice', () => { const { container } = createCalendar() const availableDate = container.querySelector( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDate).toBeInTheDocument() // First click - select fireEvent.click(availableDate!) expect(availableDate).toHaveClass('pkt-calendar__date--selected') // Second click - deselect fireEvent.click(availableDate!) expect(availableDate).not.toHaveClass('pkt-calendar__date--selected') }) }) describe('Range selection functionality', () => { test('handles range selection correctly', () => { const { container } = createCalendar({ range: true }) const availableDates = container.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDates.length).toBeGreaterThan(3) // Select start date fireEvent.click(availableDates[5]) // Select end date fireEvent.click(availableDates[10]) // Check for range styling const rangeStart = container.querySelector('.pkt-calendar__date--range-start') const rangeEnd = container.querySelector('.pkt-calendar__date--range-end') const rangeInBetween = container.querySelectorAll('.pkt-calendar__date--in-range') expect(rangeStart).toBeInTheDocument() expect(rangeEnd).toBeInTheDocument() expect(rangeInBetween.length).toBeGreaterThan(0) }) test('shows range hover preview', () => { const { container } = createCalendar({ range: true }) const availableDates = container.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) // Select start date fireEvent.click(availableDates[5]) // Hover over potential end date fireEvent.mouseOver(availableDates[10]) // Should show hover preview styling const hoveredRanges = container.querySelectorAll('.pkt-calendar__date--in-range-hover') expect(hoveredRanges.length).toBeGreaterThan(0) }) test('clears range when selecting new start date', () => { const { container } = createCalendar({ range: true }) const availableDates = container.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) // Create initial range fireEvent.click(availableDates[5]) fireEvent.click(availableDates[10]) // Select new start date fireEvent.click(availableDates[2]) // Old range should be cleared const selectedDates = container.querySelectorAll('.pkt-calendar__date--selected') expect(selectedDates.length).toBe(1) }) }) describe('API methods', () => { test('addToSelected method works correctly', () => { const ref = createRef() const { container } = render( , ) const testDate = parseISODateString('2024-06-15') act(() => { ref.current!.addToSelected(testDate) }) const dateButton = container.querySelector('button[data-date="2024-06-15"]') expect(dateButton).toHaveClass('pkt-calendar__date--selected') }) test('removeFromSelected method works correctly', () => { const ref = createRef() const { container } = render( , ) const testDate = parseISODateString('2024-06-15') act(() => { ref.current!.addToSelected(testDate) }) act(() => { ref.current!.removeFromSelected(testDate) }) const dateButton = container.querySelector('button[data-date="2024-06-15"]') expect(dateButton).not.toHaveClass('pkt-calendar__date--selected') }) test('toggleSelected method works correctly', () => { const ref = createRef() const { container } = render( , ) const testDate = parseISODateString('2024-06-15') // Toggle on act(() => { ref.current!.toggleSelected(testDate) }) let dateButton = container.querySelector('button[data-date="2024-06-15"]') expect(dateButton).toHaveClass('pkt-calendar__date--selected') // Toggle off act(() => { ref.current!.toggleSelected(testDate) }) dateButton = container.querySelector('button[data-date="2024-06-15"]') expect(dateButton).not.toHaveClass('pkt-calendar__date--selected') }) test('focusOnCurrentDate method works correctly', () => { const ref = createRef() render() act(() => { ref.current!.focusOnCurrentDate() }) // Should focus on a date element const focusedElement = document.activeElement expect(focusedElement).toHaveClass('pkt-calendar__date') }) }) })