diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/__mock__/index.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/__mock__/case_data.tsx
similarity index 54%
rename from x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/__mock__/index.tsx
rename to x-pack/legacy/plugins/siem/public/pages/case/components/__mock__/case_data.tsx
index b3037e6839b79..64c6276fc1be2 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/__mock__/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/__mock__/case_data.tsx
@@ -4,31 +4,105 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { SortFieldCase } from '../../../../../containers/case/types';
-import { UseGetCasesState } from '../../../../../containers/case/use_get_cases';
+import { CaseProps } from '../case_view';
+import { Case, Comment, SortFieldCase } from '../../../../containers/case/types';
+import { UseGetCasesState } from '../../../../containers/case/use_get_cases';
+import { UserAction, UserActionField } from '../../../../../../../../plugins/case/common/api/cases';
+
+const updateCase = jest.fn();
+const fetchCase = jest.fn();
+
+const basicCaseId = 'basic-case-id';
+const basicCommentId = 'basic-comment-id';
+const basicCreatedAt = '2020-02-20T23:06:33.798Z';
+const elasticUser = {
+ fullName: 'Leslie Knope',
+ username: 'lknope',
+ email: 'leslie.knope@elastic.co',
+};
+
+export const basicComment: Comment = {
+ comment: 'Solve this fast!',
+ id: basicCommentId,
+ createdAt: basicCreatedAt,
+ createdBy: elasticUser,
+ pushedAt: null,
+ pushedBy: null,
+ updatedAt: '2020-02-20T23:06:33.798Z',
+ updatedBy: {
+ username: 'elastic',
+ },
+ version: 'WzQ3LDFc',
+};
+
+export const basicCase: Case = {
+ closedAt: null,
+ closedBy: null,
+ id: basicCaseId,
+ comments: [basicComment],
+ createdAt: '2020-02-13T19:44:23.627Z',
+ createdBy: elasticUser,
+ description: 'Security banana Issue',
+ externalService: null,
+ status: 'open',
+ tags: ['defacement'],
+ title: 'Another horrible breach!!',
+ totalComment: 1,
+ updatedAt: '2020-02-19T15:02:57.995Z',
+ updatedBy: {
+ username: 'elastic',
+ },
+ version: 'WzQ3LDFd',
+};
+
+export const caseProps: CaseProps = {
+ caseId: basicCaseId,
+ userCanCrud: true,
+ caseData: basicCase,
+ fetchCase,
+ updateCase,
+};
+
+export const caseClosedProps: CaseProps = {
+ ...caseProps,
+ caseData: {
+ ...caseProps.caseData,
+ closedAt: '2020-02-20T23:06:33.798Z',
+ closedBy: {
+ username: 'elastic',
+ },
+ status: 'closed',
+ },
+};
+
+export const basicCaseClosed: Case = {
+ ...caseClosedProps.caseData,
+};
+
+const basicAction = {
+ actionAt: basicCreatedAt,
+ actionBy: elasticUser,
+ oldValue: null,
+ newValue: 'what a cool value',
+ caseId: basicCaseId,
+ commentId: null,
+};
+export const caseUserActions = [
+ {
+ ...basicAction,
+ actionBy: elasticUser,
+ actionField: ['comment'],
+ action: 'create',
+ actionId: 'tt',
+ },
+];
export const useGetCasesMockState: UseGetCasesState = {
data: {
countClosedCases: 0,
countOpenCases: 5,
cases: [
- {
- closedAt: null,
- closedBy: null,
- id: '3c4ddcc0-4e99-11ea-9290-35d05cb55c15',
- createdAt: '2020-02-13T19:44:23.627Z',
- createdBy: { username: 'elastic' },
- comments: [],
- description: 'Security banana Issue',
- externalService: null,
- status: 'open',
- tags: ['defacement'],
- title: 'Another horrible breach',
- totalComment: 0,
- updatedAt: null,
- updatedBy: null,
- version: 'WzQ3LDFd',
- },
+ basicCase,
{
closedAt: null,
closedBy: null,
@@ -129,3 +203,24 @@ export const useGetCasesMockState: UseGetCasesState = {
},
filterOptions: { search: '', reporters: [], tags: [], status: 'open' },
};
+
+const basicPush = {
+ connector_id: 'connector_id',
+ connector_name: 'connector name',
+ external_id: 'external_id',
+ external_title: 'external title',
+ external_url: 'basicPush.com',
+ pushed_at: basicCreatedAt,
+ pushed_by: elasticUser,
+};
+export const getUserAction = (af: UserActionField, a: UserAction) => ({
+ ...basicAction,
+ actionId: `${af[0]}-${a}`,
+ actionField: af,
+ action: a,
+ commentId: af[0] === 'comment' ? basicCommentId : null,
+ newValue:
+ a === 'push-to-service' && af[0] === 'pushed'
+ ? JSON.stringify(basicPush)
+ : basicAction.newValue,
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/columns.test.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/columns.test.tsx
index 28577898b548e..e008b94ab9e16 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/columns.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/columns.test.tsx
@@ -9,7 +9,7 @@ import { mount } from 'enzyme';
import { ServiceNowColumn } from './columns';
-import { useGetCasesMockState } from './__mock__';
+import { useGetCasesMockState } from '../__mock__/case_data';
describe('ServiceNowColumn ', () => {
it('Not pushed render', () => {
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/index.test.tsx
index cd1730e373829..f65736e7cd109 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/all_cases/index.test.tsx
@@ -9,7 +9,7 @@ import { mount } from 'enzyme';
import moment from 'moment-timezone';
import { AllCases } from './';
import { TestProviders } from '../../../../mock';
-import { useGetCasesMockState } from './__mock__';
+import { useGetCasesMockState } from '../__mock__/case_data';
import * as i18n from './translations';
import { getEmptyTagValue } from '../../../../components/empty_value';
@@ -120,7 +120,7 @@ describe('AllCases', () => {
.find(`[data-test-subj="case-table-column-createdBy"]`)
.first()
.text()
- ).toEqual(useGetCasesMockState.data.cases[0].createdBy.username);
+ ).toEqual(useGetCasesMockState.data.cases[0].createdBy.fullName);
expect(
wrapper
.find(`[data-test-subj="case-table-column-createdAt"]`)
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/__mock__/index.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/__mock__/index.tsx
deleted file mode 100644
index 0e57326707e97..0000000000000
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/__mock__/index.tsx
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { CaseProps } from '../index';
-import { Case } from '../../../../../containers/case/types';
-
-const updateCase = jest.fn();
-const fetchCase = jest.fn();
-
-export const caseProps: CaseProps = {
- caseId: '3c4ddcc0-4e99-11ea-9290-35d05cb55c15',
- userCanCrud: true,
- caseData: {
- closedAt: null,
- closedBy: null,
- id: '3c4ddcc0-4e99-11ea-9290-35d05cb55c15',
- comments: [
- {
- comment: 'Solve this fast!',
- id: 'a357c6a0-5435-11ea-b427-fb51a1fcb7b8',
- createdAt: '2020-02-20T23:06:33.798Z',
- createdBy: {
- fullName: 'Steph Milovic',
- username: 'smilovic',
- email: 'notmyrealemailfool@elastic.co',
- },
- pushedAt: null,
- pushedBy: null,
- updatedAt: '2020-02-20T23:06:33.798Z',
- updatedBy: {
- username: 'elastic',
- },
- version: 'WzQ3LDFd',
- },
- ],
- createdAt: '2020-02-13T19:44:23.627Z',
- createdBy: { fullName: null, email: 'testemail@elastic.co', username: 'elastic' },
- description: 'Security banana Issue',
- externalService: null,
- status: 'open',
- tags: ['defacement'],
- title: 'Another horrible breach!!',
- totalComment: 1,
- updatedAt: '2020-02-19T15:02:57.995Z',
- updatedBy: {
- username: 'elastic',
- },
- version: 'WzQ3LDFd',
- },
- fetchCase,
- updateCase,
-};
-
-export const caseClosedProps: CaseProps = {
- ...caseProps,
- caseData: {
- ...caseProps.caseData,
- closedAt: '2020-02-20T23:06:33.798Z',
- closedBy: {
- username: 'elastic',
- },
- status: 'closed',
- },
-};
-
-export const data: Case = {
- ...caseProps.caseData,
-};
-
-export const dataClosed: Case = {
- ...caseClosedProps.caseData,
-};
-
-export const caseUserActions = [
- {
- actionField: ['comment'],
- action: 'create',
- actionAt: '2020-03-20T17:10:09.814Z',
- actionBy: {
- fullName: 'Steph Milovic',
- username: 'smilovic',
- email: 'notmyrealemailfool@elastic.co',
- },
- newValue: 'Solve this fast!',
- oldValue: null,
- actionId: '3c4ddcc0-4e99-11ea-9290-35d05cb55c15',
- caseId: '9b833a50-6acd-11ea-8fad-af86b1071bd9',
- commentId: 'a357c6a0-5435-11ea-b427-fb51a1fcb7b8',
- },
-];
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/actions.test.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/actions.test.tsx
index 49f5f44cba271..8a25a2121104d 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/actions.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/actions.test.tsx
@@ -9,7 +9,7 @@ import { mount } from 'enzyme';
import { useDeleteCases } from '../../../../containers/case/use_delete_cases';
import { TestProviders } from '../../../../mock';
-import { data } from './__mock__';
+import { basicCase } from '../__mock__/case_data';
import { CaseViewActions } from './actions';
jest.mock('../../../../containers/case/use_delete_cases');
const useDeleteCasesMock = useDeleteCases as jest.Mock;
@@ -34,7 +34,7 @@ describe('CaseView actions', () => {
it('clicking trash toggles modal', () => {
const wrapper = mount(
-
+
);
@@ -54,12 +54,14 @@ describe('CaseView actions', () => {
}));
const wrapper = mount(
-
+
);
expect(wrapper.find('[data-test-subj="confirm-delete-case-modal"]').exists()).toBeTruthy();
wrapper.find('button[data-test-subj="confirmModalConfirmButton"]').simulate('click');
- expect(handleOnDeleteConfirm.mock.calls[0][0]).toEqual([{ id: data.id, title: data.title }]);
+ expect(handleOnDeleteConfirm.mock.calls[0][0]).toEqual([
+ { id: basicCase.id, title: basicCase.title },
+ ]);
});
});
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/index.test.tsx
index 81ce9b4b3d413..5056199649df0 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/case_view/index.test.tsx
@@ -9,7 +9,12 @@ import { mount } from 'enzyme';
import { Router, routeData, mockHistory, mockLocation } from '../__mock__/router';
import { CaseComponent, CaseView } from './';
-import { caseProps, caseClosedProps, data, dataClosed, caseUserActions } from './__mock__';
+import {
+ basicCaseClosed,
+ caseClosedProps,
+ caseProps,
+ caseUserActions,
+} from '../__mock__/case_data';
import { TestProviders } from '../../../../mock';
import { useUpdateCase } from '../../../../containers/case/use_update_case';
import { useGetCase } from '../../../../containers/case/use_get_case';
@@ -29,10 +34,11 @@ describe('CaseView ', () => {
const fetchCaseUserActions = jest.fn();
const fetchCase = jest.fn();
const updateCase = jest.fn();
+ const data = caseProps.caseData;
const defaultGetCase = {
isLoading: false,
isError: false,
- data: caseProps.caseData,
+ data,
updateCase,
fetchCase,
};
@@ -126,7 +132,7 @@ describe('CaseView ', () => {
).toEqual(data.createdAt);
expect(
wrapper
- .find(`[data-test-subj="case-view-description"]`)
+ .find(`[data-test-subj="description-action"] [data-test-subj="user-action-markdown"]`)
.first()
.prop('raw')
).toEqual(data.description);
@@ -135,7 +141,7 @@ describe('CaseView ', () => {
it('should show closed indicators in header when case is closed', async () => {
useUpdateCaseMock.mockImplementation(() => ({
...defaultUpdateCaseState,
- caseData: dataClosed,
+ caseData: basicCaseClosed,
}));
const wrapper = mount(
@@ -151,13 +157,13 @@ describe('CaseView ', () => {
.find(`[data-test-subj="case-view-closedAt"]`)
.first()
.prop('value')
- ).toEqual(dataClosed.closedAt);
+ ).toEqual(basicCaseClosed.closedAt);
expect(
wrapper
.find(`[data-test-subj="case-view-status"]`)
.first()
.text()
- ).toEqual(dataClosed.status);
+ ).toEqual(basicCaseClosed.status);
});
it('should dispatch update state when button is toggled', async () => {
@@ -175,43 +181,6 @@ describe('CaseView ', () => {
expect(updateCaseProperty).toHaveBeenCalled();
});
- it('should render comments', async () => {
- const wrapper = mount(
-
-
-
-
-
- );
- await wait();
- expect(
- wrapper
- .find(
- `div[data-test-subj="user-action-${data.comments[0].id}-avatar"] [data-test-subj="user-action-avatar"]`
- )
- .first()
- .prop('name')
- ).toEqual(data.comments[0].createdBy.fullName);
-
- expect(
- wrapper
- .find(
- `div[data-test-subj="user-action-${data.comments[0].id}"] [data-test-subj="user-action-title"] strong`
- )
- .first()
- .text()
- ).toEqual(data.comments[0].createdBy.username);
-
- expect(
- wrapper
- .find(
- `div[data-test-subj="user-action-${data.comments[0].id}"] [data-test-subj="markdown"]`
- )
- .first()
- .prop('source')
- ).toEqual(data.comments[0].comment);
- });
-
it('should display EditableTitle isLoading', () => {
useUpdateCaseMock.mockImplementation(() => ({
...defaultUpdateCaseState,
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/index.test.tsx
index 58c261f5d1e32..7e4dac2bd8cf1 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/tag_list/index.test.tsx
@@ -32,10 +32,9 @@ describe('TagList ', () => {
(useForm as jest.Mock).mockImplementation(() => ({ form: formHookMock }));
});
it('Renders no tags, and then edit', () => {
- const props = defaultProps;
const wrapper = mount(
-
+
);
expect(
@@ -62,10 +61,9 @@ describe('TagList ', () => {
).toBeTruthy();
});
it('Edit tag on submit', async () => {
- const props = defaultProps;
const wrapper = mount(
-
+
);
wrapper
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/helpers.test.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/helpers.test.tsx
new file mode 100644
index 0000000000000..5c342538f0feb
--- /dev/null
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/helpers.test.tsx
@@ -0,0 +1,143 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { getUserAction } from '../__mock__/case_data';
+import { getLabelTitle } from './helpers';
+import * as i18n from '../case_view/translations';
+import { mount } from 'enzyme';
+
+describe('User action tree helpers', () => {
+ it('label title generated for update tags', () => {
+ const action = getUserAction(['title'], 'update');
+ const result: string | JSX.Element = getLabelTitle({
+ action,
+ field: 'tags',
+ firstIndexPushToService: 0,
+ index: 0,
+ });
+
+ const wrapper = mount(<>{result}>);
+ expect(
+ wrapper
+ .find(`[data-test-subj="ua-tags-label"]`)
+ .first()
+ .text()
+ ).toEqual(` ${i18n.TAGS.toLowerCase()}`);
+
+ expect(
+ wrapper
+ .find(`[data-test-subj="ua-tag"]`)
+ .first()
+ .text()
+ ).toEqual(action.newValue);
+ });
+ it('label title generated for update title', () => {
+ const action = getUserAction(['title'], 'update');
+ const result: string | JSX.Element = getLabelTitle({
+ action,
+ field: 'title',
+ firstIndexPushToService: 0,
+ index: 0,
+ });
+
+ expect(result).toEqual(
+ `${i18n.CHANGED_FIELD.toLowerCase()} ${i18n.CASE_NAME.toLowerCase()} ${i18n.TO} "${
+ action.newValue
+ }"`
+ );
+ });
+ it('label title generated for update description', () => {
+ const action = getUserAction(['description'], 'update');
+ const result: string | JSX.Element = getLabelTitle({
+ action,
+ field: 'description',
+ firstIndexPushToService: 0,
+ index: 0,
+ });
+
+ expect(result).toEqual(`${i18n.EDITED_FIELD} ${i18n.DESCRIPTION.toLowerCase()}`);
+ });
+ it('label title generated for update status to open', () => {
+ const action = { ...getUserAction(['status'], 'update'), newValue: 'open' };
+ const result: string | JSX.Element = getLabelTitle({
+ action,
+ field: 'status',
+ firstIndexPushToService: 0,
+ index: 0,
+ });
+
+ expect(result).toEqual(`${i18n.REOPENED_CASE.toLowerCase()} ${i18n.CASE}`);
+ });
+ it('label title generated for update status to closed', () => {
+ const action = { ...getUserAction(['status'], 'update'), newValue: 'closed' };
+ const result: string | JSX.Element = getLabelTitle({
+ action,
+ field: 'status',
+ firstIndexPushToService: 0,
+ index: 0,
+ });
+
+ expect(result).toEqual(`${i18n.CLOSED_CASE.toLowerCase()} ${i18n.CASE}`);
+ });
+ it('label title generated for update comment', () => {
+ const action = getUserAction(['comment'], 'update');
+ const result: string | JSX.Element = getLabelTitle({
+ action,
+ field: 'comment',
+ firstIndexPushToService: 0,
+ index: 0,
+ });
+
+ expect(result).toEqual(`${i18n.EDITED_FIELD} ${i18n.COMMENT.toLowerCase()}`);
+ });
+ it('label title generated for pushed incident', () => {
+ const action = getUserAction(['pushed'], 'push-to-service');
+ const result: string | JSX.Element = getLabelTitle({
+ action,
+ field: 'pushed',
+ firstIndexPushToService: 0,
+ index: 0,
+ });
+
+ const wrapper = mount(<>{result}>);
+ expect(
+ wrapper
+ .find(`[data-test-subj="pushed-label"]`)
+ .first()
+ .text()
+ ).toEqual(i18n.PUSHED_NEW_INCIDENT);
+ expect(
+ wrapper
+ .find(`[data-test-subj="pushed-value"]`)
+ .first()
+ .prop('href')
+ ).toEqual(JSON.parse(action.newValue).external_url);
+ });
+ it('label title generated for needs update incident', () => {
+ const action = getUserAction(['pushed'], 'push-to-service');
+ const result: string | JSX.Element = getLabelTitle({
+ action,
+ field: 'pushed',
+ firstIndexPushToService: 0,
+ index: 1,
+ });
+
+ const wrapper = mount(<>{result}>);
+ expect(
+ wrapper
+ .find(`[data-test-subj="pushed-label"]`)
+ .first()
+ .text()
+ ).toEqual(i18n.UPDATE_INCIDENT);
+ expect(
+ wrapper
+ .find(`[data-test-subj="pushed-value"]`)
+ .first()
+ .prop('href')
+ ).toEqual(JSON.parse(action.newValue).external_url);
+ });
+});
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/helpers.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/helpers.tsx
index 008f4d7048f56..d6016e540bdc0 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/helpers.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/helpers.tsx
@@ -41,14 +41,16 @@ export const getLabelTitle = ({ action, field, firstIndexPushToService, index }:
const getTagsLabelTitle = (action: CaseUserActions) => (
-
+
{action.action === 'add' && i18n.ADDED_FIELD}
{action.action === 'delete' && i18n.REMOVED_FIELD} {i18n.TAGS.toLowerCase()}
{action.newValue != null &&
action.newValue.split(',').map(tag => (
- {tag}
+
+ {tag}
+
))}
@@ -61,12 +63,12 @@ const getPushedServiceLabelTitle = (
) => {
const pushedVal = JSON.parse(action.newValue ?? '') as CaseFullExternalService;
return (
-
-
+
+
{firstIndexPushToService === index ? i18n.PUSHED_NEW_INCIDENT : i18n.UPDATE_INCIDENT}
-
+
{pushedVal?.connector_name} {pushedVal?.external_title}
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/index.test.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/index.test.tsx
index 2bc3606ec4225..c06d3d686af88 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/index.test.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/index.test.tsx
@@ -7,36 +7,24 @@
import React from 'react';
import { mount } from 'enzyme';
-import { Router, routeData, mockHistory } from '../__mock__/router';
+import { Router, routeData, mockHistory, mockLocation } from '../__mock__/router';
+import { getFormMock } from '../__mock__/form';
+import { useUpdateComment } from '../../../../containers/case/use_update_comment';
+import { basicCase, getUserAction } from '../__mock__/case_data';
import { UserActionTree } from './';
import { TestProviders } from '../../../../mock';
-import { UserActionField } from '../../../../../../../../plugins/case/common/api/cases';
+import { useFormMock } from '../create/index.test';
+import { wait } from '../../../../lib/helpers';
+import { act } from 'react-dom/test-utils';
+jest.mock(
+ '../../../../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'
+);
const fetchUserActions = jest.fn();
const onUpdateField = jest.fn();
const updateCase = jest.fn();
const defaultProps = {
- data: {
- id: '89bae2b0-74f4-11ea-a8d2-2bcd64fb2cdd',
- version: 'WzcxNiwxXQ==',
- comments: [],
- totalComment: 0,
- description: 'This looks not so good',
- title: 'Bad meanie defacing data',
- tags: ['defacement'],
- closedAt: null,
- closedBy: null,
- createdAt: '2020-04-02T15:13:41.925Z',
- createdBy: {
- email: 'Steph.milovic@elastic.co',
- fullName: 'Steph Milovic',
- username: 'smilovic',
- },
- externalService: null,
- status: 'open',
- updatedAt: null,
- updatedBy: null,
- },
+ data: basicCase,
caseUserActions: [],
firstIndexPushToService: -1,
isLoadingDescription: false,
@@ -47,40 +35,235 @@ const defaultProps = {
onUpdateField,
updateCase,
};
+const useUpdateCommentMock = useUpdateComment as jest.Mock;
+jest.mock('../../../../containers/case/use_update_comment');
-describe.skip('UserActionTree ', () => {
+const patchComment = jest.fn();
+describe('UserActionTree ', () => {
+ const sampleData = {
+ content: 'what a great comment update',
+ };
beforeEach(() => {
+ jest.clearAllMocks();
jest.resetAllMocks();
- jest.spyOn(routeData, 'useParams').mockReturnValue({ commentId: '123' });
+ useUpdateCommentMock.mockImplementation(() => ({
+ isLoadingIds: [],
+ patchComment,
+ }));
+ const formHookMock = getFormMock(sampleData);
+ useFormMock.mockImplementation(() => ({ form: formHookMock }));
+ jest.spyOn(routeData, 'useLocation').mockReturnValue(mockLocation);
});
- it('Loading spinner when user actions loading', async () => {
- const props = defaultProps;
+ it('Loading spinner when user actions loading', () => {
const wrapper = mount(
-
+
);
expect(wrapper.find(`[data-test-subj="user-actions-loading"]`).exists()).toBeTruthy();
});
- it.only('Renders user action items', async () => {
- const commentAction = {
- actionField: [('comment' as unknown) as UserActionField['comment']],
- action: 'create',
- actionAt: '2020-04-06T21:54:19.459Z',
- actionBy: { email: '', fullName: '', username: 'casetester3' },
- newValue: 'sdfsd',
- oldValue: null,
- actionId: '2b825fb0-7851-11ea-8b3c-092fb98f129e',
- caseId: '89bae2b0-74f4-11ea-a8d2-2bcd64fb2cdd',
- commentId: '2adcf7f0-7851-11ea-8b3c-092fb98f129e',
+
+ it('Outlines comment when update move to link is clicked', () => {
+ const ourActions = [getUserAction(['comment'], 'create'), getUserAction(['comment'], 'update')];
+ const props = {
+ ...defaultProps,
+ caseUserActions: ourActions,
+ };
+ const wrapper = mount(
+
+
+
+
+
+ );
+ expect(
+ wrapper
+ .find(`[data-test-subj="comment-create-action"]`)
+ .first()
+ .prop('idToOutline')
+ ).toEqual('');
+ wrapper
+ .find(`[data-test-subj="comment-update-action"] [data-test-subj="move-to-link"]`)
+ .first()
+ .simulate('click');
+ expect(
+ wrapper
+ .find(`[data-test-subj="comment-create-action"]`)
+ .first()
+ .prop('idToOutline')
+ ).toEqual(ourActions[0].commentId);
+ });
+
+ it('Switches to markdown when edit is clicked and back to panel when canceled', () => {
+ const ourActions = [getUserAction(['comment'], 'create')];
+ const props = {
+ ...defaultProps,
+ caseUserActions: ourActions,
};
+ const wrapper = mount(
+
+
+
+
+
+ );
+ expect(
+ wrapper
+ .find(
+ `[data-test-subj="user-action-${props.data.comments[0].id}"] [data-test-subj="user-action-markdown-form"]`
+ )
+ .exists()
+ ).toEqual(false);
+ wrapper
+ .find(`[data-test-subj="comment-create-action"] [data-test-subj="property-actions-ellipses"]`)
+ .first()
+ .simulate('click');
+ wrapper
+ .find(`[data-test-subj="comment-create-action"] [data-test-subj="property-actions-pencil"]`)
+ .first()
+ .simulate('click');
+ expect(
+ wrapper
+ .find(
+ `[data-test-subj="user-action-${props.data.comments[0].id}"] [data-test-subj="user-action-markdown-form"]`
+ )
+ .exists()
+ ).toEqual(true);
+ wrapper
+ .find(
+ `[data-test-subj="user-action-${props.data.comments[0].id}"] [data-test-subj="user-action-cancel-markdown"]`
+ )
+ .first()
+ .simulate('click');
+ expect(
+ wrapper
+ .find(
+ `[data-test-subj="user-action-${props.data.comments[0].id}"] [data-test-subj="user-action-markdown-form"]`
+ )
+ .exists()
+ ).toEqual(false);
+ });
+
+ it('calls update comment when comment markdown is saved', async () => {
+ const ourActions = [getUserAction(['comment'], 'create')];
+ const props = {
+ ...defaultProps,
+ caseUserActions: ourActions,
+ };
+ const wrapper = mount(
+
+
+
+
+
+ );
+ wrapper
+ .find(`[data-test-subj="comment-create-action"] [data-test-subj="property-actions-ellipses"]`)
+ .first()
+ .simulate('click');
+ wrapper
+ .find(`[data-test-subj="comment-create-action"] [data-test-subj="property-actions-pencil"]`)
+ .first()
+ .simulate('click');
+ wrapper
+ .find(
+ `[data-test-subj="user-action-${props.data.comments[0].id}"] [data-test-subj="user-action-save-markdown"]`
+ )
+ .first()
+ .simulate('click');
+ await act(async () => {
+ await wait();
+ wrapper.update();
+ expect(
+ wrapper
+ .find(
+ `[data-test-subj="user-action-${props.data.comments[0].id}"] [data-test-subj="user-action-markdown-form"]`
+ )
+ .exists()
+ ).toEqual(false);
+ expect(patchComment).toBeCalledWith({
+ commentUpdate: sampleData.content,
+ caseId: props.data.id,
+ commentId: props.data.comments[0].id,
+ fetchUserActions,
+ updateCase,
+ version: props.data.comments[0].version,
+ });
+ });
+ });
+
+ it('calls update description when description markdown is saved', async () => {
+ const props = defaultProps;
+ const wrapper = mount(
+
+
+
+
+
+ );
+ wrapper
+ .find(`[data-test-subj="description-action"] [data-test-subj="property-actions-ellipses"]`)
+ .first()
+ .simulate('click');
+ wrapper
+ .find(`[data-test-subj="description-action"] [data-test-subj="property-actions-pencil"]`)
+ .first()
+ .simulate('click');
+ wrapper
+ .find(
+ `[data-test-subj="user-action-description"] [data-test-subj="user-action-save-markdown"]`
+ )
+ .first()
+ .simulate('click');
+ await act(async () => {
+ await wait();
+ expect(
+ wrapper
+ .find(
+ `[data-test-subj="user-action-${props.data.id}"] [data-test-subj="user-action-markdown-form"]`
+ )
+ .exists()
+ ).toEqual(false);
+ expect(onUpdateField).toBeCalledWith('description', sampleData.content);
+ });
+ });
+
+ it('quotes', async () => {
+ const commentData = {
+ comment: '',
+ };
+ const formHookMock = getFormMock(commentData);
+ const setFieldValue = jest.fn();
+ useFormMock.mockImplementation(() => ({ form: { ...formHookMock, setFieldValue } }));
+ const props = defaultProps;
+ const wrapper = mount(
+
+
+
+
+
+ );
+ wrapper
+ .find(`[data-test-subj="description-action"] [data-test-subj="property-actions-ellipses"]`)
+ .first()
+ .simulate('click');
+ wrapper
+ .find(`[data-test-subj="description-action"] [data-test-subj="property-actions-quote"]`)
+ .first()
+ .simulate('click');
+ expect(setFieldValue).toBeCalledWith('comment', `> ${props.data.description} \n`);
+ });
+ it('Outlines comment when url param is provided', () => {
+ const commentId = 'neat-comment-id';
+ const ourActions = [getUserAction(['comment'], 'create')];
const props = {
...defaultProps,
- caseUserActions: [commentAction],
+ caseUserActions: ourActions,
};
+ jest.spyOn(routeData, 'useParams').mockReturnValue({ commentId });
const wrapper = mount(
@@ -90,8 +273,9 @@ describe.skip('UserActionTree ', () => {
);
expect(
wrapper
- .find(`[data-test-subj="comment-action"] [data-test-subj="user-action-title"] strong`)
- .text()
- ).toEqual(commentAction.actionBy.username);
+ .find(`[data-test-subj="comment-create-action"]`)
+ .first()
+ .prop('idToOutline')
+ ).toEqual(commentId);
});
});
diff --git a/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/index.tsx b/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/index.tsx
index d3baf2060f595..a8585a8190215 100644
--- a/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/index.tsx
+++ b/x-pack/legacy/plugins/siem/public/pages/case/components/user_action_tree/index.tsx
@@ -52,26 +52,12 @@ export const UserActionTree = React.memo(
updateCase,
userCanCrud,
}: UserActionTreeProps) => {
- // console.log('userActionTree props', {
- // data: caseData,
- // caseUserActions,
- // fetchUserActions,
- // firstIndexPushToService,
- // isLoadingDescription,
- // isLoadingUserActions,
- // lastIndexPushToService,
- // onUpdateField,
- // updateCase,
- // userCanCrud,
- // });
const { commentId } = useParams();
const handlerTimeoutId = useRef(0);
const [initLoading, setInitLoading] = useState(true);
const [selectedOutlineCommentId, setSelectedOutlineCommentId] = useState('');
const { isLoadingIds, patchComment } = useUpdateComment();
- // console.log('useUpdateComment', { isLoadingIds, patchComment })
const currentUser = useCurrentUser();
- // console.log('useCurrentUser', currentUser)
const [manageMarkdownEditIds, setManangeMardownEditIds] = useState([]);
const [insertQuote, setInsertQuote] = useState(null);
const handleManageMarkdownEditId = useCallback(
@@ -87,7 +73,7 @@ export const UserActionTree = React.memo(
const handleSaveComment = useCallback(
({ id, version }: { id: string; version: string }, content: string) => {
- handleManageMarkdownEditId(id);
+ // handleManageMarkdownEditId(id);
patchComment({
caseId: caseData.id,
commentId: id,
@@ -148,7 +134,6 @@ export const UserActionTree = React.memo(
content={caseData.description}
isEditable={manageMarkdownEditIds.includes(DESCRIPTION_ID)}
onSaveContent={(content: string) => {
- handleManageMarkdownEditId(DESCRIPTION_ID);
onUpdateField(DESCRIPTION_ID, content);
}}
onChangeEditable={handleManageMarkdownEditId}
@@ -179,7 +164,6 @@ export const UserActionTree = React.memo(
}
}
}, [commentId, initLoading, isLoadingUserActions, isLoadingIds]);
-
return (
<>
}>
@@ -164,6 +162,7 @@ export const UserActionTitle = ({
{i18n.COPY_REFERENCE_LINK}}>