UNPKG

@oslokommune/punkt-elements

Version:

Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo

325 lines (243 loc) 11.7 kB
import '@testing-library/jest-dom' import { toHaveNoViolations } from 'jest-axe' import { fireEvent } from '@testing-library/dom' import { parseISODateString } from 'shared-utils/date-utils' expect.extend(toHaveNoViolations) import './datepicker' import '../calendar/calendar' import { PktDatepicker } from './datepicker' import { PktCalendar } from '../calendar/calendar' import { PktDatepickerPopup } from './datepicker-popup' const waitForCustomElements = async () => { await customElements.whenDefined('pkt-datepicker') await customElements.whenDefined('pkt-calendar') } // Helper function to create datepicker markup const createDatepicker = async (datepickerProps = '') => { const container = document.createElement('div') container.innerHTML = ` <pkt-datepicker ${datepickerProps}></pkt-datepicker> ` document.body.appendChild(container) await waitForCustomElements() return container } // Cleanup after each test afterEach(() => { document.body.innerHTML = '' }) describe('PktDatepicker', () => { describe('Rendering and basic functionality', () => { test('renders without errors', async () => { const container = await createDatepicker() const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker expect(datepicker).toBeInTheDocument() await datepicker.updateComplete expect(datepicker).toBeTruthy() }) test('renders with correct structure', async () => { const container = await createDatepicker('label="Test Datepicker"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const inputWrapper = datepicker.querySelector('pkt-input-wrapper') const input = datepicker.querySelector('input') const calendarButton = datepicker.querySelector('button[type="button"]') expect(inputWrapper).toBeInTheDocument() expect(input).toBeInTheDocument() expect(calendarButton).toBeInTheDocument() }) test('renders calendar when opened', async () => { const container = await createDatepicker('label="Test Datepicker"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const calendarButton = datepicker.querySelector('button[type="button"]') fireEvent.click(calendarButton!) await datepicker.updateComplete const calendar = datepicker.querySelector('pkt-calendar') expect(calendar).toBeInTheDocument() }) test('closes calendar when clicking outside', async () => { const container = await createDatepicker('label="Test Datepicker"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete // Open calendar const calendarButton = datepicker.querySelector('button[type="button"]') fireEvent.click(calendarButton!) await datepicker.updateComplete // Click outside fireEvent.click(document.body) await datepicker.updateComplete expect(datepicker.calendarOpen).toBe(false) }) test('closes calendar when clicking outside', async () => { const container = await createDatepicker('label="Test Datepicker"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete // Open calendar const calendarButton = datepicker.querySelector('button[type="button"]') fireEvent.click(calendarButton!) await datepicker.updateComplete // Click outside fireEvent.click(document.body) await datepicker.updateComplete expect(datepicker.calendarOpen).toBe(false) }) }) describe('Properties and attributes', () => { test('applies default properties correctly', async () => { const container = await createDatepicker('name="test" id="test"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete expect(datepicker.value).toBe('') expect(datepicker.label).toBe('Datovelger') expect(datepicker.multiple).toBe(false) expect(datepicker.range).toBe(false) expect(datepicker.maxlength).toBe(null) expect(datepicker.showRangeLabels).toBe(false) }) test('handles value property correctly', async () => { const testDate = '2024-06-15' const container = await createDatepicker(`value="${testDate}"`) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete expect(datepicker.value).toBe(testDate) const input = datepicker.querySelector('input') as HTMLInputElement expect(input.value).toBeTruthy() }) test('handles multiple values correctly', async () => { const testDates = '2024-06-15,2024-06-20,2024-06-25' const container = await createDatepicker(`value="${testDates}" multiple`) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete expect(datepicker.value).toBe(testDates) expect(datepicker.multiple).toBe(true) // Should show tags for multiple values const tags = datepicker.querySelectorAll('pkt-tag') expect(tags.length).toBe(3) }) test('handles range values correctly', async () => { const rangeValue = '2024-06-15,2024-06-20' const container = await createDatepicker(`value="${rangeValue}" range`) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete expect(datepicker.value).toBe(rangeValue) expect(datepicker.range).toBe(true) }) test('handles label property correctly', async () => { const testLabel = 'Select your date' const container = await createDatepicker(`label="${testLabel}"`) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete expect(datepicker.label).toBe(testLabel) const label = datepicker.querySelector('label') expect(label?.textContent).toContain(testLabel) }) test('handles dateformat property correctly', async () => { const customFormat = 'MM/dd/yyyy' const container = await createDatepicker( `dateformat="${customFormat}" value="2024-06-15" multiple`, ) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete expect(datepicker.dateformat).toBe(customFormat) // Multiple mode input should be empty (for new input) const input = datepicker.querySelector('input') as HTMLInputElement expect(input.value).toBe('') // Selected dates should show in tags with custom format const tag = datepicker.querySelector('pkt-tag time') expect(tag).toBeInTheDocument() if (tag) { expect(tag.textContent).toMatch(/\d{2}\/\d{2}\/\d{4}/) } }) test('handles maxlength property correctly', async () => { const container = await createDatepicker('multiple maxlength="3"') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete expect(datepicker.maxlength).toBe(3) }) test('handles disabled property correctly', async () => { const container = await createDatepicker('disabled') const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete expect(datepicker.disabled).toBe(true) const input = datepicker.querySelector('input') as HTMLInputElement const calendarButton = datepicker.querySelector('button[type="button"]') as HTMLButtonElement expect(input.disabled).toBe(true) expect(calendarButton.disabled).toBe(true) }) test('handles currentmonth property correctly', async () => { const testMonth = '2024-03-01' const container = await createDatepicker(`currentmonth="${testMonth}"`) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete // Open calendar to see the month const calendarButton = datepicker.querySelector('button[type="button"]') fireEvent.click(calendarButton!) await datepicker.updateComplete const calendar = datepicker.querySelector('pkt-calendar') as PktCalendar expect(calendar.currentmonth).toEqual(parseISODateString(testMonth)) }) }) describe('Calendar integration', () => { test('passes properties to calendar correctly', async () => { const container = await createDatepicker( 'min="2024-06-01" max="2024-06-30" excludeweekdays="0,6"', ) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete // Open calendar const calendarButton = datepicker.querySelector('button[type="button"]') fireEvent.click(calendarButton!) await datepicker.updateComplete const calendar = datepicker.querySelector('pkt-calendar') as PktCalendar expect(calendar.earliest).toBe('2024-06-01') expect(calendar.latest).toBe('2024-06-30') expect(calendar.excludeweekdays).toEqual(['0', '6']) }) test('syncs selected dates between input and calendar', async () => { const testDate = '2024-06-15' const container = await createDatepicker(`value="${testDate}" calendar-open`) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const popup = datepicker.querySelector('pkt-datepicker-popup') as PktDatepickerPopup await popup?.updateComplete const calendar = datepicker.querySelector('pkt-calendar') as PktCalendar await calendar?.updateComplete expect(calendar.selected).toContain(testDate) const selectedDate = datepicker.querySelector('.pkt-calendar__date--selected') expect(selectedDate).toBeInTheDocument() }) test('updates input when date selected in calendar', async () => { const container = await createDatepicker() const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete // Open calendar const calendarButton = datepicker.querySelector('button[type="button"]') fireEvent.click(calendarButton!) await datepicker.updateComplete // Select a date const availableDate = datepicker.querySelector( '.pkt-calendar__date:not(.pkt-calendar__date--disabled)', ) fireEvent.click(availableDate!) await datepicker.updateComplete // Input should be updated const input = datepicker.querySelector('input') as HTMLInputElement expect(input.value).toBeTruthy() expect(datepicker.value).toBeTruthy() }) test('shows current month correctly in calendar', async () => { const currentMonth = '2024-06-01' const container = await createDatepicker(`currentmonth="${currentMonth}" calendar-open`) const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker await datepicker.updateComplete const popup = datepicker.querySelector('pkt-datepicker-popup') as PktDatepickerPopup await popup?.updateComplete const calendar = datepicker.querySelector('pkt-calendar') as PktCalendar await calendar?.updateComplete const monthTitle = datepicker.querySelector('.pkt-calendar__month-title') expect(monthTitle?.textContent).toContain('2024') }) }) })