Skip to content

Commit

Permalink
[GS] add tag and dashboard suggestion results (#85144)
Browse files Browse the repository at this point in the history
* initial draft

* polish

* fix mocks

* add tests

* tests on suggestions

* add comment

* add FTR tests

* factorize getSearchableTypes

* move to bottom
  • Loading branch information
pgayvallet committed Dec 9, 2020
1 parent 648da2d commit 2350791
Show file tree
Hide file tree
Showing 37 changed files with 1,226 additions and 379 deletions.
28 changes: 20 additions & 8 deletions src/plugins/saved_objects_tagging_oss/public/api.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
*/

import { ITagsClient } from '../common';
import { SavedObjectsTaggingApiUi, SavedObjectsTaggingApiUiComponent } from './api';
import { SavedObjectsTaggingApiUi, SavedObjectsTaggingApiUiComponent, ITagsCache } from './api';

const createClientMock = (): jest.Mocked<ITagsClient> => {
const mock = {
const createClientMock = () => {
const mock: jest.Mocked<ITagsClient> = {
create: jest.fn(),
get: jest.fn(),
getAll: jest.fn(),
Expand All @@ -32,14 +32,25 @@ const createClientMock = (): jest.Mocked<ITagsClient> => {
return mock;
};

const createCacheMock = () => {
const mock: jest.Mocked<ITagsCache> = {
getState: jest.fn(),
getState$: jest.fn(),
};

return mock;
};

interface SavedObjectsTaggingApiMock {
client: jest.Mocked<ITagsClient>;
cache: jest.Mocked<ITagsCache>;
ui: SavedObjectsTaggingApiUiMock;
}

const createApiMock = (): SavedObjectsTaggingApiMock => {
const mock = {
const mock: SavedObjectsTaggingApiMock = {
client: createClientMock(),
cache: createCacheMock(),
ui: createApiUiMock(),
};

Expand All @@ -50,8 +61,8 @@ type SavedObjectsTaggingApiUiMock = Omit<jest.Mocked<SavedObjectsTaggingApiUi>,
components: SavedObjectsTaggingApiUiComponentMock;
};

const createApiUiMock = (): SavedObjectsTaggingApiUiMock => {
const mock = {
const createApiUiMock = () => {
const mock: SavedObjectsTaggingApiUiMock = {
components: createApiUiComponentsMock(),
// TS is very picky with type guards
hasTagDecoration: jest.fn() as any,
Expand All @@ -69,8 +80,8 @@ const createApiUiMock = (): SavedObjectsTaggingApiUiMock => {

type SavedObjectsTaggingApiUiComponentMock = jest.Mocked<SavedObjectsTaggingApiUiComponent>;

const createApiUiComponentsMock = (): SavedObjectsTaggingApiUiComponentMock => {
const mock = {
const createApiUiComponentsMock = () => {
const mock: SavedObjectsTaggingApiUiComponentMock = {
TagList: jest.fn(),
TagSelector: jest.fn(),
SavedObjectSaveModalTagSelector: jest.fn(),
Expand All @@ -82,6 +93,7 @@ const createApiUiComponentsMock = (): SavedObjectsTaggingApiUiComponentMock => {
export const taggingApiMock = {
create: createApiMock,
createClient: createClientMock,
createCache: createCacheMock,
createUi: createApiUiMock,
createComponents: createApiUiComponentsMock,
};
29 changes: 28 additions & 1 deletion src/plugins/saved_objects_tagging_oss/public/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,49 @@
* under the License.
*/

import { Observable } from 'rxjs';
import { SearchFilterConfig, EuiTableFieldDataColumnType } from '@elastic/eui';
import type { FunctionComponent } from 'react';
import { SavedObject, SavedObjectReference } from '../../../core/types';
import { SavedObjectsFindOptionsReference } from '../../../core/public';
import { SavedObject as SavedObjectClass } from '../../saved_objects/public';
import { TagDecoratedSavedObject } from './decorator';
import { ITagsClient } from '../common';
import { ITagsClient, Tag } from '../common';

/**
* @public
*/
export interface SavedObjectsTaggingApi {
/**
* The client to perform tag-related operations on the server-side
*/
client: ITagsClient;
/**
* A client-side auto-refreshing cache of the existing tags. Can be used
* to synchronously access the list of tags.
*/
cache: ITagsCache;
/**
* UI API to use to add tagging capabilities to an application
*/
ui: SavedObjectsTaggingApiUi;
}

/**
* @public
*/
export interface ITagsCache {
/**
* Return the current state of the cache
*/
getState(): Tag[];

/**
* Return an observable that will emit everytime the cache's state mutates.
*/
getState$(): Observable<Tag[]>;
}

/**
* @public
*/
Expand Down
1 change: 1 addition & 0 deletions src/plugins/saved_objects_tagging_oss/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export {
SavedObjectsTaggingApi,
SavedObjectsTaggingApiUi,
SavedObjectsTaggingApiUiComponent,
ITagsCache,
TagListComponentProps,
TagSelectorComponentProps,
GetSearchBarFilterOptions,
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/global_search/public/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const createStartMock = (): jest.Mocked<GlobalSearchPluginStart> => {

return {
find: searchMock.find,
getSearchableTypes: searchMock.getSearchableTypes,
};
};

Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/global_search/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ export class GlobalSearchPlugin

start({ http }: CoreStart, { licensing }: GlobalSearchPluginStartDeps) {
this.licenseChecker = new LicenseChecker(licensing.license$);
const { find } = this.searchService.start({
const { find, getSearchableTypes } = this.searchService.start({
http,
licenseChecker: this.licenseChecker,
});

return {
find,
getSearchableTypes,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { httpServiceMock } from '../../../../../src/core/public/mocks';
import { fetchServerSearchableTypes } from './fetch_server_searchable_types';

describe('fetchServerSearchableTypes', () => {
let http: ReturnType<typeof httpServiceMock.createStartContract>;

beforeEach(() => {
http = httpServiceMock.createStartContract();
});

it('perform a GET request to the endpoint with valid options', () => {
http.get.mockResolvedValue({ results: [] });

fetchServerSearchableTypes(http);

expect(http.get).toHaveBeenCalledTimes(1);
expect(http.get).toHaveBeenCalledWith('/internal/global_search/searchable_types');
});

it('returns the results from the server', async () => {
const types = ['typeA', 'typeB'];

http.get.mockResolvedValue({ types });

const results = await fetchServerSearchableTypes(http);

expect(http.get).toHaveBeenCalledTimes(1);
expect(results).toEqual(types);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { HttpStart } from 'src/core/public';

interface ServerSearchableTypesResponse {
types: string[];
}

export const fetchServerSearchableTypes = async (http: HttpStart) => {
const { types } = await http.get<ServerSearchableTypesResponse>(
'/internal/global_search/searchable_types'
);
return types;
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,21 @@
import { SearchServiceSetup, SearchServiceStart } from './search_service';
import { of } from 'rxjs';

const createSetupMock = (): jest.Mocked<SearchServiceSetup> => {
return {
const createSetupMock = () => {
const mock: jest.Mocked<SearchServiceSetup> = {
registerResultProvider: jest.fn(),
};

return mock;
};

const createStartMock = (): jest.Mocked<SearchServiceStart> => {
const mock = {
const createStartMock = () => {
const mock: jest.Mocked<SearchServiceStart> = {
find: jest.fn(),
getSearchableTypes: jest.fn(),
};
mock.find.mockReturnValue(of({ results: [] }));
mock.getSearchableTypes.mockResolvedValue([]);

return mock;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ jest.doMock('./fetch_server_results', () => ({
fetchServerResults: fetchServerResultsMock,
}));

export const fetchServerSearchableTypesMock = jest.fn();
jest.doMock('./fetch_server_searchable_types', () => ({
fetchServerSearchableTypes: fetchServerSearchableTypesMock,
}));

export const getDefaultPreferenceMock = jest.fn();
jest.doMock('./utils', () => {
const original = jest.requireActual('./utils');
Expand Down
Loading

0 comments on commit 2350791

Please sign in to comment.