@oslokommune/punkt-elements
Version:
Komponentbiblioteket til Punkt, et designsystem laget av Oslo Origo
169 lines (132 loc) • 6.26 kB
text/typescript
import '@testing-library/jest-dom'
import './datepicker'
import '../calendar/calendar'
import { PktDatepicker } from './datepicker'
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('Date boundary testing', () => {
test('handles minimum possible dates', async () => {
const minDate = '1900-01-01'
const container = await createDatepicker(`value="${minDate}" earliest="${minDate}"`)
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
expect(datepicker.value).toBe(minDate)
})
test('handles maximum possible dates', async () => {
const maxDate = '2100-12-31'
const container = await createDatepicker(`value="${maxDate}" latest="${maxDate}"`)
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
expect(datepicker.value).toBe(maxDate)
})
test('handles year boundaries correctly', async () => {
const yearBoundaryDates = ['1999-12-31', '2000-01-01', '2000-12-31', '2001-01-01']
for (const date of yearBoundaryDates) {
const container = await createDatepicker(`value="${date}"`)
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
expect(datepicker.value).toBe(date)
container.remove()
}
})
test('handles month boundaries correctly', async () => {
const monthBoundaryDates = [
'2024-01-31',
'2024-02-01',
'2024-02-28',
'2024-02-29', // Leap year
'2024-03-01',
]
for (const date of monthBoundaryDates) {
const container = await createDatepicker(`value="${date}"`)
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
expect(datepicker.value).toBe(date)
container.remove()
}
})
test.each`
description | value | expectedRangeUnderflow | expectedValid
${'Test date before min - component should mark it invalid'} | ${'2024-06-05'} | ${true} | ${false}
${'Test date after max - component should mark it invalid'} | ${'2024-06-25'} | ${false} | ${false}
${'Test valid date - should be accepted and marked valid'} | ${'2024-06-15'} | ${false} | ${true}
`(
'validates dates against earliest/latest boundaries - $description',
async ({ value, expectedRangeUnderflow, expectedValid }) => {
const container = await createDatepicker('min="2024-06-10" max="2024-06-20"')
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
const input = datepicker.querySelector('input') as HTMLInputElement
datepicker.value = value
await datepicker.updateComplete
expect(datepicker.value).toBe(value)
expect(input.value).toBe(value)
expect(datepicker._value).toEqual([value])
expect(input.validity.rangeUnderflow).toBe(expectedRangeUnderflow)
expect(input.validity.valid).toBe(expectedValid)
},
)
})
describe('Error handling and edge cases', () => {
test('handles invalid date formats gracefully', async () => {
const container = await createDatepicker('value="not-a-date"')
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
// Should not crash
expect(datepicker).toBeInTheDocument()
})
test('handles empty values correctly', async () => {
const container = await createDatepicker('value=""')
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
expect(datepicker.value).toBe('')
expect(datepicker.hasError).toBe(false)
})
test('handles malformed multiple values', async () => {
const malformedDates = '2024-06-15,,2024-06-20,,,'
const container = await createDatepicker(`value="${malformedDates}" multiple`)
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
// Should filter out empty values
const tags = datepicker.querySelectorAll('pkt-tag')
expect(tags.length).toBe(2) // Only valid dates
})
test('handles very long value strings', async () => {
// Create a string with many dates
const longValueArray = Array.from({ length: 100 }, (_, i) => `2024-06-${(i % 30) + 1}`)
const longValue = longValueArray.join(',')
const container = await createDatepicker(`value="${longValue}" multiple maxlength="50"`)
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
// Should handle gracefully - maxlength may or may not be enforced at render time
const tags = datepicker.querySelectorAll('pkt-tag')
expect(tags.length).toBeGreaterThan(0) // Should show some tags
expect(datepicker).toBeInTheDocument() // Should not crash
})
test('handles conflicting properties gracefully', async () => {
// Both multiple and range shouldn't typically be used together
const container = await createDatepicker('multiple range value="2024-06-15,2024-06-20"')
const datepicker = container.querySelector('pkt-datepicker') as PktDatepicker
await datepicker.updateComplete
// Should still render without errors
expect(datepicker).toBeInTheDocument()
})
})
})