Skip to content

Commit

Permalink
use suspendedComponentWithProps when iconClass is a react component a…
Browse files Browse the repository at this point in the history
…nd write some tests
  • Loading branch information
mgiota committed May 18, 2022
1 parent 292a67b commit 8b6c669
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ const triggersActionsUiStartMock = {
get: jest.fn(),
list: jest.fn(),
},
actionTypeRegistry: {
has: jest.fn((x) => true),
register: jest.fn(),
get: jest.fn(),
list: jest.fn(),
},
};
},
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* 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 { ReactWrapper, mount } from 'enzyme';
import { Actions } from './actions';
import { observabilityPublicPluginsStartMock } from '../../../observability_public_plugins_start.mock';
import { kibanaStartMock } from '../../../utils/kibana_react.mock';

const mockUseKibanaReturnValue = kibanaStartMock.startContract();

jest.mock('../../../utils/kibana_react', () => ({
__esModule: true,
useKibana: jest.fn(() => mockUseKibanaReturnValue),
}));

jest.mock('../../../hooks/use_fetch_rule_actions', () => ({
useFetchRuleActions: jest.fn(),
}));

const { useFetchRuleActions } = jest.requireMock('../../../hooks/use_fetch_rule_actions');

describe('Actions', () => {
let wrapper: ReactWrapper<any>;
async function setup() {
const ruleActions = [
{
id: 1,
group: 'metrics.inventory_threshold.fired',
actionTypeId: '.server-log',
},
{
id: 2,
group: 'metrics.inventory_threshold.fired',
actionTypeId: '.slack',
},
];
const allActions = [
{
id: 1,
name: 'Server log',
actionTypeId: '.server-log',
},
{
id: 2,
name: 'Slack',
actionTypeId: '.slack',
},
{
id: 3,
name: 'Email',
actionTypeId: '.email',
},
];
useFetchRuleActions.mockReturnValue({
allActions,
});

const actionTypeRegistryMock =
observabilityPublicPluginsStartMock.createStart().triggersActionsUi.actionTypeRegistry;
actionTypeRegistryMock.list.mockReturnValue([
{ id: '.server-log', iconClass: 'logsApp' },
{ id: '.slack', iconClass: 'logoSlack' },
{ id: '.email', iconClass: 'email' },
{ id: '.index', iconClass: 'indexOpen' },
]);
wrapper = mount(
<Actions ruleActions={ruleActions} actionTypeRegistry={actionTypeRegistryMock} />
);
}

it("renders action connector icons for user's selected rule actions", async () => {
await setup();
wrapper.debug();
expect(wrapper.find('[data-euiicon-type]').length).toBe(2);
expect(wrapper.find('[data-euiicon-type="logsApp"]').length).toBe(1);
expect(wrapper.find('[data-euiicon-type="logoSlack"]').length).toBe(1);
expect(wrapper.find('[data-euiicon-type="index"]').length).toBe(0);
expect(wrapper.find('[data-euiicon-type="email"]').length).toBe(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import {
EuiLoadingSpinner,
} from '@elastic/eui';
import { intersectionBy } from 'lodash';
import { suspendedComponentWithProps } from '@kbn/triggers-actions-ui-plugin/public';
import { ActionsProps } from '../types';
import { useFetchRuleActions } from '../../../hooks/use_fetch_rule_actions';
import { useKibana } from '../../../utils/kibana_react';

export function Actions({ ruleActions, actionTypeRegistry }: ActionsProps) {
const {
http,
Expand All @@ -28,29 +30,29 @@ export function Actions({ ruleActions, actionTypeRegistry }: ActionsProps) {

function getActionIconClass(actionGroupId?: string): IconType | undefined {
const actionGroup = actionTypeRegistry.list().find((group) => group.id === actionGroupId);
return actionGroup?.iconClass;
return typeof actionGroup?.iconClass === 'string'
? actionGroup?.iconClass
: suspendedComponentWithProps(actionGroup?.iconClass as React.ComponentType);
}
const actions = intersectionBy(allActions, ruleActions, 'actionTypeId');
if (isLoadingActions) return <EuiLoadingSpinner size="s" />;
return (
<EuiFlexGroup direction="column">
{actions.map((actionType) => {
const actionTypeId = actionType.actionTypeId;
return (
<>
<EuiFlexGroup alignItems="flexStart">
<EuiFlexItem grow={false}>
<EuiIcon size="l" type={getActionIconClass(actionType.actionTypeId) ?? 'apps'} />
</EuiFlexItem>
<EuiFlexItem>
{/* TODO: Get the user-typed connector name? */}
<EuiText size="m">{actionTypeId}</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="s" />
</>
);
})}
{actions.map(({ actionTypeId, name }) => (
<React.Fragment key={actionTypeId}>
<EuiFlexGroup alignItems="baseline">
<EuiFlexItem grow={false}>
<EuiIcon size="m" type={getActionIconClass(actionTypeId) ?? 'apps'} />
</EuiFlexItem>
<EuiFlexItem>
<EuiText data-test-subj={`actionConnectorName-${name}`} size="s">
{name}
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="s" />
</React.Fragment>
))}
{errorActions && toasts.addDanger({ title: errorActions })}
</EuiFlexGroup>
);
Expand Down
2 changes: 1 addition & 1 deletion x-pack/plugins/triggers_actions_ui/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export { loadRuleAggregations, loadRuleTags } from './application/lib/rule_api/a
export { useLoadRuleTypes } from './application/hooks/use_load_rule_types';
export { loadRule } from './application/lib/rule_api/get_rule';
export { loadAllActions } from './application/lib/action_connector_api';

export { suspendedComponentWithProps } from './application/lib/suspended_component_with_props';
export { loadActionTypes } from './application/lib/action_connector_api/connector_types';

export type { TIME_UNITS } from './application/constants';
Expand Down

0 comments on commit 8b6c669

Please sign in to comment.