Skip to content

Commit

Permalink
Merge branch 'master' into fix/112793
Browse files Browse the repository at this point in the history
  • Loading branch information
kibanamachine authored Oct 1, 2021
2 parents 11e2372 + 56e17cd commit 606a0c6
Show file tree
Hide file tree
Showing 40 changed files with 642 additions and 139 deletions.
8 changes: 8 additions & 0 deletions src/dev/run_precommit_hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
* Side Public License, v 1.
*/

import SimpleGit from 'simple-git/promise';

import { REPO_ROOT } from '@kbn/utils';
import { run, combineErrors, createFlagError, createFailError } from '@kbn/dev-utils';
import * as Eslint from './eslint';
import * as Stylelint from './stylelint';
Expand Down Expand Up @@ -48,6 +51,11 @@ run(
await Linter.lintFiles(log, filesToLint, {
fix: flags.fix,
});

if (flags.fix) {
const simpleGit = new SimpleGit(REPO_ROOT);
await simpleGit.add(filesToLint);
}
} catch (error) {
errors.push(error);
}
Expand Down
14 changes: 8 additions & 6 deletions src/plugins/custom_integrations/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
export const PLUGIN_ID = 'customIntegrations';
export const PLUGIN_NAME = 'customIntegrations';

export interface CategoryCount {
export interface IntegrationCategoryCount {
count: number;
id: Category;
id: IntegrationCategory;
}

export const CATEGORY_DISPLAY = {
export const INTEGRATION_CATEGORY_DISPLAY = {
aws: 'AWS',
azure: 'Azure',
cloud: 'Cloud',
Expand Down Expand Up @@ -44,7 +44,7 @@ export const CATEGORY_DISPLAY = {
updates_available: 'Updates available',
};

export type Category = keyof typeof CATEGORY_DISPLAY;
export type IntegrationCategory = keyof typeof INTEGRATION_CATEGORY_DISPLAY;

export interface CustomIntegrationIcon {
src: string;
Expand All @@ -59,8 +59,10 @@ export interface CustomIntegration {
uiInternalPath: string;
isBeta: boolean;
icons: CustomIntegrationIcon[];
categories: Category[];
categories: IntegrationCategory[];
shipper: string;
eprOverlap?: string; // name of the equivalent Elastic Agent integration in EPR. e.g. a beat module can correspond to an EPR-package, or an APM-tutorial. When completed, Integrations-UX can preferentially show the EPR-package, rather than the custom-integration
}

export const ROUTES_ADDABLECUSTOMINTEGRATIONS = `/api/${PLUGIN_ID}/appendCustomIntegrations`;
export const ROUTES_APPEND_CUSTOM_INTEGRATIONS = `/internal/${PLUGIN_ID}/appendCustomIntegrations`;
export const ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS = `/internal/${PLUGIN_ID}/replacementCustomIntegrations`;
4 changes: 2 additions & 2 deletions src/plugins/custom_integrations/public/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
import { CustomIntegrationsSetup } from './types';

function createCustomIntegrationsSetup(): jest.Mocked<CustomIntegrationsSetup> {
const mock = {
const mock: jest.Mocked<CustomIntegrationsSetup> = {
getAppendCustomIntegrations: jest.fn(),
getReplacementCustomIntegrations: jest.fn(),
};

return mock;
}

Expand Down
14 changes: 11 additions & 3 deletions src/plugins/custom_integrations/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@

import { CoreSetup, CoreStart, Plugin } from 'src/core/public';
import { CustomIntegrationsSetup, CustomIntegrationsStart } from './types';
import { CustomIntegration, ROUTES_ADDABLECUSTOMINTEGRATIONS } from '../common';
import {
CustomIntegration,
ROUTES_APPEND_CUSTOM_INTEGRATIONS,
ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS,
} from '../common';

export class CustomIntegrationsPlugin
implements Plugin<CustomIntegrationsSetup, CustomIntegrationsStart>
{
public setup(core: CoreSetup): CustomIntegrationsSetup {
// Return methods that should be available to other plugins
return {
async getReplacementCustomIntegrations(): Promise<CustomIntegration[]> {
return core.http.get(ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS);
},

async getAppendCustomIntegrations(): Promise<CustomIntegration[]> {
return core.http.get(ROUTES_ADDABLECUSTOMINTEGRATIONS);
return core.http.get(ROUTES_APPEND_CUSTOM_INTEGRATIONS);
},
} as CustomIntegrationsSetup;
};
}

public start(core: CoreStart): CustomIntegrationsStart {
Expand Down
1 change: 1 addition & 0 deletions src/plugins/custom_integrations/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { CustomIntegration } from '../common';

export interface CustomIntegrationsSetup {
getAppendCustomIntegrations: () => Promise<CustomIntegration[]>;
getReplacementCustomIntegrations: () => Promise<CustomIntegration[]>;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface CustomIntegrationsStart {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import { CustomIntegrationRegistry } from './custom_integration_registry';
import { loggerMock, MockedLogger } from '@kbn/logging/mocks';
import { CustomIntegration } from '../common';
import { IntegrationCategory, CustomIntegration } from '../common';

describe('CustomIntegrationsRegistry', () => {
let mockLogger: MockedLogger;
Expand Down Expand Up @@ -44,6 +44,27 @@ describe('CustomIntegrationsRegistry', () => {
expect(mockLogger.debug.mock.calls.length).toBe(1);
});
});

test('should strip unsupported categories', () => {
const registry = new CustomIntegrationRegistry(mockLogger, true);
registry.registerCustomIntegration({
...integration,
categories: ['upload_file', 'foobar'] as IntegrationCategory[],
});
expect(registry.getAppendCustomIntegrations()).toEqual([
{
categories: ['upload_file'],
description: 'test integration',
icons: [],
id: 'foo',
isBeta: false,
shipper: 'tests',
title: 'Foo',
type: 'ui_link',
uiInternalPath: '/path/to/foo',
},
]);
});
});

describe('getAppendCustomCategories', () => {
Expand Down Expand Up @@ -76,7 +97,7 @@ describe('CustomIntegrationsRegistry', () => {
},
]);
});
test('should ignore duplicate ids', () => {
test('should filter duplicate ids', () => {
const registry = new CustomIntegrationRegistry(mockLogger, true);
registry.registerCustomIntegration(integration);
registry.registerCustomIntegration(integration);
Expand All @@ -94,7 +115,7 @@ describe('CustomIntegrationsRegistry', () => {
},
]);
});
test('should ignore integrations without category', () => {
test('should filter integrations without category', () => {
const registry = new CustomIntegrationRegistry(mockLogger, true);
registry.registerCustomIntegration(integration);
registry.registerCustomIntegration({ ...integration, id: 'bar', categories: [] });
Expand All @@ -113,5 +134,44 @@ describe('CustomIntegrationsRegistry', () => {
},
]);
});

test('should filter integrations that need to replace EPR packages', () => {
const registry = new CustomIntegrationRegistry(mockLogger, true);
registry.registerCustomIntegration({ ...integration, id: 'bar', eprOverlap: 'aws' });
expect(registry.getAppendCustomIntegrations()).toEqual([]);
});
});

describe('getReplacementCustomIntegrations', () => {
test('should only return integrations with corresponding epr package ', () => {
const registry = new CustomIntegrationRegistry(mockLogger, true);
registry.registerCustomIntegration(integration);
registry.registerCustomIntegration({ ...integration, id: 'bar', eprOverlap: 'aws' });
expect(registry.getReplacementCustomIntegrations()).toEqual([
{
categories: ['upload_file'],
description: 'test integration',
icons: [],
id: 'bar',
isBeta: false,
shipper: 'tests',
title: 'Foo',
type: 'ui_link',
uiInternalPath: '/path/to/foo',
eprOverlap: 'aws',
},
]);
});

test('should filter registrations without valid categories', () => {
const registry = new CustomIntegrationRegistry(mockLogger, true);
registry.registerCustomIntegration({
...integration,
id: 'bar',
eprOverlap: 'aws',
categories: ['foobar'] as unknown as IntegrationCategory[],
});
expect(registry.getReplacementCustomIntegrations()).toEqual([]);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
*/

import { Logger } from 'kibana/server';
import { CustomIntegration } from '../common';
import { IntegrationCategory, INTEGRATION_CATEGORY_DISPLAY, CustomIntegration } from '../common';

function isAddable(integration: CustomIntegration) {
return integration.categories.length;
function isAddable(integration: CustomIntegration): boolean {
return !!integration.categories.length && !integration.eprOverlap;
}

function isReplacement(integration: CustomIntegration): boolean {
return !!integration.categories.length && !!integration.eprOverlap;
}

export class CustomIntegrationRegistry {
Expand Down Expand Up @@ -39,10 +43,20 @@ export class CustomIntegrationRegistry {
return;
}

this._integrations.push(customIntegration);
const allowedCategories: IntegrationCategory[] = (customIntegration.categories ?? []).filter(
(category) => {
return INTEGRATION_CATEGORY_DISPLAY.hasOwnProperty(category);
}
) as IntegrationCategory[];

this._integrations.push({ ...customIntegration, categories: allowedCategories });
}

getAppendCustomIntegrations(): CustomIntegration[] {
return this._integrations.filter(isAddable);
}

getReplacementCustomIntegrations(): CustomIntegration[] {
return this._integrations.filter(isReplacement);
}
}
2 changes: 1 addition & 1 deletion src/plugins/custom_integrations/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function plugin(initializerContext: PluginInitializerContext) {

export { CustomIntegrationsPluginSetup, CustomIntegrationsPluginStart } from './types';

export type { Category, CategoryCount, CustomIntegration } from '../common';
export type { IntegrationCategory, IntegrationCategoryCount, CustomIntegration } from '../common';

export const config = {
schema: schema.object({}),
Expand Down
1 change: 0 additions & 1 deletion src/plugins/custom_integrations/server/plugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ describe('CustomIntegrationsPlugin', () => {
test('wires up tutorials provider service and returns registerTutorial and addScopedTutorialContextFactory', () => {
const setup = new CustomIntegrationsPlugin(initContext).setup(mockCoreSetup);
expect(setup).toHaveProperty('registerCustomIntegration');
expect(setup).toHaveProperty('getAppendCustomIntegrations');
});
});
});
3 changes: 0 additions & 3 deletions src/plugins/custom_integrations/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ export class CustomIntegrationsPlugin
...integration,
});
},
getAppendCustomIntegrations: (): CustomIntegration[] => {
return this.customIngegrationRegistry.getAppendCustomIntegrations();
},
} as CustomIntegrationsPluginSetup;
}

Expand Down
20 changes: 18 additions & 2 deletions src/plugins/custom_integrations/server/routes/define_routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@

import { IRouter } from 'src/core/server';
import { CustomIntegrationRegistry } from '../custom_integration_registry';
import { ROUTES_ADDABLECUSTOMINTEGRATIONS } from '../../common';
import {
ROUTES_APPEND_CUSTOM_INTEGRATIONS,
ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS,
} from '../../common';

export function defineRoutes(
router: IRouter,
customIntegrationsRegistry: CustomIntegrationRegistry
) {
router.get(
{
path: ROUTES_ADDABLECUSTOMINTEGRATIONS,
path: ROUTES_APPEND_CUSTOM_INTEGRATIONS,
validate: false,
},
async (context, request, response) => {
Expand All @@ -26,4 +29,17 @@ export function defineRoutes(
});
}
);

router.get(
{
path: ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS,
validate: false,
},
async (context, request, response) => {
const integrations = customIntegrationsRegistry.getReplacementCustomIntegrations();
return response.ok({
body: integrations,
});
}
);
}
3 changes: 3 additions & 0 deletions src/plugins/discover/public/__mocks__/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,7 @@ export const discoverServiceMock = {
useChartsTheme: jest.fn(() => EUI_CHARTS_THEME_LIGHT.theme),
useChartsBaseTheme: jest.fn(() => EUI_CHARTS_THEME_LIGHT.theme),
},
storage: {
get: jest.fn(),
},
} as unknown as DiscoverServices;
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React from 'react';
import { Subject, BehaviorSubject } from 'rxjs';
import { mountWithIntl } from '@kbn/test/jest';
import { setHeaderActionMenuMounter } from '../../../../../kibana_services';
import { DiscoverLayout } from './discover_layout';
import { DiscoverLayout, SIDEBAR_CLOSED_KEY } from './discover_layout';
import { esHits } from '../../../../../__mocks__/es_hits';
import { indexPatternMock } from '../../../../../__mocks__/index_pattern';
import { savedSearchMock } from '../../../../../__mocks__/saved_search';
Expand All @@ -31,15 +31,21 @@ import { FetchStatus } from '../../../../types';
import { ElasticSearchHit } from '../../../../doc_views/doc_views_types';
import { RequestAdapter } from '../../../../../../../inspector';
import { Chart } from '../chart/point_series';
import { DiscoverSidebar } from '../sidebar/discover_sidebar';

setHeaderActionMenuMounter(jest.fn());

function getProps(indexPattern: IndexPattern): DiscoverLayoutProps {
function getProps(indexPattern: IndexPattern, wasSidebarClosed?: boolean): DiscoverLayoutProps {
const searchSourceMock = createSearchSourceMock({});
const services = discoverServiceMock;
services.data.query.timefilter.timefilter.getAbsoluteTime = () => {
return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' };
};
services.storage.get = (key: string) => {
if (key === SIDEBAR_CLOSED_KEY) {
return wasSidebarClosed;
}
};

const indexPatternList = [indexPattern].map((ip) => {
return { ...ip, ...{ attributes: { title: ip.title } } };
Expand Down Expand Up @@ -139,10 +145,34 @@ describe('Discover component', () => {
const component = mountWithIntl(<DiscoverLayout {...getProps(indexPatternMock)} />);
expect(component.find('[data-test-subj="discoverChartOptionsToggle"]').exists()).toBeFalsy();
});

test('selected index pattern with time field displays chart toggle', () => {
const component = mountWithIntl(
<DiscoverLayout {...getProps(indexPatternWithTimefieldMock)} />
);
expect(component.find('[data-test-subj="discoverChartOptionsToggle"]').exists()).toBeTruthy();
});

describe('sidebar', () => {
test('should be opened if discover:sidebarClosed was not set', () => {
const component = mountWithIntl(
<DiscoverLayout {...getProps(indexPatternWithTimefieldMock)} />
);
expect(component.find(DiscoverSidebar).length).toBe(1);
});

test('should be opened if discover:sidebarClosed is false', () => {
const component = mountWithIntl(
<DiscoverLayout {...getProps(indexPatternWithTimefieldMock, false)} />
);
expect(component.find(DiscoverSidebar).length).toBe(1);
});

test('should be closed if discover:sidebarClosed is true', () => {
const component = mountWithIntl(
<DiscoverLayout {...getProps(indexPatternWithTimefieldMock, true)} />
);
expect(component.find(DiscoverSidebar).length).toBe(0);
});
});
});
Loading

0 comments on commit 606a0c6

Please sign in to comment.