Skip to content

Commit

Permalink
[Security Solution] Update button text according to status (#80389)
Browse files Browse the repository at this point in the history
* update button text according to status

* remove unused translations

* fix functional test

* fixup

* fix unit test

* update unit tests

* update unit test
  • Loading branch information
angorayc authored Oct 15, 2020
1 parent 41db7d1 commit 6b8e8a5
Show file tree
Hide file tree
Showing 11 changed files with 492 additions and 124 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
*/

import React from 'react';
import { shallow } from 'enzyme';
import { waitFor } from '@testing-library/react';
import { shallow, mount, ReactWrapper } from 'enzyme';

import '../../../../common/mock/match_media';
import { PrePackagedRulesPrompt } from './load_empty_prompt';
import { getPrePackagedRulesStatus } from '../../../containers/detection_engine/rules/api';

jest.mock('react-router-dom', () => {
const original = jest.requireActual('react-router-dom');
Expand All @@ -23,16 +25,94 @@ jest.mock('react-router-dom', () => {

jest.mock('../../../../common/components/link_to');

jest.mock('../../../containers/detection_engine/rules/api', () => ({
getPrePackagedRulesStatus: jest.fn().mockResolvedValue({
rules_not_installed: 0,
rules_installed: 0,
rules_not_updated: 0,
timelines_not_installed: 0,
timelines_installed: 0,
timelines_not_updated: 0,
}),
createPrepackagedRules: jest.fn(),
}));

const props = {
createPrePackagedRules: jest.fn(),
loading: false,
userHasNoPermissions: false,
'data-test-subj': 'load-prebuilt-rules',
};

describe('PrePackagedRulesPrompt', () => {
it('renders correctly', () => {
const wrapper = shallow(
<PrePackagedRulesPrompt
createPrePackagedRules={jest.fn()}
loading={false}
userHasNoPermissions={false}
/>
);
const wrapper = shallow(<PrePackagedRulesPrompt {...props} />);

expect(wrapper.find('EmptyPrompt')).toHaveLength(1);
});
});

describe('LoadPrebuiltRulesAndTemplatesButton', () => {
it('renders correct button with correct text - Load Elastic prebuilt rules and timeline templates', async () => {
(getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({
rules_not_installed: 3,
rules_installed: 0,
rules_not_updated: 0,
timelines_not_installed: 3,
timelines_installed: 0,
timelines_not_updated: 0,
});

const wrapper: ReactWrapper = mount(<PrePackagedRulesPrompt {...props} />);
await waitFor(() => {
wrapper.update();

expect(wrapper.find('[data-test-subj="load-prebuilt-rules"]').exists()).toEqual(true);
expect(wrapper.find('[data-test-subj="load-prebuilt-rules"]').last().text()).toEqual(
'Load Elastic prebuilt rules and timeline templates'
);
});
});

it('renders correct button with correct text - Load Elastic prebuilt rules', async () => {
(getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({
rules_not_installed: 3,
rules_installed: 0,
rules_not_updated: 0,
timelines_not_installed: 0,
timelines_installed: 0,
timelines_not_updated: 0,
});

const wrapper: ReactWrapper = mount(<PrePackagedRulesPrompt {...props} />);
await waitFor(() => {
wrapper.update();

expect(wrapper.find('[data-test-subj="load-prebuilt-rules"]').exists()).toEqual(true);
expect(wrapper.find('[data-test-subj="load-prebuilt-rules"]').last().text()).toEqual(
'Load Elastic prebuilt rules'
);
});
});

it('renders correct button with correct text - Load Elastic prebuilt timeline templates', async () => {
(getPrePackagedRulesStatus as jest.Mock).mockResolvedValue({
rules_not_installed: 0,
rules_installed: 0,
rules_not_updated: 0,
timelines_not_installed: 3,
timelines_installed: 0,
timelines_not_updated: 0,
});

const wrapper: ReactWrapper = mount(<PrePackagedRulesPrompt {...props} />);
await waitFor(() => {
wrapper.update();

expect(wrapper.find('[data-test-subj="load-prebuilt-rules"]').exists()).toEqual(true);
expect(wrapper.find('[data-test-subj="load-prebuilt-rules"]').last().text()).toEqual(
'Load Elastic prebuilt timeline templates'
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, EuiButton } from '@elastic/eui';
import React, { memo, useCallback } from 'react';
import { EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React, { memo, useCallback, useMemo } from 'react';
import styled from 'styled-components';

import { useHistory } from 'react-router-dom';
Expand All @@ -14,6 +14,8 @@ import * as i18n from './translations';
import { LinkButton } from '../../../../common/components/links';
import { SecurityPageName } from '../../../../app/types';
import { useFormatUrl } from '../../../../common/components/link_to';
import { usePrePackagedRules } from '../../../containers/detection_engine/rules';
import { useUserData } from '../../user_info';

const EmptyPrompt = styled(EuiEmptyPrompt)`
align-self: center; /* Corrects horizontal centering in IE11 */
Expand Down Expand Up @@ -46,24 +48,36 @@ const PrePackagedRulesPromptComponent: React.FC<PrePackagedRulesPromptProps> = (
[history]
);

const [
{ isSignalIndexExists, isAuthenticated, hasEncryptionKey, canUserCRUD, hasIndexWrite },
] = useUserData();

const { getLoadPrebuiltRulesAndTemplatesButton } = usePrePackagedRules({
canUserCRUD,
hasIndexWrite,
isSignalIndexExists,
isAuthenticated,
hasEncryptionKey,
});

const loadPrebuiltRulesAndTemplatesButton = useMemo(
() =>
getLoadPrebuiltRulesAndTemplatesButton({
isDisabled: userHasNoPermissions,
onClick: handlePreBuiltCreation,
fill: true,
'data-test-subj': 'load-prebuilt-rules',
}),
[getLoadPrebuiltRulesAndTemplatesButton, handlePreBuiltCreation, userHasNoPermissions]
);

return (
<EmptyPrompt
title={<h2>{i18n.PRE_BUILT_TITLE}</h2>}
body={<p>{i18n.PRE_BUILT_MSG}</p>}
actions={
<EuiFlexGroup justifyContent="center">
<EuiFlexItem grow={false}>
<EuiButton
fill
iconType="indexOpen"
isDisabled={userHasNoPermissions}
isLoading={loading}
onClick={handlePreBuiltCreation}
data-test-subj="load-prebuilt-rules"
>
{i18n.PRE_BUILT_ACTION}
</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>{loadPrebuiltRulesAndTemplatesButton}</EuiFlexItem>
<EuiFlexItem grow={false}>
<LinkButton
isDisabled={userHasNoPermissions}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ export const PRE_BUILT_MSG = i18n.translate(
}
);

export const PRE_BUILT_ACTION = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.prePackagedRules.loadPreBuiltButton',
{
defaultMessage: 'Load prebuilt detection rules and timeline templates',
}
);

export const CREATE_RULE_ACTION = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.prePackagedRules.createOwnRuletButton',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,57 @@ export const TAG_FETCH_FAILURE = i18n.translate(
defaultMessage: 'Failed to fetch Tags',
}
);

export const LOAD_PREPACKAGED_RULES = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesButton',
{
defaultMessage: 'Load Elastic prebuilt rules',
}
);

export const LOAD_PREPACKAGED_TIMELINE_TEMPLATES = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.loadPrePackagedTimelineTemplatesButton',
{
defaultMessage: 'Load Elastic prebuilt timeline templates',
}
);

export const LOAD_PREPACKAGED_RULES_AND_TEMPLATES = i18n.translate(
'xpack.securitySolution.detectionEngine.rules.loadPrePackagedRulesAndTemplatesButton',
{
defaultMessage: 'Load Elastic prebuilt rules and timeline templates',
}
);

export const RELOAD_MISSING_PREPACKAGED_RULES = (missingRules: number) =>
i18n.translate(
'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesButton',
{
values: { missingRules },
defaultMessage:
'Install {missingRules} Elastic prebuilt {missingRules, plural, =1 {rule} other {rules}} ',
}
);

export const RELOAD_MISSING_PREPACKAGED_TIMELINES = (missingTimelines: number) =>
i18n.translate(
'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedTimelinesButton',
{
values: { missingTimelines },
defaultMessage:
'Install {missingTimelines} Elastic prebuilt {missingTimelines, plural, =1 {timeline} other {timelines}} ',
}
);

export const RELOAD_MISSING_PREPACKAGED_RULES_AND_TIMELINES = (
missingRules: number,
missingTimelines: number
) =>
i18n.translate(
'xpack.securitySolution.detectionEngine.rules.reloadMissingPrePackagedRulesAndTimelinesButton',
{
values: { missingRules, missingTimelines },
defaultMessage:
'Install {missingRules} Elastic prebuilt {missingRules, plural, =1 {rule} other {rules}} and {missingTimelines} Elastic prebuilt {missingTimelines, plural, =1 {timeline} other {timelines}} ',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ describe('usePrePackagedRules', () => {
await waitForNextUpdate();

expect(result.current).toEqual({
getLoadPrebuiltRulesAndTemplatesButton:
result.current.getLoadPrebuiltRulesAndTemplatesButton,
getReloadPrebuiltRulesAndTemplatesButton:
result.current.getReloadPrebuiltRulesAndTemplatesButton,
createPrePackagedRules: null,
loading: true,
loadingCreatePrePackagedRules: false,
Expand Down Expand Up @@ -63,6 +67,10 @@ describe('usePrePackagedRules', () => {
await waitForNextUpdate();

expect(result.current).toEqual({
getLoadPrebuiltRulesAndTemplatesButton:
result.current.getLoadPrebuiltRulesAndTemplatesButton,
getReloadPrebuiltRulesAndTemplatesButton:
result.current.getReloadPrebuiltRulesAndTemplatesButton,
createPrePackagedRules: result.current.createPrePackagedRules,
loading: false,
loadingCreatePrePackagedRules: false,
Expand Down Expand Up @@ -100,6 +108,10 @@ describe('usePrePackagedRules', () => {
expect(resp).toEqual(true);
expect(spyOnCreatePrepackagedRules).toHaveBeenCalled();
expect(result.current).toEqual({
getLoadPrebuiltRulesAndTemplatesButton:
result.current.getLoadPrebuiltRulesAndTemplatesButton,
getReloadPrebuiltRulesAndTemplatesButton:
result.current.getReloadPrebuiltRulesAndTemplatesButton,
createPrePackagedRules: result.current.createPrePackagedRules,
loading: false,
loadingCreatePrePackagedRules: false,
Expand Down
Loading

0 comments on commit 6b8e8a5

Please sign in to comment.