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:
Brandon Kobel 2018-02-13 12:09:42 -05:00 committed by GitHub
parent 9062f116f2
commit b677848bee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 132 additions and 13 deletions

View 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();
});
});
});

View file

@ -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 })
};
};

View file

@ -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('');
});
});

View file

@ -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' }}"