Skip to content

Commit

Permalink
Add ingestManager as optional dependency and render CTA to composable…
Browse files Browse the repository at this point in the history
… index templates or Ingest Manager dependent upon its presence.
  • Loading branch information
cjcenizal committed Jun 23, 2020
1 parent a424d65 commit 4670f98
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import React from 'react';
import axios from 'axios';
import axiosXhrAdapter from 'axios/lib/adapters/xhr';
import { merge } from 'lodash';

import {
notificationServiceMock,
Expand Down Expand Up @@ -51,8 +52,13 @@ export const setupEnvironment = () => {
};
};

export const WithAppDependencies = (Comp: any) => (props: any) => (
<AppContextProvider value={appDependencies}>
<Comp {...props} />
</AppContextProvider>
);
export const WithAppDependencies = (Comp: any, overridingDependencies: any = {}) => (
props: any
) => {
const dependencies = merge(appDependencies, overridingDependencies);
return (
<AppContextProvider value={appDependencies}>
<Comp {...props} />
</AppContextProvider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ import { IndexManagementHome } from '../../../public/application/sections/home';
import { indexManagementStore } from '../../../public/application/store'; // eslint-disable-line @kbn/eslint/no-restricted-paths
import { WithAppDependencies, services, TestSubjects } from '../helpers';

const testBedConfig: TestBedConfig = {
store: () => indexManagementStore(services as any),
memoryRouter: {
initialEntries: [`/indices`],
componentRoutePath: `/:section(indices|data_streams)`,
},
doMountAsync: true,
};

const initTestBed = registerTestBed(WithAppDependencies(IndexManagementHome), testBedConfig);

export interface DataStreamsTabTestBed extends TestBed<TestSubjects> {
actions: {
goToDataStreamsList: () => void;
Expand All @@ -43,9 +32,23 @@ export interface DataStreamsTabTestBed extends TestBed<TestSubjects> {
findDeleteConfirmationModal: () => ReactWrapper;
findDetailPanel: () => ReactWrapper;
findDetailPanelTitle: () => string;
findEmptyPromptIndexTemplateLink: () => ReactWrapper;
}

export const setup = async (): Promise<DataStreamsTabTestBed> => {
export const setup = async (overridingDependencies: any = {}): Promise<DataStreamsTabTestBed> => {
const testBedConfig: TestBedConfig = {
store: () => indexManagementStore(services as any),
memoryRouter: {
initialEntries: [`/indices`],
componentRoutePath: `/:section(indices|data_streams|templates)`,
},
doMountAsync: true,
};

const initTestBed = registerTestBed(
WithAppDependencies(IndexManagementHome, overridingDependencies),
testBedConfig
);
const testBed = await initTestBed();

/**
Expand All @@ -56,15 +59,17 @@ export const setup = async (): Promise<DataStreamsTabTestBed> => {
testBed.find('data_streamsTab').simulate('click');
};

const clickEmptyPromptIndexTemplateLink = async () => {
const { find, component, router } = testBed;

const findEmptyPromptIndexTemplateLink = () => {
const { find } = testBed;
const templateLink = find('dataStreamsEmptyPromptTemplateLink');
return templateLink;
};

const clickEmptyPromptIndexTemplateLink = async () => {
const { component, router } = testBed;
await act(async () => {
router.navigateTo(templateLink.props().href!);
router.navigateTo(findEmptyPromptIndexTemplateLink().props().href!);
});

component.update();
};

Expand Down Expand Up @@ -148,6 +153,7 @@ export const setup = async (): Promise<DataStreamsTabTestBed> => {
findDeleteConfirmationModal,
findDetailPanel,
findDetailPanelTitle,
findEmptyPromptIndexTemplateLink,
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,73 +19,99 @@ describe('Data Streams tab', () => {
server.restore();
});

beforeEach(async () => {
httpRequestsMockHelpers.setLoadIndicesResponse([
{
health: '',
status: '',
primary: '',
replica: '',
documents: '',
documents_deleted: '',
size: '',
primary_size: '',
name: 'data-stream-index',
data_stream: 'dataStream1',
},
{
health: 'green',
status: 'open',
primary: 1,
replica: 1,
documents: 10000,
documents_deleted: 100,
size: '156kb',
primary_size: '156kb',
name: 'non-data-stream-index',
},
]);

await act(async () => {
testBed = await setup();
});
});

describe('when there are no data streams', () => {
beforeEach(async () => {
const { actions, component } = testBed;

httpRequestsMockHelpers.setLoadIndicesResponse([]);
httpRequestsMockHelpers.setLoadDataStreamsResponse([]);
httpRequestsMockHelpers.setLoadTemplatesResponse({ templates: [], legacyTemplates: [] });
});

test('displays an empty prompt', async () => {
await act(async () => {
actions.goToDataStreamsList();
testBed = await setup();
testBed.actions.goToDataStreamsList();
});

const { exists, component } = testBed;
testBed.component.update();

expect(exists('sectionLoading')).toBe(false);
expect(exists('emptyPrompt')).toBe(true);
});

test('when Ingest Manager is disabled, goes to index templates tab when "Get started" link is clicked', async () => {
await act(async () => {
testBed = await setup({
plugins: {},
});
testBed.actions.goToDataStreamsList();
});

const { actions, exists, component } = testBed;
component.update();

await act(async () => {
actions.clickEmptyPromptIndexTemplateLink();
});

expect(exists('templateList')).toBe(true);
});

test('displays an empty prompt', async () => {
const { exists } = testBed;
test('when Ingest Manager is enabled, links to Ingest Manager', async () => {
await act(async () => {
testBed = await setup({
plugins: { ingestManager: {} },
});
testBed.actions.goToDataStreamsList();
});

expect(exists('sectionLoading')).toBe(false);
expect(exists('emptyPrompt')).toBe(true);
const { findEmptyPromptIndexTemplateLink, component } = testBed;
component.update();

// Assert against the text because the href won't be available, due to dependency upon our core mock.
expect(findEmptyPromptIndexTemplateLink().props().children).toBe('Ingest Manager');
});
});

describe('when there are data streams', () => {
beforeEach(async () => {
const { actions, component } = testBed;
httpRequestsMockHelpers.setLoadIndicesResponse([
{
health: '',
status: '',
primary: '',
replica: '',
documents: '',
documents_deleted: '',
size: '',
primary_size: '',
name: 'data-stream-index',
data_stream: 'dataStream1',
},
{
health: 'green',
status: 'open',
primary: 1,
replica: 1,
documents: 10000,
documents_deleted: 100,
size: '156kb',
primary_size: '156kb',
name: 'non-data-stream-index',
},
]);

httpRequestsMockHelpers.setLoadDataStreamsResponse([
createDataStreamPayload('dataStream1'),
createDataStreamPayload('dataStream2'),
]);

await act(async () => {
actions.goToDataStreamsList();
testBed = await setup();
testBed.actions.goToDataStreamsList();
});

component.update();
testBed.component.update();
});

test('lists them in the table', async () => {
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/index_management/kibana.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
],
"optionalPlugins": [
"security",
"usageCollection"
"usageCollection",
"ingestManager"
],
"configPath": ["xpack", "index_management"]
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

import React, { createContext, useContext } from 'react';
import { ScopedHistory } from 'kibana/public';
import { CoreStart } from '../../../../../src/core/public';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/public';

import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/public';
import { CoreStart } from '../../../../../src/core/public';
import { IngestManagerSetup } from '../../../ingest_manager/public';
import { IndexMgmtMetricsType } from '../types';
import { UiMetricService, NotificationService, HttpService } from './services';
import { ExtensionsService } from '../services';
Expand All @@ -22,6 +23,7 @@ export interface AppDependencies {
};
plugins: {
usageCollection: UsageCollectionSetup;
ingestManager?: IngestManagerSetup;
};
services: {
uiMetricService: UiMetricService<IndexMgmtMetricsType>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CoreSetup } from 'src/core/public';
import { ManagementAppMountParams } from 'src/plugins/management/public/';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/public';

import { IngestManagerSetup } from '../../../ingest_manager/public';
import { ExtensionsService } from '../services';
import { IndexMgmtMetricsType } from '../types';
import { AppDependencies } from './app_context';
Expand All @@ -28,7 +29,8 @@ export async function mountManagementSection(
coreSetup: CoreSetup,
usageCollection: UsageCollectionSetup,
services: InternalServices,
params: ManagementAppMountParams
params: ManagementAppMountParams,
ingestManager?: IngestManagerSetup
) {
const { element, setBreadcrumbs, history } = params;
const [core] = await coreSetup.getStartServices();
Expand All @@ -44,6 +46,7 @@ export async function mountManagementSection(
},
plugins: {
usageCollection,
ingestManager,
},
services,
history,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { i18n } from '@kbn/i18n';
import { EuiTitle, EuiText, EuiSpacer, EuiEmptyPrompt, EuiLink } from '@elastic/eui';
import { ScopedHistory } from 'kibana/public';

import { reactRouterNavigate } from '../../../../shared_imports';
import { useAppContext } from '../../../app_context';
import { SectionError, SectionLoading, Error } from '../../../components';
import { useLoadDataStreams } from '../../../services/api';
Expand All @@ -31,7 +32,9 @@ export const DataStreamList: React.FunctionComponent<RouteComponentProps<MatchPa
}) => {
const {
core: { getUrlForApp },
plugins: { ingestManager },
} = useAppContext();

const { error, isLoading, data: dataStreams, sendRequest: reload } = useLoadDataStreams();

let content;
Expand Down Expand Up @@ -73,20 +76,51 @@ export const DataStreamList: React.FunctionComponent<RouteComponentProps<MatchPa
<p>
<FormattedMessage
id="xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsDescription"
defaultMessage="Data streams represent collections of time series indices. Get started with data streams in {link}."
values={{
link: (
<EuiLink
data-test-subj="dataStreamsEmptyPromptTemplateLink"
href={getUrlForApp('ingestManager')}
>
{i18n.translate('xpack.idxMgmt.dataStreamList.emptyPrompt.getStartedLink', {
defaultMessage: 'Ingest Manager',
})}
</EuiLink>
),
}}
/>
defaultMessage="Data streams represent collections of time series indices."
/>{' '}
{ingestManager ? (
<FormattedMessage
id="xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIngestManagerMessage"
defaultMessage="Get started with data streams in {link}."
values={{
link: (
<EuiLink
data-test-subj="dataStreamsEmptyPromptTemplateLink"
href={getUrlForApp('ingestManager')}
>
{i18n.translate(
'xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIngestManagerLink',
{
defaultMessage: 'Ingest Manager',
}
)}
</EuiLink>
),
}}
/>
) : (
<FormattedMessage
id="xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIngestManagerMessage"
defaultMessage="Get started with data streams by creating a {link}."
values={{
link: (
<EuiLink
data-test-subj="dataStreamsEmptyPromptTemplateLink"
{...reactRouterNavigate(history, {
pathname: '/templates',
})}
>
{i18n.translate(
'xpack.idxMgmt.dataStreamList.emptyPrompt.noDataStreamsCtaIngestManagerLink',
{
defaultMessage: 'composable index template',
}
)}
</EuiLink>
),
}}
/>
)}
</p>
}
data-test-subj="emptyPrompt"
Expand Down
Loading

0 comments on commit 4670f98

Please sign in to comment.