import { mount } from '@vue/test-utils' import { describe, expect, it } from 'vitest' import TimeRangeInput from '../../components/TimeRangeInput.vue' describe('TimeRangeInput', () => { it('should render the duration after the end picker when both times are set', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '09:00', end: '10:30' } } }) expect(wrapper.get('.mint-time-range__end').element.nextElementSibling?.classList.contains('mint-time-range__duration')).toBe(true) }) it('should spell the duration as hours and minutes when both parts are set', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '09:00', end: '10:30' } } }) expect(wrapper.get('.mint-time-range__duration').text()).toBe('1 h 30 min') }) it('should drop the minutes when the duration is whole hours', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '09:00', end: '17:00' } } }) expect(wrapper.get('.mint-time-range__duration').text()).toBe('8 h') }) it('should drop the hours when the duration is under an hour', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '09:00', end: '09:45' } } }) expect(wrapper.get('.mint-time-range__duration').text()).toBe('45 min') }) it('should show an error message when the end is not after the start', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '10:00', end: '09:30' } } }) expect(wrapper.get('.mint-time-range__error').text()).toBe('End time must be after start time') }) it('should put both pickers in the error state when the end equals the start', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '10:00', end: '10:00' } } }) expect(wrapper.findAll('.mint-time-picker__input--error')).toHaveLength(2) }) it('should not print a negative duration when the end is before the start', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '10:00', end: '09:30' } } }) expect(wrapper.get('.mint-time-range__duration').text()).toBe('—') }) it('should show a placeholder duration when a time is missing', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '10:00', end: '' } } }) expect(wrapper.get('.mint-time-range__duration').text()).toBe('—') }) it('should emit validity-change false when the end is not after the start', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '10:00', end: '09:30' } } }) expect(wrapper.emitted('validity-change')?.at(-1)).toEqual([false]) }) it('should emit validity-change true when the range becomes valid', async () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '10:00', end: '09:30' } } }) await wrapper.setProps({ modelValue: { start: '10:00', end: '11:00' } }) expect(wrapper.emitted('validity-change')?.at(-1)).toEqual([true]) }) it('should expose isValid false when the end is not after the start', () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '10:00', end: '09:30' } } }) expect((wrapper.vm as unknown as { isValid: boolean }).isValid).toBe(false) }) it('should forward disabledSlots to the end picker when set', async () => { const wrapper = mount(TimeRangeInput, { props: { modelValue: { start: '09:00', end: '' }, disabledSlots: (time: string) => time === '09:15' && 'Booked' }, }) await wrapper.get('.mint-time-range__end input').trigger('click') expect(wrapper.get('.mint-time-range__end .mint-time-picker__slot-reason').text()).toBe('Booked') }) })