[Actionable observability] Add tests for alert search bar (#145259)

Closes https://github.com/elastic/kibana/issues/143641

## Summary

As a follow-up to this PR https://github.com/elastic/kibana/pull/145067,
in this PR I've added tests to make sure the same issue will not happen
in the future.

### Checklist

- [X] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
This commit is contained in:
Maryam Saeidi 2022-11-16 12:34:11 +01:00 committed by GitHub
parent 768d5b8b8c
commit 1566897d39
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 148 additions and 5 deletions

View file

@ -0,0 +1,130 @@
/*
* 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 { triggersActionsUiMock } from '@kbn/triggers-actions-ui-plugin/public/mocks';
import React from 'react';
import { act, waitFor } from '@testing-library/react';
import { AlertSearchBarProps } from './types';
import { ObservabilityAlertSearchBar } from './alert_search_bar';
import { observabilityAlertFeatureIds } from '../../../config';
import { useKibana } from '../../../utils/kibana_react';
import { kibanaStartMock } from '../../../utils/kibana_react.mock';
import { render } from '../../../utils/test_helper';
const useKibanaMock = useKibana as jest.Mock;
const getAlertsSearchBarMock = jest.fn();
const ALERT_SEARCH_BAR_DATA_TEST_SUBJ = 'alerts-search-bar';
const ACTIVE_BUTTON_DATA_TEST_SUBJ = 'alert-status-filter-active-button';
jest.mock('../../../utils/kibana_react');
const mockKibana = () => {
useKibanaMock.mockReturnValue({
services: {
...kibanaStartMock.startContract().services,
triggersActionsUi: {
...triggersActionsUiMock.createStart(),
getAlertsSearchBar: getAlertsSearchBarMock.mockReturnValue(
<div data-test-subj={ALERT_SEARCH_BAR_DATA_TEST_SUBJ} />
),
},
},
});
};
describe('ObservabilityAlertSearchBar', () => {
const renderComponent = (props: Partial<AlertSearchBarProps> = {}) => {
const alertSearchBarProps: AlertSearchBarProps = {
appName: 'testAppName',
rangeFrom: 'now-15m',
setRangeFrom: jest.fn(),
rangeTo: 'now',
setRangeTo: jest.fn(),
kuery: '',
setKuery: jest.fn(),
status: 'active',
setStatus: jest.fn(),
setEsQuery: jest.fn(),
...props,
};
return render(<ObservabilityAlertSearchBar {...alertSearchBarProps} />);
};
beforeAll(() => {
mockKibana();
});
beforeEach(() => {
jest.clearAllMocks();
});
it('should render alert search bar', async () => {
const observabilitySearchBar = renderComponent();
await waitFor(() =>
expect(observabilitySearchBar.queryByTestId(ALERT_SEARCH_BAR_DATA_TEST_SUBJ)).toBeTruthy()
);
});
it('should call alert search bar with correct props', () => {
act(() => {
renderComponent();
});
expect(getAlertsSearchBarMock).toHaveBeenCalledWith(
expect.objectContaining({
appName: 'testAppName',
featureIds: observabilityAlertFeatureIds,
rangeFrom: 'now-15m',
rangeTo: 'now',
query: '',
}),
{}
);
});
it('should filter active alerts', async () => {
const mockedSetEsQuery = jest.fn();
const mockedFrom = '2022-11-15T09:38:13.604Z';
const mockedTo = '2022-11-15T09:53:13.604Z';
const { getByTestId } = renderComponent({
setEsQuery: mockedSetEsQuery,
rangeFrom: mockedFrom,
rangeTo: mockedTo,
});
await act(async () => {
const activeButton = getByTestId(ACTIVE_BUTTON_DATA_TEST_SUBJ);
activeButton.click();
});
expect(mockedSetEsQuery).toHaveBeenCalledWith({
bool: {
filter: [
{
bool: {
minimum_should_match: 1,
should: [{ match_phrase: { 'kibana.alert.status': 'active' } }],
},
},
{
range: {
'@timestamp': expect.objectContaining({
format: 'strict_date_optional_time',
gte: mockedFrom,
lte: mockedTo,
}),
},
},
],
must: [],
must_not: [],
should: [],
},
});
});
});

View file

@ -10,7 +10,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React, { useCallback, useEffect } from 'react';
import { i18n } from '@kbn/i18n';
import { Query } from '@kbn/es-query';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { useKibana } from '../../../utils/kibana_react';
import { observabilityAlertFeatureIds } from '../../../config';
import { ObservabilityAppServices } from '../../../application/types';
import { AlertsStatusFilter } from './components';

View file

@ -21,10 +21,10 @@ interface AlertSearchBarContainerState {
}
interface AlertSearchBarStateTransitions {
setRangeFrom: (rangeFrom: string) => AlertSearchBarContainerState;
setRangeTo: (rangeTo: string) => AlertSearchBarContainerState;
setKuery: (kuery: string) => AlertSearchBarContainerState;
setStatus: (status: AlertStatus) => AlertSearchBarContainerState;
setRangeFrom: (rangeFrom: string) => void;
setRangeTo: (rangeTo: string) => void;
setKuery: (kuery: string) => void;
setStatus: (status: AlertStatus) => void;
}
export interface CommonAlertSearchBarProps {

View file

@ -27,6 +27,7 @@ const triggersActionsUiStartMock = {
createStart() {
return {
getAddAlertFlyout: jest.fn(),
getAlertsSearchBar: jest.fn(),
getRuleStatusDropdown: jest.fn(),
getRuleTagBadge: jest.fn(),
getRuleStatusFilter: jest.fn(),
@ -54,6 +55,11 @@ const data = {
dataViews: {
create: jest.fn(),
},
query: {
timefilter: {
timefilter: jest.fn(),
},
},
};
},
};

View file

@ -85,6 +85,13 @@ export default ({ getService }: FtrProviderContext) => {
await testSubjects.existOrFail('autocompleteSuggestion-field-kibana.alert.status-');
});
it('Invalid input should not break the page', async () => {
await observability.alerts.common.submitQuery('""""');
await testSubjects.existOrFail('errorToastMessage');
// Page should not go blank with invalid input
await testSubjects.existOrFail('alertsPageWithData');
});
it('Applies filters correctly', async () => {
await observability.alerts.common.submitQuery('kibana.alert.status: recovered');
await retry.try(async () => {