Use forceNow
query parameter when parsing timefilter (#16236)
* Using "forceNow" parameter to adjust "now" and exposing timeRange * Moving forceNow parameter to the hash, adding tests * Renaming test
This commit is contained in:
parent
9062f116f2
commit
b677848bee
65
src/ui/public/timefilter/__tests__/timefilter.js
Normal file
65
src/ui/public/timefilter/__tests__/timefilter.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
import sinon from 'sinon';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
|
||||
describe('Timefilter service', function () {
|
||||
|
||||
describe('calculateBounds', function () {
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
|
||||
const fifteenMinutesInMilliseconds = 15 * 60 * 1000;
|
||||
const clockNowTicks = new Date(2000, 1, 1, 0, 0, 0, 0).valueOf();
|
||||
|
||||
let timefilter;
|
||||
let $location;
|
||||
let clock;
|
||||
|
||||
beforeEach(ngMock.inject(function (_timefilter_, _$location_) {
|
||||
timefilter = _timefilter_;
|
||||
$location = _$location_;
|
||||
|
||||
clock = sinon.useFakeTimers(clockNowTicks);
|
||||
}));
|
||||
|
||||
afterEach(function () {
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('uses clock time by default', function () {
|
||||
const timeRange = {
|
||||
from: 'now-15m',
|
||||
to: 'now'
|
||||
};
|
||||
|
||||
const result = timefilter.calculateBounds(timeRange);
|
||||
expect(result.min.valueOf()).to.eql(clockNowTicks - fifteenMinutesInMilliseconds);
|
||||
expect(result.max.valueOf()).to.eql(clockNowTicks);
|
||||
});
|
||||
|
||||
it('uses forceNow string', function () {
|
||||
const timeRange = {
|
||||
from: 'now-15m',
|
||||
to: 'now'
|
||||
};
|
||||
|
||||
const forceNowString = '1999-01-01T00:00:00.000Z';
|
||||
$location.search('forceNow', forceNowString);
|
||||
const result = timefilter.calculateBounds(timeRange);
|
||||
|
||||
const forceNowTicks = Date.parse(forceNowString);
|
||||
expect(result.min.valueOf()).to.eql(forceNowTicks - fifteenMinutesInMilliseconds);
|
||||
expect(result.max.valueOf()).to.eql(forceNowTicks);
|
||||
});
|
||||
|
||||
it(`throws Error if forceNow can't be parsed`, function () {
|
||||
const timeRange = {
|
||||
from: 'now-15m',
|
||||
to: 'now'
|
||||
};
|
||||
|
||||
$location.search('forceNow', 'malformed%20string');
|
||||
expect(() => timefilter.calculateBounds(timeRange)).to.throwError();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
|
@ -16,7 +16,7 @@ uiRoutes
|
|||
|
||||
uiModules
|
||||
.get('kibana')
|
||||
.service('timefilter', function (Private, globalState, $rootScope, config) {
|
||||
.service('timefilter', function (Private, globalState, $rootScope, config, $location) {
|
||||
const Events = Private(EventsProvider);
|
||||
|
||||
function convertISO8601(stringTime) {
|
||||
|
@ -105,10 +105,25 @@ uiModules
|
|||
return this.calculateBounds(this.time);
|
||||
};
|
||||
|
||||
Timefilter.prototype.getForceNow = function () {
|
||||
const query = $location.search().forceNow;
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ticks = Date.parse(query);
|
||||
if (isNaN(ticks)) {
|
||||
throw new Error(`forceNow query parameter can't be parsed`);
|
||||
}
|
||||
return new Date(ticks);
|
||||
};
|
||||
|
||||
Timefilter.prototype.calculateBounds = function (timeRange) {
|
||||
const forceNow = this.getForceNow();
|
||||
|
||||
return {
|
||||
min: dateMath.parse(timeRange.from),
|
||||
max: dateMath.parse(timeRange.to, { roundUp: true })
|
||||
min: dateMath.parse(timeRange.from, { forceNow }),
|
||||
max: dateMath.parse(timeRange.to, { roundUp: true, forceNow })
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import moment from 'moment';
|
||||
import expect from 'expect.js';
|
||||
import ngMock from 'ng_mock';
|
||||
import $ from 'jquery';
|
||||
|
@ -24,28 +25,60 @@ describe('kbnGlobalTimepicker', function () {
|
|||
expect($el.attr('data-test-subj')).to.be('globalTimepicker');
|
||||
});
|
||||
|
||||
it('sets data-shared-timefilter to true when auto-refresh selector is enabled', function () {
|
||||
it('sets data-shared-timefilter-* using the timefilter when auto-refresh selector is enabled', function () {
|
||||
const minString = '2000-01-01T00:00:00Z';
|
||||
const maxString = '2001-01-01T00:00:00Z';
|
||||
const bounds = {
|
||||
min: moment(minString),
|
||||
max: moment(maxString),
|
||||
};
|
||||
scope.timefilter = {
|
||||
isAutoRefreshSelectorEnabled: true,
|
||||
isTimeRangeSelectorEnabled: false
|
||||
isTimeRangeSelectorEnabled: false,
|
||||
getBounds: () => bounds
|
||||
};
|
||||
|
||||
const $el = compile();
|
||||
expect($el.attr('data-shared-timefilter')).to.eql('true');
|
||||
|
||||
expect($el.attr('data-shared-timefilter-from')).to.eql(minString);
|
||||
expect($el.attr('data-shared-timefilter-to')).to.eql(maxString);
|
||||
});
|
||||
it('sets data-shared-timefilter to true when time range selector is enabled', function () {
|
||||
|
||||
it('sets data-shared-timefilter-* using the timefilter when time range selector is enabled', function () {
|
||||
const minString = '2000-01-01T00:00:00Z';
|
||||
const maxString = '2001-01-01T00:00:00Z';
|
||||
const bounds = {
|
||||
min: moment(minString),
|
||||
max: moment(maxString),
|
||||
};
|
||||
scope.timefilter = {
|
||||
isAutoRefreshSelectorEnabled: false,
|
||||
isTimeRangeSelectorEnabled: true
|
||||
isTimeRangeSelectorEnabled: true,
|
||||
getBounds: () => bounds
|
||||
};
|
||||
|
||||
const $el = compile();
|
||||
expect($el.attr('data-shared-timefilter')).to.eql('true');
|
||||
|
||||
expect($el.attr('data-shared-timefilter-from')).to.eql(minString);
|
||||
expect($el.attr('data-shared-timefilter-to')).to.eql(maxString);
|
||||
});
|
||||
it(`sets data-shared-timefilter to false when auto-refresh and time range selectors are both disabled`, function () {
|
||||
|
||||
it(`doesn't set data-shared-timefilter-* when auto-refresh and time range selectors are both disabled`, function () {
|
||||
const minString = '2000-01-01T00:00:00Z';
|
||||
const maxString = '2001-01-01T00:00:00Z';
|
||||
const bounds = {
|
||||
min: moment(minString),
|
||||
max: moment(maxString),
|
||||
};
|
||||
scope.timefilter = {
|
||||
isAutoRefreshSelectorEnabled: false,
|
||||
isTimeRangeSelectorEnabled: false
|
||||
isTimeRangeSelectorEnabled: false,
|
||||
getBounds: () => bounds
|
||||
};
|
||||
|
||||
const $el = compile();
|
||||
expect($el.attr('data-shared-timefilter')).to.eql('false');
|
||||
|
||||
expect($el.attr('data-shared-timefilter-from')).to.eql('');
|
||||
expect($el.attr('data-shared-timefilter-to')).to.eql('');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
<div ng-show="timefilter.isAutoRefreshSelectorEnabled || timefilter.isTimeRangeSelectorEnabled" data-shared-timefilter="{{timefilter.isAutoRefreshSelectorEnabled || timefilter.isTimeRangeSelectorEnabled}}" class="kuiLocalMenu" data-test-subj="globalTimepicker">
|
||||
<div
|
||||
ng-show="timefilter.isAutoRefreshSelectorEnabled || timefilter.isTimeRangeSelectorEnabled"
|
||||
data-shared-timefilter-from="{{timefilter.isAutoRefreshSelectorEnabled || timefilter.isTimeRangeSelectorEnabled ? timefilter.getBounds().min.utc().format() : null }}"
|
||||
data-shared-timefilter-to="{{timefilter.isAutoRefreshSelectorEnabled || timefilter.isTimeRangeSelectorEnabled ? timefilter.getBounds().max.utc().format() : null }}"
|
||||
class="kuiLocalMenu"
|
||||
data-test-subj="globalTimepicker"
|
||||
>
|
||||
<button
|
||||
class="kuiLocalMenuItem"
|
||||
aria-label="{{ timefilter.refreshInterval.pause ? 'Resume refreshing data' : 'Pause refreshing data' }}"
|
||||
|
|
Loading…
Reference in a new issue