Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Security Solution] Update button text according to status #80389

Merged
merged 8 commits into from
Oct 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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