Skip to content

Commit

Permalink
[Alerting] Edit alert should show and update all actions with deleted…
Browse files Browse the repository at this point in the history
… connectors (#86838)

* Showing all broken connectors and updating all matching broken connectors on new connector create

* Adding unit test

* Adding functional test

* Fixing functional test

* Simplifying logic

* Fixing functional test

* Fixing functional test

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
ymao1 and kibanamachine authored Jan 6, 2021
1 parent 63f7105 commit ff2d0f4
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
import React, { Fragment, lazy } from 'react';
import { mountWithIntl, nextTick } from '@kbn/test/jest';
import { EuiAccordion } from '@elastic/eui';
import { coreMock } from '../../../../../../../src/core/public/mocks';
import { act } from 'react-dom/test-utils';
import { actionTypeRegistryMock } from '../../action_type_registry.mock';
Expand Down Expand Up @@ -521,7 +522,7 @@ describe('action_form', () => {
});

it('recognizes actions with broken connectors', async () => {
await setup([
const wrapper = await setup([
{
group: 'default',
id: 'test',
Expand All @@ -538,8 +539,18 @@ describe('action_form', () => {
message: 'broken',
},
},
{
group: 'not the default',
id: 'connector-doesnt-exist',
actionTypeId: actionType.id,
params: {
message: 'broken',
},
},
]);
expect(setHasActionsWithBrokenConnector).toHaveBeenLastCalledWith(true);
expect(wrapper.find(EuiAccordion)).toHaveLength(3);
expect(wrapper.find(`div[data-test-subj="alertActionAccordionCallout"]`)).toHaveLength(2);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export interface ActionAccordionFormProps {

interface ActiveActionConnectorState {
actionTypeId: string;
index: number;
indices: number[];
}

export const ActionForm = ({
Expand Down Expand Up @@ -307,7 +307,6 @@ export const ActionForm = ({
index={index}
key={`action-form-action-at-${index}`}
actionTypeRegistry={actionTypeRegistry}
defaultActionGroupId={defaultActionGroupId}
emptyActionsIds={emptyActionsIds}
onDeleteConnector={() => {
const updatedActions = actions.filter(
Expand All @@ -321,7 +320,14 @@ export const ActionForm = ({
setActiveActionItem(undefined);
}}
onAddConnector={() => {
setActiveActionItem({ actionTypeId: actionItem.actionTypeId, index });
setActiveActionItem({
actionTypeId: actionItem.actionTypeId,
indices: actions
.map((item: AlertAction, idx: number) =>
item.id === actionItem.id ? idx : -1
)
.filter((idx: number) => idx >= 0),
});
setAddModalVisibility(true);
}}
/>
Expand Down Expand Up @@ -350,7 +356,7 @@ export const ActionForm = ({
isActionGroupDisabledForActionType={isActionGroupDisabledForActionType}
setActionGroupIdByIndex={setActionGroupIdByIndex}
onAddConnector={() => {
setActiveActionItem({ actionTypeId: actionItem.actionTypeId, index });
setActiveActionItem({ actionTypeId: actionItem.actionTypeId, indices: [index] });
setAddModalVisibility(true);
}}
onConnectorSelected={(id: string) => {
Expand Down Expand Up @@ -437,12 +443,12 @@ export const ActionForm = ({
)}
{actionTypesIndex && activeActionItem && addModalVisible ? (
<ConnectorAddModal
key={activeActionItem.index}
actionType={actionTypesIndex[activeActionItem.actionTypeId]}
onClose={closeAddConnectorModal}
postSaveEventHandler={(savedAction: ActionConnector) => {
connectors.push(savedAction);
setActionIdByIndex(savedAction.id, activeActionItem.index);
const indicesToUpdate = activeActionItem.indices || [];
indicesToUpdate.forEach((index: number) => setActionIdByIndex(savedAction.id, index));
}}
actionTypeRegistry={actionTypeRegistry}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type AddConnectorInFormProps = {
onAddConnector: () => void;
onDeleteConnector: () => void;
emptyActionsIds: string[];
} & Pick<ActionAccordionFormProps, 'actionTypeRegistry' | 'defaultActionGroupId'>;
} & Pick<ActionAccordionFormProps, 'actionTypeRegistry'>;

export const AddConnectorInline = ({
actionTypesIndex,
Expand All @@ -41,7 +41,6 @@ export const AddConnectorInline = ({
onDeleteConnector,
actionTypeRegistry,
emptyActionsIds,
defaultActionGroupId,
}: AddConnectorInFormProps) => {
const {
application: { capabilities },
Expand All @@ -52,7 +51,6 @@ export const AddConnectorInline = ({
? actionTypesIndex[actionItem.actionTypeId].name
: actionItem.actionTypeId;
const actionTypeRegistered = actionTypeRegistry.get(actionItem.actionTypeId);
if (!actionTypeRegistered || actionItem.group !== defaultActionGroupId) return null;

const noConnectorsLabel = (
<FormattedMessage
Expand Down Expand Up @@ -114,6 +112,7 @@ export const AddConnectorInline = ({
noConnectorsLabel
) : (
<EuiCallOut
data-test-subj="alertActionAccordionCallout"
title={i18n.translate(
'xpack.triggersActionsUI.sections.alertForm.unableToLoadConnectorTitle',
{
Expand All @@ -129,7 +128,7 @@ export const AddConnectorInline = ({
color="primary"
fill
size="s"
data-test-subj="createActionConnectorButton"
data-test-subj={`createActionConnectorButton-${index}`}
onClick={onAddConnector}
>
<FormattedMessage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export const ConnectorAddModal = ({

return (
<EuiOverlayMask className="actConnectorModal">
<EuiModal onClose={closeModal}>
<EuiModal data-test-subj="connectorAddModal" onClose={closeModal}>
<EuiModalHeader>
<EuiModalHeaderTitle>
<EuiFlexGroup gutterSize="m" alignItems="center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,17 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const objectRemover = new ObjectRemover(supertest);

async function createAction(overwrites: Record<string, any> = {}) {
async function createActionManualCleanup(overwrites: Record<string, any> = {}) {
const { body: createdAction } = await supertest
.post(`/api/actions/action`)
.set('kbn-xsrf', 'foo')
.send(getTestActionData(overwrites))
.expect(200);
return createdAction;
}

async function createAction(overwrites: Record<string, any> = {}) {
const createdAction = await createActionManualCleanup(overwrites);
objectRemover.add(createdAction.id, 'action', 'actions');
return createdAction;
}
Expand Down Expand Up @@ -303,6 +308,78 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
});
});

describe('Edit alert with deleted connector', function () {
const testRunUuid = uuid.v4();

after(async () => {
await objectRemover.removeAll();
});

it('should show and update deleted connectors', async () => {
const action = await createActionManualCleanup({
name: `slack-${testRunUuid}-${0}`,
});

await pageObjects.common.navigateToApp('triggersActions');
const alert = await createAlwaysFiringAlert({
name: testRunUuid,
actions: [
{
group: 'default',
id: action.id,
params: { level: 'info', message: ' {{context.message}}' },
},
{
group: 'other',
id: action.id,
params: { level: 'info', message: ' {{context.message}}' },
},
],
});

// refresh to see alert
await browser.refresh();
await pageObjects.header.waitUntilLoadingHasFinished();

// verify content
await testSubjects.existOrFail('alertsList');

// delete connector
await pageObjects.triggersActionsUI.changeTabs('connectorsTab');
await pageObjects.triggersActionsUI.searchConnectors(action.name);
await testSubjects.click('deleteConnector');
await testSubjects.existOrFail('deleteIdsConfirmation');
await testSubjects.click('deleteIdsConfirmation > confirmModalConfirmButton');
await testSubjects.missingOrFail('deleteIdsConfirmation');

const toastTitle = await pageObjects.common.closeToast();
expect(toastTitle).to.eql('Deleted 1 connector');

// click on first alert
await pageObjects.triggersActionsUI.changeTabs('alertsTab');
await pageObjects.triggersActionsUI.clickOnAlertInAlertsList(alert.name);

const editButton = await testSubjects.find('openEditAlertFlyoutButton');
await editButton.click();
expect(await testSubjects.exists('hasActionsDisabled')).to.eql(false);

expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).to.eql(false);
expect(await testSubjects.exists('alertActionAccordion-0')).to.eql(true);
expect(await testSubjects.exists('addNewActionConnectorActionGroup-1')).to.eql(false);
expect(await testSubjects.exists('alertActionAccordion-1')).to.eql(true);

await testSubjects.click('createActionConnectorButton-0');
await testSubjects.existOrFail('connectorAddModal');
await testSubjects.setValue('nameInput', 'new connector');
await testSubjects.setValue('slackWebhookUrlInput', 'https://test');
await testSubjects.click('connectorAddModal > saveActionButtonModal');
await testSubjects.missingOrFail('deleteIdsConfirmation');

expect(await testSubjects.exists('addNewActionConnectorActionGroup-0')).to.eql(true);
expect(await testSubjects.exists('addNewActionConnectorActionGroup-1')).to.eql(true);
});
});

describe('View In App', function () {
const alertName = uuid.v4();

Expand Down

0 comments on commit ff2d0f4

Please sign in to comment.