[7.6] Remove injected reference from home app (#57836) (#57996)

This commit is contained in:
Joe Reuter 2020-02-20 13:48:03 +01:00 committed by GitHub
parent 60092c2bd3
commit d523039764
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 288 additions and 13 deletions

View file

@ -29,7 +29,11 @@ import {
UiSettingsState,
} from 'kibana/public';
import { UiStatsMetricType } from '@kbn/analytics';
import { Environment, FeatureCatalogueEntry } from '../../../../../plugins/home/public';
import {
Environment,
FeatureCatalogueEntry,
TutorialStart,
} from '../../../../../plugins/home/public';
export interface HomeKibanaServices {
indexPatternService: any;
@ -47,7 +51,6 @@ export interface HomeKibanaServices {
devMode: boolean;
uiSettings: { defaults: UiSettingsState; user?: UiSettingsState | undefined };
};
getInjected: (name: string, defaultValue?: any) => unknown;
chrome: ChromeStart;
telemetryOptInProvider: any;
uiSettings: IUiSettingsClient;
@ -62,6 +65,8 @@ export interface HomeKibanaServices {
docLinks: DocLinksStart;
addBasePath: (url: string) => string;
environment: Environment;
tutorialVariables: TutorialStart['get'];
getInjected: (name: string, defaultValue?: any) => unknown;
}
let services: HomeKibanaServices | null = null;

View file

@ -29,6 +29,7 @@ import { FeatureCatalogueCategory } from '../../../../../../../plugins/home/publ
jest.mock('../../kibana_services', () => ({
getServices: () => ({
getBasePath: () => 'path',
tutorialVariables: () => ({}),
getInjected: () => '',
}),
}));

View file

@ -33,7 +33,7 @@ mustacheWriter.escapedValue = function escapedValue(token, context) {
};
export function replaceTemplateStrings(text, params = {}) {
const { getInjected, metadata, docLinks } = getServices();
const { tutorialVariables, metadata, docLinks } = getServices();
const variables = {
// '{' and '}' can not be used in template since they are used as template tags.
@ -41,9 +41,7 @@ export function replaceTemplateStrings(text, params = {}) {
curlyOpen: '{',
curlyClose: '}',
config: {
cloud: {
id: getInjected('cloudId'),
},
...tutorialVariables(),
docs: {
base_url: docLinks.ELASTIC_WEBSITE_URL,
beats: {

View file

@ -68,7 +68,7 @@ export class HomePlugin implements Plugin {
private environment: Environment | null = null;
setup(
core: CoreSetup,
core: CoreSetup<HomePluginStartDependencies>,
{
kibana_legacy,
__LEGACY: { getAngularDependencies, ...legacyServices },
@ -79,12 +79,12 @@ export class HomePlugin implements Plugin {
title: 'Home',
mount: async ({ core: contextCore }, params) => {
const angularDependencies = await getAngularDependencies();
const [, { home: homeStart }] = await core.getStartServices();
setServices({
...legacyServices,
http: contextCore.http,
toastNotifications: core.notifications.toasts,
banners: contextCore.overlays.banners,
getInjected: core.injectedMetadata.getInjectedVar,
docLinks: contextCore.docLinks,
savedObjectsClient: this.savedObjectsClient!,
chrome: contextCore.chrome,
@ -93,6 +93,8 @@ export class HomePlugin implements Plugin {
getBasePath: core.http.basePath.get,
indexPatternService: this.dataStart!.indexPatterns,
environment: this.environment!,
tutorialVariables: homeStart.tutorials.get,
getInjected: core.injectedMetadata.getInjectedVar,
...angularDependencies,
});
const { renderApp } = await import('./np_ready/application');

View file

@ -20,10 +20,19 @@
export {
FeatureCatalogueSetup,
FeatureCatalogueStart,
EnvironmentSetup,
EnvironmentStart,
TutorialSetup,
TutorialStart,
HomePublicPluginSetup,
HomePublicPluginStart,
} from './plugin';
export { FeatureCatalogueEntry, FeatureCatalogueCategory, Environment } from './services';
export {
FeatureCatalogueEntry,
FeatureCatalogueCategory,
Environment,
TutorialVariables,
} from './services';
import { HomePublicPlugin } from './plugin';
export const plugin = () => new HomePublicPlugin();

View file

@ -0,0 +1,39 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { featureCatalogueRegistryMock } from '../services/feature_catalogue/feature_catalogue_registry.mock';
import { environmentServiceMock } from '../services/environment/environment.mock';
import { tutorialServiceMock } from '../services/tutorials/tutorial_service.mock';
const createSetupContract = () => ({
featureCatalogue: featureCatalogueRegistryMock.createSetup(),
environment: environmentServiceMock.createSetup(),
tutorials: tutorialServiceMock.createSetup(),
});
const createStartContract = () => ({
featureCatalogue: featureCatalogueRegistryMock.createStart(),
environment: environmentServiceMock.createStart(),
tutorials: tutorialServiceMock.createStart(),
});
export const homePluginMock = {
createSetupContract,
createStartContract,
};

View file

@ -19,10 +19,13 @@
import { featureCatalogueRegistryMock } from './services/feature_catalogue/feature_catalogue_registry.mock';
import { environmentServiceMock } from './services/environment/environment.mock';
import { tutorialServiceMock } from './services/tutorials/tutorial_service.mock';
export const registryMock = featureCatalogueRegistryMock.create();
export const environmentMock = environmentServiceMock.create();
export const tutorialMock = tutorialServiceMock.create();
jest.doMock('./services', () => ({
FeatureCatalogueRegistry: jest.fn(() => registryMock),
EnvironmentService: jest.fn(() => environmentMock),
TutorialService: jest.fn(() => tutorialMock),
}));

View file

@ -17,15 +17,17 @@
* under the License.
*/
import { registryMock, environmentMock } from './plugin.test.mocks';
import { registryMock, environmentMock, tutorialMock } from './plugin.test.mocks';
import { HomePublicPlugin } from './plugin';
describe('HomePublicPlugin', () => {
beforeEach(() => {
registryMock.setup.mockClear();
registryMock.start.mockClear();
tutorialMock.setup.mockClear();
environmentMock.setup.mockClear();
environmentMock.start.mockClear();
tutorialMock.start.mockClear();
});
describe('setup', () => {
@ -40,6 +42,12 @@ describe('HomePublicPlugin', () => {
expect(setup).toHaveProperty('environment');
expect(setup.environment).toHaveProperty('update');
});
test('wires up and returns tutorial service', async () => {
const setup = await new HomePublicPlugin().setup();
expect(setup).toHaveProperty('tutorials');
expect(setup.tutorials).toHaveProperty('setVariable');
});
});
describe('start', () => {
@ -63,5 +71,14 @@ describe('HomePublicPlugin', () => {
expect(environmentMock.start).toHaveBeenCalled();
expect(start.environment.get).toBeDefined();
});
test('wires up and returns tutorial service', async () => {
const service = new HomePublicPlugin();
await service.setup();
const core = { application: { capabilities: { catalogue: {} } } } as any;
const start = await service.start(core);
expect(tutorialMock.start).toHaveBeenCalled();
expect(start.tutorials.get).toBeDefined();
});
});
});

View file

@ -25,16 +25,21 @@ import {
FeatureCatalogueRegistry,
FeatureCatalogueRegistrySetup,
FeatureCatalogueRegistryStart,
TutorialService,
TutorialServiceSetup,
TutorialServiceStart,
} from './services';
export class HomePublicPlugin implements Plugin<HomePublicPluginSetup, HomePublicPluginStart> {
private readonly featuresCatalogueRegistry = new FeatureCatalogueRegistry();
private readonly environmentService = new EnvironmentService();
private readonly tutorialService = new TutorialService();
public async setup() {
return {
featureCatalogue: { ...this.featuresCatalogueRegistry.setup() },
environment: { ...this.environmentService.setup() },
tutorials: { ...this.tutorialService.setup() },
};
}
@ -45,6 +50,7 @@ export class HomePublicPlugin implements Plugin<HomePublicPluginSetup, HomePubli
capabilities: core.application.capabilities,
}),
},
tutorials: { ...this.tutorialService.start() },
environment: { ...this.environmentService.start() },
};
}
@ -62,8 +68,15 @@ export type EnvironmentSetup = EnvironmentServiceSetup;
/** @public */
export type EnvironmentStart = EnvironmentServiceStart;
/** @public */
export type TutorialSetup = TutorialServiceSetup;
/** @public */
export type TutorialStart = TutorialServiceStart;
/** @public */
export interface HomePublicPluginSetup {
tutorials: TutorialServiceSetup;
featureCatalogue: FeatureCatalogueSetup;
/**
* The environment service is only available for a transition period and will
@ -75,6 +88,7 @@ export interface HomePublicPluginSetup {
/** @public */
export interface HomePublicPluginStart {
tutorials: TutorialServiceStart;
featureCatalogue: FeatureCatalogueStart;
environment: EnvironmentStart;
}

View file

@ -20,15 +20,15 @@
/** @public */
export interface Environment {
/**
* Flag whether the home app should advertize cloud features
* Flag whether the home app should advertise cloud features
*/
readonly cloud: boolean;
/**
* Flag whether the home app should advertize apm features
* Flag whether the home app should advertise apm features
*/
readonly apmUi: boolean;
/**
* Flag whether the home app should advertize ml features
* Flag whether the home app should advertise ml features
*/
readonly ml: boolean;
}

View file

@ -19,3 +19,4 @@
export * from './feature_catalogue';
export * from './environment';
export * from './tutorials';

View file

@ -0,0 +1,25 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export {
TutorialService,
TutorialVariables,
TutorialServiceSetup,
TutorialServiceStart,
} from './tutorial_service';

View file

@ -0,0 +1,50 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { TutorialService, TutorialServiceSetup, TutorialServiceStart } from './tutorial_service';
const createSetupMock = (): jest.Mocked<TutorialServiceSetup> => {
const setup = {
setVariable: jest.fn(),
};
return setup;
};
const createStartMock = (): jest.Mocked<TutorialServiceStart> => {
const start = {
get: jest.fn(),
};
return start;
};
const createMock = (): jest.Mocked<PublicMethodsOf<TutorialService>> => {
const service = {
setup: jest.fn(),
start: jest.fn(),
};
service.setup.mockImplementation(createSetupMock);
service.start.mockImplementation(createStartMock);
return service;
};
export const tutorialServiceMock = {
createSetup: createSetupMock,
createStart: createStartMock,
create: createMock,
};

View file

@ -0,0 +1,55 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { TutorialService } from './tutorial_service';
describe('TutorialService', () => {
describe('setup', () => {
test('allows multiple set calls', () => {
const setup = new TutorialService().setup();
expect(() => {
setup.setVariable('abc', 123);
setup.setVariable('def', 456);
}).not.toThrow();
});
test('throws when same variable is set twice', () => {
const setup = new TutorialService().setup();
expect(() => {
setup.setVariable('abc', 123);
setup.setVariable('abc', 456);
}).toThrow();
});
});
describe('start', () => {
test('returns empty object', () => {
const service = new TutorialService();
expect(service.start().get()).toEqual({});
});
test('returns last state of update calls', () => {
const service = new TutorialService();
const setup = service.setup();
setup.setVariable('abc', 123);
setup.setVariable('def', { subKey: 456 });
expect(service.start().get()).toEqual({ abc: 123, def: { subKey: 456 } });
});
});
});

View file

@ -0,0 +1,53 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/** @public */
export type TutorialVariables = Partial<Record<string, unknown>>;
export class TutorialService {
private tutorialVariables: TutorialVariables = {};
public setup() {
return {
/**
* Set a variable usable in tutorial templates. Access with `{config.<key>}`.
*/
setVariable: (key: string, value: unknown) => {
if (this.tutorialVariables[key]) {
throw new Error('variable already set');
}
this.tutorialVariables[key] = value;
},
};
}
public start() {
return {
/**
* Retrieve the variables for substitution in tutorials. This API is only intended for internal
* use and is only exposed during a transition period of migrating the home app to the new platform.
* @deprecated
*/
get: (): TutorialVariables => this.tutorialVariables,
};
}
}
export type TutorialServiceSetup = ReturnType<TutorialService['setup']>;
export type TutorialServiceStart = ReturnType<TutorialService['start']>;

View file

@ -31,6 +31,9 @@ export class CloudPlugin implements Plugin<CloudSetup> {
if (home) {
home.environment.update({ cloud: isCloudEnabled });
if (isCloudEnabled) {
home.tutorials.setVariable('cloud', { id });
}
}
return {