Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('CustomFields', () => {
configurationCustomFields: customFieldsConfigurationMock,
isLoading: false,
setCustomFieldsOptional: false,
isEditMode: false,
};

beforeEach(() => {
Expand Down Expand Up @@ -77,6 +78,23 @@ describe('CustomFields', () => {
expect(screen.getAllByTestId('form-optional-field-label')).toHaveLength(2);
});

it('should not set default value when in edit mode', async () => {
appMockRender.render(
<FormTestComponent onSubmit={onSubmit}>
<CustomFields
isLoading={false}
configurationCustomFields={[customFieldsConfigurationMock[0]]}
setCustomFieldsOptional={false}
isEditMode={true}
/>
</FormTestComponent>
);

expect(
screen.queryByText(`${customFieldsConfigurationMock[0].defaultValue}`)
).not.toBeInTheDocument();
});

it('should sort the custom fields correctly', async () => {
const reversedCustomFieldsConfiguration = [...customFieldsConfigurationMock].reverse();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ interface Props {
isLoading: boolean;
setCustomFieldsOptional: boolean;
configurationCustomFields: CasesConfigurationUI['customFields'];
isEditMode?: boolean;
}

const CustomFieldsComponent: React.FC<Props> = ({
isLoading,
setCustomFieldsOptional,
configurationCustomFields,
isEditMode,
}) => {
const sortedCustomFields = useMemo(
() => sortCustomFieldsByLabel(configurationCustomFields),
Expand All @@ -42,6 +44,7 @@ const CustomFieldsComponent: React.FC<Props> = ({
customFieldConfiguration={customField}
key={customField.key}
setAsOptional={setCustomFieldsOptional}
setDefaultValue={!isEditMode}
/>
);
}
Expand Down
120 changes: 111 additions & 9 deletions x-pack/plugins/cases/public/components/case_form_fields/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ jest.mock('../../containers/user_profiles/api');
describe('CaseFormFields', () => {
let appMock: AppMockRenderer;
const onSubmit = jest.fn();
const formDefaultValue = { tags: [] };
const defaultProps = {
isLoading: false,
configurationCustomFields: [],
Expand All @@ -36,7 +37,7 @@ describe('CaseFormFields', () => {

it('renders correctly', async () => {
appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);
Expand All @@ -46,7 +47,7 @@ describe('CaseFormFields', () => {

it('renders case fields correctly', async () => {
appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);
Expand All @@ -60,7 +61,7 @@ describe('CaseFormFields', () => {

it('does not render customFields when empty', () => {
appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);
Expand All @@ -70,7 +71,7 @@ describe('CaseFormFields', () => {

it('renders customFields when not empty', async () => {
appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields
isLoading={false}
configurationCustomFields={customFieldsConfigurationMock}
Expand All @@ -83,7 +84,7 @@ describe('CaseFormFields', () => {

it('does not render assignees when no platinum license', () => {
appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);
Expand All @@ -99,7 +100,7 @@ describe('CaseFormFields', () => {
appMock = createAppMockRenderer({ license });

appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);
Expand All @@ -109,7 +110,7 @@ describe('CaseFormFields', () => {

it('calls onSubmit with case fields', async () => {
appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);
Expand Down Expand Up @@ -145,14 +146,44 @@ describe('CaseFormFields', () => {
});
});

it('calls onSubmit with existing case fields', async () => {
appMock.render(
<FormTestComponent
formDefaultValue={{
title: 'Case with Template 1',
description: 'This is a case description',
tags: ['case-tag-1', 'case-tag-2'],
category: null,
}}
onSubmit={onSubmit}
>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);

userEvent.click(await screen.findByText('Submit'));

await waitFor(() => {
expect(onSubmit).toBeCalledWith(
{
category: null,
tags: ['case-tag-1', 'case-tag-2'],
description: 'This is a case description',
title: 'Case with Template 1',
},
true
);
});
});

it('calls onSubmit with custom fields', async () => {
const newProps = {
...defaultProps,
configurationCustomFields: customFieldsConfigurationMock,
};

appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields {...newProps} />
</FormTestComponent>
);
Expand Down Expand Up @@ -191,6 +222,44 @@ describe('CaseFormFields', () => {
});
});

it('calls onSubmit with existing custom fields', async () => {
const newProps = {
...defaultProps,
configurationCustomFields: customFieldsConfigurationMock,
};

appMock.render(
<FormTestComponent
formDefaultValue={{
customFields: { [customFieldsConfigurationMock[0].key]: 'Test custom filed value' },
tags: [],
}}
onSubmit={onSubmit}
>
<CaseFormFields {...newProps} />
</FormTestComponent>
);

expect(await screen.findByTestId('caseCustomFields')).toBeInTheDocument();

userEvent.click(await screen.findByText('Submit'));

await waitFor(() => {
expect(onSubmit).toBeCalledWith(
{
category: null,
tags: [],
customFields: {
test_key_1: 'Test custom filed value',
test_key_2: true,
test_key_4: false,
},
},
true
);
});
});

it('calls onSubmit with assignees', async () => {
const license = licensingMock.createLicense({
license: { type: 'platinum' },
Expand All @@ -199,7 +268,7 @@ describe('CaseFormFields', () => {
appMock = createAppMockRenderer({ license });

appMock.render(
<FormTestComponent onSubmit={onSubmit}>
<FormTestComponent formDefaultValue={formDefaultValue} onSubmit={onSubmit}>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);
Expand All @@ -225,4 +294,37 @@ describe('CaseFormFields', () => {
);
});
});

it('calls onSubmit with existing assignees', async () => {
const license = licensingMock.createLicense({
license: { type: 'platinum' },
});

appMock = createAppMockRenderer({ license });

appMock.render(
<FormTestComponent
formDefaultValue={{
assignees: [{ uid: userProfiles[1].uid }],
tags: [],
}}
onSubmit={onSubmit}
>
<CaseFormFields {...defaultProps} />
</FormTestComponent>
);

userEvent.click(await screen.findByText('Submit'));

await waitFor(() => {
expect(onSubmit).toBeCalledWith(
{
category: null,
tags: [],
assignees: [{ uid: userProfiles[1].uid }],
},
true
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ interface Props {
isLoading: boolean;
configurationCustomFields: CasesConfigurationUI['customFields'];
setCustomFieldsOptional?: boolean;
isEditMode?: boolean;
}

const CaseFormFieldsComponent: React.FC<Props> = ({
isLoading,
configurationCustomFields,
setCustomFieldsOptional = false,
isEditMode,
}) => {
const { caseAssignmentAuthorized } = useCasesFeatures();

Expand All @@ -48,6 +50,7 @@ const CaseFormFieldsComponent: React.FC<Props> = ({
isLoading={isLoading}
setCustomFieldsOptional={setCustomFieldsOptional}
configurationCustomFields={configurationCustomFields}
isEditMode={isEditMode}
/>
</EuiFlexGroup>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* 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 userEvent from '@testing-library/user-event';
import React from 'react';
import type { AppMockRenderer } from '../../common/mock';
import { createAppMockRenderer } from '../../common/mock';
import { DeleteConfirmationModal } from './delete_confirmation_modal';

describe('DeleteConfirmationModal', () => {
let appMock: AppMockRenderer;
const props = {
title: 'My custom field',
message: 'This is a sample message',
onCancel: jest.fn(),
onConfirm: jest.fn(),
};

beforeEach(() => {
appMock = createAppMockRenderer();
jest.clearAllMocks();
});

it('renders correctly', async () => {
const result = appMock.render(<DeleteConfirmationModal {...props} />);

expect(result.getByTestId('confirm-delete-modal')).toBeInTheDocument();
expect(result.getByText('Delete')).toBeInTheDocument();
expect(result.getByText('Cancel')).toBeInTheDocument();
});

it('calls onConfirm', async () => {
const result = appMock.render(<DeleteConfirmationModal {...props} />);

expect(result.getByText('Delete')).toBeInTheDocument();
userEvent.click(result.getByText('Delete'));

expect(props.onConfirm).toHaveBeenCalled();
});

it('calls onCancel', async () => {
const result = appMock.render(<DeleteConfirmationModal {...props} />);

expect(result.getByText('Cancel')).toBeInTheDocument();
userEvent.click(result.getByText('Cancel'));

expect(props.onCancel).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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 { EuiConfirmModal } from '@elastic/eui';
import * as i18n from '../custom_fields/translations';

interface ConfirmDeleteCaseModalProps {
title: string;
message: string;
onCancel: () => void;
onConfirm: () => void;
}

const DeleteConfirmationModalComponent: React.FC<ConfirmDeleteCaseModalProps> = ({
title,
message,
onCancel,
onConfirm,
}) => {
return (
<EuiConfirmModal
buttonColor="danger"
cancelButtonText={i18n.CANCEL}
data-test-subj="confirm-delete-modal"
defaultFocusedButton="confirm"
onCancel={onCancel}
onConfirm={onConfirm}
title={title}
confirmButtonText={i18n.DELETE}
>
{message}
</EuiConfirmModal>
);
};
DeleteConfirmationModalComponent.displayName = 'DeleteConfirmationModal';

export const DeleteConfirmationModal = React.memo(DeleteConfirmationModalComponent);
Loading