Skip to content

Commit

Permalink
Navigation panel editor unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nickpeihl committed Sep 19, 2023
1 parent f987bb8 commit 9ab67b5
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import React from 'react';

import userEvent from '@testing-library/user-event';
import { createEvent, fireEvent, render, screen } from '@testing-library/react';
import { createEvent, fireEvent, render, screen, waitFor } from '@testing-library/react';
import { DEFAULT_DASHBOARD_DRILLDOWN_OPTIONS } from '@kbn/presentation-util-plugin/public';
import { DashboardLinkStrings } from './dashboard_link_strings';
import {
NavigationEmbeddable,
NavigationEmbeddableContext,
Expand All @@ -19,7 +21,6 @@ import { NAV_VERTICAL_LAYOUT } from '../../../common/content_management';
import { DashboardLinkComponent } from './dashboard_link_component';
import { fetchDashboard, getDashboardHref, getDashboardLocator } from './dashboard_link_tools';
import { coreServices } from '../../services/kibana_services';
import { DEFAULT_DASHBOARD_DRILLDOWN_OPTIONS } from '@kbn/presentation-util-plugin/public';

jest.mock('./dashboard_link_tools');

Expand Down Expand Up @@ -82,7 +83,7 @@ describe('Dashboard link component', () => {
</NavigationEmbeddableContext.Provider>
);

expect(fetchDashboard).toHaveBeenCalledTimes(1);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(1));
expect(fetchDashboard).toHaveBeenCalledWith(defaultLinkInfo.destination);
expect(getDashboardLocator).toHaveBeenCalledTimes(1);
expect(getDashboardLocator).toHaveBeenCalledWith({
Expand All @@ -93,7 +94,6 @@ describe('Dashboard link component', () => {
navEmbeddable,
});

expect(screen.getByTestId('dashboardLink--foo--loading')).toBeInTheDocument();
const link = await screen.findByTestId('dashboardLink--foo');
expect(link).toHaveTextContent('another dashboard');
await userEvent.click(link);
Expand All @@ -110,6 +110,7 @@ describe('Dashboard link component', () => {
<DashboardLinkComponent link={defaultLinkInfo} layout={NAV_VERTICAL_LAYOUT} />
</NavigationEmbeddableContext.Provider>
);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(1));
const link = await screen.findByTestId('dashboardLink--foo');
const clickEvent = createEvent.click(link, { ctrlKey: true });
const preventDefault = jest.spyOn(clickEvent, 'preventDefault');
Expand All @@ -127,7 +128,7 @@ describe('Dashboard link component', () => {
<DashboardLinkComponent link={linkInfo} layout={NAV_VERTICAL_LAYOUT} />
</NavigationEmbeddableContext.Provider>
);

await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(1));
expect(fetchDashboard).toHaveBeenCalledWith(linkInfo.destination);
expect(getDashboardLocator).toHaveBeenCalledWith({ link: linkInfo, navEmbeddable });
const link = await screen.findByTestId('dashboardLink--foo');
Expand All @@ -152,6 +153,7 @@ describe('Dashboard link component', () => {
<DashboardLinkComponent link={linkInfo} layout={NAV_VERTICAL_LAYOUT} />
</NavigationEmbeddableContext.Provider>
);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(1));
expect(getDashboardLocator).toHaveBeenCalledWith({ link: linkInfo, navEmbeddable });
});

Expand All @@ -166,8 +168,9 @@ describe('Dashboard link component', () => {
<DashboardLinkComponent link={linkInfo} layout={NAV_VERTICAL_LAYOUT} />
</NavigationEmbeddableContext.Provider>
);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(1));
const link = await screen.findByTestId('dashboardLink--notfound--error');
expect(link).toHaveTextContent('Error fetching dashboard');
expect(link).toHaveTextContent(DashboardLinkStrings.getDashboardErrorLabel());
});

test('current dashboard is not a clickable href', async () => {
Expand All @@ -181,6 +184,7 @@ describe('Dashboard link component', () => {
<DashboardLinkComponent link={linkInfo} layout={NAV_VERTICAL_LAYOUT} />
</NavigationEmbeddableContext.Provider>
);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(1));
const link = await screen.findByTestId('dashboardLink--bar');
expect(link).toHaveTextContent('current dashboard');
await userEvent.click(link);
Expand All @@ -194,6 +198,7 @@ describe('Dashboard link component', () => {
<DashboardLinkComponent link={defaultLinkInfo} layout={NAV_VERTICAL_LAYOUT} />
</NavigationEmbeddableContext.Provider>
);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(1));
const link = await screen.findByTestId('dashboardLink--foo');
await userEvent.hover(link);
const tooltip = await screen.findByTestId('dashboardLink--foo--tooltip');
Expand All @@ -212,6 +217,7 @@ describe('Dashboard link component', () => {
<DashboardLinkComponent link={linkInfo} layout={NAV_VERTICAL_LAYOUT} />
</NavigationEmbeddableContext.Provider>
);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(1));
const link = await screen.findByTestId('dashboardLink--foo');
expect(link).toHaveTextContent(label);
await userEvent.hover(link);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import React from 'react';
import userEvent from '@testing-library/user-event';
import { render, screen, waitFor } from '@testing-library/react';
import NavigationEmbeddablePanelEditor from './navigation_embeddable_panel_editor';
import { NavEmbeddableStrings } from '../navigation_embeddable_strings';
import { NavigationEmbeddableLink, NAV_VERTICAL_LAYOUT } from '../../../common/content_management';
import { fetchDashboard } from '../dashboard_link/dashboard_link_tools';

jest.mock('../dashboard_link/dashboard_link_tools', () => {
return {
fetchDashboard: jest.fn().mockImplementation((id: string) =>
Promise.resolve({
id,
status: 'success',
attributes: {
title: `dashboard #${id}`,
description: '',
panelsJSON: [],
timeRestore: false,
version: '1',
},
references: [],
})
),
};
});

describe('NavigationEmbeddablePanelEditor', () => {
const defaultProps = {
onSaveToLibrary: jest.fn().mockImplementation(() => Promise.resolve()),
onAddToDashboard: jest.fn(),
onClose: jest.fn(),
isByReference: false,
};

const someLinks: NavigationEmbeddableLink[] = [
{
id: 'foo',
type: 'dashboardLink' as const,
order: 1,
destination: '123',
},
{
id: 'bar',
type: 'dashboardLink' as const,
order: 4,
destination: '456',
},
{
id: 'bizz',
type: 'externalLink' as const,
order: 3,
destination: 'http://example.com',
},
{
id: 'buzz',
type: 'externalLink' as const,
order: 2,
destination: 'http://elastic.co',
},
];

afterEach(() => {
jest.clearAllMocks();
});

test('shows empty state with no links', async () => {
render(<NavigationEmbeddablePanelEditor {...defaultProps} />);
expect(screen.getByTestId('navEmbeddable--panelEditor--title')).toHaveTextContent(
NavEmbeddableStrings.editor.panelEditor.getCreateFlyoutTitle()
);
expect(screen.getByTestId('navEmbeddable--panelEditor--emptyPrompt')).toBeInTheDocument();
expect(screen.getByTestId('navEmbeddable--panelEditor--saveBtn')).toBeDisabled();

await userEvent.click(screen.getByTestId('navEmbeddable--panelEditor--closeBtn'));
expect(defaultProps.onClose).toHaveBeenCalledTimes(1);
});

test('shows links in order', async () => {
const expectedLinkIds = [...someLinks].sort((a, b) => a.order - b.order).map(({ id }) => id);
render(<NavigationEmbeddablePanelEditor {...defaultProps} initialLinks={someLinks} />);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(2));
expect(screen.getByTestId('navEmbeddable--panelEditor--title')).toHaveTextContent(
NavEmbeddableStrings.editor.panelEditor.getEditFlyoutTitle()
);
const draggableLinks = screen.getAllByTestId('navEmbeddable--panelEditor--draggableLink');
expect(draggableLinks.length).toEqual(4);

draggableLinks.forEach((link, idx) => {
expect(link).toHaveAttribute('data-rfd-draggable-id', expectedLinkIds[idx]);
});
});

test('saving by reference panels calls onSaveToLibrary', async () => {
const orderedLinks = [...someLinks].sort((a, b) => a.order - b.order);
render(
<NavigationEmbeddablePanelEditor {...defaultProps} initialLinks={someLinks} isByReference />
);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(2));
const saveButton = screen.getByTestId('navEmbeddable--panelEditor--saveBtn');
await userEvent.click(saveButton);
await waitFor(() => expect(defaultProps.onSaveToLibrary).toHaveBeenCalledTimes(1));
expect(defaultProps.onSaveToLibrary).toHaveBeenCalledWith(orderedLinks, NAV_VERTICAL_LAYOUT);
});

test('saving by value panel calls onAddToDashboard', async () => {
const orderedLinks = [...someLinks].sort((a, b) => a.order - b.order);
render(
<NavigationEmbeddablePanelEditor
{...defaultProps}
initialLinks={someLinks}
isByReference={false}
/>
);
await waitFor(() => expect(fetchDashboard).toHaveBeenCalledTimes(2));
const saveButton = screen.getByTestId('navEmbeddable--panelEditor--saveBtn');
await userEvent.click(saveButton);
expect(defaultProps.onAddToDashboard).toHaveBeenCalledTimes(1);
expect(defaultProps.onAddToDashboard).toHaveBeenCalledWith(orderedLinks, NAV_VERTICAL_LAYOUT);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const NavigationEmbeddablePanelEditor = ({
<>
<div ref={editLinkFlyoutRef} />
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<EuiTitle size="m" data-test-subj="navEmbeddable--panelEditor--title">
<h2>
{isEditingExisting
? NavEmbeddableStrings.editor.panelEditor.getEditFlyoutTitle()
Expand Down Expand Up @@ -201,6 +201,7 @@ const NavigationEmbeddablePanelEditor = ({
draggableId={link.id}
customDragHandle={true}
hasInteractiveChildren={true}
data-test-subj={`navEmbeddable--panelEditor--draggableLink`}
>
{(provided) => (
<NavigationEmbeddablePanelEditorLink
Expand Down Expand Up @@ -232,7 +233,12 @@ const NavigationEmbeddablePanelEditor = ({
<EuiFlyoutFooter>
<EuiFlexGroup responsive={false} justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<EuiButtonEmpty onClick={onClose} iconType="cross" flush="left">
<EuiButtonEmpty
onClick={onClose}
iconType="cross"
flush="left"
data-test-subj="navEmbeddable--panelEditor--closeBtn"
>
{NavEmbeddableStrings.editor.getCancelButtonLabel()}
</EuiButtonEmpty>
</EuiFlexItem>
Expand All @@ -243,12 +249,14 @@ const NavigationEmbeddablePanelEditor = ({
<TooltipWrapper
condition={!hasZeroLinks}
tooltipContent={NavEmbeddableStrings.editor.panelEditor.getSaveToLibrarySwitchTooltip()}
data-test-subj="navEmbeddable--panelEditor--saveByReferenceTooltip"
>
<EuiSwitch
label={NavEmbeddableStrings.editor.panelEditor.getSaveToLibrarySwitchLabel()}
checked={saveByReference}
disabled={hasZeroLinks}
onChange={() => setSaveByReference(!saveByReference)}
data-test-subj="navEmbeddable--panelEditor--saveByReferenceSwitch"
/>
</TooltipWrapper>
</EuiFlexItem>
Expand All @@ -257,11 +265,13 @@ const NavigationEmbeddablePanelEditor = ({
<TooltipWrapper
condition={hasZeroLinks}
tooltipContent={NavEmbeddableStrings.editor.panelEditor.getEmptyLinksTooltip()}
data-test-id={'navEmbeddable--panelEditor--saveBtnTooltip'}
>
<EuiButton
fill
isLoading={isSaving}
disabled={hasZeroLinks}
data-test-subj={'navEmbeddable--panelEditor--saveBtn'}
onClick={async () => {
if (saveByReference) {
setIsSaving(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const NavigationEmbeddablePanelEditorEmptyPrompt = ({
addLink: () => Promise<void>;
}) => {
return (
<EuiFormRow>
<EuiFormRow data-test-subj="navEmbeddable--panelEditor--emptyPrompt">
<EuiPanel paddingSize="m" hasBorder={true}>
<EuiEmptyPrompt
color="plain"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export const NavigationEmbeddablePanelEditorLink = ({
hasShadow={false}
color={destinationError ? 'warning' : 'plain'}
className={`navEmbeddableLinkPanel ${destinationError ? 'linkError' : ''}`}
data-test-subj={`panelEditorLink${linkLabelLoading ? '--loading' : ''}`}
>
<EuiFlexGroup gutterSize="s" responsive={false} wrap={false} alignItems="center">
<EuiFlexItem grow={false}>
Expand Down

0 comments on commit 9ab67b5

Please sign in to comment.