123 lines
5.4 KiB
TypeScript
123 lines
5.4 KiB
TypeScript
import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'
|
|
import {mount} from '@vue/test-utils'
|
|
import type {DefineComponent} from 'vue'
|
|
import DateWeek from './DateWeek.vue'
|
|
|
|
type DateWeekProps = {
|
|
modelValue?: string | null
|
|
label?: string
|
|
disabled?: boolean
|
|
readonly?: boolean
|
|
error?: string
|
|
min?: string
|
|
max?: string
|
|
}
|
|
|
|
const DateWeekForTest = DateWeek as DefineComponent<DateWeekProps>
|
|
const mountWeek = (props: DateWeekProps = {}) =>
|
|
mount(DateWeekForTest, {props, attachTo: document.body})
|
|
|
|
describe('MalioDateWeek', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers()
|
|
vi.setSystemTime(new Date(2026, 4, 19)) // 19 mai 2026
|
|
})
|
|
afterEach(() => vi.useRealTimers())
|
|
|
|
it('renders the label and calendar icon', () => {
|
|
const wrapper = mountWeek({label: 'Semaine'})
|
|
expect(wrapper.get('label').text()).toBe('Semaine')
|
|
expect(wrapper.find('[data-test="calendar-icon"]').exists()).toBe(true)
|
|
})
|
|
|
|
it('displays the formatted week when modelValue is set', () => {
|
|
const wrapper = mountWeek({modelValue: '2026-W21'})
|
|
const input = wrapper.get('[data-test="date-input"]').element as HTMLInputElement
|
|
expect(input.value).toBe('Semaine 21 (18/05 → 24/05/2026)')
|
|
})
|
|
|
|
it('shows an empty field without a value', () => {
|
|
const wrapper = mountWeek()
|
|
const input = wrapper.get('[data-test="date-input"]').element as HTMLInputElement
|
|
expect(input.value).toBe('')
|
|
})
|
|
|
|
it('opens on the month of the selected week', async () => {
|
|
const wrapper = mountWeek({modelValue: '2026-W01'}) // lundi 2025-12-29
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
expect(wrapper.get('[data-test="header-toggle"]').text()).toContain('Décembre 2025')
|
|
})
|
|
|
|
it('selects the week when a day is clicked', async () => {
|
|
const wrapper = mountWeek()
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
await wrapper.get('[data-test="day"][data-iso="2026-05-20"]').trigger('click')
|
|
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['2026-W21'])
|
|
expect(wrapper.find('[data-test="popover"]').exists()).toBe(false)
|
|
})
|
|
|
|
it('selects the week when the week number is clicked', async () => {
|
|
const wrapper = mountWeek()
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
await wrapper.get('[data-test="week-number"][data-week-start="2026-05-18"]').trigger('click')
|
|
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual(['2026-W21'])
|
|
expect(wrapper.find('[data-test="popover"]').exists()).toBe(false)
|
|
})
|
|
|
|
it('previews the whole week on day hover', async () => {
|
|
const wrapper = mountWeek()
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
await wrapper.get('[data-test="day"][data-iso="2026-05-20"]').trigger('mouseenter')
|
|
expect(wrapper.get('[data-test="day"][data-iso="2026-05-18"]').attributes('data-range-role')).toBe('start')
|
|
expect(wrapper.get('[data-test="day"][data-iso="2026-05-24"]').attributes('data-range-role')).toBe('end')
|
|
expect(wrapper.get('[data-test="day"][data-iso="2026-05-20"]').attributes('data-range-role')).toBe('in-range')
|
|
})
|
|
|
|
it('previews the whole week on week-number hover', async () => {
|
|
const wrapper = mountWeek()
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
await wrapper.get('[data-test="week-number"][data-week-start="2026-05-18"]').trigger('mouseenter')
|
|
expect(wrapper.get('[data-test="day"][data-iso="2026-05-22"]').attributes('data-range-role')).toBe('in-range')
|
|
})
|
|
|
|
it('marks the committed week number', async () => {
|
|
const wrapper = mountWeek({modelValue: '2026-W21'})
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
expect(wrapper.get('[data-test="week-number"][data-week-start="2026-05-18"]').attributes('data-marked')).toBe('true')
|
|
expect(wrapper.get('[data-test="day"][data-iso="2026-05-18"]').attributes('data-range-role')).toBe('start')
|
|
})
|
|
|
|
it('emits null on clear', async () => {
|
|
const wrapper = mountWeek({modelValue: '2026-W21'})
|
|
await wrapper.get('[data-test="clear"]').trigger('click')
|
|
expect(wrapper.emitted('update:modelValue')?.at(-1)).toEqual([null])
|
|
})
|
|
|
|
it('disables a week fully outside min/max', async () => {
|
|
const wrapper = mountWeek({min: '2026-05-18', max: '2026-05-31'})
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
const earlyWeek = wrapper.get('[data-test="week-number"][data-week-start="2026-05-11"]')
|
|
expect((earlyWeek.element as HTMLButtonElement).disabled).toBe(true)
|
|
const selectableWeek = wrapper.get('[data-test="week-number"][data-week-start="2026-05-18"]')
|
|
expect((selectableWeek.element as HTMLButtonElement).disabled).toBe(false)
|
|
})
|
|
|
|
it('does not open when disabled', async () => {
|
|
const wrapper = mountWeek({disabled: true})
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
expect(wrapper.find('[data-test="popover"]').exists()).toBe(false)
|
|
})
|
|
|
|
it('does not open when readonly', async () => {
|
|
const wrapper = mountWeek({readonly: true, modelValue: '2026-W21'})
|
|
await wrapper.get('[data-test="date-input"]').trigger('click')
|
|
expect(wrapper.find('[data-test="popover"]').exists()).toBe(false)
|
|
})
|
|
|
|
it('sets aria-invalid on error', () => {
|
|
const wrapper = mountWeek({error: 'Semaine requise'})
|
|
expect(wrapper.get('[data-test="date-input"]').attributes('aria-invalid')).toBe('true')
|
|
expect(wrapper.text()).toContain('Semaine requise')
|
|
})
|
|
})
|