UNPKG

@gitlab/ui

Version:
308 lines (240 loc) • 9.79 kB
import { shallowMount } from '@vue/test-utils'; import Datepicker from '../datepicker/datepicker.vue'; import Icon from '../icon/icon.vue'; import DaterangePicker from './daterange_picker.vue'; describe('Daterange Picker', () => { let wrapper; const startDate = new Date('2020-08-27'); const endDate = new Date('2020-08-29'); const defaultMaxDate = new Date('2021-01-01'); const factory = (props = {}, scopedSlots = {}) => { wrapper = shallowMount(DaterangePicker, { propsData: { defaultStartDate: startDate, defaultEndDate: endDate, ...props, }, scopedSlots, }); }; const findStartPicker = () => wrapper.findAllComponents(Datepicker).at(0); const findEndPicker = () => wrapper.findAllComponents(Datepicker).at(1); it('renders two datepickers', () => { factory(); expect(findStartPicker().exists()).toBe(true); expect(findEndPicker().exists()).toBe(true); }); describe('from date picker', () => { describe('emits the input event', () => { beforeEach(() => { factory(); findStartPicker().vm.$emit('input', startDate); }); it('updates startDate correctly', () => { expect(wrapper.vm.startDate).toBe(startDate); }); it("sets the end date picker's minDate to one day after the startDate", () => { const toCalendarMinDate = new Date('2020-08-28'); expect(findEndPicker().props('minDate')).toEqual(toCalendarMinDate); }); it('emits `start-date-open` event on component when `open` event fires', () => { findStartPicker().vm.$emit('open'); expect(wrapper.emitted('start-picker-open')).toHaveLength(1); }); it('emits `start-date-close` event on component when `close` event fires', () => { findStartPicker().vm.$emit('close'); expect(wrapper.emitted('start-picker-close')).toHaveLength(1); }); describe('with a date range violation', () => { beforeEach(() => { factory({ defaultEndDate: new Date('2020-08-26'), }); findStartPicker().vm.$emit('input', startDate); }); it('does not emit the "input" event when there is a date range violation', () => { expect(Object.keys(wrapper.emitted())).toHaveLength(0); }); it('sets openToCalendar=true', () => { expect(wrapper.vm.openToCalendar).toBe(true); }); it('sets endDate=null', () => { expect(wrapper.vm.endDate).toBe(null); }); }); describe('date range violation with maxDateRange and sameDaySelection', () => { describe.each` maxDateRange | sameDaySelection | violation ${2} | ${false} | ${false} ${1} | ${false} | ${true} ${2} | ${true} | ${true} ${3} | ${true} | ${false} `( 'with maxDateRange = $maxDateRange, sameDaySelection = $sameDaySelection and violation = $violation', ({ maxDateRange, sameDaySelection, violation }) => { beforeEach(() => { factory({ maxDateRange, sameDaySelection, }); findStartPicker().vm.$emit('input', startDate); }); it(`${violation ? 'has' : 'does not have'} a date range violation`, () => { const events = violation ? 0 : 1; expect(Object.keys(wrapper.emitted())).toHaveLength(events); }); } ); }); describe('with no date range violation', () => { it('emits the "input" event', () => { expect(wrapper.emitted('input')).toEqual([[{ startDate, endDate: wrapper.vm.endDate }]]); }); }); }); }); describe('end date picker', () => { describe('emits the input event', () => { beforeEach(() => { factory(); findEndPicker().vm.$emit('input', endDate); }); it('updates endDate correctly', () => { expect(wrapper.vm.endDate).toBe(endDate); }); it('sets openToCalendar=false', () => { expect(wrapper.vm.openToCalendar).toBe(false); }); it('calls the event handler', () => { expect(wrapper.emitted('input')).toEqual([[{ startDate: wrapper.vm.startDate, endDate }]]); }); it('emits `end-date-open` event on component when `open` event fires', () => { findEndPicker().vm.$emit('open'); expect(wrapper.emitted('end-picker-open')).toHaveLength(1); }); it('emits `end-date-close` event on component when `close` event fires', () => { findEndPicker().vm.$emit('close'); expect(wrapper.emitted('end-picker-close')).toHaveLength(1); }); }); }); describe('with maxDateRange = 10', () => { beforeEach(() => { factory({ maxDateRange: 10, defaultMaxDate }); }); it('sets the maxDate to the startDate + the maxDateRange', () => { const maxDate = new Date('2020-09-06'); expect(findEndPicker().props('maxDate')).toEqual(maxDate); }); }); describe('with startPickerTarget/endPickerTarget defined', () => { beforeEach(() => { factory({ startPickerTarget: '.btn', endPickerTarget: '.btn' }); }); it('sets the `target` prop to startPickerTarget', () => { expect(findStartPicker().props('target')).toBe('.btn'); }); it('sets the `target` prop to endPickerTarget', () => { expect(findEndPicker().props('target')).toBe('.btn'); }); }); describe('with startPickerContainer/endPickerContainer defined', () => { beforeEach(() => { factory({ startPickerContainer: 'body', endPickerContainer: 'body' }); }); it('sets the `container` prop to startPickerContainer', () => { expect(findStartPicker().props('container')).toBe('body'); }); it('sets the `container` prop to endPickerContainer', () => { expect(findEndPicker().props('container')).toBe('body'); }); }); describe('sameDaySelection = true', () => { describe('from date picker', () => { beforeEach(() => { factory({ sameDaySelection: true }); }); it('updates startDate correctly', () => { expect(wrapper.vm.startDate).toBe(startDate); }); it("sets the end date picker's minDate to the startDate", () => { expect(findEndPicker().props('minDate')).toEqual(startDate); }); describe('with maxDateRange = 10', () => { beforeEach(() => { factory({ sameDaySelection: true, maxDateRange: 10, defaultMaxDate }); }); it('sets the maxDate to the startDate + the maxDateRange - 1', () => { const maxDate = new Date('2020-09-05'); expect(findEndPicker().props('maxDate')).toEqual(maxDate); }); }); }); }); describe('labelClass', () => { const customClass = 'foobar'; const findLabelsWithCustomClass = () => wrapper.findAll('label').filter((label) => label.classes(customClass)); it('does not have the class by default', () => { factory(); expect(findLabelsWithCustomClass()).toHaveLength(0); }); it('adds the label class when provided', () => { factory({ labelClass: customClass }); expect(findLabelsWithCustomClass()).toHaveLength(2); }); }); describe('with date range indicator and tooltip', () => { const tooltip = 'Date range limited to 31 days'; const dateRangeIndicatorClass = 'indicator-container-class'; const findDateRangeIndicator = () => wrapper.find('[data-testid="daterange-picker-indicator"]'); const findTooltipIcon = () => wrapper.findComponent(Icon); const slots = { default: `<div>{{ props.daysSelected }} days selected</div>`, }; it('does not show default slot or tooltip icon by default', () => { factory(); expect(findDateRangeIndicator().exists()).toBe(false); expect(findTooltipIcon().exists()).toBe(false); }); it('shows the default slot when provided', () => { factory({}, slots); expect(findDateRangeIndicator().text()).toBe('2 days selected'); }); it('shows the effective days selected for the default slot when sameDaySelection is true', () => { factory({ sameDaySelection: true }, slots); expect(findDateRangeIndicator().text()).toBe('3 days selected'); }); it('shows the icon with the provided tooltip', () => { factory({ tooltip }); expect(findTooltipIcon().attributes('title')).toBe(tooltip); }); it('adds the indicator class when provided', () => { factory({ dateRangeIndicatorClass }, slots); expect(wrapper.find(`.${dateRangeIndicatorClass}`).exists()).toBe(true); }); }); it.each` prop | value | testid ${'startPickerClass'} | ${'gl-text-blue-500'} | ${'daterange-picker-start-container'} ${'endPickerClass'} | ${'gl-text-red-500'} | ${'daterange-picker-end-container'} `('adds the provided $value class to $testid', ({ prop, value, testid }) => { factory({ [prop]: value }); expect(wrapper.find(`[data-testid="${testid}"]`).classes()).toContain(value); }); describe('startOpened', () => { beforeEach(() => { factory({ startOpened: true }); }); it('sets start-opened on the from date picker', () => { expect(findStartPicker().props('startOpened')).toBe(true); }); it('defaults to false', () => { factory(); expect(findStartPicker().props('startOpened')).toBe(false); }); it('does not set start-opened on the end date picker', () => { expect(findEndPicker().props('startOpened')).toBe(false); }); }); });