Skip to content

Commit

Permalink
[Uptime] Edit uptime alerts (#68005)
Browse files Browse the repository at this point in the history
* Extract store creation to plugin start, add redux providers to alert registration.

* Update unit test.

* Move alert registration to `setup` function.

* Allow external editing of uptime client alert types.

* Move alert initialization back to `start`.

* Clean up interfaces for alert types.

* Add code that will work for settings link even outside uptime app.

* Create new atomic params type for status alerts.

* Update executor params typing to support both alert params types.

* Update snapshot for alert factory function.

* Fix broken types and refresh snapshots.

* Allow edits of filters for monitor alerts.

* Support default parameter value for numTimes.

* Support default parameter values for timerange.

* Modify kuery bar to work for alert edits, fix some filter issues.

* Clean up tests and fix types.

* Fix types and add a test.

* Add callout and validation handling for old alerts while editing.

* Add a test for updated validation function.

* Define window for overview filters fetch action.

* Revert store initialization.

* Make monitor counter function while editing alerts.

* Refresh snapshot.

* Move snapshot count in monitor status alert to callout.

* Add new state for selected filters.

* Add basic functional tests for uptime alert flyouts.

* Fix broken types.

* Update unit tests with mock provider.

* Remove unneeded params from hook.

* Add more unit tests.

* Reducing functional test flakiness.

* Alert flyout controls update url only within Uptime app.

* Extract context interaction to container component, update snapshots.

* Add missing parameter to test file.

* Remove flaky functional test.

Co-authored-by: Elastic Machine <[email protected]>
Co-authored-by: Shahzad <[email protected]>
  • Loading branch information
3 people authored Jun 8, 2020
1 parent 891342a commit 858523e
Show file tree
Hide file tree
Showing 48 changed files with 1,518 additions and 383 deletions.
32 changes: 29 additions & 3 deletions x-pack/plugins/uptime/public/apps/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import {
CoreSetup,
CoreStart,
Expand All @@ -16,8 +17,16 @@ import { PLUGIN } from '../../common/constants';
import { FeatureCatalogueCategory } from '../../../../../src/plugins/home/public';
import { HomePublicPluginSetup } from '../../../../../src/plugins/home/public';
import { EmbeddableStart } from '../../../../../src/plugins/embeddable/public';
import { TriggersAndActionsUIPublicPluginSetup } from '../../../triggers_actions_ui/public';
import { DataPublicPluginSetup } from '../../../../../src/plugins/data/public';
import {
TriggersAndActionsUIPublicPluginSetup,
TriggersAndActionsUIPublicPluginStart,
} from '../../../triggers_actions_ui/public';
import {
DataPublicPluginSetup,
DataPublicPluginStart,
} from '../../../../../src/plugins/data/public';
import { alertTypeInitializers } from '../lib/alert_types';
import { kibanaService } from '../state/kibana_service';

export interface ClientPluginsSetup {
data: DataPublicPluginSetup;
Expand All @@ -27,6 +36,8 @@ export interface ClientPluginsSetup {

export interface ClientPluginsStart {
embeddable: EmbeddableStart;
data: DataPublicPluginStart;
triggers_actions_ui: TriggersAndActionsUIPublicPluginStart;
}

export type ClientSetup = void;
Expand Down Expand Up @@ -66,6 +77,7 @@ export class UptimePlugin
);

const { element } = params;

const libs: UMFrontendLibs = {
framework: getKibanaFrameworkAdapter(coreStart, plugins, corePlugins),
};
Expand All @@ -74,7 +86,21 @@ export class UptimePlugin
});
}

public start(_start: CoreStart, _plugins: {}): void {}
public start(start: CoreStart, plugins: ClientPluginsStart): void {
kibanaService.core = start;
alertTypeInitializers.forEach((init) => {
const alertInitializer = init({
core: start,
plugins,
});
if (
plugins.triggers_actions_ui &&
!plugins.triggers_actions_ui.alertTypeRegistry.has(alertInitializer.id)
) {
plugins.triggers_actions_ui.alertTypeRegistry.register(alertInitializer);
}
});
}

public stop(): void {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import React from 'react';
import { UptimeDatePicker } from '../uptime_date_picker';
import { renderWithRouter, shallowWithRouter } from '../../../lib';
import { renderWithRouter, shallowWithRouter, MountWithReduxProvider } from '../../../lib';

describe('UptimeDatePicker component', () => {
it('validates props with shallow render', () => {
Expand All @@ -15,7 +15,11 @@ describe('UptimeDatePicker component', () => {
});

it('renders properly with mock data', () => {
const component = renderWithRouter(<UptimeDatePicker />);
const component = renderWithRouter(
<MountWithReduxProvider>
<UptimeDatePicker />
</MountWithReduxProvider>
);
expect(component).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import React from 'react';
import { MonitorBarSeries, MonitorBarSeriesProps } from '../monitor_bar_series';
import { renderWithRouter, shallowWithRouter } from '../../../../lib';
import { renderWithRouter, shallowWithRouter, MountWithReduxProvider } from '../../../../lib';
import { HistogramPoint } from '../../../../../common/runtime_types';

describe('MonitorBarSeries component', () => {
Expand Down Expand Up @@ -197,7 +197,11 @@ describe('MonitorBarSeries component', () => {
});

it('renders if the data series is present', () => {
const component = renderWithRouter(<MonitorBarSeries histogramSeries={histogramSeries} />);
const component = renderWithRouter(
<MountWithReduxProvider>
<MonitorBarSeries histogramSeries={histogramSeries} />
</MountWithReduxProvider>
);
expect(component).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import React from 'react';
import { PingHistogramComponent, PingHistogramComponentProps } from '../ping_histogram';
import { renderWithRouter, shallowWithRouter } from '../../../../lib';
import { renderWithRouter, shallowWithRouter, MountWithReduxProvider } from '../../../../lib';

describe('PingHistogram component', () => {
const props: PingHistogramComponentProps = {
Expand Down Expand Up @@ -49,7 +49,12 @@ describe('PingHistogram component', () => {
});

it('renders the component without errors', () => {
const component = renderWithRouter(<PingHistogramComponent {...props} />);
const component = renderWithRouter(
<MountWithReduxProvider>
<PingHistogramComponent {...props} />
</MountWithReduxProvider>
);

expect(component).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
import { AddFilterButton } from '../add_filter_btn';
import { EuiButtonEmpty, EuiContextMenuItem } from '@elastic/eui';

describe('AddFilterButton component', () => {
it('provides all filter choices', () => {
const component = shallowWithIntl(
<AddFilterButton newFilters={[]} onNewFilter={jest.fn()} alertFilters={{}} />
);
expect(component).toMatchInlineSnapshot(`
<EuiPopover
anchorPosition="downLeft"
button={
<EuiButtonEmpty
data-test-subj="uptimeCreateAlertAddFilter"
disabled={false}
iconType="plusInCircleFilled"
onClick={[Function]}
>
Add filter
</EuiButtonEmpty>
}
closePopover={[Function]}
display="inlineBlock"
hasArrow={true}
id="singlePanel"
isOpen={false}
ownFocus={false}
panelPaddingSize="none"
>
<EuiContextMenuPanel
hasFocus={true}
items={
Array [
<EuiContextMenuItem
data-test-subj="uptimeAlertAddFilter.observer.geo.name"
onClick={[Function]}
>
Location
</EuiContextMenuItem>,
<EuiContextMenuItem
data-test-subj="uptimeAlertAddFilter.tags"
onClick={[Function]}
>
Tag
</EuiContextMenuItem>,
<EuiContextMenuItem
data-test-subj="uptimeAlertAddFilter.url.port"
onClick={[Function]}
>
Port
</EuiContextMenuItem>,
<EuiContextMenuItem
data-test-subj="uptimeAlertAddFilter.monitor.type"
onClick={[Function]}
>
Type
</EuiContextMenuItem>,
]
}
/>
</EuiPopover>
`);
});

it('excludes filters that already have selected values', () => {
const component = shallowWithIntl(
<AddFilterButton
newFilters={['observer.geo.name', 'tags']}
alertFilters={{ 'url.port': ['443', '80'] }}
onNewFilter={jest.fn()}
/>
);
expect(component).toMatchInlineSnapshot(`
<EuiPopover
anchorPosition="downLeft"
button={
<EuiButtonEmpty
data-test-subj="uptimeCreateAlertAddFilter"
disabled={false}
iconType="plusInCircleFilled"
onClick={[Function]}
>
Add filter
</EuiButtonEmpty>
}
closePopover={[Function]}
display="inlineBlock"
hasArrow={true}
id="singlePanel"
isOpen={false}
ownFocus={false}
panelPaddingSize="none"
>
<EuiContextMenuPanel
hasFocus={true}
items={
Array [
<EuiContextMenuItem
data-test-subj="uptimeAlertAddFilter.monitor.type"
onClick={[Function]}
>
Type
</EuiContextMenuItem>,
]
}
/>
</EuiPopover>
`);
});

it('popover is disabled if no values are available', () => {
const component = shallowWithIntl(
<AddFilterButton
newFilters={[]}
alertFilters={{
'observer.geo.name': ['fairbanks'],
tags: ['foo'],
'url.port': ['80'],
'monitor.type': ['http'],
}}
onNewFilter={jest.fn()}
/>
);
expect(component).toMatchInlineSnapshot(`
<EuiPopover
anchorPosition="downLeft"
button={
<EuiButtonEmpty
data-test-subj="uptimeCreateAlertAddFilter"
disabled={true}
iconType="plusInCircleFilled"
onClick={[Function]}
>
Add filter
</EuiButtonEmpty>
}
closePopover={[Function]}
display="inlineBlock"
hasArrow={true}
id="singlePanel"
isOpen={false}
ownFocus={false}
panelPaddingSize="none"
>
<EuiContextMenuPanel
hasFocus={true}
items={Array []}
/>
</EuiPopover>
`);
});

it('filter select', () => {
const mockOnNewFilter = jest.fn();
const component = mountWithIntl(
<AddFilterButton newFilters={[]} alertFilters={{}} onNewFilter={mockOnNewFilter} />
);
component.find(EuiButtonEmpty).simulate('click', { target: { value: '0' } });
component
.find(EuiContextMenuItem)
.first()
.simulate('click', { target: { value: '0' } });
expect(mockOnNewFilter).toHaveBeenCalled();
expect(mockOnNewFilter.mock.calls).toMatchInlineSnapshot(`
Array [
Array [
"observer.geo.name",
],
]
`);
});
});
Loading

0 comments on commit 858523e

Please sign in to comment.