Skip to content

Commit

Permalink
Discover locator (#102712) (#103072)
Browse files Browse the repository at this point in the history
* Add Discover locator

* Add Discover locator tests

* Expose locator for Discover app and deprecate URL generator

* Use Discover locator in Explore Underlying Data

* Fix explore data unit tests after refactor

* fix: 🐛 update Discover plugin mock

* style: 💄 remove any

* test: 💍 fix test mock

* fix: 🐛 adjust property name after refactor

* test: 💍 fix tests after refactor

Co-authored-by: Vadim Kibana <vadimkibana@gmail.com>

Co-authored-by: Vadim Kibana <vadimkibana@gmail.com>
  • Loading branch information
streamich and vadimkibana authored Jun 23, 2021
1 parent 8cf034b commit 9e2b89d
Show file tree
Hide file tree
Showing 11 changed files with 586 additions and 88 deletions.
2 changes: 2 additions & 0 deletions src/plugins/discover/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ export function plugin(initializerContext: PluginInitializerContext) {
export { SavedSearch, SavedSearchLoader, createSavedSearchesLoader } from './saved_searches';
export { ISearchEmbeddable, SEARCH_EMBEDDABLE_TYPE, SearchInput } from './application/embeddable';
export { loadSharingDataHelpers } from './shared';

export { DISCOVER_APP_URL_GENERATOR, DiscoverUrlGeneratorState } from './url_generator';
export { DiscoverAppLocator, DiscoverAppLocatorParams } from './locator';
270 changes: 270 additions & 0 deletions src/plugins/discover/public/locator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import { hashedItemStore, getStatesFromKbnUrl } from '../../kibana_utils/public';
import { mockStorage } from '../../kibana_utils/public/storage/hashed_item_store/mock';
import { FilterStateStore } from '../../data/common';
import { DiscoverAppLocatorDefinition } from './locator';
import { SerializableState } from 'src/plugins/kibana_utils/common';

const indexPatternId: string = 'c367b774-a4c2-11ea-bb37-0242ac130002';
const savedSearchId: string = '571aaf70-4c88-11e8-b3d7-01146121b73d';

interface SetupParams {
useHash?: boolean;
}

const setup = async ({ useHash = false }: SetupParams = {}) => {
const locator = new DiscoverAppLocatorDefinition({
useHash,
});

return {
locator,
};
};

beforeEach(() => {
// @ts-expect-error
hashedItemStore.storage = mockStorage;
});

describe('Discover url generator', () => {
test('can create a link to Discover with no state and no saved search', async () => {
const { locator } = await setup();
const { app, path } = await locator.getLocation({});
const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']);

expect(app).toBe('discover');
expect(_a).toEqual({});
expect(_g).toEqual({});
});

test('can create a link to a saved search in Discover', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({ savedSearchId });
const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']);

expect(path.startsWith(`#/view/${savedSearchId}`)).toBe(true);
expect(_a).toEqual({});
expect(_g).toEqual({});
});

test('can specify specific index pattern', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
indexPatternId,
});
const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']);

expect(_a).toEqual({
index: indexPatternId,
});
expect(_g).toEqual({});
});

test('can specify specific time range', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
timeRange: { to: 'now', from: 'now-15m', mode: 'relative' },
});
const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']);

expect(_a).toEqual({});
expect(_g).toEqual({
time: {
from: 'now-15m',
mode: 'relative',
to: 'now',
},
});
});

test('can specify query', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
query: {
language: 'kuery',
query: 'foo',
},
});
const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']);

expect(_a).toEqual({
query: {
language: 'kuery',
query: 'foo',
},
});
expect(_g).toEqual({});
});

test('can specify local and global filters', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
filters: [
{
meta: {
alias: 'foo',
disabled: false,
negate: false,
},
$state: {
store: FilterStateStore.APP_STATE,
},
},
{
meta: {
alias: 'bar',
disabled: false,
negate: false,
},
$state: {
store: FilterStateStore.GLOBAL_STATE,
},
},
],
});
const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']);

expect(_a).toEqual({
filters: [
{
$state: {
store: 'appState',
},
meta: {
alias: 'foo',
disabled: false,
negate: false,
},
},
],
});
expect(_g).toEqual({
filters: [
{
$state: {
store: 'globalState',
},
meta: {
alias: 'bar',
disabled: false,
negate: false,
},
},
],
});
});

test('can set refresh interval', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
refreshInterval: {
pause: false,
value: 666,
},
});
const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']);

expect(_a).toEqual({});
expect(_g).toEqual({
refreshInterval: {
pause: false,
value: 666,
},
});
});

test('can set time range', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
timeRange: {
from: 'now-3h',
to: 'now',
},
});
const { _a, _g } = getStatesFromKbnUrl(path, ['_a', '_g']);

expect(_a).toEqual({});
expect(_g).toEqual({
time: {
from: 'now-3h',
to: 'now',
},
});
});

test('can specify a search session id', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
searchSessionId: '__test__',
});

expect(path).toMatchInlineSnapshot(`"#/?_g=()&_a=()&searchSessionId=__test__"`);
expect(path).toContain('__test__');
});

test('can specify columns, interval, sort and savedQuery', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
columns: ['_source'],
interval: 'auto',
sort: [['timestamp, asc']] as string[][] & SerializableState,
savedQuery: '__savedQueryId__',
});

expect(path).toMatchInlineSnapshot(
`"#/?_g=()&_a=(columns:!(_source),interval:auto,savedQuery:__savedQueryId__,sort:!(!('timestamp,%20asc')))"`
);
});

describe('useHash property', () => {
describe('when default useHash is set to false', () => {
test('when using default, sets index pattern ID in the generated URL', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
indexPatternId,
});

expect(path.indexOf(indexPatternId) > -1).toBe(true);
});

test('when enabling useHash, does not set index pattern ID in the generated URL', async () => {
const { locator } = await setup();
const { path } = await locator.getLocation({
useHash: true,
indexPatternId,
});

expect(path.indexOf(indexPatternId) > -1).toBe(false);
});
});

describe('when default useHash is set to true', () => {
test('when using default, does not set index pattern ID in the generated URL', async () => {
const { locator } = await setup({ useHash: true });
const { path } = await locator.getLocation({
indexPatternId,
});

expect(path.indexOf(indexPatternId) > -1).toBe(false);
});

test('when disabling useHash, sets index pattern ID in the generated URL', async () => {
const { locator } = await setup({ useHash: true });
const { path } = await locator.getLocation({
useHash: false,
indexPatternId,
});

expect(path.indexOf(indexPatternId) > -1).toBe(true);
});
});
});
});
Loading

0 comments on commit 9e2b89d

Please sign in to comment.