Skip to content

Commit

Permalink
Merge branch 'master' into kibana-page-template-as-10
Browse files Browse the repository at this point in the history
  • Loading branch information
Constance committed Jun 22, 2021
2 parents e284370 + 84d999d commit 886803a
Show file tree
Hide file tree
Showing 12 changed files with 264 additions and 106 deletions.
1 change: 0 additions & 1 deletion jest.config.integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ module.exports = {
rootDir: '.',
roots: ['<rootDir>/src', '<rootDir>/packages'],
testMatch: ['**/integration_tests**/*.test.{js,mjs,ts,tsx}'],
testRunner: 'jasmine2',
testPathIgnorePatterns: preset.testPathIgnorePatterns.filter(
(pattern) => !pattern.includes('integration_tests')
),
Expand Down
83 changes: 81 additions & 2 deletions src/core/public/application/application_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import {
import { createElement } from 'react';
import { BehaviorSubject, Subject } from 'rxjs';
import { bufferCount, take, takeUntil } from 'rxjs/operators';
import { shallow, mount } from 'enzyme';
import { mount, shallow } from 'enzyme';

import { httpServiceMock } from '../http/http_service.mock';
import { overlayServiceMock } from '../overlays/overlay_service.mock';
import { MockLifecycle } from './test_types';
import { ApplicationService } from './application_service';
import { App, PublicAppInfo, AppNavLinkStatus, AppStatus, AppUpdater } from './types';
import { App, AppDeepLink, AppNavLinkStatus, AppStatus, AppUpdater, PublicAppInfo } from './types';
import { act } from 'react-dom/test-utils';

const createApp = (props: Partial<App>): App => {
Expand Down Expand Up @@ -365,6 +365,85 @@ describe('#setup()', () => {
expect(MockHistory.push).toHaveBeenCalledWith('/app/app1', undefined);
MockHistory.push.mockClear();
});

it('preserves the deep links if the update does not modify them', async () => {
const setup = service.setup(setupDeps);

const pluginId = Symbol('plugin');
const updater$ = new BehaviorSubject<AppUpdater>((app) => ({}));

const deepLinks: AppDeepLink[] = [
{
id: 'foo',
title: 'Foo',
searchable: true,
navLinkStatus: AppNavLinkStatus.visible,
path: '/foo',
},
{
id: 'bar',
title: 'Bar',
searchable: false,
navLinkStatus: AppNavLinkStatus.hidden,
path: '/bar',
},
];

setup.register(pluginId, createApp({ id: 'app1', deepLinks, updater$ }));

const { applications$ } = await service.start(startDeps);

updater$.next((app) => ({ defaultPath: '/foo' }));

let appInfos = await applications$.pipe(take(1)).toPromise();

expect(appInfos.get('app1')!.deepLinks).toEqual([
{
deepLinks: [],
id: 'foo',
keywords: [],
navLinkStatus: 1,
path: '/foo',
searchable: true,
title: 'Foo',
},
{
deepLinks: [],
id: 'bar',
keywords: [],
navLinkStatus: 3,
path: '/bar',
searchable: false,
title: 'Bar',
},
]);

updater$.next((app) => ({
deepLinks: [
{
id: 'bar',
title: 'Bar',
searchable: false,
navLinkStatus: AppNavLinkStatus.hidden,
path: '/bar',
},
],
}));

appInfos = await applications$.pipe(take(1)).toPromise();

expect(appInfos.get('app1')!.deepLinks).toEqual([
{
deepLinks: [],
id: 'bar',
keywords: [],
navLinkStatus: 3,
path: '/bar',
searchable: false,
title: 'Bar',
},
]);
});
});
});

Expand Down
7 changes: 3 additions & 4 deletions src/core/public/application/application_service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function filterAvailable<T>(m: Map<string, T>, capabilities: Capabilities) {
)
);
}

const findMounter = (mounters: Map<string, Mounter>, appRoute?: string) =>
[...mounters].find(([, mounter]) => mounter.appRoute === appRoute);

Expand Down Expand Up @@ -414,13 +415,11 @@ const updateStatus = (app: App, statusUpdaters: AppUpdaterWrapper[]): App => {
changes.navLinkStatus ?? AppNavLinkStatus.default,
fields.navLinkStatus ?? AppNavLinkStatus.default
),
// deepLinks take the last defined update
deepLinks: fields.deepLinks
? populateDeepLinkDefaults(fields.deepLinks)
: changes.deepLinks,
...(fields.deepLinks ? { deepLinks: populateDeepLinkDefaults(fields.deepLinks) } : {}),
};
}
});

return {
...app,
...changes,
Expand Down
51 changes: 27 additions & 24 deletions src/core/server/http/integration_tests/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,24 +163,24 @@ describe('KibanaRequest', () => {

describe('events', () => {
describe('aborted$', () => {
it('emits once and completes when request aborted', async (done) => {
it('emits once and completes when request aborted', async () => {
expect.assertions(1);
const { server: innerServer, createRouter } = await server.setup(setupDeps);
const router = createRouter('/');

const nextSpy = jest.fn();
router.get({ path: '/', validate: false }, async (context, request, res) => {
request.events.aborted$.subscribe({
next: nextSpy,
complete: () => {
expect(nextSpy).toHaveBeenCalledTimes(1);
done();
},
});

// prevents the server to respond
await delay(30000);
return res.ok({ body: 'ok' });
const done = new Promise<void>((resolve) => {
router.get({ path: '/', validate: false }, async (context, request, res) => {
request.events.aborted$.subscribe({
next: nextSpy,
complete: resolve,
});

// prevents the server to respond
await delay(30000);
return res.ok({ body: 'ok' });
});
});

await server.start();
Expand All @@ -191,6 +191,8 @@ describe('KibanaRequest', () => {
.end();

setTimeout(() => incomingRequest.abort(), 50);
await done;
expect(nextSpy).toHaveBeenCalledTimes(1);
});

it('completes & does not emit when request handled', async () => {
Expand Down Expand Up @@ -299,25 +301,24 @@ describe('KibanaRequest', () => {
expect(completeSpy).toHaveBeenCalledTimes(1);
});

it('emits once and completes when response is aborted', async (done) => {
it('emits once and completes when response is aborted', async () => {
expect.assertions(2);
const { server: innerServer, createRouter } = await server.setup(setupDeps);
const router = createRouter('/');

const nextSpy = jest.fn();

router.get({ path: '/', validate: false }, async (context, req, res) => {
req.events.completed$.subscribe({
next: nextSpy,
complete: () => {
expect(nextSpy).toHaveBeenCalledTimes(1);
done();
},
});
const done = new Promise<void>((resolve) => {
router.get({ path: '/', validate: false }, async (context, req, res) => {
req.events.completed$.subscribe({
next: nextSpy,
complete: resolve,
});

expect(nextSpy).not.toHaveBeenCalled();
await delay(30000);
return res.ok({ body: 'ok' });
expect(nextSpy).not.toHaveBeenCalled();
await delay(30000);
return res.ok({ body: 'ok' });
});
});

await server.start();
Expand All @@ -327,6 +328,8 @@ describe('KibanaRequest', () => {
// end required to send request
.end();
setTimeout(() => incomingRequest.abort(), 50);
await done;
expect(nextSpy).toHaveBeenCalledTimes(1);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ describe('migration v2', () => {
},
],
},
// reporting loads headless browser, that prevents nodejs process from exiting.
xpack: {
reporting: {
enabled: false,
},
},
},
{
oss,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const kibanaVersion = Env.createDefault(REPO_ROOT, getEnvOptions()).packageInfo.
const savedObjectIndex = `.kibana_${kibanaVersion}_001`;

describe('uiSettings/routes', function () {
jest.setTimeout(10000);
jest.setTimeout(120_000);

beforeAll(startServers);
/* eslint-disable jest/valid-describe */
Expand Down
4 changes: 3 additions & 1 deletion src/core/server/ui_settings/integration_tests/lib/servers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,10 @@ export function getServices() {

export async function stopServers() {
services = null!;
if (servers) {
if (esServer) {
await esServer.stop();
}
if (kbn) {
await kbn.stop();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ export const EngineRouter: React.FC = () => {
<SchemaRouter />
</Route>
)}
{canManageEngineSearchUi && (
<Route path={ENGINE_SEARCH_UI_PATH}>
<SearchUI />
</Route>
)}
{/* TODO: Remove layout once page template migration is over */}
<Layout navigation={<AppSearchNav />}>
{canManageEngineCurations && (
Expand Down Expand Up @@ -141,11 +146,6 @@ export const EngineRouter: React.FC = () => {
<ApiLogs />
</Route>
)}
{canManageEngineSearchUi && (
<Route path={ENGINE_SEARCH_UI_PATH}>
<SearchUI />
</Route>
)}
{canViewMetaEngineSourceEngines && (
<Route path={META_ENGINE_SOURCE_ENGINES_PATH}>
<SourceEngines />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';

import { shallow } from 'enzyme';

import { EuiEmptyPrompt, EuiButton } from '@elastic/eui';

import { EmptyState } from './empty_state';

describe('EmptyState', () => {
it('renders', () => {
const wrapper = shallow(<EmptyState />)
.find(EuiEmptyPrompt)
.dive();

expect(wrapper.find('h2').text()).toEqual('Add documents to generate a Search UI');
expect(wrapper.find(EuiButton).prop('href')).toEqual(
expect.stringContaining('/reference-ui-guide.html')
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';

import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

import { DOCS_PREFIX } from '../../../routes';

export const EmptyState: React.FC = () => (
<EuiEmptyPrompt
iconType="search"
title={
<h2>
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.searchUI.empty.title', {
defaultMessage: 'Add documents to generate a Search UI',
})}
</h2>
}
body={
<p>
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.searchUI.empty.description', {
defaultMessage:
'A schema will be automatically created for you after you index some documents.',
})}
</p>
}
actions={
<EuiButton
size="s"
target="_blank"
iconType="popout"
href={`${DOCS_PREFIX}/reference-ui-guide.html`}
>
{i18n.translate('xpack.enterpriseSearch.appSearch.engine.searchUI.empty.buttonLabel', {
defaultMessage: 'Read the Search UI guide',
})}
</EuiButton>
}
/>
);
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
*/

import '../../../__mocks__/shallow_useeffect.mock';
import '../../__mocks__/engine_logic.mock';

import { setMockActions } from '../../../__mocks__/kea_logic';
import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic';
import { mockEngineValues } from '../../__mocks__/engine_logic.mock';

import React from 'react';

import { shallow } from 'enzyme';

import { SearchUIForm } from './components/search_ui_form';
import { SearchUIGraphic } from './components/search_ui_graphic';

import { SearchUI } from './';

describe('SearchUI', () => {
Expand All @@ -24,11 +27,13 @@ describe('SearchUI', () => {
beforeEach(() => {
jest.clearAllMocks();
setMockActions(actions);
setMockValues(mockEngineValues);
});

it('renders', () => {
shallow(<SearchUI />);
// TODO: Check for form
const wrapper = shallow(<SearchUI />);
expect(wrapper.find(SearchUIForm).exists()).toBe(true);
expect(wrapper.find(SearchUIGraphic).exists()).toBe(true);
});

it('initializes data on mount', () => {
Expand Down
Loading

0 comments on commit 886803a

Please sign in to comment.