import MockDate from 'mockdate';
import {mountWithTheme} from 'sentry-test/enzyme';
import DateRange from 'sentry/components/organizations/timeRangeSelector/dateRange';
import ConfigStore from 'sentry/stores/configStore';
// 2017-10-14T02:38:00.000Z
// 2017-10-17T02:38:00.000Z
const start = new Date(1507948680000);
const end = new Date(1508207880000); // National Pasta Day
const getSelectedRange = wrapper => [
wrapper.find('.rdrStartEdge').closest('DayCell').find('.rdrDayNumber span').text(),
...wrapper
.find('.rdrInRange')
.map(el => el.closest('DayCell').find('.rdrDayNumber span').text()),
wrapper.find('.rdrEndEdge').closest('DayCell').find('.rdrDayNumber span').text(),
];
function getTimeText(element) {
const valueRegex = /value="([0-9]{2}:[0-9]{2})"/;
return element.html().match(valueRegex)[1];
}
describe('DateRange', function () {
let wrapper;
const onChange = jest.fn();
const routerContext = TestStubs.routerContext();
beforeAll(function () {
MockDate.set(new Date('2017-10-16T23:41:20.000Z'));
ConfigStore.loadInitialData({
user: {options: {timezone: 'America/New_York'}},
});
});
afterAll(function () {
// reset mock date
MockDate.set(new Date(1508208080000));
});
describe('Local time', function () {
beforeEach(function () {
onChange.mockReset();
});
beforeEach(async function () {
wrapper = mountWithTheme(
,
routerContext
);
await tick();
await tick();
wrapper.update();
});
it('has the right max date', function () {
expect(wrapper.find('DateRangePicker').at(0).prop('maxDate')).toEqual(
new Date('2017-10-16T23:41:20.000Z')
);
});
it('has the right days selected', function () {
// start/end inputs
const startEndInputs = wrapper.find(
'.rdrDateRangeWrapper .rdrDateDisplayItem input'
);
expect(startEndInputs.at(0).prop('value')).toBe('Oct 13, 2017');
expect(startEndInputs.at(1).prop('value')).toBe('Oct 16, 2017');
expect(getSelectedRange(wrapper)).toEqual(['13', '14', '15', '16']);
});
it('can select a date (midnight)', function () {
wrapper.find('DayCell').at(0).simulate('mouseUp');
//
expect(onChange).toHaveBeenLastCalledWith({
start: new Date('2017-10-01T04:00:00.000Z'),
end: new Date('2017-10-02T03:59:59.000Z'),
});
});
it('changes start time for existing date', function () {
wrapper
.find('input[data-test-id="startTime"]')
.simulate('change', {target: {value: '11:00'}});
expect(onChange).toHaveBeenLastCalledWith({
start: new Date('2017-10-13T15:00:00.000Z'),
end: new Date('2017-10-17T02:38:00.000Z'),
hasDateRangeErrors: false,
});
});
it('changes end time for existing date', function () {
wrapper
.find('input[data-test-id="endTime"]')
.simulate('change', {target: {value: '12:00'}});
expect(onChange).toHaveBeenLastCalledWith({
start: new Date('2017-10-14T02:38:00.000Z'),
end: new Date('2017-10-16T16:00:00.000Z'),
hasDateRangeErrors: false,
});
});
it('does not change for bad start/end time', function () {
wrapper
.find('input[data-test-id="startTime"]')
.simulate('change', {target: {value: null}});
expect(onChange).not.toHaveBeenLastCalledWith();
wrapper
.find('input[data-test-id="endTime"]')
.simulate('change', {target: {value: null}});
expect(onChange).not.toHaveBeenLastCalledWith();
});
it('updates start time input only if not focused', async function () {
const time = start.getTime() + 60000;
expect(getTimeText(wrapper.find('input[data-test-id="startTime"]'))).toEqual(
'22:38'
);
wrapper.find('input[data-test-id="startTime"]').simulate('focus');
await tick();
wrapper.update();
wrapper.setProps({start: new Date(time)});
await tick();
wrapper.update();
// because the prop change happened while the component still has focus, no update
expect(getTimeText(wrapper.find('input[data-test-id="startTime"]'))).toEqual(
'22:38'
);
wrapper.find('input[data-test-id="startTime"]').simulate('blur');
await tick();
wrapper.update();
wrapper.setProps({start: new Date(time)});
await tick();
wrapper.update();
// because the prop change happened after the component lost focus, it updates
expect(getTimeText(wrapper.find('input[data-test-id="startTime"]'))).toEqual(
'22:39'
);
});
it('updates end time input only if not focused', async function () {
const time = end.getTime() + 60000;
expect(getTimeText(wrapper.find('input[data-test-id="endTime"]'))).toEqual('22:38');
wrapper.find('input[data-test-id="endTime"]').simulate('focus');
await tick();
wrapper.update();
wrapper.setProps({end: new Date(time)});
await tick();
wrapper.update();
// because the prop change happened while the component still has focus, no update
expect(getTimeText(wrapper.find('input[data-test-id="endTime"]'))).toEqual('22:38');
wrapper.find('input[data-test-id="endTime"]').simulate('blur');
await tick();
wrapper.update();
wrapper.setProps({end: new Date(time)});
await tick();
wrapper.update();
// because the prop change happened after the component lost focus, it updates
expect(getTimeText(wrapper.find('input[data-test-id="endTime"]'))).toEqual('22:39');
});
});
describe('UTC', function () {
beforeEach(function () {
onChange.mockReset();
wrapper = mountWithTheme(
,
routerContext
);
});
it('has the right max date', function () {
expect(wrapper.find('DateRangePicker').at(0).prop('maxDate')).toEqual(
new Date('2017-10-16T23:41:20.000Z')
);
});
it('has the right days selected', function () {
// start/end inputs
const startEndInputs = wrapper.find(
'.rdrDateRangeWrapper .rdrDateDisplayItem input'
);
expect(startEndInputs.at(0).prop('value')).toBe('Oct 13, 2017');
expect(startEndInputs.at(1).prop('value')).toBe('Oct 16, 2017');
expect(getSelectedRange(wrapper)).toEqual(['13', '14', '15', '16']);
});
it('can select a date (midnight)', function () {
wrapper.find('DayCell').at(0).simulate('mouseUp');
//
expect(onChange).toHaveBeenLastCalledWith({
start: new Date('2017-10-01T04:00:00.000Z'),
end: new Date('2017-10-02T03:59:59.000Z'),
});
});
it('changes utc start time for existing date', function () {
wrapper
.find('input[data-test-id="startTime"]')
.simulate('change', {target: {value: '11:00'}});
// Initial start date is 2017-10-13T22:38:00-0400
expect(onChange).toHaveBeenLastCalledWith({
start: new Date('2017-10-13T15:00:00.000Z'),
end: new Date('2017-10-17T02:38:00.000Z'),
hasDateRangeErrors: false,
});
});
it('changes utc end time for existing date', function () {
wrapper
.find('input[data-test-id="endTime"]')
.simulate('change', {target: {value: '12:00'}});
// Initial end time is 2017-10-16T22:38:00-0400
// Setting this to 12:00 means 2017-10-16T12:00-0400
expect(onChange).toHaveBeenLastCalledWith({
start: new Date('2017-10-14T02:38:00.000Z'),
end: new Date('2017-10-16T16:00:00.000Z'),
hasDateRangeErrors: false,
});
});
it('does not change for bad start/end time', function () {
wrapper
.find('input[data-test-id="startTime"]')
.simulate('change', {target: {value: null}});
expect(onChange).not.toHaveBeenLastCalledWith();
wrapper
.find('input[data-test-id="endTime"]')
.simulate('change', {target: {value: null}});
expect(onChange).not.toHaveBeenLastCalledWith();
});
it('updates utc start time input only if not focused', async function () {
// NOTE: the DateRange component initializes the time inputs with the local time
const time = start.getTime() + 60000;
expect(getTimeText(wrapper.find('input[data-test-id="startTime"]'))).toEqual(
'22:38'
);
wrapper.find('input[data-test-id="startTime"]').simulate('focus');
await tick();
wrapper.update();
wrapper.setProps({start: new Date(time)});
await tick();
wrapper.update();
// because the prop change happened while the component still has focus, no update
expect(getTimeText(wrapper.find('input[data-test-id="startTime"]'))).toEqual(
'22:38'
);
wrapper.find('input[data-test-id="startTime"]').simulate('blur');
await tick();
wrapper.update();
wrapper.setProps({start: new Date(time)});
await tick();
wrapper.update();
// because the prop change happened after the component lost focus, it updates
expect(getTimeText(wrapper.find('input[data-test-id="startTime"]'))).toEqual(
'22:39'
);
});
it('updates utc end time input only if not focused', async function () {
// NOTE: the DateRange component initializes the time inputs with the local time
const time = end.getTime() + 60000;
expect(getTimeText(wrapper.find('input[data-test-id="endTime"]'))).toEqual('22:38');
wrapper.find('input[data-test-id="endTime"]').simulate('focus');
await tick();
wrapper.update();
wrapper.setProps({end: new Date(time)});
await tick();
wrapper.update();
// because the prop change happened while the component still has focus, no update
expect(getTimeText(wrapper.find('input[data-test-id="endTime"]'))).toEqual('22:38');
wrapper.find('input[data-test-id="endTime"]').simulate('blur');
await tick();
wrapper.update();
wrapper.setProps({end: new Date(time)});
await tick();
wrapper.update();
// because the prop change happened after the component lost focus, it updates
expect(getTimeText(wrapper.find('input[data-test-id="endTime"]'))).toEqual('22:39');
});
});
});