Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.17] [Discover] Fix csv export with relative time filter from discover main view (#123206) #133506

Merged
merged 1 commit into from
Jun 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ export function setState(stateContainer: ReduxLikeStateContainer<AppState>, newS
/**
* Helper function to compare 2 different filter states
*/
export function isEqualFilters(filtersA: Filter[], filtersB: Filter[]) {
export function isEqualFilters(filtersA?: Filter[] | Filter, filtersB?: Filter[] | Filter) {
if (!filtersA && !filtersB) {
return true;
} else if (!filtersA || !filtersB) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from '../../../../../common';
import type { SavedSearch, SortOrder } from '../../../../saved_searches';
import { getSortForSearchSource } from '../components/doc_table';
import { AppState } from '../services/discover_state';
import { AppState, isEqualFilters } from '../services/discover_state';

/**
* Preparing data to share the current state as link or CSV/Report
Expand All @@ -30,7 +30,7 @@ export async function getSharingData(
const { uiSettings: config, data } = services;
const searchSource = currentSearchSource.createCopy();
const index = searchSource.getField('index')!;
const existingFilter = searchSource.getField('filter');
let existingFilter = searchSource.getField('filter') as Filter[] | Filter | undefined;

searchSource.setField(
'sort',
Expand Down Expand Up @@ -58,11 +58,20 @@ export async function getSharingData(
}
}

const absoluteTimeFilter = data.query.timefilter.timefilter.createFilter(index);
const relativeTimeFilter = data.query.timefilter.timefilter.createRelativeFilter(index);
return {
getSearchSource: (absoluteTime?: boolean): SearchSourceFields => {
const timeFilter = absoluteTime
? data.query.timefilter.timefilter.createFilter(index)
: data.query.timefilter.timefilter.createRelativeFilter(index);
const timeFilter = absoluteTime ? absoluteTimeFilter : relativeTimeFilter;

// remove timeFilter from existing filter
if (Array.isArray(existingFilter)) {
existingFilter = existingFilter.filter(
(current) => !isEqualFilters(current, absoluteTimeFilter)
);
} else if (isEqualFilters(existingFilter, absoluteTimeFilter)) {
existingFilter = undefined;
}

if (existingFilter && timeFilter) {
searchSource.setField(
Expand Down
54 changes: 53 additions & 1 deletion x-pack/test/functional/apps/discover/reporting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

import expect from '@kbn/expect';
import { Key } from 'selenium-webdriver';
import { FtrProviderContext } from '../../ftr_provider_context';

export default function ({ getService, getPageObjects }: FtrProviderContext) {
Expand All @@ -15,9 +16,11 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const kibanaServer = getService('kibanaServer');
const browser = getService('browser');
const retry = getService('retry');
const PageObjects = getPageObjects(['reporting', 'common', 'discover', 'timePicker']);
const PageObjects = getPageObjects(['reporting', 'common', 'discover', 'timePicker', 'share']);
const filterBar = getService('filterBar');
const ecommerceSOPath = 'x-pack/test/functional/fixtures/kbn_archiver/reporting/ecommerce.json';
const find = getService('find');
const testSubjects = getService('testSubjects');

const setFieldsFromSource = async (setValue: boolean) => {
await kibanaServer.uiSettings.update({ 'discover:searchFieldsFromSource': setValue });
Expand Down Expand Up @@ -92,6 +95,55 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
describeIfEs7('Generate CSV: new search (7.17)', () => {
beforeEach(newSearchBeforeEach);

it('generates a report with single timefilter', async () => {
await PageObjects.discover.clickNewSearchButton();
await PageObjects.timePicker.setCommonlyUsedTime('Last_24 hours');
await PageObjects.discover.saveSearch('single-timefilter-search');

// get shared URL value
await PageObjects.share.clickShareTopNavButton();
const sharedURL = await PageObjects.share.getSharedUrl();

// click 'Copy POST URL'
await PageObjects.share.clickShareTopNavButton();
await PageObjects.reporting.openCsvReportingPanel();
const advOpt = await find.byXPath(`//button[descendant::*[text()='Advanced options']]`);
await advOpt.click();
const postUrl = await find.byXPath(`//button[descendant::*[text()='Copy POST URL']]`);
await postUrl.click();

// get clipboard value using field search input, since
// 'browser.getClipboardValue()' doesn't work, due to permissions
const textInput = await testSubjects.find('fieldFilterSearchInput');
await textInput.click();
await browser.getActions().keyDown(Key.CONTROL).perform();
await browser.getActions().keyDown('v').perform();

const reportURL = decodeURIComponent(await textInput.getAttribute('value'));

// get number of filters in URLs
const timeFiltersNumberInReportURL =
reportURL.split('query:(range:(order_date:(format:strict_date_optional_time').length - 1;
const timeFiltersNumberInSharedURL = sharedURL.split('time:').length - 1;

expect(timeFiltersNumberInSharedURL).to.be(1);
expect(sharedURL.includes('time:(from:now-24h%2Fh,to:now))')).to.be(true);

expect(timeFiltersNumberInReportURL).to.be(1);
expect(
reportURL.includes(
'query:(range:(order_date:(format:strict_date_optional_time,gte:now-24h/h,lte:now))))'
)
).to.be(true);

// return keyboard state
await browser.getActions().keyUp(Key.CONTROL).perform();
await browser.getActions().keyUp('v').perform();

// return field search input state
await textInput.clearValue();
});

it('generates a report from a new search with data: default', async () => {
await PageObjects.discover.clickNewSearchButton();
await PageObjects.reporting.setTimepickerInEcommerceDataRange();
Expand Down