[Infrastructure UI] Flyout metadata tests (#153683)

## Summary

Related to #150893

This PR adds tests for the flyout feature. Most of the changes are
adding test ids and helpers and the actual tests you can see in
[metadata.test.tsx](https://github.com/elastic/kibana/pull/153581/files#diff-c7a7e518f3cd536c1f63e64dfce04673790b7c4b80f78a60a6934dd14bbf402b)
and [hosts view functional
test](https://github.com/elastic/kibana/pull/153581/files#diff-cdf2ef63d7f0db051d569b09fbd2ba39eb852d3d75bf3b29d85e57de2da3af35R178)

### Functional Test 
Added a check for open/close of the flyout and metadata tab title
visibility - this can be expanded when the filtering functionality is
added

### Component Test
As we have many cases based on the metadata response I added a separate
test for the `metadata` component. Usually, we don't have this approach
but some cases like the error/no data case are hard to cover only with a
functional test.
This commit is contained in:
jennypavlova 2023-03-27 12:07:22 +02:00 committed by GitHub
parent f8cdb00fee
commit d06d2a3bc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 156 additions and 5 deletions

View file

@ -0,0 +1,121 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import React from 'react';
import { Metadata, TabProps } from './metadata';
import { useMetadata } from '../../../../metric_detail/hooks/use_metadata';
import { useSourceContext } from '../../../../../../containers/metrics_source';
import { render } from '@testing-library/react';
import { I18nProvider } from '@kbn/i18n-react';
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
jest.mock('../../../../../../containers/metrics_source');
jest.mock('../../../../metric_detail/hooks/use_metadata');
const metadataProps: TabProps = {
currentTimeRange: {
from: 1679316685686,
to: 1679585836087,
interval: '1m',
},
node: {
uuid: 'b9c06da0-b9b0-4c7e-830c-05128cb34396',
name: 'host-1',
os: 'iOS',
title: {
name: 'host-1',
cloudProvider: 'gcp',
},
rx: {
name: 'rx',
value: 0,
max: 0,
avg: 0,
},
tx: {
name: 'tx',
value: 0,
max: 0,
avg: 0,
},
memory: {
name: 'memory',
value: 0.5445920331099282,
max: 0.5445920331099282,
avg: 0.5445920331099282,
},
cpu: {
name: 'cpu',
value: 0.2000718443867342,
max: 0.2000718443867342,
avg: 0.2000718443867342,
},
diskLatency: {
name: 'diskLatency',
value: null,
max: 0,
avg: 0,
},
memoryTotal: {
name: 'memoryTotal',
value: 16777216,
max: 16777216,
avg: 16777216,
},
},
};
const renderHostMetadata = () =>
render(
<I18nProvider>
<Metadata {...metadataProps} />
</I18nProvider>,
{ wrapper: EuiThemeProvider }
);
describe('Single Host Metadata (Hosts View)', () => {
const mockUseMetadata = (props: any = {}) => {
const data = {
...props.data,
};
(useMetadata as jest.Mock).mockReturnValue({
...props,
data,
});
};
beforeAll(() => {
(useSourceContext as jest.Mock).mockReturnValue({ sourceId: '123' });
mockUseMetadata();
});
beforeEach(() => {
jest.clearAllMocks();
});
it('should show an error if fetching the metadata returns error', async () => {
mockUseMetadata({ error: 'Internal server error' });
const result = renderHostMetadata();
expect(result.queryByTestId('infraMetadataErrorCallout')).toBeInTheDocument();
});
it('should show an no data message if fetching the metadata returns an empty array', async () => {
mockUseMetadata({ metadata: [] });
const result = renderHostMetadata();
expect(result.queryByTestId('infraMetadataNoData')).toBeInTheDocument();
});
it('should return spinner if loading', async () => {
mockUseMetadata({ loading: true });
const result = renderHostMetadata();
expect(result.queryByTestId('infraHostMetadataLoading')).toBeInTheDocument();
});
});

View file

@ -26,7 +26,7 @@ export interface TabProps {
node: HostNodeRow;
}
const Metadata = ({ node, currentTimeRange }: TabProps) => {
export const Metadata = ({ node, currentTimeRange }: TabProps) => {
const nodeId = node.name;
const inventoryModel = findInventoryModel(NODE_TYPE);
const { sourceId } = useSourceContext();
@ -50,6 +50,7 @@ const Metadata = ({ node, currentTimeRange }: TabProps) => {
})}
color="danger"
iconType="error"
data-test-subj="infraMetadataErrorCallout"
>
<FormattedMessage
id="xpack.infra.hostsViewPage.hostDetail.metadata.errorMessage"
@ -57,7 +58,7 @@ const Metadata = ({ node, currentTimeRange }: TabProps) => {
values={{
reload: (
<EuiLink
data-test-subj="infraMetadataThisLinkCanHelpLink"
data-test-subj="infraMetadataReloadPageLink"
onClick={() => window.location.reload()}
>
{i18n.translate('xpack.infra.hostsViewPage.hostDetail.metadata.errorAction', {
@ -75,6 +76,7 @@ const Metadata = ({ node, currentTimeRange }: TabProps) => {
<Table rows={fields} />
) : (
<EuiCallOut
data-test-subj="infraMetadataNoData"
title={i18n.translate('xpack.infra.hostsViewPage.hostDetail.metadata.noMetadataFound', {
defaultMessage: 'Sorry, there is no metadata related to this host.',
})}
@ -96,7 +98,7 @@ const LoadingPlaceholder = () => {
justifyContent: 'center',
}}
>
<EuiLoadingChart size="xl" />
<EuiLoadingChart data-test-subj="infraHostMetadataLoading" size="xl" />
</div>
);
};
@ -107,4 +109,5 @@ export const MetadataTab = {
defaultMessage: 'Metadata',
}),
content: Metadata,
'data-test-subj': 'hostsView-flyout-tabs-metadata',
};

View file

@ -8,8 +8,8 @@
import { EuiText, EuiFlexGroup, EuiFlexItem, EuiLink, EuiBasicTable } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useMemo } from 'react';
import useToggle from 'react-use/lib/useToggle';
import { FormattedMessage } from '@kbn/i18n-react';
import useToggle from 'react-use/lib/useToggle';
interface Row {
name: string;
@ -53,7 +53,15 @@ export const Table = (props: Props) => {
[]
);
return <EuiBasicTable tableLayout={'fixed'} responsive={false} columns={columns} items={rows} />;
return (
<EuiBasicTable
data-test-subj="infraMetadataTable"
tableLayout={'fixed'}
responsive={false}
columns={columns}
items={rows}
/>
);
};
interface ExpandableContentProps {

View file

@ -20,6 +20,14 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) {
return await testSubjects.click('inventory-hostsView-link-badge');
},
async clickTableOpenFlyoutButton() {
return await testSubjects.click('hostsView-flyout-button');
},
async clickCloseFlyoutButton() {
return await testSubjects.click('euiFlyoutCloseButton');
},
async getHostsLandingPageDisabled() {
const container = await testSubjects.find('hostView-no-enable-access');
const containerText = await container.getVisibleText();
@ -90,6 +98,17 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) {
return testSubjects.existOrFail('embeddablePanelAction-openInLens');
},
// Flyout Tabs
getMetadataTab() {
return testSubjects.find('hostsView-flyout-tabs-metadata');
},
async getMetadataTabName() {
const tabElement = await this.getMetadataTab();
const tabTitle = await tabElement.findByClassName('euiTab__content');
return await tabTitle.getVisibleText();
},
// Alerts Tab
getAlertsTab() {
return testSubjects.find('hostsView-tabs-alerts');