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

add unit tests for workspace core service (#191) #197

Merged
merged 2 commits into from
Sep 25, 2023
Merged
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
6 changes: 3 additions & 3 deletions src/core/public/application/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import { IUiSettingsClient } from '../ui_settings';
import { SavedObjectsStart } from '../saved_objects';
import { AppCategory } from '../../types';
import { ScopedHistory } from './scoped_history';
import { WorkspaceStart } from '../workspace';
import { WorkspacesStart } from '../workspace';

/**
* Accessibility status of an application.
Expand Down Expand Up @@ -345,8 +345,8 @@ export interface AppMountContext {
injectedMetadata: {
getInjectedVar: (name: string, defaultValue?: any) => unknown;
};
/** {@link WorkspaceService} */
workspaces: WorkspaceStart;
/** {@link WorkspacesService} */
workspaces: WorkspacesStart;
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/public/chrome/chrome_service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { ChromeNavLinks, NavLinksService, ChromeNavLink } from './nav_links';
import { ChromeRecentlyAccessed, RecentlyAccessedService } from './recently_accessed';
import { Header } from './ui';
import { ChromeHelpExtensionMenuLink } from './ui/header/header_help_menu';
import { Branding, WorkspaceStart } from '../';
import { Branding, WorkspacesStart } from '../';
import { getLogos } from '../../common';
import type { Logos } from '../../common/types';

Expand Down Expand Up @@ -96,7 +96,7 @@ interface StartDeps {
injectedMetadata: InjectedMetadataStart;
notifications: NotificationsStart;
uiSettings: IUiSettingsClient;
workspaces: WorkspaceStart;
workspaces: WorkspacesStart;
}

/** @internal */
Expand Down
4 changes: 2 additions & 2 deletions src/core/public/chrome/ui/header/collapsible_nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import { groupBy, sortBy } from 'lodash';
import React, { useRef } from 'react';
import useObservable from 'react-use/lib/useObservable';
import * as Rx from 'rxjs';
import { WorkspaceStart } from 'opensearch-dashboards/public';
import { WorkspacesStart } from 'opensearch-dashboards/public';
import { ChromeNavLink, ChromeRecentlyAccessedHistoryItem } from '../..';
import { AppCategory } from '../../../../types';
import { InternalApplicationStart } from '../../../application';
Expand Down Expand Up @@ -132,7 +132,7 @@ interface Props {
navigateToUrl: InternalApplicationStart['navigateToUrl'];
customNavLink$: Rx.Observable<ChromeNavLink | undefined>;
logos: Logos;
workspaces: WorkspaceStart;
workspaces: WorkspacesStart;
}

export function CollapsibleNav({
Expand Down
4 changes: 2 additions & 2 deletions src/core/public/chrome/ui/header/collapsible_nav_header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { i18n } from '@osd/i18n';
import React from 'react';
import useObservable from 'react-use/lib/useObservable';
import { EuiIcon, EuiFlexGroup, EuiFlexItem, EuiText, EuiCollapsibleNavGroup } from '@elastic/eui';
import { WorkspaceStart } from '../../../../public';
import { WorkspacesStart } from '../../../../public';

interface Props {
workspaces: WorkspaceStart;
workspaces: WorkspacesStart;
}

export function CollapsibleNavHeader({ workspaces }: Props) {
Expand Down
4 changes: 2 additions & 2 deletions src/core/public/chrome/ui/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import classnames from 'classnames';
import React, { createRef, useState } from 'react';
import useObservable from 'react-use/lib/useObservable';
import { Observable } from 'rxjs';
import { WorkspaceStart } from 'opensearch-dashboards/public';
import { WorkspacesStart } from 'opensearch-dashboards/public';
import { LoadingIndicator } from '../';
import {
ChromeBadge,
Expand Down Expand Up @@ -94,7 +94,7 @@ export interface HeaderProps {
branding: ChromeBranding;
logos: Logos;
survey: string | undefined;
workspaces: WorkspaceStart;
workspaces: WorkspacesStart;
}

export function Header({
Expand Down
9 changes: 9 additions & 0 deletions src/core/public/core_system.test.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { docLinksServiceMock } from './doc_links/doc_links_service.mock';
import { renderingServiceMock } from './rendering/rendering_service.mock';
import { contextServiceMock } from './context/context_service.mock';
import { integrationsServiceMock } from './integrations/integrations_service.mock';
import { workspacesServiceMock } from './workspace/workspaces_service.mock';
import { coreAppMock } from './core_app/core_app.mock';

export const MockInjectedMetadataService = injectedMetadataServiceMock.create();
Expand Down Expand Up @@ -145,3 +146,11 @@ export const CoreAppConstructor = jest.fn().mockImplementation(() => MockCoreApp
jest.doMock('./core_app', () => ({
CoreApp: CoreAppConstructor,
}));

export const MockWorkspacesService = workspacesServiceMock.create();
export const WorkspacesServiceConstructor = jest
.fn()
.mockImplementation(() => MockWorkspacesService);
jest.doMock('./workspace', () => ({
WorkspacesService: WorkspacesServiceConstructor,
}));
25 changes: 25 additions & 0 deletions src/core/public/core_system.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ import {
MockIntegrationsService,
CoreAppConstructor,
MockCoreApp,
WorkspacesServiceConstructor,
MockWorkspacesService,
} from './core_system.test.mocks';

import { CoreSystem } from './core_system';
Expand Down Expand Up @@ -99,6 +101,7 @@ describe('constructor', () => {
expect(RenderingServiceConstructor).toHaveBeenCalledTimes(1);
expect(IntegrationsServiceConstructor).toHaveBeenCalledTimes(1);
expect(CoreAppConstructor).toHaveBeenCalledTimes(1);
expect(WorkspacesServiceConstructor).toHaveBeenCalledTimes(1);
});

it('passes injectedMetadata param to InjectedMetadataService', () => {
Expand Down Expand Up @@ -223,6 +226,11 @@ describe('#setup()', () => {
expect(MockIntegrationsService.setup).toHaveBeenCalledTimes(1);
});

it('calls workspaces#setup()', async () => {
await setupCore();
expect(MockWorkspacesService.setup).toHaveBeenCalledTimes(1);
});

it('calls coreApp#setup()', async () => {
await setupCore();
expect(MockCoreApp.setup).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -310,6 +318,15 @@ describe('#start()', () => {
expect(MockIntegrationsService.start).toHaveBeenCalledTimes(1);
});

it('calls workspaces#start()', async () => {
await startCore();
expect(MockWorkspacesService.start).toHaveBeenCalledTimes(1);
expect(MockWorkspacesService.start).toHaveBeenCalledWith({
application: expect.any(Object),
http: expect.any(Object),
});
});

it('calls coreApp#start()', async () => {
await startCore();
expect(MockCoreApp.start).toHaveBeenCalledTimes(1);
Expand Down Expand Up @@ -364,6 +381,14 @@ describe('#stop()', () => {
expect(MockIntegrationsService.stop).toHaveBeenCalled();
});

it('calls workspaces.stop()', () => {
const coreSystem = createCoreSystem();

expect(MockWorkspacesService.stop).not.toHaveBeenCalled();
coreSystem.stop();
expect(MockWorkspacesService.stop).toHaveBeenCalled();
});

it('calls coreApp.stop()', () => {
const coreSystem = createCoreSystem();

Expand Down
7 changes: 4 additions & 3 deletions src/core/public/core_system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ import { ContextService } from './context';
import { IntegrationsService } from './integrations';
import { CoreApp } from './core_app';
import type { InternalApplicationSetup, InternalApplicationStart } from './application/types';
import { WorkspaceService } from './workspace';
import { WorkspacesService } from './workspace';

interface Params {
rootDomElement: HTMLElement;
Expand Down Expand Up @@ -111,7 +111,7 @@ export class CoreSystem {

private readonly rootDomElement: HTMLElement;
private readonly coreContext: CoreContext;
private readonly workspaces: WorkspaceService;
private readonly workspaces: WorkspacesService;
private fatalErrorsSetup: FatalErrorsSetup | null = null;

constructor(params: Params) {
Expand Down Expand Up @@ -140,7 +140,7 @@ export class CoreSystem {
this.rendering = new RenderingService();
this.application = new ApplicationService();
this.integrations = new IntegrationsService();
this.workspaces = new WorkspaceService();
this.workspaces = new WorkspacesService();

this.coreContext = { coreId: Symbol('core'), env: injectedMetadata.env };

Expand Down Expand Up @@ -312,6 +312,7 @@ export class CoreSystem {
this.chrome.stop();
this.i18n.stop();
this.application.stop();
this.workspaces.stop();
this.rootDomElement.textContent = '';
}
}
16 changes: 8 additions & 8 deletions src/core/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ import {
HandlerParameters,
} from './context';
import { Branding } from '../types';
import { WorkspaceStart, WorkspaceSetup } from './workspace';
import { WorkspacesStart, WorkspacesSetup } from './workspace';

export type { Logos } from '../common';
export { PackageInfo, EnvironmentMode } from '../server/types';
Expand Down Expand Up @@ -241,8 +241,8 @@ export interface CoreSetup<TPluginsStart extends object = object, TStart = unkno
};
/** {@link StartServicesAccessor} */
getStartServices: StartServicesAccessor<TPluginsStart, TStart>;
/** {@link WorkspaceSetup} */
workspaces: WorkspaceSetup;
/** {@link WorkspacesSetup} */
workspaces: WorkspacesSetup;
}

/**
Expand Down Expand Up @@ -297,8 +297,8 @@ export interface CoreStart {
getInjectedVar: (name: string, defaultValue?: any) => unknown;
getBranding: () => Branding;
};
/** {@link WorkspaceStart} */
workspaces: WorkspaceStart;
/** {@link WorkspacesStart} */
workspaces: WorkspacesStart;
}

export {
Expand Down Expand Up @@ -349,9 +349,9 @@ export {
export { __osdBootstrap__ } from './osd_bootstrap';

export {
WorkspaceStart,
WorkspaceSetup,
WorkspaceService,
WorkspacesStart,
WorkspacesSetup,
WorkspacesService,
WorkspaceObservables,
} from './workspace';

Expand Down
2 changes: 1 addition & 1 deletion src/core/public/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function createCoreSetupMock({
getInjectedVar: injectedMetadataServiceMock.createSetupContract().getInjectedVar,
getBranding: injectedMetadataServiceMock.createSetupContract().getBranding,
},
workspaces: workspacesServiceMock,
workspaces: workspacesServiceMock.createSetupContract(),
};

return mock;
Expand Down
2 changes: 1 addition & 1 deletion src/core/public/plugins/plugins_service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ describe('PluginsService', () => {
injectedMetadata: injectedMetadataServiceMock.createStartContract(),
notifications: notificationServiceMock.createSetupContract(),
uiSettings: uiSettingsServiceMock.createSetupContract(),
workspaces: workspacesServiceMock.createSetupContractMock(),
workspaces: workspacesServiceMock.createSetupContract(),
};
mockSetupContext = {
...mockSetupDeps,
Expand Down
6 changes: 3 additions & 3 deletions src/core/public/workspace/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* SPDX-License-Identifier: Apache-2.0
*/
export {
WorkspaceStart,
WorkspaceService,
WorkspaceSetup,
WorkspacesStart,
WorkspacesService,
WorkspacesSetup,
WorkspaceObservables,
} from './workspaces_service';
13 changes: 12 additions & 1 deletion src/core/public/workspace/workspaces_service.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
*/

import { BehaviorSubject } from 'rxjs';
import type { PublicMethodsOf } from '@osd/utility-types';

import { WorkspacesService } from './workspaces_service';
import { WorkspaceAttribute } from '..';

const currentWorkspaceId$ = new BehaviorSubject<string>('');
Expand All @@ -30,7 +33,15 @@ const createWorkspacesStartContractMock = () => ({
renderWorkspaceMenu: jest.fn(),
});

export type WorkspacesServiceContract = PublicMethodsOf<WorkspacesService>;
const createMock = (): jest.Mocked<WorkspacesServiceContract> => ({
setup: jest.fn().mockReturnValue(createWorkspacesSetupContractMock()),
start: jest.fn().mockReturnValue(createWorkspacesStartContractMock()),
stop: jest.fn(),
});

export const workspacesServiceMock = {
createSetupContractMock: createWorkspacesSetupContractMock,
create: createMock,
createSetupContract: createWorkspacesSetupContractMock,
createStartContract: createWorkspacesStartContractMock,
};
94 changes: 94 additions & 0 deletions src/core/public/workspace/workspaces_service.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { httpServiceMock } from '../http/http_service.mock';
import { applicationServiceMock } from '../application/application_service.mock';
import { WorkspacesService, WorkspacesSetup, WorkspacesStart } from './workspaces_service';

describe('WorkspacesService', () => {
let workspaces: WorkspacesService;
let workspacesSetup: WorkspacesSetup;
let workspacesStart: WorkspacesStart;

beforeEach(() => {
workspaces = new WorkspacesService();
workspacesSetup = workspaces.setup();
workspacesStart = workspaces.start({
http: httpServiceMock.createStartContract(),
application: applicationServiceMock.createInternalStartContract(),
});
});

afterEach(() => {
workspaces.stop();
});

it('workspace initialized$ state is false by default', () => {
expect(workspacesStart.initialized$.value).toBe(false);
});

it('workspace is not enabled by default', () => {
expect(workspacesStart.workspaceEnabled$.value).toBe(false);
});

it('currentWorkspace is not set by default', () => {
expect(workspacesStart.currentWorkspace$.value).toBe(null);
expect(workspacesStart.currentWorkspaceId$.value).toBe('');
});

it('workspaceList$ is empty by default', () => {
expect(workspacesStart.workspaceList$.value.length).toBe(0);
});

it('should call menu render function', () => {
const renderFn = jest.fn();
workspacesSetup.registerWorkspaceMenuRender(renderFn);
workspacesStart.renderWorkspaceMenu();
expect(renderFn).toHaveBeenCalled();
});

it('should return null if NO menu render function was registered', () => {
expect(workspacesStart.renderWorkspaceMenu()).toBe(null);
});

it('the current workspace should also updated after changing current workspace id', () => {
expect(workspacesStart.currentWorkspace$.value).toBe(null);

workspacesStart.initialized$.next(true);
workspacesStart.workspaceList$.next([
{ id: 'workspace-1', name: 'workspace 1' },
{ id: 'workspace-2', name: 'workspace 2' },
]);
workspacesStart.currentWorkspaceId$.next('workspace-1');

expect(workspacesStart.currentWorkspace$.value).toEqual({
id: 'workspace-1',
name: 'workspace 1',
});

workspacesStart.currentWorkspaceId$.next('');
expect(workspacesStart.currentWorkspace$.value).toEqual(null);
});

it('should return error if the specified workspace id cannot be found', () => {
expect(workspacesStart.currentWorkspace$.hasError).toBe(false);
workspacesStart.initialized$.next(true);
workspacesStart.workspaceList$.next([
{ id: 'workspace-1', name: 'workspace 1' },
{ id: 'workspace-2', name: 'workspace 2' },
]);
workspacesStart.currentWorkspaceId$.next('workspace-3');
expect(workspacesStart.currentWorkspace$.hasError).toBe(true);
});

it('should stop all observables when workspace service stopped', () => {
workspaces.stop();
expect(workspacesStart.currentWorkspaceId$.isStopped).toBe(true);
expect(workspacesStart.currentWorkspace$.isStopped).toBe(true);
expect(workspacesStart.workspaceList$.isStopped).toBe(true);
expect(workspacesStart.workspaceEnabled$.isStopped).toBe(true);
expect(workspacesStart.initialized$.isStopped).toBe(true);
});
});
Loading
Loading