Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[core/public/navLinks] migrate ui/chrome/navLinks API #23217

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions src/core/public/core_system.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
* under the License.
*/

// tslint:disable no-unused-expression

import { BasePathService } from './base_path';
import { FatalErrorsService } from './fatal_errors';
import { InjectedMetadataService } from './injected_metadata';
import { LegacyPlatformService } from './legacy_platform';
import { LoadingCountService } from './loading_count';
import { NavLinksService } from './nav_links';
import { NotificationsService } from './notifications';
import { UiSettingsService } from './ui_settings';

Expand Down Expand Up @@ -97,6 +100,15 @@ jest.mock('./ui_settings', () => ({
UiSettingsService: MockUiSettingsService,
}));

const mockNavLinksContract = {};
const MockNavLinksService = jest.fn<NavLinksService>(function(this: any) {
this.start = jest.fn().mockReturnValue(mockNavLinksContract);
this.stop = jest.fn();
});
jest.mock('./nav_links', () => ({
NavLinksService: MockNavLinksService,
}));

import { CoreSystem } from './core_system';
jest.spyOn(CoreSystem.prototype, 'stop');

Expand All @@ -112,7 +124,6 @@ beforeEach(() => {

describe('constructor', () => {
it('creates instances of services', () => {
// tslint:disable no-unused-expression
new CoreSystem({
...defaultCoreSystemParams,
});
Expand All @@ -124,12 +135,12 @@ describe('constructor', () => {
expect(MockLoadingCountService).toHaveBeenCalledTimes(1);
expect(MockBasePathService).toHaveBeenCalledTimes(1);
expect(MockUiSettingsService).toHaveBeenCalledTimes(1);
expect(MockNavLinksService).toHaveBeenCalledTimes(1);
});

it('passes injectedMetadata param to InjectedMetadataService', () => {
const injectedMetadata = { injectedMetadata: true } as any;

// tslint:disable no-unused-expression
new CoreSystem({
...defaultCoreSystemParams,
injectedMetadata,
Expand All @@ -145,7 +156,6 @@ describe('constructor', () => {
const requireLegacyFiles = { requireLegacyFiles: true } as any;
const useLegacyTestHarness = { useLegacyTestHarness: true } as any;

// tslint:disable no-unused-expression
new CoreSystem({
...defaultCoreSystemParams,
requireLegacyFiles,
Expand All @@ -161,7 +171,6 @@ describe('constructor', () => {
});

it('passes a dom element to NotificationsService', () => {
// tslint:disable no-unused-expression
new CoreSystem({
...defaultCoreSystemParams,
});
Expand Down Expand Up @@ -231,6 +240,17 @@ describe('#stop', () => {
expect(loadingCountService.stop).toHaveBeenCalled();
});

it('calls navLinks.stop()', () => {
const coreSystem = new CoreSystem({
...defaultCoreSystemParams,
});

const [navLinksService] = MockNavLinksService.mock.instances;
expect(navLinksService.stop).not.toHaveBeenCalled();
coreSystem.stop();
expect(navLinksService.stop).toHaveBeenCalled();
});

it('clears the rootDomElement', () => {
const rootDomElement = document.createElement('div');
const coreSystem = new CoreSystem({
Expand Down Expand Up @@ -312,6 +332,16 @@ describe('#start()', () => {
expect(mockInstance.start).toHaveBeenCalledTimes(1);
expect(mockInstance.start).toHaveBeenCalledWith();
});

it('calls navLinks#start()', () => {
startCore();
const [mockInstance] = MockNavLinksService.mock.instances;
expect(mockInstance.start).toHaveBeenCalledTimes(1);
expect(mockInstance.start).toHaveBeenCalledWith({
injectedMetadata: mockInjectedMetadataStartContract,
basePath: mockBasePathStartContract,
});
});
});

describe('LegacyPlatform targetDomElement', () => {
Expand Down
6 changes: 6 additions & 0 deletions src/core/public/core_system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { FatalErrorsService } from './fatal_errors';
import { InjectedMetadataParams, InjectedMetadataService } from './injected_metadata';
import { LegacyPlatformParams, LegacyPlatformService } from './legacy_platform';
import { LoadingCountService } from './loading_count';
import { NavLinksService } from './nav_links';
import { NotificationsService } from './notifications';
import { UiSettingsService } from './ui_settings';

Expand All @@ -48,6 +49,7 @@ export class CoreSystem {
private readonly loadingCount: LoadingCountService;
private readonly uiSettings: UiSettingsService;
private readonly basePath: BasePathService;
private readonly navLinks: NavLinksService;

private readonly rootDomElement: HTMLElement;
private readonly notificationsTargetDomElement: HTMLDivElement;
Expand Down Expand Up @@ -78,6 +80,7 @@ export class CoreSystem {
this.loadingCount = new LoadingCountService();
this.basePath = new BasePathService();
this.uiSettings = new UiSettingsService();
this.navLinks = new NavLinksService();

this.legacyPlatformTargetDomElement = document.createElement('div');
this.legacyPlatform = new LegacyPlatformService({
Expand All @@ -100,6 +103,7 @@ export class CoreSystem {
const fatalErrors = this.fatalErrors.start();
const loadingCount = this.loadingCount.start({ fatalErrors });
const basePath = this.basePath.start({ injectedMetadata });
const navLinks = this.navLinks.start({ injectedMetadata, basePath });
const uiSettings = this.uiSettings.start({
notifications,
loadingCount,
Expand All @@ -112,6 +116,7 @@ export class CoreSystem {
notifications,
loadingCount,
basePath,
navLinks,
uiSettings,
});
} catch (error) {
Expand All @@ -123,6 +128,7 @@ export class CoreSystem {
this.legacyPlatform.stop();
this.notifications.stop();
this.loadingCount.stop();
this.navLinks.stop();
this.rootDomElement.textContent = '';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,30 @@ describe('start.getInjectedVars()', () => {
);
});
});

describe('start.getNavLinks()', () => {
it('returns the navLinks from the injected vars, readonly', () => {
const start = new InjectedMetadataService({
injectedMetadata: {
navLinks: [{ id: 1 }, { id: 2 }],
},
} as any).start();

const nav: any = start.getNavLinks();
expect(nav).toMatchInlineSnapshot(`
Array [
Object {
"id": 1,
},
Object {
"id": 2,
},
]
`);
expect(() => {
nav[0].id = 2;
}).toThrowErrorMatchingInlineSnapshot(
`"Cannot assign to read only property 'id' of object '#<Object>'"`
);
});
});
23 changes: 22 additions & 1 deletion src/core/public/injected_metadata/injected_metadata_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,26 @@ export interface InjectedMetadataParams {
version: string;
buildNumber: number;
basePath: string;
navLinks: Array<{
id: string;
title: string;
order: number;
url: string;
subUrlBase: string;
linkToLastSubUrl: boolean;
icon?: string;
description?: string;
disabled?: boolean;
tooltip?: string;
hidden?: boolean;
}>;
vars: {
[key: string]: unknown;
};
legacyMetadata: {
app: unknown;
translations: unknown;
bundleId: string;
nav: unknown;
version: string;
branch: string;
buildNum: number;
Expand Down Expand Up @@ -81,6 +93,15 @@ export class InjectedMetadataService {
getInjectedVars: () => {
return this.state.vars;
},

/**
* Returns the navLinks that were included in the injectedMetadata. Use navLinks.get$() to
* access the complete list of navLinks that reflect the correct application state
* @internal
*/
getNavLinks: () => {
return this.state.navLinks;
},
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Array [
"ui/chrome/api/base_path",
"ui/chrome/api/ui_settings",
"ui/chrome/api/injected_vars",
"ui/chrome/api/nav_links",
"ui/chrome",
"legacy files",
]
Expand All @@ -23,6 +24,7 @@ Array [
"ui/chrome/api/base_path",
"ui/chrome/api/ui_settings",
"ui/chrome/api/injected_vars",
"ui/chrome/api/nav_links",
"ui/test_harness",
"legacy files",
]
Expand Down
21 changes: 21 additions & 0 deletions src/core/public/legacy_platform/legacy_platform_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ jest.mock('ui/chrome/api/injected_vars', () => {
};
});

const mockNavLinksInit = jest.fn();
jest.mock('ui/chrome/api/nav_links', () => {
mockLoadOrder.push('ui/chrome/api/nav_links');
return {
__newPlatformInit__: mockNavLinksInit,
};
});

import { LegacyPlatformService } from './legacy_platform_service';

const fatalErrorsStartContract = {} as any;
Expand All @@ -118,6 +126,7 @@ const basePathStartContract = {
};

const uiSettingsStartContract: any = {};
const navLinksStartContract: any = {};

const defaultParams = {
targetDomElement: document.createElement('div'),
Expand All @@ -133,6 +142,7 @@ const defaultStartDeps = {
loadingCount: loadingCountStartContract,
basePath: basePathStartContract,
uiSettings: uiSettingsStartContract,
navLinks: navLinksStartContract,
};

afterEach(() => {
Expand Down Expand Up @@ -224,6 +234,17 @@ describe('#start()', () => {
expect(mockInjectedVarsInit).toHaveBeenCalledWith(injectedMetadataStartContract);
});

it('passes navLinks service to ui/chrome/api/nav_links', () => {
const legacyPlatform = new LegacyPlatformService({
...defaultParams,
});

legacyPlatform.start(defaultStartDeps);

expect(mockNavLinksInit).toHaveBeenCalledTimes(1);
expect(mockNavLinksInit).toHaveBeenCalledWith(navLinksStartContract);
});

describe('useLegacyTestHarness = false', () => {
it('passes the targetDomElement to ui/chrome', () => {
const legacyPlatform = new LegacyPlatformService({
Expand Down
4 changes: 4 additions & 0 deletions src/core/public/legacy_platform/legacy_platform_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { BasePathStartContract } from '../base_path';
import { FatalErrorsStartContract } from '../fatal_errors';
import { InjectedMetadataStartContract } from '../injected_metadata';
import { LoadingCountStartContract } from '../loading_count';
import { NavLinksStartContract } from '../nav_links';
import { NotificationsStartContract } from '../notifications';
import { UiSettingsClient } from '../ui_settings';

Expand All @@ -32,6 +33,7 @@ interface Deps {
loadingCount: LoadingCountStartContract;
basePath: BasePathStartContract;
uiSettings: UiSettingsClient;
navLinks: NavLinksStartContract;
}

export interface LegacyPlatformParams {
Expand All @@ -57,6 +59,7 @@ export class LegacyPlatformService {
loadingCount,
basePath,
uiSettings,
navLinks,
}: Deps) {
// Inject parts of the new platform into parts of the legacy platform
// so that legacy APIs/modules can mimic their new platform counterparts
Expand All @@ -67,6 +70,7 @@ export class LegacyPlatformService {
require('ui/chrome/api/base_path').__newPlatformInit__(basePath);
require('ui/chrome/api/ui_settings').__newPlatformInit__(uiSettings);
require('ui/chrome/api/injected_vars').__newPlatformInit__(injectedMetadata);
require('ui/chrome/api/nav_links').__newPlatformInit__(navLinks);

// Load the bootstrap module before loading the legacy platform files so that
// the bootstrap module can modify the environment a bit first
Expand Down
20 changes: 20 additions & 0 deletions src/core/public/nav_links/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 { NavLinksService, NavLinksStartContract, NavLinks, NavLink } from './nav_links_service';
Loading