Skip to content

Commit

Permalink
[SIEM] Fix draft timeline can be attached to a case (#67844)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrykkopycinski committed Jun 2, 2020
1 parent c1edded commit cee743d
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const StatefulFlyoutHeader = React.memo<Props>(
title,
noteIds,
notesById,
status,
timelineId,
toggleLock,
updateDescription,
Expand All @@ -62,6 +63,7 @@ const StatefulFlyoutHeader = React.memo<Props>(
isFavorite={isFavorite}
title={title}
noteIds={noteIds}
status={status}
timelineId={timelineId}
toggleLock={toggleLock}
updateDescription={updateDescription}
Expand Down Expand Up @@ -94,6 +96,7 @@ const makeMapStateToProps = () => {
kqlQuery,
title = '',
noteIds = emptyNotesId,
status,
} = timeline;

const history = emptyHistory; // TODO: get history from store via selector
Expand All @@ -107,6 +110,7 @@ const makeMapStateToProps = () => {
isFavorite,
isDatepickerLocked: globalInput.linkTo.includes('timeline'),
noteIds,
status,
title,
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import styled from 'styled-components';
import { useHistory } from 'react-router-dom';
import { useSelector } from 'react-redux';

import { TimelineStatus } from '../../../../../common/types/timeline';
import { Note } from '../../../../common/lib/note';
import { Notes } from '../../notes';
import { AssociateNote, UpdateNote } from '../../notes/helpers';
Expand Down Expand Up @@ -119,40 +120,44 @@ Name.displayName = 'Name';
interface NewCaseProps {
onClosePopover: () => void;
timelineId: string;
timelineStatus: TimelineStatus;
timelineTitle: string;
}

export const NewCase = React.memo<NewCaseProps>(({ onClosePopover, timelineId, timelineTitle }) => {
const history = useHistory();
const { savedObjectId } = useSelector((state: State) =>
timelineSelectors.selectTimeline(state, timelineId)
);
const handleClick = useCallback(() => {
onClosePopover();
history.push({
pathname: `/${SiemPageName.case}/create`,
state: {
insertTimeline: {
timelineId,
timelineSavedObjectId: savedObjectId,
timelineTitle: timelineTitle.length > 0 ? timelineTitle : i18n.UNTITLED_TIMELINE,
export const NewCase = React.memo<NewCaseProps>(
({ onClosePopover, timelineId, timelineStatus, timelineTitle }) => {
const history = useHistory();
const { savedObjectId } = useSelector((state: State) =>
timelineSelectors.selectTimeline(state, timelineId)
);
const handleClick = useCallback(() => {
onClosePopover();
history.push({
pathname: `/${SiemPageName.case}/create`,
state: {
insertTimeline: {
timelineId,
timelineSavedObjectId: savedObjectId,
timelineTitle: timelineTitle.length > 0 ? timelineTitle : i18n.UNTITLED_TIMELINE,
},
},
},
});
}, [onClosePopover, history, timelineId, timelineTitle]);
});
}, [onClosePopover, history, timelineId, timelineTitle]);

return (
<EuiButtonEmpty
data-test-subj="attach-timeline-case"
color="text"
iconSide="left"
iconType="paperClip"
onClick={handleClick}
>
{i18n.ATTACH_TIMELINE_TO_NEW_CASE}
</EuiButtonEmpty>
);
});
return (
<EuiButtonEmpty
data-test-subj="attach-timeline-case"
color="text"
iconSide="left"
iconType="paperClip"
disabled={timelineStatus === TimelineStatus.draft}
onClick={handleClick}
>
{i18n.ATTACH_TIMELINE_TO_NEW_CASE}
</EuiButtonEmpty>
);
}
);
NewCase.displayName = 'NewCase';

interface NewTimelineProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { mount } from 'enzyme';
import React from 'react';
import { Provider as ReduxStoreProvider } from 'react-redux';

import { TimelineStatus } from '../../../../../common/types/timeline';
import {
mockGlobalState,
apolloClientObservable,
Expand All @@ -25,6 +26,24 @@ jest.mock('../../../../common/components/utils');
width: mockedWidth,
}));

jest.mock('react-redux', () => {
const originalModule = jest.requireActual('react-redux');

return {
...originalModule,
useSelector: jest.fn().mockReturnValue({ savedObjectId: '1' }),
};
});

jest.mock('react-router-dom', () => {
const originalModule = jest.requireActual('react-router-dom');

return {
...originalModule,
useHistory: jest.fn(),
};
});

describe('Properties', () => {
const usersViewing = ['elastic'];

Expand All @@ -50,6 +69,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand All @@ -60,7 +80,45 @@ describe('Properties', () => {
/>
</ReduxStoreProvider>
);

wrapper.find('[data-test-subj="settings-gear"]').at(0).simulate('click');

expect(wrapper.find('[data-test-subj="timeline-properties"]').exists()).toEqual(true);
expect(wrapper.find('button[data-test-subj="attach-timeline-case"]').prop('disabled')).toEqual(
false
);
});

test('renders correctly draft timeline', () => {
const wrapper = mount(
<ReduxStoreProvider store={store}>
<Properties
associateNote={jest.fn()}
createTimeline={jest.fn()}
isDataInTimeline={false}
isDatepickerLocked={false}
isFavorite={false}
title=""
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.draft}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
updateIsFavorite={jest.fn()}
updateTitle={jest.fn()}
updateNote={jest.fn()}
usersViewing={usersViewing}
/>
</ReduxStoreProvider>
);

wrapper.find('[data-test-subj="settings-gear"]').at(0).simulate('click');

expect(wrapper.find('button[data-test-subj="attach-timeline-case"]').prop('disabled')).toEqual(
true
);
});

test('it renders an empty star icon when it is NOT a favorite', () => {
Expand All @@ -76,6 +134,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -103,6 +162,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -132,6 +192,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -159,6 +220,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -191,6 +253,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -222,6 +285,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -256,6 +320,7 @@ describe('Properties', () => {
description={description}
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -292,6 +357,7 @@ describe('Properties', () => {
description={description}
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -326,6 +392,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -360,6 +427,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -392,6 +460,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -421,6 +490,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down Expand Up @@ -448,6 +518,7 @@ describe('Properties', () => {
description=""
getNotesByIds={jest.fn()}
noteIds={[]}
status={TimelineStatus.active}
timelineId="abc"
toggleLock={jest.fn()}
updateDescription={jest.fn()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import React, { useState, useCallback, useMemo } from 'react';

import { TimelineStatus } from '../../../../../common/types/timeline';
import { useThrottledResizeObserver } from '../../../../common/components/utils';
import { Note } from '../../../../common/lib/note';
import { InputsModelId } from '../../../../common/store/inputs/constants';
Expand All @@ -31,6 +32,7 @@ interface Props {
isFavorite: boolean;
noteIds: string[];
timelineId: string;
status: TimelineStatus;
title: string;
toggleLock: ToggleLock;
updateDescription: UpdateDescription;
Expand Down Expand Up @@ -62,6 +64,7 @@ export const Properties = React.memo<Props>(
isDatepickerLocked,
isFavorite,
noteIds,
status,
timelineId,
title,
toggleLock,
Expand Down Expand Up @@ -140,6 +143,7 @@ export const Properties = React.memo<Props>(
showNotesFromWidth={width < showNotesThreshold}
showTimelineModal={showTimelineModal}
showUsersView={title.length > 0}
status={status}
timelineId={timelineId}
title={title}
updateDescription={updateDescription}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { InspectButton, InspectButtonContainer } from '../../../../common/compon
import * as i18n from './translations';
import { AssociateNote } from '../../notes/helpers';
import { Note } from '../../../../common/lib/note';
import { TimelineStatus } from '../../../../../common/types/timeline';

export const PropertiesRightStyle = styled(EuiFlexGroup)`
margin-right: 5px;
Expand Down Expand Up @@ -79,6 +80,7 @@ interface Props {
onCloseTimelineModal: () => void;
onOpenTimelineModal: () => void;
showTimelineModal: boolean;
status: TimelineStatus;
title: string;
updateNote: UpdateNote;
}
Expand Down Expand Up @@ -106,6 +108,7 @@ const PropertiesRightComponent: React.FC<Props> = ({
onCloseTimelineModal,
onOpenTimelineModal,
title,
status,
}) => (
<PropertiesRightStyle alignItems="flexStart" data-test-subj="properties-right" gutterSize="s">
<EuiFlexItem grow={false}>
Expand Down Expand Up @@ -142,6 +145,7 @@ const PropertiesRightComponent: React.FC<Props> = ({
onClosePopover={onClosePopover}
timelineId={timelineId}
timelineTitle={title}
timelineStatus={status}
/>
</EuiFlexItem>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export const oneTimelineQuery = gql`
updatedBy
version
}
status
title
timelineType
templateTimelineId
Expand Down

0 comments on commit cee743d

Please sign in to comment.