UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

274 lines (208 loc) 9.22 kB
import '@testing-library/jest-dom' import { fireEvent } from '@testing-library/dom' import { parseISODateString } from 'shared-utils/date-utils' import './calendar' import { PktCalendar } from './calendar' const waitForCustomElements = async () => { await customElements.whenDefined('pkt-calendar') } // Helper function to create calendar markup const createCalendar = async (calendarProps = '') => { const container = document.createElement('div') container.innerHTML = ` <pkt-calendar ${calendarProps}></pkt-calendar> ` document.body.appendChild(container) await waitForCustomElements() return container } // Cleanup after each test afterEach(() => { document.body.innerHTML = '' }) describe('PktCalendar', () => { describe('Date selection functionality', () => { test('selects single date correctly', async () => { const container = await createCalendar() const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete // Find and click on a date const availableDate = calendar.querySelector( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDate).toBeInTheDocument() fireEvent.click(availableDate!) await calendar.updateComplete expect(availableDate).toHaveClass('pkt-calendar__date--selected') }) test('handles multiple date selection', async () => { const container = await createCalendar('multiple') const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete // Find and click on multiple dates const availableDates = calendar.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDates.length).toBeGreaterThan(1) fireEvent.click(availableDates[0]) await calendar.updateComplete fireEvent.click(availableDates[1]) await calendar.updateComplete expect(availableDates[0]).toHaveClass('pkt-calendar__date--selected') expect(availableDates[1]).toHaveClass('pkt-calendar__date--selected') }) test('respects maxMultiple limit', async () => { const container = await createCalendar('multiple max-multiple="2"') const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete // Try to select more than maxMultiple dates const availableDates = calendar.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]) await calendar.updateComplete fireEvent.click(availableDates[1]) await calendar.updateComplete fireEvent.click(availableDates[2]) await calendar.updateComplete const selectedDates = calendar.querySelectorAll('.pkt-calendar__date--selected') expect(selectedDates.length).toBeLessThanOrEqual(2) }) test('handles pre-selected dates', async () => { const preSelectedDates = '2024-06-15,2024-06-20' const container = await createCalendar( `selected="${preSelectedDates}" currentmonth="2024-06-01"`, ) const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete expect(calendar.selected).toEqual(['2024-06-15', '2024-06-20']) const selectedDates = calendar.querySelectorAll('.pkt-calendar__date--selected') expect(selectedDates.length).toBe(2) }) test('toggles date selection when clicking same date twice', async () => { const container = await createCalendar() const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete const availableDate = calendar.querySelector( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDate).toBeInTheDocument() // First click - select fireEvent.click(availableDate!) await calendar.updateComplete expect(availableDate).toHaveClass('pkt-calendar__date--selected') // Second click - deselect fireEvent.click(availableDate!) await calendar.updateComplete expect(availableDate).not.toHaveClass('pkt-calendar__date--selected') }) }) describe('Range selection functionality', () => { test('handles range selection correctly', async () => { const container = await createCalendar('range') const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete const availableDates = calendar.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) expect(availableDates.length).toBeGreaterThan(3) // Select start date fireEvent.click(availableDates[5]) await calendar.updateComplete // Select end date fireEvent.click(availableDates[10]) await calendar.updateComplete // Check for range styling const rangeStart = calendar.querySelector('.pkt-calendar__date--range-start') const rangeEnd = calendar.querySelector('.pkt-calendar__date--range-end') const rangeInBetween = calendar.querySelectorAll('.pkt-calendar__date--in-range') expect(rangeStart).toBeInTheDocument() expect(rangeEnd).toBeInTheDocument() expect(rangeInBetween.length).toBeGreaterThan(0) }) test('shows range hover preview', async () => { const container = await createCalendar('range') const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete const availableDates = calendar.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) // Select start date fireEvent.click(availableDates[5]) await calendar.updateComplete // Hover over potential end date fireEvent.mouseOver(availableDates[10]) await calendar.updateComplete // Should show hover preview styling const hoveredRanges = calendar.querySelectorAll('.pkt-calendar__date--in-range-hover') expect(hoveredRanges.length).toBeGreaterThan(0) }) test('clears range when selecting new start date', async () => { const container = await createCalendar('range') const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete const availableDates = calendar.querySelectorAll( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) // Create initial range fireEvent.click(availableDates[5]) await calendar.updateComplete fireEvent.click(availableDates[10]) await calendar.updateComplete // Select new start date fireEvent.click(availableDates[2]) await calendar.updateComplete // Old range should be cleared const selectedDates = calendar.querySelectorAll('.pkt-calendar__date--selected') expect(selectedDates.length).toBe(1) }) }) describe('API methods', () => { test('addToSelected method works correctly', async () => { const container = await createCalendar('multiple') const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete const testDate = parseISODateString('2024-06-15') calendar.addToSelected(testDate) await calendar.updateComplete expect(calendar['_selected']).toContainEqual(testDate) }) test('removeFromSelected method works correctly', async () => { const container = await createCalendar('multiple') const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete const testDate = new Date('2024-06-15') calendar.addToSelected(testDate) await calendar.updateComplete calendar.removeFromSelected(testDate) await calendar.updateComplete expect(calendar['_selected']).not.toContainEqual(testDate) }) test('toggleSelected method works correctly', async () => { const container = await createCalendar() const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete const testDate = parseISODateString('2024-06-15') // Toggle on calendar.toggleSelected(testDate) await calendar.updateComplete expect(calendar['_selected']).toContainEqual(testDate) // Toggle off calendar.toggleSelected(testDate) await calendar.updateComplete expect(calendar['_selected']).not.toContainEqual(testDate) }) test('focusOnCurrentDate method works correctly', async () => { const container = await createCalendar() const calendar = container.querySelector('pkt-calendar') as PktCalendar await calendar.updateComplete calendar.focusOnCurrentDate() await calendar.updateComplete // Should focus on a date element const focusedElement = document.activeElement expect(focusedElement).toHaveClass('pkt-calendar__date') }) }) })