From 8e339305e62440dc2047689b70be3a639cd7a2d9 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Thu, 6 May 2021 18:33:31 +0300 Subject: [PATCH 01/17] Pass onwer to create form --- .../public/components/create/flyout.test.tsx | 1 + .../cases/public/components/create/flyout.tsx | 4 ++- .../components/create/form_context.test.tsx | 30 ++++++++++++------- .../public/components/create/form_context.tsx | 12 ++++---- .../public/components/create/index.test.tsx | 6 ++-- .../cases/public/components/create/index.tsx | 3 ++ .../create_case_modal.test.tsx | 1 + .../create_case_modal.tsx | 3 ++ .../use_create_case_modal/index.test.tsx | 10 +++---- .../use_create_case_modal/index.tsx | 5 +++- .../public/cases/components/create/flyout.tsx | 3 +- .../cases/components/create/index.test.tsx | 1 + .../public/cases/components/create/index.tsx | 2 ++ 13 files changed, 54 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/cases/public/components/create/flyout.test.tsx b/x-pack/plugins/cases/public/components/create/flyout.test.tsx index 5187029ab60c7..0dbf59f42898b 100644 --- a/x-pack/plugins/cases/public/components/create/flyout.test.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout.test.tsx @@ -59,6 +59,7 @@ const onSuccess = jest.fn(); const defaultProps = { onCloseFlyout, onSuccess, + owner: 'securitySolution', }; describe('CreateCaseFlyout', () => { diff --git a/x-pack/plugins/cases/public/components/create/flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout.tsx index 8ed09865e9eab..63fa27511bd7b 100644 --- a/x-pack/plugins/cases/public/components/create/flyout.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout.tsx @@ -19,6 +19,7 @@ export interface CreateCaseModalProps { onCloseFlyout: () => void; onSuccess: (theCase: Case) => Promise; afterCaseCreated?: (theCase: Case) => Promise; + owner: string; } const Container = styled.div` @@ -44,6 +45,7 @@ const CreateCaseFlyoutComponent: React.FC = ({ onSuccess, afterCaseCreated, onCloseFlyout, + owner, }) => { return ( @@ -54,7 +56,7 @@ const CreateCaseFlyoutComponent: React.FC = ({ - + diff --git a/x-pack/plugins/cases/public/components/create/form_context.test.tsx b/x-pack/plugins/cases/public/components/create/form_context.test.tsx index 9a8671c7fc571..282422f51cb2f 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.test.tsx @@ -138,7 +138,7 @@ describe('Create case', () => { it('it renders', async () => { const wrapper = mount( - + @@ -162,7 +162,7 @@ describe('Create case', () => { const wrapper = mount( - + @@ -182,7 +182,7 @@ describe('Create case', () => { const wrapper = mount( - + @@ -217,7 +217,7 @@ describe('Create case', () => { const wrapper = mount( - + @@ -267,7 +267,7 @@ describe('Create case', () => { const wrapper = mount( - + @@ -292,7 +292,7 @@ describe('Create case', () => { const wrapper = mount( - + @@ -359,7 +359,7 @@ describe('Create case', () => { const wrapper = mount( - + @@ -427,7 +427,7 @@ describe('Create case', () => { const wrapper = mount( - + @@ -517,7 +517,7 @@ describe('Create case', () => { const wrapper = mount( - + @@ -615,7 +615,11 @@ describe('Create case', () => { const wrapper = mount( - + @@ -652,7 +656,11 @@ describe('Create case', () => { const wrapper = mount( - + diff --git a/x-pack/plugins/cases/public/components/create/form_context.tsx b/x-pack/plugins/cases/public/components/create/form_context.tsx index 9ee8aa0fe3288..c630a6df86205 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.tsx @@ -37,6 +37,7 @@ interface Props { children?: JSX.Element | JSX.Element[]; hideConnectorServiceNowSir?: boolean; onSuccess?: (theCase: Case) => Promise; + owner: string; } export const FormContext: React.FC = ({ @@ -45,6 +46,7 @@ export const FormContext: React.FC = ({ children, hideConnectorServiceNowSir, onSuccess, + owner, }) => { const { connectors, loading: isLoadingConnectors } = useConnectors(); const { connector: configurationConnector } = useCaseConfigure(); @@ -86,8 +88,7 @@ export const FormContext: React.FC = ({ type: caseType, connector: connectorToUpdate, settings: { syncAlerts }, - // TODO: need to replace this with the value that the plugin registers in the feature registration - owner: 'securitySolution', + owner, }); if (afterCaseCreated && updatedCase) { @@ -107,13 +108,14 @@ export const FormContext: React.FC = ({ } }, [ - caseType, connectors, postCase, - postComment, + caseType, + owner, + afterCaseCreated, onSuccess, + postComment, pushCaseToExternalService, - afterCaseCreated, ] ); diff --git a/x-pack/plugins/cases/public/components/create/index.test.tsx b/x-pack/plugins/cases/public/components/create/index.test.tsx index e82af8edc6337..8eb1a565c43bf 100644 --- a/x-pack/plugins/cases/public/components/create/index.test.tsx +++ b/x-pack/plugins/cases/public/components/create/index.test.tsx @@ -91,7 +91,7 @@ describe('CreateCase case', () => { it('it renders', async () => { const wrapper = mount( - + ); @@ -102,7 +102,7 @@ describe('CreateCase case', () => { it('should call cancel on cancel click', async () => { const wrapper = mount( - + ); @@ -113,7 +113,7 @@ describe('CreateCase case', () => { it('should redirect to new case when posting the case', async () => { const wrapper = mount( - + ); diff --git a/x-pack/plugins/cases/public/components/create/index.tsx b/x-pack/plugins/cases/public/components/create/index.tsx index a1de4d9730b9f..56b995a1dadd0 100644 --- a/x-pack/plugins/cases/public/components/create/index.tsx +++ b/x-pack/plugins/cases/public/components/create/index.tsx @@ -37,6 +37,7 @@ export interface CreateCaseProps { onSuccess: (theCase: Case) => Promise; timelineIntegration?: CasesTimelineIntegration; withSteps?: boolean; + owner: string; } export const CreateCase = ({ @@ -47,6 +48,7 @@ export const CreateCase = ({ onSuccess, timelineIntegration, withSteps, + owner, }: CreateCaseProps) => ( { diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.tsx index e78b432b3a27c..0650295214c3e 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.tsx @@ -19,6 +19,7 @@ export interface CreateCaseModalProps { isModalOpen: boolean; onCloseCaseModal: () => void; onSuccess: (theCase: Case) => Promise; + owner: string; } const CreateModalComponent: React.FC = ({ @@ -27,6 +28,7 @@ const CreateModalComponent: React.FC = ({ isModalOpen, onCloseCaseModal, onSuccess, + owner, }) => { return isModalOpen ? ( @@ -40,6 +42,7 @@ const CreateModalComponent: React.FC = ({ onCancel: onCloseCaseModal, onSuccess, withSteps: false, + owner, })} diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx index b227dd4b898b2..c47e9cbe460d8 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx @@ -28,7 +28,7 @@ describe('useCreateCaseModal', () => { it('init', async () => { const { result } = renderHook( - () => useCreateCaseModal({ onCaseCreated }), + () => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), { wrapper: ({ children }) => {children}, } @@ -39,7 +39,7 @@ describe('useCreateCaseModal', () => { it('opens the modal', async () => { const { result } = renderHook( - () => useCreateCaseModal({ onCaseCreated }), + () => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), { wrapper: ({ children }) => {children}, } @@ -54,7 +54,7 @@ describe('useCreateCaseModal', () => { it('closes the modal', async () => { const { result } = renderHook( - () => useCreateCaseModal({ onCaseCreated }), + () => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), { wrapper: ({ children }) => {children}, } @@ -72,7 +72,7 @@ describe('useCreateCaseModal', () => { const { result, rerender } = renderHook< UseCreateCaseModalProps, UseCreateCaseModalReturnedValues - >(() => useCreateCaseModal({ onCaseCreated }), { + >(() => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), { wrapper: ({ children }) => {children}, }); @@ -85,7 +85,7 @@ describe('useCreateCaseModal', () => { it('closes the modal when creating a case', async () => { const { result } = renderHook( - () => useCreateCaseModal({ onCaseCreated }), + () => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), { wrapper: ({ children }) => {children}, } diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx index 7ad85773a7917..2b1f73c0411a9 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx @@ -13,6 +13,7 @@ export interface UseCreateCaseModalProps { onCaseCreated: (theCase: Case) => void; caseType?: CaseType; hideConnectorServiceNowSir?: boolean; + owner: string; } export interface UseCreateCaseModalReturnedValues { modal: JSX.Element; @@ -25,6 +26,7 @@ export const useCreateCaseModal = ({ caseType = CaseType.individual, onCaseCreated, hideConnectorServiceNowSir = false, + owner, }: UseCreateCaseModalProps) => { const [isModalOpen, setIsModalOpen] = useState(false); const closeModal = useCallback(() => setIsModalOpen(false), []); @@ -46,12 +48,13 @@ export const useCreateCaseModal = ({ isModalOpen={isModalOpen} onCloseCaseModal={closeModal} onSuccess={onSuccess} + owner={owner} /> ), isModalOpen, closeModal, openModal, }), - [caseType, closeModal, hideConnectorServiceNowSir, isModalOpen, onSuccess, openModal] + [caseType, closeModal, hideConnectorServiceNowSir, isModalOpen, onSuccess, openModal, owner] ); }; diff --git a/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx b/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx index 0f9f64b32bdd0..826810c4d4086 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx @@ -11,7 +11,7 @@ import { EuiFlyout, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eu import * as i18n from '../../translations'; import { useKibana } from '../../../common/lib/kibana'; -import { Case } from '../../../../../cases/common'; +import { APP_ID, Case } from '../../../../../cases/common'; export interface CreateCaseModalProps { afterCaseCreated?: (theCase: Case) => Promise; @@ -65,6 +65,7 @@ const CreateCaseFlyoutComponent: React.FC = ({ onCancel: onCloseFlyout, onSuccess, withSteps: false, + owner: APP_ID, })} diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx index 2d5faef8aa009..007ab7f47e301 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx @@ -47,6 +47,7 @@ describe('Create case', () => { ); expect(mockCreateCase).toHaveBeenCalled(); + expect(mockCreateCase.mock.calls[0][0].owner).toBe('securitySolution'); }); it('should redirect to all cases on cancel click', async () => { diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx index 4a1a64f5fcb41..2e6ddccddc789 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx @@ -13,6 +13,7 @@ import { getCaseDetailsUrl } from '../../../common/components/link_to'; import { useKibana } from '../../../common/lib/kibana'; import * as timelineMarkdownPlugin from '../../../common/components/markdown_editor/plugins/timeline'; import { useInsertTimeline } from '../use_insert_timeline'; +import { APP_ID } from '../../../../common/constants'; export const Create = React.memo(() => { const { cases } = useKibana().services; @@ -43,6 +44,7 @@ export const Create = React.memo(() => { useInsertTimeline, }, }, + owner: APP_ID, })} ); From cb62698c6357a4d72aa16eb31482187cfd966198 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Tue, 11 May 2021 20:36:13 +0300 Subject: [PATCH 02/17] Pass owner to get cases --- x-pack/plugins/cases/common/ui/types.ts | 1 + .../all_cases/all_cases_generic.tsx | 5 ++++- .../components/all_cases/index.test.tsx | 1 + .../public/components/all_cases/index.tsx | 1 + .../all_cases/selector_modal/index.test.tsx | 1 + .../all_cases/selector_modal/index.tsx | 3 +++ .../components/all_cases/table_filters.tsx | 1 + .../connectors/case/alert_fields.tsx | 10 ++++++++- .../connectors/case/existing_case.tsx | 22 +++++++++++++++---- .../components/recent_cases/index.test.tsx | 1 + .../public/components/recent_cases/index.tsx | 3 +++ .../components/recent_cases/recent_cases.tsx | 7 +++++- .../cases/public/containers/__mocks__/api.ts | 1 + x-pack/plugins/cases/public/containers/api.ts | 2 ++ .../cases/public/containers/use_get_cases.tsx | 13 ++++++++--- .../cases/components/all_cases/index.tsx | 1 + .../timeline_actions/add_to_case_action.tsx | 1 + .../components/recent_cases/index.tsx | 1 + .../flyout/add_to_case_button/index.tsx | 1 + 19 files changed, 66 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/cases/common/ui/types.ts b/x-pack/plugins/cases/common/ui/types.ts index 7004fd2ab2ea2..0754dd4be7971 100644 --- a/x-pack/plugins/cases/common/ui/types.ts +++ b/x-pack/plugins/cases/common/ui/types.ts @@ -101,6 +101,7 @@ export interface FilterOptions { status: CaseStatusWithAllStatus; tags: string[]; reporters: User[]; + owner: string[]; onlyCollectionType?: boolean; } diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx index 83f38aab21aa4..e4e7844939403 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx @@ -64,6 +64,7 @@ interface AllCasesGenericProps { onRowClick?: (theCase?: Case | SubCase) => void; updateCase?: (newCase: Case) => void; userCanCrud: boolean; + owner: string[]; } export const AllCasesGeneric = React.memo( @@ -77,6 +78,7 @@ export const AllCasesGeneric = React.memo( onRowClick, updateCase, userCanCrud, + owner, }) => { const { actionLicense } = useGetActionLicense(); const { @@ -90,7 +92,7 @@ export const AllCasesGeneric = React.memo( setFilters, setQueryParams, setSelectedCases, - } = useGetCases(); + } = useGetCases({ initialFilterOptions: { owner } }); // Post Comment to Case const { postComment, isLoading: isCommentUpdating } = usePostComment(); @@ -286,6 +288,7 @@ export const AllCasesGeneric = React.memo( reporters: filterOptions.reporters, tags: filterOptions.tags, status: filterOptions.status, + owner: filterOptions.owner, }} setFilterRefetch={setFilterRefetch} disabledStatuses={disabledStatuses} diff --git a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx index 7233d6bef6e4a..582209ffcbeed 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx @@ -53,6 +53,7 @@ describe('AllCasesGeneric', () => { onClick: jest.fn(), }, userCanCrud: true, + owner: ['securitySolution'], }; const dispatchResetIsDeleted = jest.fn(); diff --git a/x-pack/plugins/cases/public/components/all_cases/index.tsx b/x-pack/plugins/cases/public/components/all_cases/index.tsx index 2c506cd2da411..11b8d55b92c1e 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.tsx @@ -13,6 +13,7 @@ export interface AllCasesProps { configureCasesNavigation: CasesNavigation; // if not passed, header with nav is not displayed (Formerly dependant on isSelector) createCaseNavigation: CasesNavigation; userCanCrud: boolean; + owner: string[]; } export const AllCases: React.FC = (props) => { diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.test.tsx index b2444c5ccb0dd..8c22a2ec0dd0b 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.test.tsx @@ -20,6 +20,7 @@ const defaultProps = { createCaseNavigation, onRowClick, userCanCrud: true, + owner: ['securitySolution'], }; const updateCase = jest.fn(); diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx index 0a83ef13e8ee6..27f734123321a 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx @@ -20,6 +20,7 @@ export interface AllCasesSelectorModalProps { onRowClick: (theCase?: Case | SubCase) => void; updateCase?: (newCase: Case) => void; userCanCrud: boolean; + owner: string[]; } const Modal = styled(EuiModal)` @@ -36,6 +37,7 @@ export const AllCasesSelectorModal: React.FC = ({ onRowClick, updateCase, userCanCrud, + owner, }) => { const [isModalOpen, setIsModalOpen] = useState(true); const closeModal = useCallback(() => setIsModalOpen(false), []); @@ -60,6 +62,7 @@ export const AllCasesSelectorModal: React.FC = ({ onRowClick={onClick} userCanCrud={userCanCrud} updateCase={updateCase} + owner={owner} /> diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx index 9428a374a0314..e303479908cdd 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx @@ -47,6 +47,7 @@ const defaultInitial = { reporters: [], status: StatusAll, tags: [], + owner: [], }; const CasesTableFiltersComponent = ({ diff --git a/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx b/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx index 0c44bcab70679..82a355ca79f39 100644 --- a/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx +++ b/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx @@ -89,9 +89,17 @@ const CaseParamsFields: React.FunctionComponent - +

{i18n.CASE_CONNECTOR_CALL_OUT_MSG}

diff --git a/x-pack/plugins/cases/public/components/connectors/case/existing_case.tsx b/x-pack/plugins/cases/public/components/connectors/case/existing_case.tsx index 22798843dd856..73d3867573117 100644 --- a/x-pack/plugins/cases/public/components/connectors/case/existing_case.tsx +++ b/x-pack/plugins/cases/public/components/connectors/case/existing_case.tsx @@ -18,12 +18,25 @@ import { CasesDropdown, ADD_CASE_BUTTON_ID } from './cases_dropdown'; interface ExistingCaseProps { selectedCase: string | null; onCaseChanged: (id: string) => void; + /** + * We allow only one owner as this component queries + * for multiple cases and creates a single case. + */ + owner: string; } -const ExistingCaseComponent: React.FC = ({ onCaseChanged, selectedCase }) => { - const { data: cases, loading: isLoadingCases, refetchCases } = useGetCases(DEFAULT_QUERY_PARAMS, { - ...DEFAULT_FILTER_OPTIONS, - onlyCollectionType: true, +const ExistingCaseComponent: React.FC = ({ + onCaseChanged, + selectedCase, + owner, +}) => { + const { data: cases, loading: isLoadingCases, refetchCases } = useGetCases({ + initialQueryParams: DEFAULT_QUERY_PARAMS, + initialFilterOptions: { + ...DEFAULT_FILTER_OPTIONS, + onlyCollectionType: true, + owner: [owner], + }, }); const onCaseCreated = useCallback( @@ -41,6 +54,7 @@ const ExistingCaseComponent: React.FC = ({ onCaseChanged, sel // We are making the assumption that this component is only used in rules creation // that's why we want to hide ServiceNow SIR hideConnectorServiceNowSir: true, + owner, }); const onChange = useCallback( diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx index 933ea51bffac4..d84dd9aba8e5e 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx @@ -28,6 +28,7 @@ const defaultProps = { onClick: jest.fn(), }, maxCasesToShow: 10, + owner: ['securitySolution'], }; const setFilters = jest.fn(); const mockData = { diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.tsx index 05aff25d0dbd8..ed1a0b5c0908c 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.tsx @@ -20,6 +20,7 @@ export interface RecentCasesProps { caseDetailsNavigation: CasesNavigation; createCaseNavigation: CasesNavigation; maxCasesToShow: number; + owner: string[]; } const RecentCases = ({ @@ -27,6 +28,7 @@ const RecentCases = ({ caseDetailsNavigation, createCaseNavigation, maxCasesToShow, + owner, }: RecentCasesProps) => { const currentUser = useCurrentUser(); const [recentCasesFilterBy, setRecentCasesFilterBy] = useState( @@ -74,6 +76,7 @@ const RecentCases = ({ createCaseNavigation={createCaseNavigation} filterOptions={recentCasesFilterOptions} maxCasesToShow={maxCasesToShow} + owner={owner} /> diff --git a/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx b/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx index 12935e75c064f..905360c1754af 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx @@ -31,6 +31,7 @@ export interface RecentCasesProps { caseDetailsNavigation: CasesNavigation; createCaseNavigation: CasesNavigation; maxCasesToShow: number; + owner: string[]; } const usePrevious = (value: Partial) => { const ref = useRef(); @@ -44,9 +45,13 @@ export const RecentCasesComp = ({ createCaseNavigation, filterOptions, maxCasesToShow, + owner, }: RecentCasesProps) => { const previousFilterOptions = usePrevious(filterOptions); - const { data, loading, setFilters } = useGetCases({ perPage: maxCasesToShow }); + const { data, loading, setFilters } = useGetCases({ + initialQueryParams: { perPage: maxCasesToShow }, + initialFilterOptions: { owner }, + }); useEffect(() => { if (previousFilterOptions !== undefined && !isEqual(previousFilterOptions, filterOptions)) { diff --git a/x-pack/plugins/cases/public/containers/__mocks__/api.ts b/x-pack/plugins/cases/public/containers/__mocks__/api.ts index 4dbb10da95b2d..006ad3f7afe60 100644 --- a/x-pack/plugins/cases/public/containers/__mocks__/api.ts +++ b/x-pack/plugins/cases/public/containers/__mocks__/api.ts @@ -62,6 +62,7 @@ export const getCases = async ({ reporters: [], status: CaseStatuses.open, tags: [], + owner: [], }, queryParams = { page: 1, diff --git a/x-pack/plugins/cases/public/containers/api.ts b/x-pack/plugins/cases/public/containers/api.ts index 75263d4d38978..98b304635f7a7 100644 --- a/x-pack/plugins/cases/public/containers/api.ts +++ b/x-pack/plugins/cases/public/containers/api.ts @@ -171,6 +171,7 @@ export const getCases = async ({ reporters: [], status: StatusAll, tags: [], + owner: [], }, queryParams = { page: 1, @@ -186,6 +187,7 @@ export const getCases = async ({ status: filterOptions.status, ...(filterOptions.search.length > 0 ? { search: filterOptions.search } : {}), ...(filterOptions.onlyCollectionType ? { type: CaseType.collection } : {}), + ...(filterOptions.owner.length > 0 ? { owner: filterOptions.owner } : {}), ...queryParams, }; const response = await KibanaServices.get().http.fetch(`${CASES_URL}/_find`, { diff --git a/x-pack/plugins/cases/public/containers/use_get_cases.tsx b/x-pack/plugins/cases/public/containers/use_get_cases.tsx index ec1abd6214926..6d6fcc581ab3c 100644 --- a/x-pack/plugins/cases/public/containers/use_get_cases.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_cases.tsx @@ -105,6 +105,7 @@ export const DEFAULT_FILTER_OPTIONS: FilterOptions = { status: StatusAll, tags: [], onlyCollectionType: false, + owner: [], }; export const DEFAULT_QUERY_PARAMS: QueryParams = { @@ -139,12 +140,18 @@ export interface UseGetCases extends UseGetCasesState { const empty = {}; export const useGetCases = ( - initialQueryParams: Partial = empty, - initialFilterOptions: Partial = empty + params: Partial<{ + initialQueryParams?: Partial; + initialFilterOptions?: Partial; + }> = {} ): UseGetCases => { + const { initialQueryParams = empty, initialFilterOptions = empty } = params; const [state, dispatch] = useReducer(dataFetchReducer, { data: initialData, - filterOptions: { ...DEFAULT_FILTER_OPTIONS, ...initialFilterOptions }, + filterOptions: { + ...DEFAULT_FILTER_OPTIONS, + ...initialFilterOptions, + }, isError: false, loading: [], queryParams: { ...DEFAULT_QUERY_PARAMS, ...initialQueryParams }, diff --git a/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx index 60fa0e4aafd8e..337c07fa93eab 100644 --- a/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx @@ -73,6 +73,7 @@ export const AllCases = React.memo(({ userCanCrud }) => { onClick: goToCreateCase, }, userCanCrud, + owner: [APP_ID], }); }); diff --git a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx index f7594dbb4c180..d43ef4cd63fb8 100644 --- a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx @@ -248,6 +248,7 @@ const AddToCaseActionComponent: React.FC = ({ onRowClick: onCaseClicked, updateCase: onCaseSuccess, userCanCrud: userPermissions?.crud ?? false, + owner: [APP_ID], })} ); diff --git a/x-pack/plugins/security_solution/public/overview/components/recent_cases/index.tsx b/x-pack/plugins/security_solution/public/overview/components/recent_cases/index.tsx index bcf9953d70d83..fc2e2e87ffc5f 100644 --- a/x-pack/plugins/security_solution/public/overview/components/recent_cases/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/recent_cases/index.tsx @@ -58,6 +58,7 @@ const RecentCasesComponent = () => { }, }, maxCasesToShow: MAX_CASES_TO_SHOW, + owner: [APP_ID], }); }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/add_to_case_button/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/add_to_case_button/index.tsx index a4c6fe1e344b3..0f583b838d86c 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/add_to_case_button/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/add_to_case_button/index.tsx @@ -177,6 +177,7 @@ const AddToCaseButtonComponent: React.FC = ({ timelineId }) => { }, onRowClick, userCanCrud: userPermissions?.crud ?? false, + owner: [APP_ID], })} ); From 242f608c5ddf62f3b672fd1052f12c875730a10f Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Wed, 12 May 2021 12:35:13 +0300 Subject: [PATCH 03/17] Pass owner to tags and reporters --- .../components/all_cases/table_filters.tsx | 4 ++-- .../public/components/case_view/index.tsx | 1 + .../public/components/create/form.test.tsx | 8 ++++---- .../cases/public/components/create/form.tsx | 6 ++++-- .../public/components/create/form_context.tsx | 2 -- .../cases/public/components/create/index.tsx | 1 + .../public/components/create/tags.test.tsx | 6 +++--- .../cases/public/components/create/tags.tsx | 5 +++-- .../public/components/tag_list/index.test.tsx | 1 + .../public/components/tag_list/index.tsx | 5 +++-- .../cases/public/containers/api.test.tsx | 8 ++++---- x-pack/plugins/cases/public/containers/api.ts | 6 ++++-- .../containers/use_get_reporters.test.tsx | 12 ++++++----- .../public/containers/use_get_reporters.tsx | 6 +++--- .../public/containers/use_get_tags.test.tsx | 20 ++++++++++++++----- .../cases/public/containers/use_get_tags.tsx | 4 ++-- 16 files changed, 57 insertions(+), 38 deletions(-) diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx index e303479908cdd..0bde3a7cc7409 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx @@ -64,8 +64,8 @@ const CasesTableFiltersComponent = ({ ); const [search, setSearch] = useState(initial.search); const [selectedTags, setSelectedTags] = useState(initial.tags); - const { tags, fetchTags } = useGetTags(); - const { reporters, respReporters, fetchReporters } = useGetReporters(); + const { tags, fetchTags } = useGetTags(initial.owner); + const { reporters, respReporters, fetchReporters } = useGetReporters(initial.owner); const refetch = useCallback(() => { fetchTags(); diff --git a/x-pack/plugins/cases/public/components/case_view/index.tsx b/x-pack/plugins/cases/public/components/case_view/index.tsx index 557f736c513b9..65e241d46b9ad 100644 --- a/x-pack/plugins/cases/public/components/case_view/index.tsx +++ b/x-pack/plugins/cases/public/components/case_view/index.tsx @@ -450,6 +450,7 @@ export const CaseComponent = React.memo( tags={caseData.tags} onSubmit={onSubmitTags} isLoading={isLoading && updateKey === 'tags'} + owner={[caseData.owner]} /> { it('it renders with steps', async () => { const wrapper = mount( - + ); @@ -63,7 +63,7 @@ describe('CreateCaseForm', () => { it('it renders without steps', async () => { const wrapper = mount( - + ); @@ -73,7 +73,7 @@ describe('CreateCaseForm', () => { it('it renders all form fields', async () => { const wrapper = mount( - + ); @@ -87,7 +87,7 @@ describe('CreateCaseForm', () => { it('should render spinner when loading', async () => { const wrapper = mount( - + ); diff --git a/x-pack/plugins/cases/public/components/create/form.tsx b/x-pack/plugins/cases/public/components/create/form.tsx index 83f759947ba65..4a9d8771053c5 100644 --- a/x-pack/plugins/cases/public/components/create/form.tsx +++ b/x-pack/plugins/cases/public/components/create/form.tsx @@ -41,6 +41,7 @@ interface Props { hideConnectorServiceNowSir?: boolean; isLoadingConnectors?: boolean; withSteps?: boolean; + owner: string; } const empty: ActionConnector[] = []; export const CreateCaseForm: React.FC = React.memo( @@ -49,6 +50,7 @@ export const CreateCaseForm: React.FC = React.memo( isLoadingConnectors = false, hideConnectorServiceNowSir = false, withSteps = true, + owner, }) => { const { isSubmitting } = useFormContext(); @@ -59,7 +61,7 @@ export const CreateCaseForm: React.FC = React.memo( <> <Container> - <Tags isLoading={isSubmitting} /> + <Tags isLoading={isSubmitting} owner={[owner]} /> </Container> <Container big> <Description isLoading={isSubmitting} /> @@ -67,7 +69,7 @@ export const CreateCaseForm: React.FC<Props> = React.memo( </> ), }), - [isSubmitting] + [isSubmitting, owner] ); const secondStep = useMemo( diff --git a/x-pack/plugins/cases/public/components/create/form_context.tsx b/x-pack/plugins/cases/public/components/create/form_context.tsx index c630a6df86205..3fb9b1122c1be 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.tsx @@ -88,7 +88,6 @@ export const FormContext: React.FC<Props> = ({ type: caseType, connector: connectorToUpdate, settings: { syncAlerts }, - owner, }); if (afterCaseCreated && updatedCase) { @@ -111,7 +110,6 @@ export const FormContext: React.FC<Props> = ({ connectors, postCase, caseType, - owner, afterCaseCreated, onSuccess, postComment, diff --git a/x-pack/plugins/cases/public/components/create/index.tsx b/x-pack/plugins/cases/public/components/create/index.tsx index 56b995a1dadd0..f4307c01af6c1 100644 --- a/x-pack/plugins/cases/public/components/create/index.tsx +++ b/x-pack/plugins/cases/public/components/create/index.tsx @@ -61,6 +61,7 @@ export const CreateCase = ({ <CreateCaseForm hideConnectorServiceNowSir={hideConnectorServiceNowSir} withSteps={withSteps} + owner={owner} /> <Container> <EuiFlexGroup diff --git a/x-pack/plugins/cases/public/components/create/tags.test.tsx b/x-pack/plugins/cases/public/components/create/tags.test.tsx index 2eddb83dcac29..9443673dcd18b 100644 --- a/x-pack/plugins/cases/public/components/create/tags.test.tsx +++ b/x-pack/plugins/cases/public/components/create/tags.test.tsx @@ -42,7 +42,7 @@ describe('Tags', () => { it('it renders', async () => { const wrapper = mount( <MockHookWrapperComponent> - <Tags isLoading={false} /> + <Tags isLoading={false} owner={['securitySolution']} /> </MockHookWrapperComponent> ); @@ -54,7 +54,7 @@ describe('Tags', () => { it('it disables the input when loading', async () => { const wrapper = mount( <MockHookWrapperComponent> - <Tags isLoading={true} /> + <Tags isLoading={true} owner={['securitySolution']} /> </MockHookWrapperComponent> ); @@ -64,7 +64,7 @@ describe('Tags', () => { it('it changes the tags', async () => { const wrapper = mount( <MockHookWrapperComponent> - <Tags isLoading={false} /> + <Tags isLoading={false} owner={['securitySolution']} /> </MockHookWrapperComponent> ); diff --git a/x-pack/plugins/cases/public/components/create/tags.tsx b/x-pack/plugins/cases/public/components/create/tags.tsx index ac0b67529e15a..0bc0368373a2d 100644 --- a/x-pack/plugins/cases/public/components/create/tags.tsx +++ b/x-pack/plugins/cases/public/components/create/tags.tsx @@ -14,10 +14,11 @@ const CommonUseField = getUseField({ component: Field }); interface Props { isLoading: boolean; + owner: string[]; } -const TagsComponent: React.FC<Props> = ({ isLoading }) => { - const { tags: tagOptions, isLoading: isLoadingTags } = useGetTags(); +const TagsComponent: React.FC<Props> = ({ isLoading, owner }) => { + const { tags: tagOptions, isLoading: isLoadingTags } = useGetTags(owner); const options = useMemo( () => tagOptions.map((label) => ({ diff --git a/x-pack/plugins/cases/public/components/tag_list/index.test.tsx b/x-pack/plugins/cases/public/components/tag_list/index.test.tsx index 296c4ba0e893b..c7360c1bb67df 100644 --- a/x-pack/plugins/cases/public/components/tag_list/index.test.tsx +++ b/x-pack/plugins/cases/public/components/tag_list/index.test.tsx @@ -37,6 +37,7 @@ const defaultProps = { isLoading: false, onSubmit, tags: [], + owner: ['securitySolution'], }; describe('TagList ', () => { diff --git a/x-pack/plugins/cases/public/components/tag_list/index.tsx b/x-pack/plugins/cases/public/components/tag_list/index.tsx index 137d58932b6ef..ab4bb29d2ebba 100644 --- a/x-pack/plugins/cases/public/components/tag_list/index.tsx +++ b/x-pack/plugins/cases/public/components/tag_list/index.tsx @@ -32,6 +32,7 @@ interface TagListProps { isLoading: boolean; onSubmit: (a: string[]) => void; tags: string[]; + owner: string[]; } const MyFlexGroup = styled(EuiFlexGroup)` @@ -44,7 +45,7 @@ const MyFlexGroup = styled(EuiFlexGroup)` `; export const TagList = React.memo( - ({ disabled = false, isLoading, onSubmit, tags }: TagListProps) => { + ({ disabled = false, isLoading, onSubmit, tags, owner }: TagListProps) => { const initialState = { tags }; const { form } = useForm({ defaultValue: initialState, @@ -62,7 +63,7 @@ export const TagList = React.memo( } }, [onSubmit, submit]); - const { tags: tagOptions } = useGetTags(); + const { tags: tagOptions } = useGetTags(owner); const [options, setOptions] = useState( tagOptions.map((label) => ({ label, diff --git a/x-pack/plugins/cases/public/containers/api.test.tsx b/x-pack/plugins/cases/public/containers/api.test.tsx index ff1f2084e18de..062aba9c1c398 100644 --- a/x-pack/plugins/cases/public/containers/api.test.tsx +++ b/x-pack/plugins/cases/public/containers/api.test.tsx @@ -250,7 +250,7 @@ describe('Case Configuration API', () => { }); test('check url, method, signal', async () => { - await getReporters(abortCtrl.signal); + await getReporters(abortCtrl.signal, ['securitySolution']); expect(fetchMock).toHaveBeenCalledWith(`${CASES_URL}/reporters`, { method: 'GET', signal: abortCtrl.signal, @@ -258,7 +258,7 @@ describe('Case Configuration API', () => { }); test('happy path', async () => { - const resp = await getReporters(abortCtrl.signal); + const resp = await getReporters(abortCtrl.signal, ['securitySolution']); expect(resp).toEqual(respReporters); }); }); @@ -270,7 +270,7 @@ describe('Case Configuration API', () => { }); test('check url, method, signal', async () => { - await getTags(abortCtrl.signal); + await getTags(abortCtrl.signal, ['securitySolution']); expect(fetchMock).toHaveBeenCalledWith(`${CASES_URL}/tags`, { method: 'GET', signal: abortCtrl.signal, @@ -278,7 +278,7 @@ describe('Case Configuration API', () => { }); test('happy path', async () => { - const resp = await getTags(abortCtrl.signal); + const resp = await getTags(abortCtrl.signal, ['securitySolution']); expect(resp).toEqual(tags); }); }); diff --git a/x-pack/plugins/cases/public/containers/api.ts b/x-pack/plugins/cases/public/containers/api.ts index 98b304635f7a7..0b9b236cef6e1 100644 --- a/x-pack/plugins/cases/public/containers/api.ts +++ b/x-pack/plugins/cases/public/containers/api.ts @@ -119,18 +119,20 @@ export const getCasesStatus = async (signal: AbortSignal): Promise<CasesStatus> return convertToCamelCase<CasesStatusResponse, CasesStatus>(decodeCasesStatusResponse(response)); }; -export const getTags = async (signal: AbortSignal): Promise<string[]> => { +export const getTags = async (signal: AbortSignal, owner: string[]): Promise<string[]> => { const response = await KibanaServices.get().http.fetch<string[]>(CASE_TAGS_URL, { method: 'GET', signal, + query: { ...(owner.length > 0 ? { owner } : {}) }, }); return response ?? []; }; -export const getReporters = async (signal: AbortSignal): Promise<User[]> => { +export const getReporters = async (signal: AbortSignal, owner: string[]): Promise<User[]> => { const response = await KibanaServices.get().http.fetch<User[]>(CASE_REPORTERS_URL, { method: 'GET', signal, + query: { ...(owner.length > 0 ? { owner } : {}) }, }); return response ?? []; }; diff --git a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx index 8345ddf107872..96d20996558a6 100644 --- a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx @@ -23,7 +23,7 @@ describe('useGetReporters', () => { it('init', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters() + useGetReporters(['securitySolution']) ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -39,7 +39,9 @@ describe('useGetReporters', () => { it('calls getReporters api', async () => { const spyOnGetReporters = jest.spyOn(api, 'getReporters'); await act(async () => { - const { waitForNextUpdate } = renderHook<string, UseGetReporters>(() => useGetReporters()); + const { waitForNextUpdate } = renderHook<string, UseGetReporters>(() => + useGetReporters(['securitySolution']) + ); await waitForNextUpdate(); await waitForNextUpdate(); expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal); @@ -49,7 +51,7 @@ describe('useGetReporters', () => { it('fetch reporters', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters() + useGetReporters(['securitySolution']) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -67,7 +69,7 @@ describe('useGetReporters', () => { const spyOnGetReporters = jest.spyOn(api, 'getReporters'); await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters() + useGetReporters(['securitySolution']) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -84,7 +86,7 @@ describe('useGetReporters', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters() + useGetReporters(['securitySolution']) ); await waitForNextUpdate(); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/use_get_reporters.tsx b/x-pack/plugins/cases/public/containers/use_get_reporters.tsx index a9d28de33cb41..ed06f58008792 100644 --- a/x-pack/plugins/cases/public/containers/use_get_reporters.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_reporters.tsx @@ -31,7 +31,7 @@ export interface UseGetReporters extends ReportersState { fetchReporters: () => void; } -export const useGetReporters = (): UseGetReporters => { +export const useGetReporters = (owner: string[]): UseGetReporters => { const [reportersState, setReporterState] = useState<ReportersState>(initialData); const toasts = useToasts(); @@ -48,7 +48,7 @@ export const useGetReporters = (): UseGetReporters => { isLoading: true, }); - const response = await getReporters(abortCtrlRef.current.signal); + const response = await getReporters(abortCtrlRef.current.signal, owner); const myReporters = response .map((r) => (r.full_name == null || isEmpty(r.full_name) ? r.username ?? '' : r.full_name)) .filter((u) => !isEmpty(u)); @@ -78,7 +78,7 @@ export const useGetReporters = (): UseGetReporters => { }); } } - }, [reportersState, toasts]); + }, [owner, reportersState, toasts]); useEffect(() => { fetchReporters(); diff --git a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx index 3fecfb51b958c..7698b50128730 100644 --- a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx @@ -22,7 +22,9 @@ describe('useGetTags', () => { it('init', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => + useGetTags(['securitySolution']) + ); await waitForNextUpdate(); expect(result.current).toEqual({ tags: [], @@ -36,7 +38,9 @@ describe('useGetTags', () => { it('calls getTags api', async () => { const spyOnGetTags = jest.spyOn(api, 'getTags'); await act(async () => { - const { waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { waitForNextUpdate } = renderHook<string, UseGetTags>(() => + useGetTags(['securitySolution']) + ); await waitForNextUpdate(); await waitForNextUpdate(); expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal); @@ -45,7 +49,9 @@ describe('useGetTags', () => { it('fetch tags', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => + useGetTags(['securitySolution']) + ); await waitForNextUpdate(); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -60,7 +66,9 @@ describe('useGetTags', () => { it('refetch tags', async () => { const spyOnGetTags = jest.spyOn(api, 'getTags'); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => + useGetTags(['securitySolution']) + ); await waitForNextUpdate(); await waitForNextUpdate(); result.current.fetchTags(); @@ -75,7 +83,9 @@ describe('useGetTags', () => { }); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => + useGetTags(['securitySolution']) + ); await waitForNextUpdate(); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/use_get_tags.tsx b/x-pack/plugins/cases/public/containers/use_get_tags.tsx index 4368b025baa38..dfd9667f17c96 100644 --- a/x-pack/plugins/cases/public/containers/use_get_tags.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_tags.tsx @@ -51,7 +51,7 @@ const dataFetchReducer = (state: TagsState, action: Action): TagsState => { }; const initialData: string[] = []; -export const useGetTags = (): UseGetTags => { +export const useGetTags = (owner: string[]): UseGetTags => { const [state, dispatch] = useReducer(dataFetchReducer, { isLoading: true, isError: false, @@ -68,7 +68,7 @@ export const useGetTags = (): UseGetTags => { abortCtrlRef.current = new AbortController(); dispatch({ type: 'FETCH_INIT' }); - const response = await getTags(abortCtrlRef.current.signal); + const response = await getTags(abortCtrlRef.current.signal, owner); if (!isCancelledRef.current) { dispatch({ type: 'FETCH_SUCCESS', payload: response }); From 3b93743b2f7176c87856ace55fa70179417f2738 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Wed, 12 May 2021 13:35:01 +0300 Subject: [PATCH 04/17] Pass owner to configuration --- .../components/configure_cases/index.test.tsx | 50 ++++++++++++++----- .../components/configure_cases/index.tsx | 5 +- .../cases/public/components/create/flyout.tsx | 2 +- .../components/create/form_context.test.tsx | 1 + .../public/components/create/form_context.tsx | 2 +- .../public/containers/configure/api.test.ts | 12 +++-- .../cases/public/containers/configure/api.ts | 6 ++- .../configure/use_configure.test.tsx | 24 ++++----- .../containers/configure/use_configure.tsx | 31 +++++++----- .../public/cases/pages/configure_cases.tsx | 2 + 10 files changed, 90 insertions(+), 45 deletions(-) diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx index 898d6cde19a77..8dd1b33da81f3 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx @@ -102,7 +102,9 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => ({ ...useConnectorsResponse, connectors: [] })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); }); test('it renders the Connectors', () => { @@ -155,7 +157,9 @@ describe('ConfigureCases', () => { })); useConnectorsMock.mockImplementation(() => ({ ...useConnectorsResponse, connectors: [] })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); }); test('it shows the warning callout when configuration is invalid', () => { @@ -200,7 +204,9 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); }); test('it renders with correct props', () => { @@ -220,7 +226,7 @@ describe('ConfigureCases', () => { }); test('it disables correctly when the user cannot crud', () => { - const newWrapper = mount(<ConfigureCases userCanCrud={false} />, { + const newWrapper = mount(<ConfigureCases userCanCrud={false} owner={'securitySolution'} />, { wrappingComponent: TestProviders, }); @@ -282,7 +288,9 @@ describe('ConfigureCases', () => { })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); }); test('it disables correctly Connector when loading connectors', () => { @@ -315,7 +323,9 @@ describe('ConfigureCases', () => { useActionTypesMock.mockImplementation(() => ({ ...useActionTypesResponse, loading: true })); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); expect(wrapper.find(Connectors).prop('isLoading')).toBe(true); }); }); @@ -337,7 +347,9 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); }); test('it disables correctly Connector when saving configuration', () => { @@ -378,7 +390,9 @@ describe('ConfigureCases', () => { ...useConnectorsResponse, })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); }); test('it hides the update connector button when loading the configuration', () => { @@ -420,7 +434,9 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); }); test('it submits the configuration correctly when changing connector', () => { @@ -462,7 +478,9 @@ describe('ConfigureCases', () => { }, })); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); wrapper.update(); @@ -508,7 +526,9 @@ describe('closure options', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); }); test('it submits the configuration correctly when changing closure type', () => { @@ -555,7 +575,9 @@ describe('user interactions', () => { }); test('it show the add flyout when pressing the add connector button', () => { - const wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + const wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); wrapper.update(); wrapper.find('button[data-test-subj="dropdown-connector-add-connector"]').simulate('click'); @@ -576,7 +598,9 @@ describe('user interactions', () => { }); test('it show the edit flyout when pressing the update connector button', () => { - const wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders }); + const wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrappingComponent: TestProviders, + }); wrapper .find('button[data-test-subj="case-configure-update-selected-connector-button"]') .simulate('click'); diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.tsx index fdba148e5c61e..97bdaf5c9b73d 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.tsx @@ -52,9 +52,10 @@ const FormWrapper = styled.div` export interface ConfigureCasesProps { userCanCrud: boolean; + owner: string; } -const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud }) => { +const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud, owner }) => { const { triggersActionsUi } = useKibana().services; const [connectorIsValid, setConnectorIsValid] = useState(true); @@ -74,7 +75,7 @@ const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud }) refetchCaseConfigure, setConnector, setClosureType, - } = useCaseConfigure(); + } = useCaseConfigure(owner); const { loading: isLoadingConnectors, connectors, refetchConnectors } = useConnectors(); const { loading: isLoadingActionTypes, actionTypes, refetchActionTypes } = useActionTypes(); diff --git a/x-pack/plugins/cases/public/components/create/flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout.tsx index 63fa27511bd7b..044af65f437af 100644 --- a/x-pack/plugins/cases/public/components/create/flyout.tsx +++ b/x-pack/plugins/cases/public/components/create/flyout.tsx @@ -57,7 +57,7 @@ const CreateCaseFlyoutComponent: React.FC<CreateCaseModalProps> = ({ <EuiFlyoutBody> <FormWrapper> <FormContext onSuccess={onSuccess} afterCaseCreated={afterCaseCreated} owner={owner}> - <CreateCaseForm withSteps={false} /> + <CreateCaseForm withSteps={false} owner={owner} /> <Container> <SubmitCaseButton /> </Container> diff --git a/x-pack/plugins/cases/public/components/create/form_context.test.tsx b/x-pack/plugins/cases/public/components/create/form_context.test.tsx index 282422f51cb2f..c1e7139f4e6fb 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.test.tsx @@ -77,6 +77,7 @@ const defaultPostCase = { const defaultCreateCaseForm = { isLoadingConnectors: false, connectors: [], + owner: 'securitySolution', }; const defaultPostPushToService = { diff --git a/x-pack/plugins/cases/public/components/create/form_context.tsx b/x-pack/plugins/cases/public/components/create/form_context.tsx index 3fb9b1122c1be..b267b4713058f 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.tsx @@ -49,7 +49,7 @@ export const FormContext: React.FC<Props> = ({ owner, }) => { const { connectors, loading: isLoadingConnectors } = useConnectors(); - const { connector: configurationConnector } = useCaseConfigure(); + const { connector: configurationConnector } = useCaseConfigure(owner); const { postCase } = usePostCase(); const { postComment } = usePostComment(); const { pushCaseToExternalService } = usePostPushToService(); diff --git a/x-pack/plugins/cases/public/containers/configure/api.test.ts b/x-pack/plugins/cases/public/containers/configure/api.test.ts index 4732c030ea505..c6662bcd695f2 100644 --- a/x-pack/plugins/cases/public/containers/configure/api.test.ts +++ b/x-pack/plugins/cases/public/containers/configure/api.test.ts @@ -57,7 +57,7 @@ describe('Case Configuration API', () => { }); test('check url, method, signal', async () => { - await getCaseConfigure({ signal: abortCtrl.signal }); + await getCaseConfigure({ signal: abortCtrl.signal, owner: ['securitySolution'] }); expect(fetchMock).toHaveBeenCalledWith('/api/cases/configure', { method: 'GET', signal: abortCtrl.signal, @@ -65,13 +65,19 @@ describe('Case Configuration API', () => { }); test('happy path', async () => { - const resp = await getCaseConfigure({ signal: abortCtrl.signal }); + const resp = await getCaseConfigure({ + signal: abortCtrl.signal, + owner: ['securitySolution'], + }); expect(resp).toEqual(caseConfigurationCamelCaseResponseMock); }); test('return null on empty response', async () => { fetchMock.mockResolvedValue({}); - const resp = await getCaseConfigure({ signal: abortCtrl.signal }); + const resp = await getCaseConfigure({ + signal: abortCtrl.signal, + owner: ['securitySolution'], + }); expect(resp).toBe(null); }); }); diff --git a/x-pack/plugins/cases/public/containers/configure/api.ts b/x-pack/plugins/cases/public/containers/configure/api.ts index 2d26e39005057..4994364976935 100644 --- a/x-pack/plugins/cases/public/containers/configure/api.ts +++ b/x-pack/plugins/cases/public/containers/configure/api.ts @@ -38,12 +38,16 @@ export const fetchConnectors = async ({ signal }: ApiProps): Promise<ActionConne }; // TODO: refactor -export const getCaseConfigure = async ({ signal }: ApiProps): Promise<CaseConfigure | null> => { +export const getCaseConfigure = async ({ + signal, + owner, +}: ApiProps & { owner: string[] }): Promise<CaseConfigure | null> => { const response = await KibanaServices.get().http.fetch<CasesConfigurationsResponse>( CASE_CONFIGURE_URL, { method: 'GET', signal, + query: { ...(owner.length > 0 ? { owner } : {}) }, } ); diff --git a/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx b/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx index 4d2abbcaec4d4..fd43fbf301ff5 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx @@ -50,7 +50,7 @@ describe('useConfigure', () => { test('init', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -68,7 +68,7 @@ describe('useConfigure', () => { test('fetch case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -100,7 +100,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -112,7 +112,7 @@ describe('useConfigure', () => { test('correctly sets mappings', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -125,7 +125,7 @@ describe('useConfigure', () => { test('set isLoading to true when fetching case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -138,7 +138,7 @@ describe('useConfigure', () => { test('persist case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -167,7 +167,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -193,7 +193,7 @@ describe('useConfigure', () => { await act(async () => { const { waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -222,7 +222,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -246,7 +246,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -267,7 +267,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); @@ -303,7 +303,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + useCaseConfigure('securitySolution') ); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/configure/use_configure.tsx b/x-pack/plugins/cases/public/containers/configure/use_configure.tsx index b4a4ab35b96d7..178feffcc620b 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_configure.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_configure.tsx @@ -154,7 +154,12 @@ export const initialState: State = { id: '', }; -export const useCaseConfigure = (): ReturnUseCaseConfigure => { +/** + * Configurations across multiple plugins in + * not supported at the moment. For that reason owner: string; + * instead of owner: string[] + */ +export const useCaseConfigure = (owner: string): ReturnUseCaseConfigure => { const [state, dispatch] = useReducer(configureCasesReducer, initialState); const toasts = useToasts(); const setCurrentConfiguration = useCallback((configuration: ConnectorConfiguration) => { @@ -234,7 +239,10 @@ export const useCaseConfigure = (): ReturnUseCaseConfigure => { abortCtrlRefetchRef.current = new AbortController(); setLoading(true); - const res = await getCaseConfigure({ signal: abortCtrlRefetchRef.current.signal }); + const res = await getCaseConfigure({ + signal: abortCtrlRefetchRef.current.signal, + owner: [owner], + }); if (!isCancelledRefetchRef.current) { if (res != null) { @@ -295,8 +303,7 @@ export const useCaseConfigure = (): ReturnUseCaseConfigure => { const res = state.version.length === 0 ? await postCaseConfigure( - // TODO: use constant after https://github.com/elastic/kibana/pull/97646 is being merged - { ...connectorObj, owner: 'securitySolution' }, + { ...connectorObj, owner }, abortCtrlPersistRef.current.signal ) : await patchCaseConfigure( @@ -347,17 +354,17 @@ export const useCaseConfigure = (): ReturnUseCaseConfigure => { } }, [ - setClosureType, - setConnector, - setCurrentConfiguration, - setMappings, setPersistLoading, - setVersion, - setID, - state.currentConfiguration.connector, state.version, - // TODO: do we need this? state.id, + state.currentConfiguration.connector, + owner, + setConnector, + setClosureType, + setVersion, + setID, + setMappings, + setCurrentConfiguration, toasts, ] ); diff --git a/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx index 3e838f47e6dc2..9e7a57abff36c 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx @@ -19,6 +19,7 @@ import { navTabs } from '../../app/home/home_navigations'; import { CaseHeaderPage } from '../components/case_header_page'; import { WhitePageWrapper, SectionWrapper } from '../components/wrappers'; import * as i18n from './translations'; +import { APP_ID } from '../../../common/constants'; const ConfigureCasesPageComponent: React.FC = () => { const { cases } = useKibana().services; @@ -55,6 +56,7 @@ const ConfigureCasesPageComponent: React.FC = () => { <WhitePageWrapper> {cases.getConfigureCases({ userCanCrud: userPermissions?.crud ?? false, + owner: APP_ID, })} </WhitePageWrapper> </WrapperPage> From 240e17b5da38727447370ed5b7f4eae44942bccb Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Wed, 12 May 2021 20:47:47 +0300 Subject: [PATCH 05/17] Use owner context --- .../public/common/mock/test_providers.tsx | 5 +- .../all_cases/all_cases_generic.tsx | 6 +- .../components/all_cases/index.test.tsx | 1 - .../public/components/all_cases/index.tsx | 1 - .../all_cases/selector_modal/index.tsx | 3 - .../components/configure_cases/index.test.tsx | 26 ++-- .../components/configure_cases/index.tsx | 7 +- .../public/components/create/flyout.test.tsx | 116 ------------------ .../cases/public/components/create/flyout.tsx | 73 ----------- .../public/components/create/form.test.tsx | 8 +- .../cases/public/components/create/form.tsx | 6 +- .../components/create/form_context.test.tsx | 30 ++--- .../public/components/create/form_context.tsx | 8 +- .../public/components/create/index.test.tsx | 6 +- .../cases/public/components/create/index.tsx | 4 - .../public/components/create/tags.test.tsx | 6 +- .../cases/public/components/create/tags.tsx | 5 +- .../public/components/owner_context/index.tsx | 19 +++ .../owner_context/use_owner_context.ts | 13 ++ .../public/components/recent_cases/index.tsx | 4 +- .../create_case_modal.tsx | 2 +- .../cases/public/containers/api.test.tsx | 6 + .../public/containers/configure/api.test.ts | 3 + .../containers/use_get_reporters.test.tsx | 2 +- .../public/containers/use_get_tags.test.tsx | 2 +- .../cases/public/methods/get_all_cases.tsx | 12 +- .../methods/get_all_cases_selector_modal.tsx | 12 +- .../public/methods/get_configure_cases.tsx | 12 +- .../cases/public/methods/get_create_case.tsx | 12 +- .../cases/public/methods/get_recent_cases.tsx | 12 +- x-pack/plugins/cases/public/types.ts | 14 ++- .../public/cases/components/create/flyout.tsx | 2 +- .../cases/components/create/index.test.tsx | 2 +- .../public/cases/components/create/index.tsx | 2 +- .../public/cases/pages/configure_cases.tsx | 2 +- 35 files changed, 155 insertions(+), 289 deletions(-) delete mode 100644 x-pack/plugins/cases/public/components/create/flyout.test.tsx delete mode 100644 x-pack/plugins/cases/public/components/create/flyout.tsx create mode 100644 x-pack/plugins/cases/public/components/owner_context/index.tsx create mode 100644 x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts diff --git a/x-pack/plugins/cases/public/common/mock/test_providers.tsx b/x-pack/plugins/cases/public/common/mock/test_providers.tsx index 94ee5dd4f2743..8486350cd4e50 100644 --- a/x-pack/plugins/cases/public/common/mock/test_providers.tsx +++ b/x-pack/plugins/cases/public/common/mock/test_providers.tsx @@ -10,6 +10,7 @@ import { I18nProvider } from '@kbn/i18n/react'; import React from 'react'; import { BehaviorSubject } from 'rxjs'; import { ThemeProvider } from 'styled-components'; +import { OwnerProvider } from '../../components/owner_context'; import { createKibanaContextProviderMock, createStartServicesMock, @@ -29,7 +30,9 @@ const MockKibanaContextProvider = createKibanaContextProviderMock(); const TestProvidersComponent: React.FC<Props> = ({ children }) => ( <I18nProvider> <MockKibanaContextProvider> - <ThemeProvider theme={() => ({ eui: euiDarkVars, darkMode: true })}>{children}</ThemeProvider> + <ThemeProvider theme={() => ({ eui: euiDarkVars, darkMode: true })}> + <OwnerProvider owner={['securitySolution']}>{children}</OwnerProvider> + </ThemeProvider> </MockKibanaContextProvider> </I18nProvider> ); diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx index e4e7844939403..4ffbdf5811ca2 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx @@ -38,6 +38,8 @@ import { CasesTableFilters } from './table_filters'; import { EuiBasicTableOnChange } from './types'; import { CasesTable } from './table'; +import { useOwnerContext } from '../owner_context/use_owner_context'; + const ProgressLoader = styled(EuiProgress)` ${({ $isShow }: { $isShow: boolean }) => $isShow @@ -64,7 +66,6 @@ interface AllCasesGenericProps { onRowClick?: (theCase?: Case | SubCase) => void; updateCase?: (newCase: Case) => void; userCanCrud: boolean; - owner: string[]; } export const AllCasesGeneric = React.memo<AllCasesGenericProps>( @@ -78,9 +79,10 @@ export const AllCasesGeneric = React.memo<AllCasesGenericProps>( onRowClick, updateCase, userCanCrud, - owner, }) => { const { actionLicense } = useGetActionLicense(); + const owner = useOwnerContext(); + const { data, dispatchUpdateCaseProperty, diff --git a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx index 582209ffcbeed..7233d6bef6e4a 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx @@ -53,7 +53,6 @@ describe('AllCasesGeneric', () => { onClick: jest.fn(), }, userCanCrud: true, - owner: ['securitySolution'], }; const dispatchResetIsDeleted = jest.fn(); diff --git a/x-pack/plugins/cases/public/components/all_cases/index.tsx b/x-pack/plugins/cases/public/components/all_cases/index.tsx index 11b8d55b92c1e..2c506cd2da411 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.tsx @@ -13,7 +13,6 @@ export interface AllCasesProps { configureCasesNavigation: CasesNavigation; // if not passed, header with nav is not displayed (Formerly dependant on isSelector) createCaseNavigation: CasesNavigation; userCanCrud: boolean; - owner: string[]; } export const AllCases: React.FC<AllCasesProps> = (props) => { diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx index 27f734123321a..0a83ef13e8ee6 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx @@ -20,7 +20,6 @@ export interface AllCasesSelectorModalProps { onRowClick: (theCase?: Case | SubCase) => void; updateCase?: (newCase: Case) => void; userCanCrud: boolean; - owner: string[]; } const Modal = styled(EuiModal)` @@ -37,7 +36,6 @@ export const AllCasesSelectorModal: React.FC<AllCasesSelectorModalProps> = ({ onRowClick, updateCase, userCanCrud, - owner, }) => { const [isModalOpen, setIsModalOpen] = useState<boolean>(true); const closeModal = useCallback(() => setIsModalOpen(false), []); @@ -62,7 +60,6 @@ export const AllCasesSelectorModal: React.FC<AllCasesSelectorModalProps> = ({ onRowClick={onClick} userCanCrud={userCanCrud} updateCase={updateCase} - owner={owner} /> </EuiModalBody> </Modal> diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx index 8dd1b33da81f3..65f2755ef4545 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx @@ -102,7 +102,7 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => ({ ...useConnectorsResponse, connectors: [] })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); }); @@ -157,7 +157,7 @@ describe('ConfigureCases', () => { })); useConnectorsMock.mockImplementation(() => ({ ...useConnectorsResponse, connectors: [] })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); }); @@ -204,7 +204,7 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); }); @@ -226,7 +226,7 @@ describe('ConfigureCases', () => { }); test('it disables correctly when the user cannot crud', () => { - const newWrapper = mount(<ConfigureCases userCanCrud={false} owner={'securitySolution'} />, { + const newWrapper = mount(<ConfigureCases userCanCrud={false} />, { wrappingComponent: TestProviders, }); @@ -288,7 +288,7 @@ describe('ConfigureCases', () => { })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); }); @@ -323,7 +323,7 @@ describe('ConfigureCases', () => { useActionTypesMock.mockImplementation(() => ({ ...useActionTypesResponse, loading: true })); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); expect(wrapper.find(Connectors).prop('isLoading')).toBe(true); @@ -347,7 +347,7 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); }); @@ -390,7 +390,7 @@ describe('ConfigureCases', () => { ...useConnectorsResponse, })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); }); @@ -434,7 +434,7 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); }); @@ -478,7 +478,7 @@ describe('ConfigureCases', () => { }, })); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); @@ -526,7 +526,7 @@ describe('closure options', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); }); @@ -575,7 +575,7 @@ describe('user interactions', () => { }); test('it show the add flyout when pressing the add connector button', () => { - const wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + const wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); @@ -598,7 +598,7 @@ describe('user interactions', () => { }); test('it show the edit flyout when pressing the update connector button', () => { - const wrapper = mount(<ConfigureCases userCanCrud owner={'securitySolution'} />, { + const wrapper = mount(<ConfigureCases userCanCrud />, { wrappingComponent: TestProviders, }); wrapper diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.tsx index 97bdaf5c9b73d..61b6d23e8a1ad 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.tsx @@ -31,6 +31,7 @@ import { normalizeCaseConnector, } from './utils'; import * as i18n from './translations'; +import { useOwnerContext } from '../owner_context/use_owner_context'; const FormWrapper = styled.div` ${({ theme }) => css` @@ -52,11 +53,11 @@ const FormWrapper = styled.div` export interface ConfigureCasesProps { userCanCrud: boolean; - owner: string; } -const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud, owner }) => { +const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud }) => { const { triggersActionsUi } = useKibana().services; + const owner = useOwnerContext(); const [connectorIsValid, setConnectorIsValid] = useState(true); const [addFlyoutVisible, setAddFlyoutVisibility] = useState<boolean>(false); @@ -75,7 +76,7 @@ const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud, o refetchCaseConfigure, setConnector, setClosureType, - } = useCaseConfigure(owner); + } = useCaseConfigure(owner[0]); const { loading: isLoadingConnectors, connectors, refetchConnectors } = useConnectors(); const { loading: isLoadingActionTypes, actionTypes, refetchActionTypes } = useActionTypes(); diff --git a/x-pack/plugins/cases/public/components/create/flyout.test.tsx b/x-pack/plugins/cases/public/components/create/flyout.test.tsx deleted file mode 100644 index 0dbf59f42898b..0000000000000 --- a/x-pack/plugins/cases/public/components/create/flyout.test.tsx +++ /dev/null @@ -1,116 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { ReactNode } from 'react'; -import { mount } from 'enzyme'; - -import { CreateCaseFlyout } from './flyout'; -import { TestProviders } from '../../common/mock'; - -jest.mock('../create/form_context', () => { - return { - FormContext: ({ - children, - onSuccess, - }: { - children: ReactNode; - onSuccess: ({ id }: { id: string }) => Promise<void>; - }) => { - return ( - <> - <button - type="button" - data-test-subj="form-context-on-success" - onClick={async () => { - await onSuccess({ id: 'case-id' }); - }} - > - {'submit'} - </button> - {children} - </> - ); - }, - }; -}); - -jest.mock('../create/form', () => { - return { - CreateCaseForm: () => { - return <>{'form'}</>; - }, - }; -}); - -jest.mock('../create/submit_button', () => { - return { - SubmitCaseButton: () => { - return <>{'Submit'}</>; - }, - }; -}); - -const onCloseFlyout = jest.fn(); -const onSuccess = jest.fn(); -const defaultProps = { - onCloseFlyout, - onSuccess, - owner: 'securitySolution', -}; - -describe('CreateCaseFlyout', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - it('renders', () => { - const wrapper = mount( - <TestProviders> - <CreateCaseFlyout {...defaultProps} /> - </TestProviders> - ); - - expect(wrapper.find(`[data-test-subj='create-case-flyout']`).exists()).toBeTruthy(); - }); - - it('Closing modal calls onCloseCaseModal', () => { - const wrapper = mount( - <TestProviders> - <CreateCaseFlyout {...defaultProps} /> - </TestProviders> - ); - - wrapper.find('.euiFlyout__closeButton').first().simulate('click'); - expect(onCloseFlyout).toBeCalled(); - }); - - it('pass the correct props to FormContext component', () => { - const wrapper = mount( - <TestProviders> - <CreateCaseFlyout {...defaultProps} /> - </TestProviders> - ); - - const props = wrapper.find('FormContext').props(); - expect(props).toEqual( - expect.objectContaining({ - onSuccess, - }) - ); - }); - - it('onSuccess called when creating a case', () => { - const wrapper = mount( - <TestProviders> - <CreateCaseFlyout {...defaultProps} /> - </TestProviders> - ); - - wrapper.find(`[data-test-subj='form-context-on-success']`).first().simulate('click'); - expect(onSuccess).toHaveBeenCalledWith({ id: 'case-id' }); - }); -}); diff --git a/x-pack/plugins/cases/public/components/create/flyout.tsx b/x-pack/plugins/cases/public/components/create/flyout.tsx deleted file mode 100644 index 044af65f437af..0000000000000 --- a/x-pack/plugins/cases/public/components/create/flyout.tsx +++ /dev/null @@ -1,73 +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 - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { memo } from 'react'; -import styled from 'styled-components'; -import { EuiFlyout, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eui'; - -import { FormContext } from '../create/form_context'; -import { CreateCaseForm } from '../create/form'; -import { SubmitCaseButton } from '../create/submit_button'; -import { Case } from '../../containers/types'; -import * as i18n from '../../common/translations'; - -export interface CreateCaseModalProps { - onCloseFlyout: () => void; - onSuccess: (theCase: Case) => Promise<void>; - afterCaseCreated?: (theCase: Case) => Promise<void>; - owner: string; -} - -const Container = styled.div` - ${({ theme }) => ` - margin-top: ${theme.eui.euiSize}; - text-align: right; - `} -`; - -const StyledFlyout = styled(EuiFlyout)` - ${({ theme }) => ` - z-index: ${theme.eui.euiZModal}; - `} -`; - -// Adding bottom padding because timeline's -// bottom bar gonna hide the submit button. -const FormWrapper = styled.div` - padding-bottom: 50px; -`; - -const CreateCaseFlyoutComponent: React.FC<CreateCaseModalProps> = ({ - onSuccess, - afterCaseCreated, - onCloseFlyout, - owner, -}) => { - return ( - <StyledFlyout onClose={onCloseFlyout} data-test-subj="create-case-flyout"> - <EuiFlyoutHeader hasBorder> - <EuiTitle size="m"> - <h2>{i18n.CREATE_TITLE}</h2> - </EuiTitle> - </EuiFlyoutHeader> - <EuiFlyoutBody> - <FormWrapper> - <FormContext onSuccess={onSuccess} afterCaseCreated={afterCaseCreated} owner={owner}> - <CreateCaseForm withSteps={false} owner={owner} /> - <Container> - <SubmitCaseButton /> - </Container> - </FormContext> - </FormWrapper> - </EuiFlyoutBody> - </StyledFlyout> - ); -}; - -export const CreateCaseFlyout = memo(CreateCaseFlyoutComponent); - -CreateCaseFlyout.displayName = 'CreateCaseFlyout'; diff --git a/x-pack/plugins/cases/public/components/create/form.test.tsx b/x-pack/plugins/cases/public/components/create/form.test.tsx index e79f20b0ebcd0..9e59924bdf483 100644 --- a/x-pack/plugins/cases/public/components/create/form.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form.test.tsx @@ -53,7 +53,7 @@ describe('CreateCaseForm', () => { it('it renders with steps', async () => { const wrapper = mount( <MockHookWrapperComponent> - <CreateCaseForm owner={'securitySolution'} /> + <CreateCaseForm /> </MockHookWrapperComponent> ); @@ -63,7 +63,7 @@ describe('CreateCaseForm', () => { it('it renders without steps', async () => { const wrapper = mount( <MockHookWrapperComponent> - <CreateCaseForm withSteps={false} owner={'securitySolution'} /> + <CreateCaseForm withSteps={false} /> </MockHookWrapperComponent> ); @@ -73,7 +73,7 @@ describe('CreateCaseForm', () => { it('it renders all form fields', async () => { const wrapper = mount( <MockHookWrapperComponent> - <CreateCaseForm owner={'securitySolution'} /> + <CreateCaseForm /> </MockHookWrapperComponent> ); @@ -87,7 +87,7 @@ describe('CreateCaseForm', () => { it('should render spinner when loading', async () => { const wrapper = mount( <MockHookWrapperComponent> - <CreateCaseForm owner={'securitySolution'} /> + <CreateCaseForm /> </MockHookWrapperComponent> ); diff --git a/x-pack/plugins/cases/public/components/create/form.tsx b/x-pack/plugins/cases/public/components/create/form.tsx index 4a9d8771053c5..83f759947ba65 100644 --- a/x-pack/plugins/cases/public/components/create/form.tsx +++ b/x-pack/plugins/cases/public/components/create/form.tsx @@ -41,7 +41,6 @@ interface Props { hideConnectorServiceNowSir?: boolean; isLoadingConnectors?: boolean; withSteps?: boolean; - owner: string; } const empty: ActionConnector[] = []; export const CreateCaseForm: React.FC<Props> = React.memo( @@ -50,7 +49,6 @@ export const CreateCaseForm: React.FC<Props> = React.memo( isLoadingConnectors = false, hideConnectorServiceNowSir = false, withSteps = true, - owner, }) => { const { isSubmitting } = useFormContext(); @@ -61,7 +59,7 @@ export const CreateCaseForm: React.FC<Props> = React.memo( <> <Title isLoading={isSubmitting} /> <Container> - <Tags isLoading={isSubmitting} owner={[owner]} /> + <Tags isLoading={isSubmitting} /> </Container> <Container big> <Description isLoading={isSubmitting} /> @@ -69,7 +67,7 @@ export const CreateCaseForm: React.FC<Props> = React.memo( </> ), }), - [isSubmitting, owner] + [isSubmitting] ); const secondStep = useMemo( diff --git a/x-pack/plugins/cases/public/components/create/form_context.test.tsx b/x-pack/plugins/cases/public/components/create/form_context.test.tsx index c1e7139f4e6fb..5e61d726b8b9f 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.test.tsx @@ -139,7 +139,7 @@ describe('Create case', () => { it('it renders', async () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -163,7 +163,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -183,7 +183,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -218,7 +218,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -268,7 +268,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -293,7 +293,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -360,7 +360,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -428,7 +428,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -518,7 +518,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext onSuccess={onFormSubmitSuccess} owner={'securitySolution'}> + <FormContext onSuccess={onFormSubmitSuccess}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -616,11 +616,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext - onSuccess={onFormSubmitSuccess} - afterCaseCreated={afterCaseCreated} - owner={'securitySolution'} - > + <FormContext onSuccess={onFormSubmitSuccess} afterCaseCreated={afterCaseCreated}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> @@ -657,11 +653,7 @@ describe('Create case', () => { const wrapper = mount( <TestProviders> - <FormContext - onSuccess={onFormSubmitSuccess} - afterCaseCreated={afterCaseCreated} - owner={'securitySolution'} - > + <FormContext onSuccess={onFormSubmitSuccess} afterCaseCreated={afterCaseCreated}> <CreateCaseForm {...defaultCreateCaseForm} /> <SubmitCaseButton /> </FormContext> diff --git a/x-pack/plugins/cases/public/components/create/form_context.tsx b/x-pack/plugins/cases/public/components/create/form_context.tsx index b267b4713058f..0b2ff086c1b57 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.tsx @@ -21,6 +21,7 @@ import { useCaseConfigure } from '../../containers/configure/use_configure'; import { Case } from '../../containers/types'; import { CaseType, ConnectorTypes } from '../../../common'; import { UsePostComment, usePostComment } from '../../containers/use_post_comment'; +import { useOwnerContext } from '../owner_context/use_owner_context'; const initialCaseValue: FormProps = { description: '', @@ -37,7 +38,6 @@ interface Props { children?: JSX.Element | JSX.Element[]; hideConnectorServiceNowSir?: boolean; onSuccess?: (theCase: Case) => Promise<void>; - owner: string; } export const FormContext: React.FC<Props> = ({ @@ -46,10 +46,10 @@ export const FormContext: React.FC<Props> = ({ children, hideConnectorServiceNowSir, onSuccess, - owner, }) => { const { connectors, loading: isLoadingConnectors } = useConnectors(); - const { connector: configurationConnector } = useCaseConfigure(owner); + const owner = useOwnerContext(); + const { connector: configurationConnector } = useCaseConfigure(owner[0]); const { postCase } = usePostCase(); const { postComment } = usePostComment(); const { pushCaseToExternalService } = usePostPushToService(); @@ -88,6 +88,7 @@ export const FormContext: React.FC<Props> = ({ type: caseType, connector: connectorToUpdate, settings: { syncAlerts }, + owner: owner[0], }); if (afterCaseCreated && updatedCase) { @@ -110,6 +111,7 @@ export const FormContext: React.FC<Props> = ({ connectors, postCase, caseType, + owner, afterCaseCreated, onSuccess, postComment, diff --git a/x-pack/plugins/cases/public/components/create/index.test.tsx b/x-pack/plugins/cases/public/components/create/index.test.tsx index 8eb1a565c43bf..e82af8edc6337 100644 --- a/x-pack/plugins/cases/public/components/create/index.test.tsx +++ b/x-pack/plugins/cases/public/components/create/index.test.tsx @@ -91,7 +91,7 @@ describe('CreateCase case', () => { it('it renders', async () => { const wrapper = mount( <TestProviders> - <CreateCase {...defaultProps} owner={'securitySolution'} /> + <CreateCase {...defaultProps} /> </TestProviders> ); @@ -102,7 +102,7 @@ describe('CreateCase case', () => { it('should call cancel on cancel click', async () => { const wrapper = mount( <TestProviders> - <CreateCase {...defaultProps} owner={'securitySolution'} /> + <CreateCase {...defaultProps} /> </TestProviders> ); @@ -113,7 +113,7 @@ describe('CreateCase case', () => { it('should redirect to new case when posting the case', async () => { const wrapper = mount( <TestProviders> - <CreateCase {...defaultProps} owner={'securitySolution'} /> + <CreateCase {...defaultProps} /> </TestProviders> ); diff --git a/x-pack/plugins/cases/public/components/create/index.tsx b/x-pack/plugins/cases/public/components/create/index.tsx index f4307c01af6c1..a1de4d9730b9f 100644 --- a/x-pack/plugins/cases/public/components/create/index.tsx +++ b/x-pack/plugins/cases/public/components/create/index.tsx @@ -37,7 +37,6 @@ export interface CreateCaseProps { onSuccess: (theCase: Case) => Promise<void>; timelineIntegration?: CasesTimelineIntegration; withSteps?: boolean; - owner: string; } export const CreateCase = ({ @@ -48,7 +47,6 @@ export const CreateCase = ({ onSuccess, timelineIntegration, withSteps, - owner, }: CreateCaseProps) => ( <CasesTimelineIntegrationProvider timelineIntegration={timelineIntegration}> <FormContext @@ -56,12 +54,10 @@ export const CreateCase = ({ caseType={caseType} hideConnectorServiceNowSir={hideConnectorServiceNowSir} onSuccess={onSuccess} - owner={owner} > <CreateCaseForm hideConnectorServiceNowSir={hideConnectorServiceNowSir} withSteps={withSteps} - owner={owner} /> <Container> <EuiFlexGroup diff --git a/x-pack/plugins/cases/public/components/create/tags.test.tsx b/x-pack/plugins/cases/public/components/create/tags.test.tsx index 9443673dcd18b..2eddb83dcac29 100644 --- a/x-pack/plugins/cases/public/components/create/tags.test.tsx +++ b/x-pack/plugins/cases/public/components/create/tags.test.tsx @@ -42,7 +42,7 @@ describe('Tags', () => { it('it renders', async () => { const wrapper = mount( <MockHookWrapperComponent> - <Tags isLoading={false} owner={['securitySolution']} /> + <Tags isLoading={false} /> </MockHookWrapperComponent> ); @@ -54,7 +54,7 @@ describe('Tags', () => { it('it disables the input when loading', async () => { const wrapper = mount( <MockHookWrapperComponent> - <Tags isLoading={true} owner={['securitySolution']} /> + <Tags isLoading={true} /> </MockHookWrapperComponent> ); @@ -64,7 +64,7 @@ describe('Tags', () => { it('it changes the tags', async () => { const wrapper = mount( <MockHookWrapperComponent> - <Tags isLoading={false} owner={['securitySolution']} /> + <Tags isLoading={false} /> </MockHookWrapperComponent> ); diff --git a/x-pack/plugins/cases/public/components/create/tags.tsx b/x-pack/plugins/cases/public/components/create/tags.tsx index 0bc0368373a2d..59374d3963b58 100644 --- a/x-pack/plugins/cases/public/components/create/tags.tsx +++ b/x-pack/plugins/cases/public/components/create/tags.tsx @@ -9,15 +9,16 @@ import React, { memo, useMemo } from 'react'; import { Field, getUseField } from '../../common/shared_imports'; import { useGetTags } from '../../containers/use_get_tags'; +import { useOwnerContext } from '../owner_context/use_owner_context'; const CommonUseField = getUseField({ component: Field }); interface Props { isLoading: boolean; - owner: string[]; } -const TagsComponent: React.FC<Props> = ({ isLoading, owner }) => { +const TagsComponent: React.FC<Props> = ({ isLoading }) => { + const owner = useOwnerContext(); const { tags: tagOptions, isLoading: isLoadingTags } = useGetTags(owner); const options = useMemo( () => diff --git a/x-pack/plugins/cases/public/components/owner_context/index.tsx b/x-pack/plugins/cases/public/components/owner_context/index.tsx new file mode 100644 index 0000000000000..87934c4d4f58e --- /dev/null +++ b/x-pack/plugins/cases/public/components/owner_context/index.tsx @@ -0,0 +1,19 @@ +/* + * 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, { useState } from 'react'; + +// This context is available to all children of the stateful_event component where the provider is currently set +export const OwnerContext = React.createContext<string[]>([]); + +export const OwnerProvider: React.FC<{ + owner: string[]; +}> = ({ children, owner }) => { + const [currentOwner] = useState(owner); + + return <OwnerContext.Provider value={currentOwner}>{children}</OwnerContext.Provider>; +}; diff --git a/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts b/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts new file mode 100644 index 0000000000000..6f3d2fc240e68 --- /dev/null +++ b/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts @@ -0,0 +1,13 @@ +/* + * 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 { useContext } from 'react'; +import { OwnerContext } from '.'; + +export const useOwnerContext = () => { + return useContext(OwnerContext); +}; diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.tsx index ed1a0b5c0908c..e0dc12810f543 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.tsx @@ -14,13 +14,13 @@ import { RecentCasesFilters } from './filters'; import { RecentCasesComp } from './recent_cases'; import { FilterMode as RecentCasesFilterMode } from './types'; import { useCurrentUser } from '../../common/lib/kibana'; +import { useOwnerContext } from '../owner_context/use_owner_context'; export interface RecentCasesProps { allCasesNavigation: CasesNavigation; caseDetailsNavigation: CasesNavigation<CaseDetailsHrefSchema, 'configurable'>; createCaseNavigation: CasesNavigation; maxCasesToShow: number; - owner: string[]; } const RecentCases = ({ @@ -28,8 +28,8 @@ const RecentCases = ({ caseDetailsNavigation, createCaseNavigation, maxCasesToShow, - owner, }: RecentCasesProps) => { + const owner = useOwnerContext(); const currentUser = useCurrentUser(); const [recentCasesFilterBy, setRecentCasesFilterBy] = useState<RecentCasesFilterMode>( 'recentlyCreated' diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.tsx index 0650295214c3e..a4278e53ea341 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.tsx @@ -42,7 +42,7 @@ const CreateModalComponent: React.FC<CreateCaseModalProps> = ({ onCancel: onCloseCaseModal, onSuccess, withSteps: false, - owner, + owner: [owner], })} </EuiModalBody> </EuiModal> diff --git a/x-pack/plugins/cases/public/containers/api.test.tsx b/x-pack/plugins/cases/public/containers/api.test.tsx index 062aba9c1c398..17a532a2a9e7e 100644 --- a/x-pack/plugins/cases/public/containers/api.test.tsx +++ b/x-pack/plugins/cases/public/containers/api.test.tsx @@ -254,6 +254,9 @@ describe('Case Configuration API', () => { expect(fetchMock).toHaveBeenCalledWith(`${CASES_URL}/reporters`, { method: 'GET', signal: abortCtrl.signal, + query: { + owner: 'securitySolution', + }, }); }); @@ -274,6 +277,9 @@ describe('Case Configuration API', () => { expect(fetchMock).toHaveBeenCalledWith(`${CASES_URL}/tags`, { method: 'GET', signal: abortCtrl.signal, + query: { + owner: 'securitySolution', + }, }); }); diff --git a/x-pack/plugins/cases/public/containers/configure/api.test.ts b/x-pack/plugins/cases/public/containers/configure/api.test.ts index c6662bcd695f2..8529b19c3df2b 100644 --- a/x-pack/plugins/cases/public/containers/configure/api.test.ts +++ b/x-pack/plugins/cases/public/containers/configure/api.test.ts @@ -61,6 +61,9 @@ describe('Case Configuration API', () => { expect(fetchMock).toHaveBeenCalledWith('/api/cases/configure', { method: 'GET', signal: abortCtrl.signal, + query: { + owner: 'securitySolution', + }, }); }); diff --git a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx index 96d20996558a6..36ab7f8d4e57d 100644 --- a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx @@ -44,7 +44,7 @@ describe('useGetReporters', () => { ); await waitForNextUpdate(); await waitForNextUpdate(); - expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal); + expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal, ['securitySolution']); }); }); diff --git a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx index 7698b50128730..9d433dea77429 100644 --- a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx @@ -43,7 +43,7 @@ describe('useGetTags', () => { ); await waitForNextUpdate(); await waitForNextUpdate(); - expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal); + expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal, ['securitySolution']); }); }); diff --git a/x-pack/plugins/cases/public/methods/get_all_cases.tsx b/x-pack/plugins/cases/public/methods/get_all_cases.tsx index d3e7a924788f3..413af03264371 100644 --- a/x-pack/plugins/cases/public/methods/get_all_cases.tsx +++ b/x-pack/plugins/cases/public/methods/get_all_cases.tsx @@ -8,10 +8,14 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import React, { lazy, Suspense } from 'react'; import { AllCasesProps } from '../components/all_cases'; +import { OwnerProvider } from '../components/owner_context'; +import { Owner } from '../types'; const AllCasesLazy = lazy(() => import('../components/all_cases')); -export const getAllCasesLazy = (props: AllCasesProps) => ( - <Suspense fallback={<EuiLoadingSpinner />}> - <AllCasesLazy {...props} /> - </Suspense> +export const getAllCasesLazy = (props: AllCasesProps & Owner) => ( + <OwnerProvider owner={props.owner}> + <Suspense fallback={<EuiLoadingSpinner />}> + <AllCasesLazy {...props} /> + </Suspense> + </OwnerProvider> ); diff --git a/x-pack/plugins/cases/public/methods/get_all_cases_selector_modal.tsx b/x-pack/plugins/cases/public/methods/get_all_cases_selector_modal.tsx index b6caae39c284a..dbb466129c60b 100644 --- a/x-pack/plugins/cases/public/methods/get_all_cases_selector_modal.tsx +++ b/x-pack/plugins/cases/public/methods/get_all_cases_selector_modal.tsx @@ -8,10 +8,14 @@ import React, { lazy, Suspense } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; import { AllCasesSelectorModalProps } from '../components/all_cases/selector_modal'; +import { OwnerProvider } from '../components/owner_context'; +import { Owner } from '../types'; const AllCasesSelectorModalLazy = lazy(() => import('../components/all_cases/selector_modal')); -export const getAllCasesSelectorModalLazy = (props: AllCasesSelectorModalProps) => ( - <Suspense fallback={<EuiLoadingSpinner />}> - <AllCasesSelectorModalLazy {...props} /> - </Suspense> +export const getAllCasesSelectorModalLazy = (props: AllCasesSelectorModalProps & Owner) => ( + <OwnerProvider owner={props.owner}> + <Suspense fallback={<EuiLoadingSpinner />}> + <AllCasesSelectorModalLazy {...props} /> + </Suspense> + </OwnerProvider> ); diff --git a/x-pack/plugins/cases/public/methods/get_configure_cases.tsx b/x-pack/plugins/cases/public/methods/get_configure_cases.tsx index 96a3dbd55d7de..5c17f3ae2bb9a 100644 --- a/x-pack/plugins/cases/public/methods/get_configure_cases.tsx +++ b/x-pack/plugins/cases/public/methods/get_configure_cases.tsx @@ -7,11 +7,15 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import React, { lazy, Suspense } from 'react'; +import { OwnerProvider } from '../components/owner_context'; import { ConfigureCasesProps } from '../components/configure_cases'; +import { Owner } from '../types'; const ConfigureCasesLazy = lazy(() => import('../components/configure_cases')); -export const getConfigureCasesLazy = (props: ConfigureCasesProps) => ( - <Suspense fallback={<EuiLoadingSpinner />}> - <ConfigureCasesLazy {...props} /> - </Suspense> +export const getConfigureCasesLazy = (props: ConfigureCasesProps & Owner) => ( + <OwnerProvider owner={props.owner}> + <Suspense fallback={<EuiLoadingSpinner />}> + <ConfigureCasesLazy {...props} /> + </Suspense> + </OwnerProvider> ); diff --git a/x-pack/plugins/cases/public/methods/get_create_case.tsx b/x-pack/plugins/cases/public/methods/get_create_case.tsx index b030ed669b663..86fcb3e2d29a8 100644 --- a/x-pack/plugins/cases/public/methods/get_create_case.tsx +++ b/x-pack/plugins/cases/public/methods/get_create_case.tsx @@ -8,10 +8,14 @@ import React, { lazy, Suspense } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; import { CreateCaseProps } from '../components/create'; +import { Owner } from '../types'; +import { OwnerProvider } from '../components/owner_context'; const CreateCaseLazy = lazy(() => import('../components/create')); -export const getCreateCaseLazy = (props: CreateCaseProps) => ( - <Suspense fallback={<EuiLoadingSpinner />}> - <CreateCaseLazy {...props} /> - </Suspense> +export const getCreateCaseLazy = (props: CreateCaseProps & Owner) => ( + <OwnerProvider owner={props.owner}> + <Suspense fallback={<EuiLoadingSpinner />}> + <CreateCaseLazy {...props} /> + </Suspense> + </OwnerProvider> ); diff --git a/x-pack/plugins/cases/public/methods/get_recent_cases.tsx b/x-pack/plugins/cases/public/methods/get_recent_cases.tsx index e87db9320ca3d..1dc1be59d65e0 100644 --- a/x-pack/plugins/cases/public/methods/get_recent_cases.tsx +++ b/x-pack/plugins/cases/public/methods/get_recent_cases.tsx @@ -8,10 +8,14 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import React, { lazy, Suspense } from 'react'; import { RecentCasesProps } from '../components/recent_cases'; +import { OwnerProvider } from '../components/owner_context'; +import { Owner } from '../types'; const RecentCasesLazy = lazy(() => import('../components/recent_cases')); -export const getRecentCasesLazy = (props: RecentCasesProps) => ( - <Suspense fallback={<EuiLoadingSpinner />}> - <RecentCasesLazy {...props} /> - </Suspense> +export const getRecentCasesLazy = (props: RecentCasesProps & Owner) => ( + <OwnerProvider owner={props.owner}> + <Suspense fallback={<EuiLoadingSpinner />}> + <RecentCasesLazy {...props} /> + </Suspense> + </OwnerProvider> ); diff --git a/x-pack/plugins/cases/public/types.ts b/x-pack/plugins/cases/public/types.ts index 269d1773b3404..1336b8f7dba46 100644 --- a/x-pack/plugins/cases/public/types.ts +++ b/x-pack/plugins/cases/public/types.ts @@ -39,13 +39,17 @@ export type StartServices = CoreStart & security: SecurityPluginSetup; }; +export interface Owner { + owner: string[]; +} + export interface CasesUiStart { - getAllCases: (props: AllCasesProps) => ReactElement<AllCasesProps>; + getAllCases: (props: AllCasesProps & Owner) => ReactElement<AllCasesProps>; getAllCasesSelectorModal: ( - props: AllCasesSelectorModalProps + props: AllCasesSelectorModalProps & Owner ) => ReactElement<AllCasesSelectorModalProps>; getCaseView: (props: CaseViewProps) => ReactElement<CaseViewProps>; - getConfigureCases: (props: ConfigureCasesProps) => ReactElement<ConfigureCasesProps>; - getCreateCase: (props: CreateCaseProps) => ReactElement<CreateCaseProps>; - getRecentCases: (props: RecentCasesProps) => ReactElement<RecentCasesProps>; + getConfigureCases: (props: ConfigureCasesProps & Owner) => ReactElement<ConfigureCasesProps>; + getCreateCase: (props: CreateCaseProps & Owner) => ReactElement<CreateCaseProps>; + getRecentCases: (props: RecentCasesProps & Owner) => ReactElement<RecentCasesProps>; } diff --git a/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx b/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx index 826810c4d4086..3e70b22825df5 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx @@ -65,7 +65,7 @@ const CreateCaseFlyoutComponent: React.FC<CreateCaseModalProps> = ({ onCancel: onCloseFlyout, onSuccess, withSteps: false, - owner: APP_ID, + owner: [APP_ID], })} </FormWrapper> </StyledEuiFlyoutBody> diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx index 007ab7f47e301..5cb834ef51ec1 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx @@ -47,7 +47,7 @@ describe('Create case', () => { ); expect(mockCreateCase).toHaveBeenCalled(); - expect(mockCreateCase.mock.calls[0][0].owner).toBe('securitySolution'); + expect(mockCreateCase.mock.calls[0][0].owner).toBe(['securitySolution']); }); it('should redirect to all cases on cancel click', async () => { diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx index 2e6ddccddc789..f946cefd3494c 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx @@ -44,7 +44,7 @@ export const Create = React.memo(() => { useInsertTimeline, }, }, - owner: APP_ID, + owner: [APP_ID], })} </EuiPanel> ); diff --git a/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx index 9e7a57abff36c..c735fd5bc8567 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx @@ -56,7 +56,7 @@ const ConfigureCasesPageComponent: React.FC = () => { <WhitePageWrapper> {cases.getConfigureCases({ userCanCrud: userPermissions?.crud ?? false, - owner: APP_ID, + owner: [APP_ID], })} </WhitePageWrapper> </WrapperPage> From 9fc4772b9c2d8e2b354dbb8a92be500fb5dbeaf9 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 13 May 2021 12:27:51 +0300 Subject: [PATCH 06/17] Throw an error if owner context is not set --- .../components/owner_context/use_owner_context.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts b/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts index 6f3d2fc240e68..2523d80e82837 100644 --- a/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts +++ b/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts @@ -9,5 +9,13 @@ import { useContext } from 'react'; import { OwnerContext } from '.'; export const useOwnerContext = () => { - return useContext(OwnerContext); + const ownerContext = useContext(OwnerContext); + + if (ownerContext.length === 0) { + throw new Error( + 'useOwnerContext must be used within a OwnerProvider and not be an empty array' + ); + } + + return ownerContext; }; From 5fd963fdd8f10babf6ce682e1328a6a11cbb8ce3 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 13 May 2021 12:41:16 +0300 Subject: [PATCH 07/17] Add owner provider to case view --- .../public/components/add_comment/index.tsx | 7 ++-- .../public/components/case_view/index.tsx | 35 ++++++++++--------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/cases/public/components/add_comment/index.tsx b/x-pack/plugins/cases/public/components/add_comment/index.tsx index 2995fcb4fc35f..04104f0b9471d 100644 --- a/x-pack/plugins/cases/public/components/add_comment/index.tsx +++ b/x-pack/plugins/cases/public/components/add_comment/index.tsx @@ -18,6 +18,7 @@ import { Form, useForm, UseField, useFormData } from '../../common/shared_import import * as i18n from './translations'; import { schema, AddCommentFormSchema } from './schema'; import { InsertTimeline } from '../insert_timeline'; +import { useOwnerContext } from '../owner_context/use_owner_context'; const MySpinner = styled(EuiLoadingSpinner)` position: absolute; top: 50%; @@ -47,6 +48,7 @@ export const AddComment = React.memo( { caseId, disabled, onCommentPosted, onCommentSaving, showLoading = true, subCaseId }, ref ) => { + const owner = useOwnerContext(); const { isLoading, postComment } = usePostComment(); const { form } = useForm<AddCommentFormSchema>({ @@ -78,14 +80,13 @@ export const AddComment = React.memo( } postComment({ caseId, - // TODO: get plugin name - data: { ...data, type: CommentType.user, owner: 'securitySolution' }, + data: { ...data, type: CommentType.user, owner: owner[0] }, updateCase: onCommentPosted, subCaseId, }); reset(); } - }, [caseId, onCommentPosted, onCommentSaving, postComment, reset, submit, subCaseId]); + }, [submit, onCommentSaving, postComment, caseId, owner, onCommentPosted, subCaseId, reset]); return ( <span id="add-comment-permLink"> diff --git a/x-pack/plugins/cases/public/components/case_view/index.tsx b/x-pack/plugins/cases/public/components/case_view/index.tsx index 65e241d46b9ad..86b13ae5a863c 100644 --- a/x-pack/plugins/cases/public/components/case_view/index.tsx +++ b/x-pack/plugins/cases/public/components/case_view/index.tsx @@ -43,6 +43,7 @@ import { Ecs } from '../../../common'; import { CasesTimelineIntegration, CasesTimelineIntegrationProvider } from '../timeline_context'; import { useTimelineContext } from '../timeline_context/use_timeline_context'; import { CasesNavigation } from '../links'; +import { OwnerProvider } from '../owner_context'; const gutterTimeline = '70px'; // seems to be a timeline reference from the original file export interface CaseViewComponentProps { @@ -510,22 +511,24 @@ export const CaseView = React.memo( return ( data && ( <CasesTimelineIntegrationProvider timelineIntegration={timelineIntegration}> - <CaseComponent - allCasesNavigation={allCasesNavigation} - caseData={data} - caseDetailsNavigation={caseDetailsNavigation} - caseId={caseId} - configureCasesNavigation={configureCasesNavigation} - getCaseDetailHrefWithCommentId={getCaseDetailHrefWithCommentId} - fetchCase={fetchCase} - onComponentInitialized={onComponentInitialized} - ruleDetailsNavigation={ruleDetailsNavigation} - showAlertDetails={showAlertDetails} - subCaseId={subCaseId} - updateCase={updateCase} - useFetchAlertData={useFetchAlertData} - userCanCrud={userCanCrud} - /> + <OwnerProvider owner={[data.owner]}> + <CaseComponent + allCasesNavigation={allCasesNavigation} + caseData={data} + caseDetailsNavigation={caseDetailsNavigation} + caseId={caseId} + configureCasesNavigation={configureCasesNavigation} + getCaseDetailHrefWithCommentId={getCaseDetailHrefWithCommentId} + fetchCase={fetchCase} + onComponentInitialized={onComponentInitialized} + ruleDetailsNavigation={ruleDetailsNavigation} + showAlertDetails={showAlertDetails} + subCaseId={subCaseId} + updateCase={updateCase} + useFetchAlertData={useFetchAlertData} + userCanCrud={userCanCrud} + /> + </OwnerProvider> </CasesTimelineIntegrationProvider> ) ); From c680d712a3a6ad5c1dcc439e57b0cfaf0a82f998 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 13 May 2021 12:42:36 +0300 Subject: [PATCH 08/17] Use APP_ID when attaching an alert to a case --- .../cases/components/timeline_actions/add_to_case_action.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx index d43ef4cd63fb8..23ae979a3c137 100644 --- a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx @@ -111,8 +111,7 @@ const AddToCaseActionComponent: React.FC<AddToCaseActionProps> = ({ id: rule?.id != null ? rule.id[0] : null, name: rule?.name != null ? rule.name[0] : null, }, - // TODO: refactor - owner: 'securitySolution', + owner: APP_ID, }, updateCase, }); From 243936154231b516fcb0c1e8588134445aed4c68 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 13 May 2021 12:43:01 +0300 Subject: [PATCH 09/17] Clean up TODOs --- .../plugins/cases/public/components/configure_cases/button.tsx | 1 - x-pack/plugins/cases/public/components/create/schema.tsx | 1 - x-pack/plugins/cases/public/containers/configure/api.ts | 1 - .../plugins/cases/public/containers/configure/use_configure.tsx | 1 - x-pack/plugins/cases/public/containers/utils.ts | 1 - 5 files changed, 5 deletions(-) diff --git a/x-pack/plugins/cases/public/components/configure_cases/button.tsx b/x-pack/plugins/cases/public/components/configure_cases/button.tsx index 1830380be3765..8b3c78ee3aede 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/button.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/button.tsx @@ -10,7 +10,6 @@ import React, { memo, useMemo } from 'react'; import { CasesNavigation, LinkButton } from '../links'; // TODO: Potentially move into links component? - export interface ConfigureCaseButtonProps { configureCasesNavigation: CasesNavigation; isDisabled: boolean; diff --git a/x-pack/plugins/cases/public/components/create/schema.tsx b/x-pack/plugins/cases/public/components/create/schema.tsx index ccf9013e6a6fa..6e6d1a414280e 100644 --- a/x-pack/plugins/cases/public/components/create/schema.tsx +++ b/x-pack/plugins/cases/public/components/create/schema.tsx @@ -19,7 +19,6 @@ export const schemaTags = { labelAppend: OptionalFieldLabel, }; -// TODO: remove owner from here? export type FormProps = Omit<CasePostRequest, 'connector' | 'settings' | 'owner'> & { connectorId: string; fields: ConnectorTypeFields['fields']; diff --git a/x-pack/plugins/cases/public/containers/configure/api.ts b/x-pack/plugins/cases/public/containers/configure/api.ts index 4994364976935..a6d530caa588e 100644 --- a/x-pack/plugins/cases/public/containers/configure/api.ts +++ b/x-pack/plugins/cases/public/containers/configure/api.ts @@ -37,7 +37,6 @@ export const fetchConnectors = async ({ signal }: ApiProps): Promise<ActionConne return response; }; -// TODO: refactor export const getCaseConfigure = async ({ signal, owner, diff --git a/x-pack/plugins/cases/public/containers/configure/use_configure.tsx b/x-pack/plugins/cases/public/containers/configure/use_configure.tsx index 178feffcc620b..25e0782f6c13b 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_configure.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_configure.tsx @@ -218,7 +218,6 @@ export const useCaseConfigure = (owner: string): ReturnUseCaseConfigure => { }); }, []); - // TODO: refactor const setID = useCallback((id: string) => { dispatch({ payload: id, diff --git a/x-pack/plugins/cases/public/containers/utils.ts b/x-pack/plugins/cases/public/containers/utils.ts index fc8064adf5d94..de67b1cfbd6fa 100644 --- a/x-pack/plugins/cases/public/containers/utils.ts +++ b/x-pack/plugins/cases/public/containers/utils.ts @@ -94,7 +94,6 @@ export const decodeCasesResponse = (respCase?: CasesResponse) => export const decodeCasesFindResponse = (respCases?: CasesFindResponse) => pipe(CasesFindResponseRt.decode(respCases), fold(throwErrors(createToasterPlainError), identity)); -// TODO: might need to refactor this export const decodeCaseConfigurationsResponse = (respCase?: CasesConfigurationsResponse) => { return pipe( CaseConfigurationsResponseRt.decode(respCase), From 29068cbbb49226ac054931e183a9d5892033d6eb Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 13 May 2021 13:13:01 +0300 Subject: [PATCH 10/17] Use constants for owner --- x-pack/plugins/cases/common/constants.ts | 2 ++ .../public/common/mock/test_providers.tsx | 3 +- .../components/add_comment/index.test.tsx | 4 +-- .../components/all_cases/index.test.tsx | 4 +-- .../all_cases/selector_modal/index.test.tsx | 5 +-- .../components/case_view/helpers.test.tsx | 6 ++-- .../components/create/form_context.test.tsx | 4 +-- .../cases/public/components/create/mock.ts | 9 ++++-- .../components/recent_cases/index.test.tsx | 4 ++- .../public/components/tag_list/index.test.tsx | 3 +- .../create_case_modal.test.tsx | 3 +- .../use_create_case_modal/index.test.tsx | 11 ++++--- .../cases/public/containers/api.test.tsx | 18 +++++------ .../public/containers/configure/api.test.ts | 10 +++--- .../cases/public/containers/configure/mock.ts | 7 +++-- .../configure/use_configure.test.tsx | 26 ++++++++-------- .../plugins/cases/public/containers/mock.ts | 17 +++++----- .../containers/use_get_reporters.test.tsx | 13 ++++---- .../public/containers/use_get_tags.test.tsx | 13 ++++---- .../public/containers/use_post_case.test.tsx | 4 +-- .../containers/use_post_comment.test.tsx | 4 +-- .../plugins/cases/server/client/cases/mock.ts | 19 ++++++------ .../cases/server/client/cases/utils.test.ts | 3 +- .../plugins/cases/server/common/utils.test.ts | 25 ++++++++------- .../server/connectors/case/index.test.ts | 15 ++++----- .../api/__fixtures__/mock_saved_objects.ts | 31 ++++++++++--------- .../routes/api/__mocks__/request_responses.ts | 4 +-- .../cases/server/scripts/sub_cases/index.ts | 11 +++++-- .../cases/components/create/index.test.tsx | 3 +- .../add_to_case_action.test.tsx | 6 ++-- .../timeline_actions/add_to_case_action.tsx | 2 +- 31 files changed, 160 insertions(+), 129 deletions(-) diff --git a/x-pack/plugins/cases/common/constants.ts b/x-pack/plugins/cases/common/constants.ts index 6bd2204e39be7..72c21aa12dcf2 100644 --- a/x-pack/plugins/cases/common/constants.ts +++ b/x-pack/plugins/cases/common/constants.ts @@ -79,6 +79,8 @@ export const MAX_GENERATED_ALERTS_PER_SUB_CASE = 50; /** * This must be the same value that the security solution plugin uses to define the case kind when it registers the * feature for the 7.13 migration only. + * + * This variable is being also used by test files and mocks. */ export const SECURITY_SOLUTION_OWNER = 'securitySolution'; diff --git a/x-pack/plugins/cases/public/common/mock/test_providers.tsx b/x-pack/plugins/cases/public/common/mock/test_providers.tsx index 8486350cd4e50..9a08918a483a5 100644 --- a/x-pack/plugins/cases/public/common/mock/test_providers.tsx +++ b/x-pack/plugins/cases/public/common/mock/test_providers.tsx @@ -10,6 +10,7 @@ import { I18nProvider } from '@kbn/i18n/react'; import React from 'react'; import { BehaviorSubject } from 'rxjs'; import { ThemeProvider } from 'styled-components'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; import { OwnerProvider } from '../../components/owner_context'; import { createKibanaContextProviderMock, @@ -31,7 +32,7 @@ const TestProvidersComponent: React.FC<Props> = ({ children }) => ( <I18nProvider> <MockKibanaContextProvider> <ThemeProvider theme={() => ({ eui: euiDarkVars, darkMode: true })}> - <OwnerProvider owner={['securitySolution']}>{children}</OwnerProvider> + <OwnerProvider owner={[SECURITY_SOLUTION_OWNER]}>{children}</OwnerProvider> </ThemeProvider> </MockKibanaContextProvider> </I18nProvider> diff --git a/x-pack/plugins/cases/public/components/add_comment/index.test.tsx b/x-pack/plugins/cases/public/components/add_comment/index.test.tsx index 95f642c7e625a..23a0fca48592f 100644 --- a/x-pack/plugins/cases/public/components/add_comment/index.test.tsx +++ b/x-pack/plugins/cases/public/components/add_comment/index.test.tsx @@ -13,7 +13,7 @@ import { noop } from 'lodash/fp'; import { TestProviders } from '../../common/mock'; import { Router, routeData, mockHistory, mockLocation } from '../__mock__/router'; -import { CommentRequest, CommentType } from '../../../common'; +import { CommentRequest, CommentType, SECURITY_SOLUTION_OWNER } from '../../../common'; import { usePostComment } from '../../containers/use_post_comment'; import { AddComment, AddCommentRefObject } from '.'; import { CasesTimelineIntegrationProvider } from '../timeline_context'; @@ -44,7 +44,7 @@ const defaultPostComment = { const sampleData: CommentRequest = { comment: 'what a cool comment', type: CommentType.user, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; describe('AddComment ', () => { diff --git a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx index 7233d6bef6e4a..2abdbdea5cd77 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx @@ -13,7 +13,7 @@ import '../../common/mock/match_media'; import { TestProviders } from '../../common/mock'; import { casesStatus, useGetCasesMockState, collectionCase } from '../../containers/mock'; -import { CaseStatuses, CaseType, StatusAll } from '../../../common'; +import { CaseStatuses, CaseType, SECURITY_SOLUTION_OWNER, StatusAll } from '../../../common'; import { getEmptyTagValue } from '../empty_value'; import { useDeleteCases } from '../../containers/use_delete_cases'; import { useGetCases } from '../../containers/use_get_cases'; @@ -815,7 +815,7 @@ describe('AllCasesGeneric', () => { }, }, id: '1', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, status: 'open', subCaseIds: [], tags: ['coke', 'pepsi'], diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.test.tsx index 8c22a2ec0dd0b..47db45699f8fb 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.test.tsx @@ -11,6 +11,7 @@ import { mount } from 'enzyme'; import { AllCasesSelectorModal } from '.'; import { TestProviders } from '../../../common/mock'; import { AllCasesGeneric } from '../all_cases_generic'; +import { SECURITY_SOLUTION_OWNER } from '../../../../common'; jest.mock('../../../methods'); jest.mock('../all_cases_generic'); @@ -20,7 +21,7 @@ const defaultProps = { createCaseNavigation, onRowClick, userCanCrud: true, - owner: ['securitySolution'], + owner: [SECURITY_SOLUTION_OWNER], }; const updateCase = jest.fn(); @@ -60,7 +61,7 @@ describe('AllCasesSelectorModal', () => { }, index: 'index-id', alertId: 'alert-id', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, disabledStatuses: [], updateCase, diff --git a/x-pack/plugins/cases/public/components/case_view/helpers.test.tsx b/x-pack/plugins/cases/public/components/case_view/helpers.test.tsx index 47ab272bdc3f8..bf5a9fe5d0a22 100644 --- a/x-pack/plugins/cases/public/components/case_view/helpers.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/helpers.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { AssociationType, CommentType } from '../../../common'; +import { AssociationType, CommentType, SECURITY_SOLUTION_OWNER } from '../../../common'; import { Comment } from '../../containers/types'; import { getManualAlertIdsWithNoRuleId } from './helpers'; @@ -28,7 +28,7 @@ const comments: Comment[] = [ updatedAt: null, updatedBy: null, version: 'WzQ3LDFc', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, { associationType: AssociationType.case, @@ -47,7 +47,7 @@ const comments: Comment[] = [ updatedAt: null, updatedBy: null, version: 'WzQ3LDFc', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, ]; diff --git a/x-pack/plugins/cases/public/components/create/form_context.test.tsx b/x-pack/plugins/cases/public/components/create/form_context.test.tsx index 5e61d726b8b9f..cb053b2e784cd 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.test.tsx @@ -10,7 +10,7 @@ import { mount, ReactWrapper } from 'enzyme'; import { act, waitFor } from '@testing-library/react'; import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; -import { ConnectorTypes } from '../../../common'; +import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common'; import { TestProviders } from '../../common/mock'; import { usePostCase } from '../../containers/use_post_case'; import { usePostComment } from '../../containers/use_post_comment'; @@ -77,7 +77,7 @@ const defaultPostCase = { const defaultCreateCaseForm = { isLoadingConnectors: false, connectors: [], - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; const defaultPostPushToService = { diff --git a/x-pack/plugins/cases/public/components/create/mock.ts b/x-pack/plugins/cases/public/components/create/mock.ts index 5a4c00ba8a91c..fb00f114f480c 100644 --- a/x-pack/plugins/cases/public/components/create/mock.ts +++ b/x-pack/plugins/cases/public/components/create/mock.ts @@ -5,7 +5,12 @@ * 2.0. */ -import { CasePostRequest, CaseType, ConnectorTypes } from '../../../common'; +import { + CasePostRequest, + CaseType, + ConnectorTypes, + SECURITY_SOLUTION_OWNER, +} from '../../../common'; import { choices } from '../connectors/mock'; export const sampleTags = ['coke', 'pepsi']; @@ -23,7 +28,7 @@ export const sampleData: CasePostRequest = { settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; export const sampleConnectorData = { loading: false, connectors: [] }; diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx index d84dd9aba8e5e..595be65fa5d77 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx @@ -12,6 +12,8 @@ import RecentCases from '.'; import { TestProviders } from '../../common/mock'; import { useGetCases } from '../../containers/use_get_cases'; import { useGetCasesMockState } from '../../containers/mock'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; + jest.mock('../../containers/use_get_cases'); configure({ testIdAttribute: 'data-test-subj' }); const defaultProps = { @@ -28,7 +30,7 @@ const defaultProps = { onClick: jest.fn(), }, maxCasesToShow: 10, - owner: ['securitySolution'], + owner: [SECURITY_SOLUTION_OWNER], }; const setFilters = jest.fn(); const mockData = { diff --git a/x-pack/plugins/cases/public/components/tag_list/index.test.tsx b/x-pack/plugins/cases/public/components/tag_list/index.test.tsx index c7360c1bb67df..b3fbcd30d4e97 100644 --- a/x-pack/plugins/cases/public/components/tag_list/index.test.tsx +++ b/x-pack/plugins/cases/public/components/tag_list/index.test.tsx @@ -14,6 +14,7 @@ import { TestProviders } from '../../common/mock'; import { waitFor } from '@testing-library/react'; import { useForm } from '../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'; import { useGetTags } from '../../containers/use_get_tags'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; jest.mock('../../../../../../src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form'); jest.mock('../../containers/use_get_tags'); @@ -37,7 +38,7 @@ const defaultProps = { isLoading: false, onSubmit, tags: [], - owner: ['securitySolution'], + owner: [SECURITY_SOLUTION_OWNER], }; describe('TagList ', () => { diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.test.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.test.tsx index b869a187fbdd5..4c39b721cac47 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.test.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/create_case_modal.test.tsx @@ -11,6 +11,7 @@ import { mount } from 'enzyme'; import { CreateCaseModal } from './create_case_modal'; import { TestProviders } from '../../common/mock'; import { getCreateCaseLazy as getCreateCase } from '../../methods'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; jest.mock('../../methods'); const getCreateCaseMock = getCreateCase as jest.Mock; @@ -20,7 +21,7 @@ const defaultProps = { isModalOpen: true, onCloseCaseModal, onSuccess, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; describe('CreateCaseModal', () => { diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx index c47e9cbe460d8..2f8d139cd0a23 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx @@ -12,6 +12,7 @@ import { render } from '@testing-library/react'; import { useKibana } from '../../common/lib/kibana'; import { useCreateCaseModal, UseCreateCaseModalProps, UseCreateCaseModalReturnedValues } from '.'; import { TestProviders } from '../../common/mock'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; jest.mock('../../common/lib/kibana'); @@ -28,7 +29,7 @@ describe('useCreateCaseModal', () => { it('init', async () => { const { result } = renderHook<UseCreateCaseModalProps, UseCreateCaseModalReturnedValues>( - () => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), + () => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, } @@ -39,7 +40,7 @@ describe('useCreateCaseModal', () => { it('opens the modal', async () => { const { result } = renderHook<UseCreateCaseModalProps, UseCreateCaseModalReturnedValues>( - () => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), + () => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, } @@ -54,7 +55,7 @@ describe('useCreateCaseModal', () => { it('closes the modal', async () => { const { result } = renderHook<UseCreateCaseModalProps, UseCreateCaseModalReturnedValues>( - () => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), + () => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, } @@ -72,7 +73,7 @@ describe('useCreateCaseModal', () => { const { result, rerender } = renderHook< UseCreateCaseModalProps, UseCreateCaseModalReturnedValues - >(() => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), { + >(() => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); @@ -85,7 +86,7 @@ describe('useCreateCaseModal', () => { it('closes the modal when creating a case', async () => { const { result } = renderHook<UseCreateCaseModalProps, UseCreateCaseModalReturnedValues>( - () => useCreateCaseModal({ onCaseCreated, owner: 'securitySolution' }), + () => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, } diff --git a/x-pack/plugins/cases/public/containers/api.test.tsx b/x-pack/plugins/cases/public/containers/api.test.tsx index 17a532a2a9e7e..3fe61a640a679 100644 --- a/x-pack/plugins/cases/public/containers/api.test.tsx +++ b/x-pack/plugins/cases/public/containers/api.test.tsx @@ -7,7 +7,7 @@ import { KibanaServices } from '../common/lib/kibana'; -import { ConnectorTypes, CommentType, CaseStatuses } from '../../common'; +import { ConnectorTypes, CommentType, CaseStatuses, SECURITY_SOLUTION_OWNER } from '../../common'; import { CASES_URL } from '../../common'; import { @@ -250,18 +250,18 @@ describe('Case Configuration API', () => { }); test('check url, method, signal', async () => { - await getReporters(abortCtrl.signal, ['securitySolution']); + await getReporters(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); expect(fetchMock).toHaveBeenCalledWith(`${CASES_URL}/reporters`, { method: 'GET', signal: abortCtrl.signal, query: { - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, }); }); test('happy path', async () => { - const resp = await getReporters(abortCtrl.signal, ['securitySolution']); + const resp = await getReporters(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); expect(resp).toEqual(respReporters); }); }); @@ -273,18 +273,18 @@ describe('Case Configuration API', () => { }); test('check url, method, signal', async () => { - await getTags(abortCtrl.signal, ['securitySolution']); + await getTags(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); expect(fetchMock).toHaveBeenCalledWith(`${CASES_URL}/tags`, { method: 'GET', signal: abortCtrl.signal, query: { - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, }); }); test('happy path', async () => { - const resp = await getTags(abortCtrl.signal, ['securitySolution']); + const resp = await getTags(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); expect(resp).toEqual(tags); }); }); @@ -401,7 +401,7 @@ describe('Case Configuration API', () => { settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; test('check url, method, signal', async () => { @@ -426,7 +426,7 @@ describe('Case Configuration API', () => { }); const data = { comment: 'comment', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, type: CommentType.user as const, }; diff --git a/x-pack/plugins/cases/public/containers/configure/api.test.ts b/x-pack/plugins/cases/public/containers/configure/api.test.ts index 8529b19c3df2b..9194921ab4b34 100644 --- a/x-pack/plugins/cases/public/containers/configure/api.test.ts +++ b/x-pack/plugins/cases/public/containers/configure/api.test.ts @@ -19,7 +19,7 @@ import { caseConfigurationResposeMock, caseConfigurationCamelCaseResponseMock, } from './mock'; -import { ConnectorTypes } from '../../../common'; +import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common'; import { KibanaServices } from '../../common/lib/kibana'; const abortCtrl = new AbortController(); @@ -57,12 +57,12 @@ describe('Case Configuration API', () => { }); test('check url, method, signal', async () => { - await getCaseConfigure({ signal: abortCtrl.signal, owner: ['securitySolution'] }); + await getCaseConfigure({ signal: abortCtrl.signal, owner: [SECURITY_SOLUTION_OWNER] }); expect(fetchMock).toHaveBeenCalledWith('/api/cases/configure', { method: 'GET', signal: abortCtrl.signal, query: { - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, }); }); @@ -70,7 +70,7 @@ describe('Case Configuration API', () => { test('happy path', async () => { const resp = await getCaseConfigure({ signal: abortCtrl.signal, - owner: ['securitySolution'], + owner: [SECURITY_SOLUTION_OWNER], }); expect(resp).toEqual(caseConfigurationCamelCaseResponseMock); }); @@ -79,7 +79,7 @@ describe('Case Configuration API', () => { fetchMock.mockResolvedValue({}); const resp = await getCaseConfigure({ signal: abortCtrl.signal, - owner: ['securitySolution'], + owner: [SECURITY_SOLUTION_OWNER], }); expect(resp).toBe(null); }); diff --git a/x-pack/plugins/cases/public/containers/configure/mock.ts b/x-pack/plugins/cases/public/containers/configure/mock.ts index 3329fa02a54b9..ef287ea866dcb 100644 --- a/x-pack/plugins/cases/public/containers/configure/mock.ts +++ b/x-pack/plugins/cases/public/containers/configure/mock.ts @@ -11,6 +11,7 @@ import { CasesConfigureResponse, CasesConfigureRequest, ConnectorTypes, + SECURITY_SOLUTION_OWNER, } from '../../../common'; import { CaseConfigure, CaseConnectorMapping } from './types'; @@ -130,7 +131,7 @@ export const caseConfigurationResposeMock: CasesConfigureResponse = { mappings: [], updated_at: '2020-04-06T14:03:18.657Z', updated_by: { username: 'elastic', full_name: 'Elastic', email: 'elastic@elastic.co' }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, version: 'WzHJ12', }; @@ -141,7 +142,7 @@ export const caseConfigurationMock: CasesConfigureRequest = { type: ConnectorTypes.jira, fields: null, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, closure_type: 'close-by-user', }; @@ -161,5 +162,5 @@ export const caseConfigurationCamelCaseResponseMock: CaseConfigure = { updatedAt: '2020-04-06T14:03:18.657Z', updatedBy: { username: 'elastic', fullName: 'Elastic', email: 'elastic@elastic.co' }, version: 'WzHJ12', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; diff --git a/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx b/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx index fd43fbf301ff5..094083d6a2c7c 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx @@ -14,7 +14,7 @@ import { } from './use_configure'; import { mappings, caseConfigurationCamelCaseResponseMock } from './mock'; import * as api from './api'; -import { ConnectorTypes } from '../../../common'; +import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common'; const mockErrorToast = jest.fn(); const mockSuccessToast = jest.fn(); @@ -50,7 +50,7 @@ describe('useConfigure', () => { test('init', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -68,7 +68,7 @@ describe('useConfigure', () => { test('fetch case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -100,7 +100,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -112,7 +112,7 @@ describe('useConfigure', () => { test('correctly sets mappings', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -125,7 +125,7 @@ describe('useConfigure', () => { test('set isLoading to true when fetching case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -138,7 +138,7 @@ describe('useConfigure', () => { test('persist case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -167,7 +167,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -193,7 +193,7 @@ describe('useConfigure', () => { await act(async () => { const { waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -222,7 +222,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -246,7 +246,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -267,7 +267,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); @@ -303,7 +303,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure('securitySolution') + useCaseConfigure(SECURITY_SOLUTION_OWNER) ); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/mock.ts b/x-pack/plugins/cases/public/containers/mock.ts index 4871fa1555a12..72fee3c602c4e 100644 --- a/x-pack/plugins/cases/public/containers/mock.ts +++ b/x-pack/plugins/cases/public/containers/mock.ts @@ -19,6 +19,7 @@ import { CommentResponse, CommentType, ConnectorTypes, + SECURITY_SOLUTION_OWNER, UserAction, UserActionField, } from '../../common'; @@ -47,7 +48,7 @@ export const basicComment: Comment = { id: basicCommentId, createdAt: basicCreatedAt, createdBy: elasticUser, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushedAt: null, pushedBy: null, updatedAt: null, @@ -63,7 +64,7 @@ export const alertComment: Comment = { id: 'alert-comment-id', createdAt: basicCreatedAt, createdBy: elasticUser, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushedAt: null, pushedBy: null, rule: { @@ -77,7 +78,7 @@ export const alertComment: Comment = { export const basicCase: Case = { type: CaseType.individual, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, closedAt: null, closedBy: null, id: basicCaseId, @@ -108,7 +109,7 @@ export const basicCase: Case = { export const collectionCase: Case = { type: CaseType.collection, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, closedAt: null, closedBy: null, id: 'collection-id', @@ -185,7 +186,7 @@ const basicAction = { newValue: 'what a cool value', caseId: basicCaseId, commentId: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; export const cases: Case[] = [ @@ -235,7 +236,7 @@ export const basicCommentSnake: CommentResponse = { id: basicCommentId, created_at: basicCreatedAt, created_by: elasticUserSnake, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, updated_at: null, @@ -260,7 +261,7 @@ export const basicCaseSnake: CaseResponse = { external_service: null, updated_at: basicUpdatedAt, updated_by: elasticUserSnake, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, } as CaseResponse; export const casesStatusSnake: CasesStatusResponse = { @@ -318,7 +319,7 @@ const basicActionSnake = { new_value: 'what a cool value', case_id: basicCaseId, comment_id: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; export const getUserActionSnake = (af: UserActionField, a: UserAction) => ({ ...basicActionSnake, diff --git a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx index 36ab7f8d4e57d..5d403a5a850ed 100644 --- a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx @@ -9,6 +9,7 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { useGetReporters, UseGetReporters } from './use_get_reporters'; import { reporters, respReporters } from './mock'; import * as api from './api'; +import { SECURITY_SOLUTION_OWNER } from '../../common'; jest.mock('./api'); jest.mock('../common/lib/kibana'); @@ -23,7 +24,7 @@ describe('useGetReporters', () => { it('init', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters(['securitySolution']) + useGetReporters([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -40,18 +41,18 @@ describe('useGetReporters', () => { const spyOnGetReporters = jest.spyOn(api, 'getReporters'); await act(async () => { const { waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters(['securitySolution']) + useGetReporters([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); await waitForNextUpdate(); - expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal, ['securitySolution']); + expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); }); }); it('fetch reporters', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters(['securitySolution']) + useGetReporters([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -69,7 +70,7 @@ describe('useGetReporters', () => { const spyOnGetReporters = jest.spyOn(api, 'getReporters'); await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters(['securitySolution']) + useGetReporters([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -86,7 +87,7 @@ describe('useGetReporters', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters(['securitySolution']) + useGetReporters([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx index 9d433dea77429..c7ed0d8563c51 100644 --- a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx @@ -9,6 +9,7 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { useGetTags, UseGetTags } from './use_get_tags'; import { tags } from './mock'; import * as api from './api'; +import { SECURITY_SOLUTION_OWNER } from '../../common'; jest.mock('./api'); jest.mock('../common/lib/kibana'); @@ -23,7 +24,7 @@ describe('useGetTags', () => { it('init', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags(['securitySolution']) + useGetTags([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -39,18 +40,18 @@ describe('useGetTags', () => { const spyOnGetTags = jest.spyOn(api, 'getTags'); await act(async () => { const { waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags(['securitySolution']) + useGetTags([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); await waitForNextUpdate(); - expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal, ['securitySolution']); + expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); }); }); it('fetch tags', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags(['securitySolution']) + useGetTags([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -67,7 +68,7 @@ describe('useGetTags', () => { const spyOnGetTags = jest.spyOn(api, 'getTags'); await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags(['securitySolution']) + useGetTags([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -84,7 +85,7 @@ describe('useGetTags', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags(['securitySolution']) + useGetTags([SECURITY_SOLUTION_OWNER]) ); await waitForNextUpdate(); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/use_post_case.test.tsx b/x-pack/plugins/cases/public/containers/use_post_case.test.tsx index c1d030e7618c3..d2b638b4c846f 100644 --- a/x-pack/plugins/cases/public/containers/use_post_case.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_post_case.test.tsx @@ -8,7 +8,7 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { usePostCase, UsePostCase } from './use_post_case'; import * as api from './api'; -import { ConnectorTypes } from '../../common'; +import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../common'; import { basicCasePost } from './mock'; jest.mock('./api'); @@ -29,7 +29,7 @@ describe('usePostCase', () => { settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; beforeEach(() => { jest.clearAllMocks(); diff --git a/x-pack/plugins/cases/public/containers/use_post_comment.test.tsx b/x-pack/plugins/cases/public/containers/use_post_comment.test.tsx index a9750f213f3d6..8a86d9becdfde 100644 --- a/x-pack/plugins/cases/public/containers/use_post_comment.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_post_comment.test.tsx @@ -7,7 +7,7 @@ import { renderHook, act } from '@testing-library/react-hooks'; -import { CommentType } from '../../common'; +import { CommentType, SECURITY_SOLUTION_OWNER } from '../../common'; import { usePostComment, UsePostComment } from './use_post_comment'; import { basicCaseId, basicSubCaseId } from './mock'; import * as api from './api'; @@ -20,7 +20,7 @@ describe('usePostComment', () => { const samplePost = { comment: 'a comment', type: CommentType.user as const, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; const updateCaseCallback = jest.fn(); beforeEach(() => { diff --git a/x-pack/plugins/cases/server/client/cases/mock.ts b/x-pack/plugins/cases/server/client/cases/mock.ts index a8079d6095ba3..23db57c6d3097 100644 --- a/x-pack/plugins/cases/server/client/cases/mock.ts +++ b/x-pack/plugins/cases/server/client/cases/mock.ts @@ -12,6 +12,7 @@ import { CaseUserActionsResponse, AssociationType, CommentResponseAlertsType, + SECURITY_SOLUTION_OWNER, } from '../../../common'; import { BasicParams } from './types'; @@ -39,7 +40,7 @@ export const comment: CommentResponse = { email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, updated_at: '2019-11-25T21:55:00.177Z', @@ -67,7 +68,7 @@ export const commentAlert: CommentResponse = { email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, updated_at: '2019-11-25T21:55:00.177Z', @@ -85,7 +86,7 @@ export const commentAlertMultipleIds: CommentResponseAlertsType = { alertId: ['alert-id-1', 'alert-id-2'], index: 'alert-index-1', type: CommentType.alert as const, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; export const commentGeneratedAlert: CommentResponseAlertsType = { @@ -135,7 +136,7 @@ export const userActions: CaseUserActionsResponse = [ action_id: 'fd830c60-6646-11eb-a291-51bf6b175a53', case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53', comment_id: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, { action_field: ['pushed'], @@ -152,7 +153,7 @@ export const userActions: CaseUserActionsResponse = [ action_id: '0a801750-6647-11eb-a291-51bf6b175a53', case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53', comment_id: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, { action_field: ['comment'], @@ -168,7 +169,7 @@ export const userActions: CaseUserActionsResponse = [ action_id: '7373eb60-6647-11eb-a291-51bf6b175a53', case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53', comment_id: 'comment-alert-1', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, { action_field: ['comment'], @@ -184,7 +185,7 @@ export const userActions: CaseUserActionsResponse = [ action_id: '7abc6410-6647-11eb-a291-51bf6b175a53', case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53', comment_id: 'comment-alert-2', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, { action_field: ['pushed'], @@ -201,7 +202,7 @@ export const userActions: CaseUserActionsResponse = [ action_id: '9b91d8f0-6647-11eb-a291-51bf6b175a53', case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53', comment_id: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, { action_field: ['comment'], @@ -217,6 +218,6 @@ export const userActions: CaseUserActionsResponse = [ action_id: '0818e5e0-6648-11eb-a291-51bf6b175a53', case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53', comment_id: 'comment-user-1', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, ]; diff --git a/x-pack/plugins/cases/server/client/cases/utils.test.ts b/x-pack/plugins/cases/server/client/cases/utils.test.ts index 9dd36d2f8e534..9f18fa4931e62 100644 --- a/x-pack/plugins/cases/server/client/cases/utils.test.ts +++ b/x-pack/plugins/cases/server/client/cases/utils.test.ts @@ -29,6 +29,7 @@ import { transformFields, } from './utils'; import { flattenCaseSavedObject } from '../../common'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; const formatComment = { commentId: commentObj.id, @@ -701,7 +702,7 @@ describe('utils', () => { action_id: '9b91d8f0-6647-11eb-a291-51bf6b175a53', case_id: 'fcdedd20-6646-11eb-a291-51bf6b175a53', comment_id: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, ]); diff --git a/x-pack/plugins/cases/server/common/utils.test.ts b/x-pack/plugins/cases/server/common/utils.test.ts index 4057cf4f3f52d..322e45094eda4 100644 --- a/x-pack/plugins/cases/server/common/utils.test.ts +++ b/x-pack/plugins/cases/server/common/utils.test.ts @@ -6,6 +6,7 @@ */ import { SavedObjectsFindResponse } from 'kibana/server'; +import { SECURITY_SOLUTION_OWNER } from '../../common'; import { AssociationType, CaseResponse, @@ -587,7 +588,7 @@ describe('common utils', () => { full_name: 'Elastic', username: 'elastic', associationType: AssociationType.case, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; const res = transformNewComment(comment); @@ -616,7 +617,7 @@ describe('common utils', () => { comment: 'A comment', type: CommentType.user as const, createdDate: '2020-04-09T09:43:51.778Z', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, associationType: AssociationType.case, }; @@ -650,7 +651,7 @@ describe('common utils', () => { email: null, full_name: null, username: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, associationType: AssociationType.case, }; @@ -684,7 +685,7 @@ describe('common utils', () => { createCommentFindResponse([ { ids: ['1'], - comments: [{ comment: '', type: CommentType.user, owner: 'securitySolution' }], + comments: [{ comment: '', type: CommentType.user, owner: SECURITY_SOLUTION_OWNER }], }, ]).saved_objects[0] ) @@ -706,7 +707,7 @@ describe('common utils', () => { id: 'rule-id-1', name: 'rule-name-1', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, ], }, @@ -730,7 +731,7 @@ describe('common utils', () => { id: 'rule-id-1', name: 'rule-name-1', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, ], }, @@ -751,7 +752,7 @@ describe('common utils', () => { { alertId: ['a', 'b'], index: '', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, type: CommentType.alert, rule: { id: 'rule-id-1', @@ -760,7 +761,7 @@ describe('common utils', () => { }, { comment: '', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, type: CommentType.user, }, ], @@ -780,7 +781,7 @@ describe('common utils', () => { ids: ['1'], comments: [ { - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, alertId: ['a', 'b'], index: '', type: CommentType.alert, @@ -795,7 +796,7 @@ describe('common utils', () => { ids: ['2'], comments: [ { - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, comment: '', type: CommentType.user, }, @@ -819,7 +820,7 @@ describe('common utils', () => { ids: ['1', '2'], comments: [ { - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, alertId: ['a', 'b'], index: '', type: CommentType.alert, @@ -851,7 +852,7 @@ describe('common utils', () => { ids: ['1', '2'], comments: [ { - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, alertId: ['a', 'b'], index: '', type: CommentType.alert, diff --git a/x-pack/plugins/cases/server/connectors/case/index.test.ts b/x-pack/plugins/cases/server/connectors/case/index.test.ts index a2afc1df4ecf7..4a5fa8149c406 100644 --- a/x-pack/plugins/cases/server/connectors/case/index.test.ts +++ b/x-pack/plugins/cases/server/connectors/case/index.test.ts @@ -27,6 +27,7 @@ import { createCasesClientFactory, createCasesClientMock, } from '../../client/mocks'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; const services = actionsMock.createServices(); let caseActionType: CaseActionType; @@ -753,7 +754,7 @@ describe('case connector', () => { comment: { comment: 'a comment', type: CommentType.user, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, }, }; @@ -774,7 +775,7 @@ describe('case connector', () => { id: null, name: null, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, }, }; @@ -958,7 +959,7 @@ describe('case connector', () => { settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; mockCasesClient.cases.create.mockReturnValue(Promise.resolve(createReturn)); @@ -1055,7 +1056,7 @@ describe('case connector', () => { settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, ]; @@ -1136,7 +1137,7 @@ describe('case connector', () => { username: 'awesome', }, id: 'mock-comment', - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, updated_at: null, @@ -1147,7 +1148,7 @@ describe('case connector', () => { settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; mockCasesClient.attachments.add.mockReturnValue(Promise.resolve(commentReturn)); @@ -1160,7 +1161,7 @@ describe('case connector', () => { comment: { comment: 'a comment', type: CommentType.user, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, }, }; diff --git a/x-pack/plugins/cases/server/routes/api/__fixtures__/mock_saved_objects.ts b/x-pack/plugins/cases/server/routes/api/__fixtures__/mock_saved_objects.ts index ff188426dd96d..bddceef8d782e 100644 --- a/x-pack/plugins/cases/server/routes/api/__fixtures__/mock_saved_objects.ts +++ b/x-pack/plugins/cases/server/routes/api/__fixtures__/mock_saved_objects.ts @@ -21,6 +21,7 @@ import { import { CASE_CONNECTOR_MAPPINGS_SAVED_OBJECT, CASE_USER_ACTION_SAVED_OBJECT, + SECURITY_SOLUTION_OWNER, } from '../../../../common/constants'; import { mappings } from '../../../client/configure/mock'; @@ -58,7 +59,7 @@ export const mockCases: Array<SavedObject<ESCaseAttributes>> = [ settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, references: [], updated_at: '2019-11-25T21:54:48.952Z', @@ -97,7 +98,7 @@ export const mockCases: Array<SavedObject<ESCaseAttributes>> = [ settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, references: [], updated_at: '2019-11-25T22:32:00.900Z', @@ -140,7 +141,7 @@ export const mockCases: Array<SavedObject<ESCaseAttributes>> = [ settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, references: [], updated_at: '2019-11-25T22:32:17.947Z', @@ -187,7 +188,7 @@ export const mockCases: Array<SavedObject<ESCaseAttributes>> = [ settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, references: [], updated_at: '2019-11-25T22:32:17.947Z', @@ -250,7 +251,7 @@ export const mockCaseComments: Array<SavedObject<CommentAttributes>> = [ email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, updated_at: '2019-11-25T21:55:00.177Z', @@ -283,7 +284,7 @@ export const mockCaseComments: Array<SavedObject<CommentAttributes>> = [ email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, updated_at: '2019-11-25T21:55:14.633Z', @@ -317,7 +318,7 @@ export const mockCaseComments: Array<SavedObject<CommentAttributes>> = [ email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, updated_at: '2019-11-25T22:32:30.608Z', @@ -351,7 +352,7 @@ export const mockCaseComments: Array<SavedObject<CommentAttributes>> = [ email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, rule: { @@ -389,7 +390,7 @@ export const mockCaseComments: Array<SavedObject<CommentAttributes>> = [ email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, rule: { @@ -427,7 +428,7 @@ export const mockCaseComments: Array<SavedObject<CommentAttributes>> = [ email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, pushed_at: null, pushed_by: null, rule: { @@ -477,7 +478,7 @@ export const mockCaseConfigure: Array<SavedObject<ESCasesConfigureAttributes>> = email: 'testemail@elastic.co', username: 'elastic', }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, references: [], updated_at: '2020-04-09T09:43:51.778Z', @@ -491,7 +492,7 @@ export const mockCaseMappings: Array<SavedObject<ConnectorMappings>> = [ id: 'mock-mappings-1', attributes: { mappings: mappings[ConnectorTypes.jira], - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, references: [], }, @@ -503,7 +504,7 @@ export const mockCaseMappingsResilient: Array<SavedObject<ConnectorMappings>> = id: 'mock-mappings-1', attributes: { mappings: mappings[ConnectorTypes.resilient], - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, references: [], }, @@ -534,7 +535,7 @@ export const mockUserActions: Array<SavedObject<CaseUserActionAttributes>> = [ new_value: '{"title":"A case","tags":["case"],"description":"Yeah!","connector":{"id":"connector-od","name":"My Connector","type":".servicenow-sir","fields":{"category":"Denial of Service","destIp":true,"malwareHash":true,"malwareUrl":true,"priority":"2","sourceIp":true,"subcategory":"45"}},"settings":{"syncAlerts":true}}', old_value: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, version: 'WzYsMV0=', references: [], @@ -554,7 +555,7 @@ export const mockUserActions: Array<SavedObject<CaseUserActionAttributes>> = [ new_value: '{"type":"alert","alertId":"cec3da90fb37a44407145adf1593f3b0d5ad94c4654201f773d63b5d4706128e","index":".siem-signals-default-000008"}', old_value: null, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }, version: 'WzYsMV0=', references: [], diff --git a/x-pack/plugins/cases/server/routes/api/__mocks__/request_responses.ts b/x-pack/plugins/cases/server/routes/api/__mocks__/request_responses.ts index 32e42fea5c207..f3e6bcd7fc9ff 100644 --- a/x-pack/plugins/cases/server/routes/api/__mocks__/request_responses.ts +++ b/x-pack/plugins/cases/server/routes/api/__mocks__/request_responses.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { CasePostRequest, ConnectorTypes } from '../../../../common/api'; +import { SECURITY_SOLUTION_OWNER, CasePostRequest, ConnectorTypes } from '../../../../common'; export const newCase: CasePostRequest = { title: 'My new case', @@ -20,5 +20,5 @@ export const newCase: CasePostRequest = { settings: { syncAlerts: true, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }; diff --git a/x-pack/plugins/cases/server/scripts/sub_cases/index.ts b/x-pack/plugins/cases/server/scripts/sub_cases/index.ts index 2d37916919084..edabe9c4d4a1f 100644 --- a/x-pack/plugins/cases/server/scripts/sub_cases/index.ts +++ b/x-pack/plugins/cases/server/scripts/sub_cases/index.ts @@ -8,7 +8,14 @@ import yargs from 'yargs'; import { ToolingLog } from '@kbn/dev-utils'; import { KbnClient } from '@kbn/test'; -import { CaseResponse, CaseType, CommentType, ConnectorTypes, CASES_URL } from '../../../common'; +import { + CaseResponse, + CaseType, + CommentType, + ConnectorTypes, + CASES_URL, + SECURITY_SOLUTION_OWNER, +} from '../../../common'; import { ActionResult, ActionTypeExecutorResult } from '../../../../actions/common'; import { ContextTypeGeneratedAlertType, createAlertsString } from '../../connectors'; @@ -101,7 +108,7 @@ async function handleGenGroupAlerts(argv: any) { console.log('Case id: ', caseID); const comment: ContextTypeGeneratedAlertType = { - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, type: CommentType.generatedAlert, alerts: createAlertsString( argv.ids.map((id: string) => ({ diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx index 5cb834ef51ec1..9268131fbb020 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx @@ -17,6 +17,7 @@ import { Create } from '.'; import { useKibana } from '../../../common/lib/kibana'; import { Case } from '../../../../../cases/public/containers/types'; import { basicCase } from '../../../../../cases/public/containers/mock'; +import { APP_ID } from '../../../../common/constants'; jest.mock('../use_insert_timeline'); jest.mock('../../../common/lib/kibana'); @@ -47,7 +48,7 @@ describe('Create case', () => { ); expect(mockCreateCase).toHaveBeenCalled(); - expect(mockCreateCase.mock.calls[0][0].owner).toBe(['securitySolution']); + expect(mockCreateCase.mock.calls[0][0].owner).toBe([APP_ID]); }); it('should redirect to all cases on cancel click', async () => { diff --git a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.test.tsx b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.test.tsx index fa37fb53a54b0..162758a90b7ba 100644 --- a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.test.tsx @@ -14,7 +14,7 @@ import { useStateToaster } from '../../../common/components/toasters'; import { TestProviders } from '../../../common/mock'; import { AddToCaseAction } from './add_to_case_action'; import { basicCase } from '../../../../../cases/public/containers/mock'; -import { Case } from '../../../../../cases/common'; +import { Case, SECURITY_SOLUTION_OWNER } from '../../../../../cases/common'; jest.mock('../../../common/lib/kibana'); jest.mock('../../../common/components/link_to', () => { @@ -116,7 +116,7 @@ describe('AddToCaseAction', () => { alertId: 'test-id', index: 'test-index', rule: { id: 'rule-id', name: 'rule-name' }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }); }); @@ -143,7 +143,7 @@ describe('AddToCaseAction', () => { id: 'rule-id', name: null, }, - owner: 'securitySolution', + owner: SECURITY_SOLUTION_OWNER, }); }); diff --git a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx index 23ae979a3c137..19c59f2f57d87 100644 --- a/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/timeline_actions/add_to_case_action.tsx @@ -237,7 +237,7 @@ const AddToCaseActionComponent: React.FC<AddToCaseActionProps> = ({ id: rule?.id != null ? rule.id[0] : null, name: rule?.name != null ? rule.name[0] : null, }, - owner: 'securitySolution', + owner: APP_ID, }, createCaseNavigation: { href: formatUrl(getCreateCaseUrl()), From 12ac71dfae278a65ecf2ad9e201440cfcf41986d Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 13 May 2021 13:39:52 +0300 Subject: [PATCH 11/17] Fix tests --- .../public/components/connectors/case/alert_fields.tsx | 4 ++-- .../plugins/cases/public/components/create/form.test.tsx | 8 +++++++- .../plugins/cases/public/components/create/tags.test.tsx | 8 +++++++- .../cases/public/components/owner_context/index.tsx | 1 - .../public/components/owner_context/use_owner_context.ts | 2 +- .../cases/public/components/recent_cases/index.test.tsx | 9 ++++++++- x-pack/plugins/cases/public/containers/api.test.tsx | 4 ++-- .../cases/public/containers/configure/api.test.ts | 2 +- .../cases/public/containers/configure/use_configure.tsx | 2 +- .../public/cases/components/create/index.test.tsx | 2 +- 10 files changed, 30 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx b/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx index 82a355ca79f39..07249f02033f5 100644 --- a/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx +++ b/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx @@ -12,7 +12,7 @@ import styled from 'styled-components'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { ActionParamsProps } from '../../../../../triggers_actions_ui/public/types'; -import { CommentType } from '../../../../common'; +import { CommentType, SECURITY_SOLUTION_OWNER } from '../../../../common'; import { CaseActionParams } from './types'; import { ExistingCase } from './existing_case'; @@ -98,7 +98,7 @@ const CaseParamsFields: React.FunctionComponent<ActionParamsProps<CaseActionPara <ExistingCase onCaseChanged={onCaseChanged} selectedCase={selectedCase} - owner="securitySolution" + owner={SECURITY_SOLUTION_OWNER} /> <EuiSpacer size="m" /> <EuiCallOut size="s" title={i18n.CASE_CONNECTOR_CALL_OUT_TITLE} iconType="iInCircle"> diff --git a/x-pack/plugins/cases/public/components/create/form.test.tsx b/x-pack/plugins/cases/public/components/create/form.test.tsx index 9e59924bdf483..5f3b778a7cafc 100644 --- a/x-pack/plugins/cases/public/components/create/form.test.tsx +++ b/x-pack/plugins/cases/public/components/create/form.test.tsx @@ -15,6 +15,8 @@ import { useConnectors } from '../../containers/configure/use_connectors'; import { connectorsMock } from '../../containers/mock'; import { schema, FormProps } from './schema'; import { CreateCaseForm } from './form'; +import { OwnerProvider } from '../owner_context'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; jest.mock('../../containers/use_get_tags'); jest.mock('../../containers/configure/use_connectors'); @@ -41,7 +43,11 @@ describe('CreateCaseForm', () => { globalForm = form; - return <Form form={form}>{children}</Form>; + return ( + <OwnerProvider owner={[SECURITY_SOLUTION_OWNER]}> + <Form form={form}>{children}</Form> + </OwnerProvider> + ); }; beforeEach(() => { diff --git a/x-pack/plugins/cases/public/components/create/tags.test.tsx b/x-pack/plugins/cases/public/components/create/tags.test.tsx index 2eddb83dcac29..6efbf1b8c7107 100644 --- a/x-pack/plugins/cases/public/components/create/tags.test.tsx +++ b/x-pack/plugins/cases/public/components/create/tags.test.tsx @@ -14,6 +14,8 @@ import { useForm, Form, FormHook } from '../../common/shared_imports'; import { useGetTags } from '../../containers/use_get_tags'; import { Tags } from './tags'; import { schema, FormProps } from './schema'; +import { OwnerProvider } from '../owner_context'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; jest.mock('../../containers/use_get_tags'); const useGetTagsMock = useGetTags as jest.Mock; @@ -31,7 +33,11 @@ describe('Tags', () => { globalForm = form; - return <Form form={form}>{children}</Form>; + return ( + <OwnerProvider owner={[SECURITY_SOLUTION_OWNER]}> + <Form form={form}>{children}</Form> + </OwnerProvider> + ); }; beforeEach(() => { diff --git a/x-pack/plugins/cases/public/components/owner_context/index.tsx b/x-pack/plugins/cases/public/components/owner_context/index.tsx index 87934c4d4f58e..5df7eeadd70d5 100644 --- a/x-pack/plugins/cases/public/components/owner_context/index.tsx +++ b/x-pack/plugins/cases/public/components/owner_context/index.tsx @@ -7,7 +7,6 @@ import React, { useState } from 'react'; -// This context is available to all children of the stateful_event component where the provider is currently set export const OwnerContext = React.createContext<string[]>([]); export const OwnerProvider: React.FC<{ diff --git a/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts b/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts index 2523d80e82837..a443df1809315 100644 --- a/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts +++ b/x-pack/plugins/cases/public/components/owner_context/use_owner_context.ts @@ -13,7 +13,7 @@ export const useOwnerContext = () => { if (ownerContext.length === 0) { throw new Error( - 'useOwnerContext must be used within a OwnerProvider and not be an empty array' + 'useOwnerContext must be used within an OwnerProvider and not be an empty array' ); } diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx index 595be65fa5d77..e6610f6b27900 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx @@ -43,6 +43,7 @@ describe('RecentCases', () => { jest.clearAllMocks(); useGetCasesMock.mockImplementation(() => mockData); }); + it('is good at loading', () => { useGetCasesMock.mockImplementation(() => ({ ...mockData, @@ -55,6 +56,7 @@ describe('RecentCases', () => { ); expect(getAllByTestId('loadingPlaceholders')).toHaveLength(3); }); + it('is good at rendering cases', () => { const { getAllByTestId } = render( <TestProviders> @@ -63,14 +65,19 @@ describe('RecentCases', () => { ); expect(getAllByTestId('case-details-link')).toHaveLength(5); }); + it('is good at rendering max cases', () => { render( <TestProviders> <RecentCases {...{ ...defaultProps, maxCasesToShow: 2 }} /> </TestProviders> ); - expect(useGetCasesMock).toBeCalledWith({ perPage: 2 }); + expect(useGetCasesMock).toBeCalledWith({ + initialQueryParams: { perPage: 2 }, + initialFilterOptions: { owner: [SECURITY_SOLUTION_OWNER] }, + }); }); + it('updates filters', () => { const { getByTestId } = render( <TestProviders> diff --git a/x-pack/plugins/cases/public/containers/api.test.tsx b/x-pack/plugins/cases/public/containers/api.test.tsx index 3fe61a640a679..d3469e1c8867e 100644 --- a/x-pack/plugins/cases/public/containers/api.test.tsx +++ b/x-pack/plugins/cases/public/containers/api.test.tsx @@ -255,7 +255,7 @@ describe('Case Configuration API', () => { method: 'GET', signal: abortCtrl.signal, query: { - owner: SECURITY_SOLUTION_OWNER, + owner: [SECURITY_SOLUTION_OWNER], }, }); }); @@ -278,7 +278,7 @@ describe('Case Configuration API', () => { method: 'GET', signal: abortCtrl.signal, query: { - owner: SECURITY_SOLUTION_OWNER, + owner: [SECURITY_SOLUTION_OWNER], }, }); }); diff --git a/x-pack/plugins/cases/public/containers/configure/api.test.ts b/x-pack/plugins/cases/public/containers/configure/api.test.ts index 9194921ab4b34..ad13526b41d38 100644 --- a/x-pack/plugins/cases/public/containers/configure/api.test.ts +++ b/x-pack/plugins/cases/public/containers/configure/api.test.ts @@ -62,7 +62,7 @@ describe('Case Configuration API', () => { method: 'GET', signal: abortCtrl.signal, query: { - owner: SECURITY_SOLUTION_OWNER, + owner: [SECURITY_SOLUTION_OWNER], }, }); }); diff --git a/x-pack/plugins/cases/public/containers/configure/use_configure.tsx b/x-pack/plugins/cases/public/containers/configure/use_configure.tsx index 25e0782f6c13b..4e3ad44b53472 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_configure.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_configure.tsx @@ -155,7 +155,7 @@ export const initialState: State = { }; /** - * Configurations across multiple plugins in + * Configurations across multiple plugins is * not supported at the moment. For that reason owner: string; * instead of owner: string[] */ diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx index 9268131fbb020..1a6015d1bbd45 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx @@ -48,7 +48,7 @@ describe('Create case', () => { ); expect(mockCreateCase).toHaveBeenCalled(); - expect(mockCreateCase.mock.calls[0][0].owner).toBe([APP_ID]); + expect(mockCreateCase.mock.calls[0][0].owner).toEqual([APP_ID]); }); it('should redirect to all cases on cancel click', async () => { From 997364802bbb85687c6917d85653522939f12664 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 13 May 2021 15:12:55 +0300 Subject: [PATCH 12/17] Move owner to child --- .../plugins/cases/public/components/recent_cases/index.tsx | 3 --- .../cases/public/components/recent_cases/recent_cases.tsx | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.tsx index e0dc12810f543..05aff25d0dbd8 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.tsx @@ -14,7 +14,6 @@ import { RecentCasesFilters } from './filters'; import { RecentCasesComp } from './recent_cases'; import { FilterMode as RecentCasesFilterMode } from './types'; import { useCurrentUser } from '../../common/lib/kibana'; -import { useOwnerContext } from '../owner_context/use_owner_context'; export interface RecentCasesProps { allCasesNavigation: CasesNavigation; @@ -29,7 +28,6 @@ const RecentCases = ({ createCaseNavigation, maxCasesToShow, }: RecentCasesProps) => { - const owner = useOwnerContext(); const currentUser = useCurrentUser(); const [recentCasesFilterBy, setRecentCasesFilterBy] = useState<RecentCasesFilterMode>( 'recentlyCreated' @@ -76,7 +74,6 @@ const RecentCases = ({ createCaseNavigation={createCaseNavigation} filterOptions={recentCasesFilterOptions} maxCasesToShow={maxCasesToShow} - owner={owner} /> <EuiHorizontalRule margin="s" /> <EuiText size="xs"> diff --git a/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx b/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx index 905360c1754af..2878037f68f43 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx @@ -19,6 +19,7 @@ import { NoCases } from './no_cases'; import { isSubCase } from '../all_cases/helpers'; import { MarkdownRenderer } from '../markdown_editor'; import { FilterOptions } from '../../containers/types'; +import { useOwnerContext } from '../owner_context/use_owner_context'; const MarkdownContainer = styled.div` max-height: 150px; @@ -31,8 +32,8 @@ export interface RecentCasesProps { caseDetailsNavigation: CasesNavigation<CaseDetailsHrefSchema, 'configurable'>; createCaseNavigation: CasesNavigation; maxCasesToShow: number; - owner: string[]; } + const usePrevious = (value: Partial<FilterOptions>) => { const ref = useRef(); useEffect(() => { @@ -45,8 +46,8 @@ export const RecentCasesComp = ({ createCaseNavigation, filterOptions, maxCasesToShow, - owner, }: RecentCasesProps) => { + const owner = useOwnerContext(); const previousFilterOptions = usePrevious(filterOptions); const { data, loading, setFilters } = useGetCases({ initialQueryParams: { perPage: maxCasesToShow }, From 5acfe9955f9f8b0ea114b5ad031755a3133f5bc3 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Thu, 13 May 2021 15:58:02 +0300 Subject: [PATCH 13/17] Fix type --- x-pack/plugins/cases/public/containers/use_get_cases.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/cases/public/containers/use_get_cases.tsx b/x-pack/plugins/cases/public/containers/use_get_cases.tsx index 6d6fcc581ab3c..eacad3c8ca020 100644 --- a/x-pack/plugins/cases/public/containers/use_get_cases.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_cases.tsx @@ -140,10 +140,10 @@ export interface UseGetCases extends UseGetCasesState { const empty = {}; export const useGetCases = ( - params: Partial<{ + params: { initialQueryParams?: Partial<QueryParams>; initialFilterOptions?: Partial<FilterOptions>; - }> = {} + } = {} ): UseGetCases => { const { initialQueryParams = empty, initialFilterOptions = empty } = params; const [state, dispatch] = useReducer(dataFetchReducer, { From 11f48b2d4d3952f46c5763bccc98f549aed5690d Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Fri, 14 May 2021 11:47:08 +0300 Subject: [PATCH 14/17] Move owner inside the hooks & components --- x-pack/plugins/cases/common/ui/types.ts | 3 +-- .../all_cases/all_cases_generic.tsx | 5 +---- .../public/components/all_cases/index.tsx | 10 ++++++++-- .../all_cases/selector_modal/index.tsx | 14 ++++++++++++-- .../components/all_cases/table_filters.tsx | 5 ++--- .../components/configure_cases/index.tsx | 19 +++++++++++++------ .../connectors/case/alert_fields.tsx | 9 ++++----- .../connectors/case/existing_case.tsx | 13 +------------ .../public/components/create/form_context.tsx | 2 +- .../cases/public/components/create/index.tsx | 15 ++++++++++++--- .../public/components/recent_cases/index.tsx | 16 +++++++++++++--- .../components/recent_cases/recent_cases.tsx | 3 --- .../use_create_case_modal/index.tsx | 6 +++--- .../containers/configure/use_configure.tsx | 14 ++++++-------- .../cases/public/containers/use_get_cases.tsx | 7 ++++--- .../public/containers/use_get_reporters.tsx | 4 +++- .../cases/public/containers/use_get_tags.tsx | 4 +++- .../cases/public/methods/get_all_cases.tsx | 12 ++++-------- .../public/methods/get_configure_cases.tsx | 12 ++++-------- .../cases/public/methods/get_create_case.tsx | 12 ++++-------- .../cases/public/methods/get_recent_cases.tsx | 12 ++++-------- x-pack/plugins/cases/public/types.ts | 10 +++++----- 22 files changed, 108 insertions(+), 99 deletions(-) diff --git a/x-pack/plugins/cases/common/ui/types.ts b/x-pack/plugins/cases/common/ui/types.ts index 0754dd4be7971..284f5e706292c 100644 --- a/x-pack/plugins/cases/common/ui/types.ts +++ b/x-pack/plugins/cases/common/ui/types.ts @@ -101,7 +101,6 @@ export interface FilterOptions { status: CaseStatusWithAllStatus; tags: string[]; reporters: User[]; - owner: string[]; onlyCollectionType?: boolean; } @@ -131,7 +130,7 @@ export interface ElasticUser { export interface FetchCasesProps extends ApiProps { queryParams?: QueryParams; - filterOptions?: FilterOptions; + filterOptions?: FilterOptions & { owner: string[] }; } export interface ApiProps { diff --git a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx index 4ffbdf5811ca2..429532c86e4da 100644 --- a/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/all_cases_generic.tsx @@ -38,7 +38,6 @@ import { CasesTableFilters } from './table_filters'; import { EuiBasicTableOnChange } from './types'; import { CasesTable } from './table'; -import { useOwnerContext } from '../owner_context/use_owner_context'; const ProgressLoader = styled(EuiProgress)` ${({ $isShow }: { $isShow: boolean }) => @@ -81,7 +80,6 @@ export const AllCasesGeneric = React.memo<AllCasesGenericProps>( userCanCrud, }) => { const { actionLicense } = useGetActionLicense(); - const owner = useOwnerContext(); const { data, @@ -94,7 +92,7 @@ export const AllCasesGeneric = React.memo<AllCasesGenericProps>( setFilters, setQueryParams, setSelectedCases, - } = useGetCases({ initialFilterOptions: { owner } }); + } = useGetCases(); // Post Comment to Case const { postComment, isLoading: isCommentUpdating } = usePostComment(); @@ -290,7 +288,6 @@ export const AllCasesGeneric = React.memo<AllCasesGenericProps>( reporters: filterOptions.reporters, tags: filterOptions.tags, status: filterOptions.status, - owner: filterOptions.owner, }} setFilterRefetch={setFilterRefetch} disabledStatuses={disabledStatuses} diff --git a/x-pack/plugins/cases/public/components/all_cases/index.tsx b/x-pack/plugins/cases/public/components/all_cases/index.tsx index 2c506cd2da411..3d6c039aa001c 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.tsx @@ -6,9 +6,11 @@ */ import React from 'react'; +import { Owner } from '../../types'; import { CaseDetailsHrefSchema, CasesNavigation } from '../links'; +import { OwnerProvider } from '../owner_context'; import { AllCasesGeneric } from './all_cases_generic'; -export interface AllCasesProps { +export interface AllCasesProps extends Owner { caseDetailsNavigation: CasesNavigation<CaseDetailsHrefSchema, 'configurable'>; // if not passed, case name is not displayed as a link (Formerly dependant on isSelector) configureCasesNavigation: CasesNavigation; // if not passed, header with nav is not displayed (Formerly dependant on isSelector) createCaseNavigation: CasesNavigation; @@ -16,7 +18,11 @@ export interface AllCasesProps { } export const AllCases: React.FC<AllCasesProps> = (props) => { - return <AllCasesGeneric {...props} />; + return ( + <OwnerProvider owner={props.owner}> + <AllCasesGeneric {...props} /> + </OwnerProvider> + ); }; // eslint-disable-next-line import/no-default-export diff --git a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx index 0a83ef13e8ee6..e7bce984b3cd1 100644 --- a/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/selector_modal/index.tsx @@ -12,8 +12,10 @@ import { Case, CaseStatuses, CommentRequestAlertType, SubCase } from '../../../. import { CasesNavigation } from '../../links'; import * as i18n from '../../../common/translations'; import { AllCasesGeneric } from '../all_cases_generic'; +import { Owner } from '../../../types'; +import { OwnerProvider } from '../../owner_context'; -export interface AllCasesSelectorModalProps { +export interface AllCasesSelectorModalProps extends Owner { alertData?: Omit<CommentRequestAlertType, 'type'>; createCaseNavigation: CasesNavigation; disabledStatuses?: CaseStatuses[]; @@ -29,7 +31,7 @@ const Modal = styled(EuiModal)` `} `; -export const AllCasesSelectorModal: React.FC<AllCasesSelectorModalProps> = ({ +const AllCasesSelectorModalComponent: React.FC<AllCasesSelectorModalProps> = ({ alertData, createCaseNavigation, disabledStatuses, @@ -65,5 +67,13 @@ export const AllCasesSelectorModal: React.FC<AllCasesSelectorModalProps> = ({ </Modal> ) : null; }; + +export const AllCasesSelectorModal: React.FC<AllCasesSelectorModalProps> = React.memo((props) => { + return ( + <OwnerProvider owner={props.owner}> + <AllCasesSelectorModalComponent {...props} /> + </OwnerProvider> + ); +}); // eslint-disable-next-line import/no-default-export export { AllCasesSelectorModal as default }; diff --git a/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx b/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx index 0bde3a7cc7409..9428a374a0314 100644 --- a/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/table_filters.tsx @@ -47,7 +47,6 @@ const defaultInitial = { reporters: [], status: StatusAll, tags: [], - owner: [], }; const CasesTableFiltersComponent = ({ @@ -64,8 +63,8 @@ const CasesTableFiltersComponent = ({ ); const [search, setSearch] = useState(initial.search); const [selectedTags, setSelectedTags] = useState(initial.tags); - const { tags, fetchTags } = useGetTags(initial.owner); - const { reporters, respReporters, fetchReporters } = useGetReporters(initial.owner); + const { tags, fetchTags } = useGetTags(); + const { reporters, respReporters, fetchReporters } = useGetReporters(); const refetch = useCallback(() => { fetchTags(); diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.tsx index 61b6d23e8a1ad..3ee4bc77cd237 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.tsx @@ -31,7 +31,8 @@ import { normalizeCaseConnector, } from './utils'; import * as i18n from './translations'; -import { useOwnerContext } from '../owner_context/use_owner_context'; +import { Owner } from '../../types'; +import { OwnerProvider } from '../owner_context'; const FormWrapper = styled.div` ${({ theme }) => css` @@ -51,13 +52,12 @@ const FormWrapper = styled.div` `} `; -export interface ConfigureCasesProps { +export interface ConfigureCasesProps extends Owner { userCanCrud: boolean; } -const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud }) => { +const ConfigureCasesComponent: React.FC<Omit<ConfigureCasesProps, 'owner'>> = ({ userCanCrud }) => { const { triggersActionsUi } = useKibana().services; - const owner = useOwnerContext(); const [connectorIsValid, setConnectorIsValid] = useState(true); const [addFlyoutVisible, setAddFlyoutVisibility] = useState<boolean>(false); @@ -76,7 +76,7 @@ const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud }) refetchCaseConfigure, setConnector, setClosureType, - } = useCaseConfigure(owner[0]); + } = useCaseConfigure(); const { loading: isLoadingConnectors, connectors, refetchConnectors } = useConnectors(); const { loading: isLoadingActionTypes, actionTypes, refetchActionTypes } = useActionTypes(); @@ -225,6 +225,13 @@ const ConfigureCasesComponent: React.FC<ConfigureCasesProps> = ({ userCanCrud }) ); }; -export const ConfigureCases = React.memo(ConfigureCasesComponent); +export const ConfigureCases: React.FC<ConfigureCasesProps> = React.memo((props) => { + return ( + <OwnerProvider owner={props.owner}> + <ConfigureCasesComponent {...props} /> + </OwnerProvider> + ); +}); + // eslint-disable-next-line import/no-default-export export default ConfigureCases; diff --git a/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx b/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx index 07249f02033f5..8fb34e0cdcbf5 100644 --- a/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx +++ b/x-pack/plugins/cases/public/components/connectors/case/alert_fields.tsx @@ -18,6 +18,7 @@ import { CaseActionParams } from './types'; import { ExistingCase } from './existing_case'; import * as i18n from './translations'; +import { OwnerProvider } from '../../owner_context'; const Container = styled.div` ${({ theme }) => ` @@ -95,11 +96,9 @@ const CaseParamsFields: React.FunctionComponent<ActionParamsProps<CaseActionPara */ return ( <Container> - <ExistingCase - onCaseChanged={onCaseChanged} - selectedCase={selectedCase} - owner={SECURITY_SOLUTION_OWNER} - /> + <OwnerProvider owner={[SECURITY_SOLUTION_OWNER]}> + <ExistingCase onCaseChanged={onCaseChanged} selectedCase={selectedCase} /> + </OwnerProvider> <EuiSpacer size="m" /> <EuiCallOut size="s" title={i18n.CASE_CONNECTOR_CALL_OUT_TITLE} iconType="iInCircle"> <p>{i18n.CASE_CONNECTOR_CALL_OUT_MSG}</p> diff --git a/x-pack/plugins/cases/public/components/connectors/case/existing_case.tsx b/x-pack/plugins/cases/public/components/connectors/case/existing_case.tsx index 73d3867573117..aafbfb8b43b78 100644 --- a/x-pack/plugins/cases/public/components/connectors/case/existing_case.tsx +++ b/x-pack/plugins/cases/public/components/connectors/case/existing_case.tsx @@ -18,24 +18,14 @@ import { CasesDropdown, ADD_CASE_BUTTON_ID } from './cases_dropdown'; interface ExistingCaseProps { selectedCase: string | null; onCaseChanged: (id: string) => void; - /** - * We allow only one owner as this component queries - * for multiple cases and creates a single case. - */ - owner: string; } -const ExistingCaseComponent: React.FC<ExistingCaseProps> = ({ - onCaseChanged, - selectedCase, - owner, -}) => { +const ExistingCaseComponent: React.FC<ExistingCaseProps> = ({ onCaseChanged, selectedCase }) => { const { data: cases, loading: isLoadingCases, refetchCases } = useGetCases({ initialQueryParams: DEFAULT_QUERY_PARAMS, initialFilterOptions: { ...DEFAULT_FILTER_OPTIONS, onlyCollectionType: true, - owner: [owner], }, }); @@ -54,7 +44,6 @@ const ExistingCaseComponent: React.FC<ExistingCaseProps> = ({ // We are making the assumption that this component is only used in rules creation // that's why we want to hide ServiceNow SIR hideConnectorServiceNowSir: true, - owner, }); const onChange = useCallback( diff --git a/x-pack/plugins/cases/public/components/create/form_context.tsx b/x-pack/plugins/cases/public/components/create/form_context.tsx index 0b2ff086c1b57..8584892e1286c 100644 --- a/x-pack/plugins/cases/public/components/create/form_context.tsx +++ b/x-pack/plugins/cases/public/components/create/form_context.tsx @@ -49,7 +49,7 @@ export const FormContext: React.FC<Props> = ({ }) => { const { connectors, loading: isLoadingConnectors } = useConnectors(); const owner = useOwnerContext(); - const { connector: configurationConnector } = useCaseConfigure(owner[0]); + const { connector: configurationConnector } = useCaseConfigure(); const { postCase } = usePostCase(); const { postComment } = usePostComment(); const { pushCaseToExternalService } = usePostPushToService(); diff --git a/x-pack/plugins/cases/public/components/create/index.tsx b/x-pack/plugins/cases/public/components/create/index.tsx index a1de4d9730b9f..3362aa6af2078 100644 --- a/x-pack/plugins/cases/public/components/create/index.tsx +++ b/x-pack/plugins/cases/public/components/create/index.tsx @@ -20,6 +20,8 @@ import { CasesTimelineIntegration, CasesTimelineIntegrationProvider } from '../t import { fieldName as descriptionFieldName } from './description'; import { InsertTimeline } from '../insert_timeline'; import { UsePostComment } from '../../containers/use_post_comment'; +import { Owner } from '../../types'; +import { OwnerProvider } from '../owner_context'; export const CommonUseField = getUseField({ component: Field }); @@ -29,7 +31,7 @@ const Container = styled.div` `} `; -export interface CreateCaseProps { +export interface CreateCaseProps extends Owner { afterCaseCreated?: (theCase: Case, postComment: UsePostComment['postComment']) => Promise<void>; caseType?: CaseType; hideConnectorServiceNowSir?: boolean; @@ -39,7 +41,7 @@ export interface CreateCaseProps { withSteps?: boolean; } -export const CreateCase = ({ +const CreateCaseComponent = ({ afterCaseCreated, caseType, hideConnectorServiceNowSir, @@ -47,7 +49,7 @@ export const CreateCase = ({ onSuccess, timelineIntegration, withSteps, -}: CreateCaseProps) => ( +}: Omit<CreateCaseProps, 'owner'>) => ( <CasesTimelineIntegrationProvider timelineIntegration={timelineIntegration}> <FormContext afterCaseCreated={afterCaseCreated} @@ -86,5 +88,12 @@ export const CreateCase = ({ </CasesTimelineIntegrationProvider> ); +export const CreateCase: React.FC<CreateCaseProps> = React.memo((props) => { + return ( + <OwnerProvider owner={props.owner}> + <CreateCaseComponent {...props} /> + </OwnerProvider> + ); +}); // eslint-disable-next-line import/no-default-export export { CreateCase as default }; diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.tsx index 05aff25d0dbd8..bb34f651d52df 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.tsx @@ -14,20 +14,22 @@ import { RecentCasesFilters } from './filters'; import { RecentCasesComp } from './recent_cases'; import { FilterMode as RecentCasesFilterMode } from './types'; import { useCurrentUser } from '../../common/lib/kibana'; +import { Owner } from '../../types'; +import { OwnerProvider } from '../owner_context'; -export interface RecentCasesProps { +export interface RecentCasesProps extends Owner { allCasesNavigation: CasesNavigation; caseDetailsNavigation: CasesNavigation<CaseDetailsHrefSchema, 'configurable'>; createCaseNavigation: CasesNavigation; maxCasesToShow: number; } -const RecentCases = ({ +const RecentCasesComponent = ({ allCasesNavigation, caseDetailsNavigation, createCaseNavigation, maxCasesToShow, -}: RecentCasesProps) => { +}: Omit<RecentCasesProps, 'owner'>) => { const currentUser = useCurrentUser(); const [recentCasesFilterBy, setRecentCasesFilterBy] = useState<RecentCasesFilterMode>( 'recentlyCreated' @@ -87,5 +89,13 @@ const RecentCases = ({ ); }; +export const RecentCases: React.FC<RecentCasesProps> = React.memo((props) => { + return ( + <OwnerProvider owner={props.owner}> + <RecentCasesComponent {...props} /> + </OwnerProvider> + ); +}); + // eslint-disable-next-line import/no-default-export export { RecentCases as default }; diff --git a/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx b/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx index 2878037f68f43..5b4313530e490 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/recent_cases.tsx @@ -19,7 +19,6 @@ import { NoCases } from './no_cases'; import { isSubCase } from '../all_cases/helpers'; import { MarkdownRenderer } from '../markdown_editor'; import { FilterOptions } from '../../containers/types'; -import { useOwnerContext } from '../owner_context/use_owner_context'; const MarkdownContainer = styled.div` max-height: 150px; @@ -47,11 +46,9 @@ export const RecentCasesComp = ({ filterOptions, maxCasesToShow, }: RecentCasesProps) => { - const owner = useOwnerContext(); const previousFilterOptions = usePrevious(filterOptions); const { data, loading, setFilters } = useGetCases({ initialQueryParams: { perPage: maxCasesToShow }, - initialFilterOptions: { owner }, }); useEffect(() => { diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx index 2b1f73c0411a9..09f8eb65b12b7 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/index.tsx @@ -7,13 +7,13 @@ import React, { useState, useCallback, useMemo } from 'react'; import { Case, CaseType } from '../../../common'; +import { useOwnerContext } from '../owner_context/use_owner_context'; import { CreateCaseModal } from './create_case_modal'; export interface UseCreateCaseModalProps { onCaseCreated: (theCase: Case) => void; caseType?: CaseType; hideConnectorServiceNowSir?: boolean; - owner: string; } export interface UseCreateCaseModalReturnedValues { modal: JSX.Element; @@ -26,8 +26,8 @@ export const useCreateCaseModal = ({ caseType = CaseType.individual, onCaseCreated, hideConnectorServiceNowSir = false, - owner, }: UseCreateCaseModalProps) => { + const owner = useOwnerContext(); const [isModalOpen, setIsModalOpen] = useState<boolean>(false); const closeModal = useCallback(() => setIsModalOpen(false), []); const openModal = useCallback(() => setIsModalOpen(true), []); @@ -48,7 +48,7 @@ export const useCreateCaseModal = ({ isModalOpen={isModalOpen} onCloseCaseModal={closeModal} onSuccess={onSuccess} - owner={owner} + owner={owner[0]} /> ), isModalOpen, diff --git a/x-pack/plugins/cases/public/containers/configure/use_configure.tsx b/x-pack/plugins/cases/public/containers/configure/use_configure.tsx index 4e3ad44b53472..d02a22bde408c 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_configure.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_configure.tsx @@ -12,6 +12,7 @@ import * as i18n from './translations'; import { ClosureType, CaseConfigure, CaseConnector, CaseConnectorMapping } from './types'; import { ConnectorTypes } from '../../../common'; import { useToasts } from '../../common/lib/kibana'; +import { useOwnerContext } from '../../components/owner_context/use_owner_context'; export type ConnectorConfiguration = { connector: CaseConnector } & { closureType: CaseConfigure['closureType']; @@ -154,12 +155,8 @@ export const initialState: State = { id: '', }; -/** - * Configurations across multiple plugins is - * not supported at the moment. For that reason owner: string; - * instead of owner: string[] - */ -export const useCaseConfigure = (owner: string): ReturnUseCaseConfigure => { +export const useCaseConfigure = (): ReturnUseCaseConfigure => { + const owner = useOwnerContext(); const [state, dispatch] = useReducer(configureCasesReducer, initialState); const toasts = useToasts(); const setCurrentConfiguration = useCallback((configuration: ConnectorConfiguration) => { @@ -240,7 +237,7 @@ export const useCaseConfigure = (owner: string): ReturnUseCaseConfigure => { setLoading(true); const res = await getCaseConfigure({ signal: abortCtrlRefetchRef.current.signal, - owner: [owner], + owner, }); if (!isCancelledRefetchRef.current) { @@ -302,7 +299,8 @@ export const useCaseConfigure = (owner: string): ReturnUseCaseConfigure => { const res = state.version.length === 0 ? await postCaseConfigure( - { ...connectorObj, owner }, + // The first owner will be used for case creation + { ...connectorObj, owner: owner[0] }, abortCtrlPersistRef.current.signal ) : await patchCaseConfigure( diff --git a/x-pack/plugins/cases/public/containers/use_get_cases.tsx b/x-pack/plugins/cases/public/containers/use_get_cases.tsx index eacad3c8ca020..b3aa374f5418e 100644 --- a/x-pack/plugins/cases/public/containers/use_get_cases.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_cases.tsx @@ -19,6 +19,7 @@ import { import { useToasts } from '../common/lib/kibana'; import * as i18n from './translations'; import { getCases, patchCase } from './api'; +import { useOwnerContext } from '../components/owner_context/use_owner_context'; export interface UseGetCasesState { data: AllCases; @@ -105,7 +106,6 @@ export const DEFAULT_FILTER_OPTIONS: FilterOptions = { status: StatusAll, tags: [], onlyCollectionType: false, - owner: [], }; export const DEFAULT_QUERY_PARAMS: QueryParams = { @@ -145,6 +145,7 @@ export const useGetCases = ( initialFilterOptions?: Partial<FilterOptions>; } = {} ): UseGetCases => { + const owner = useOwnerContext(); const { initialQueryParams = empty, initialFilterOptions = empty } = params; const [state, dispatch] = useReducer(dataFetchReducer, { data: initialData, @@ -184,7 +185,7 @@ export const useGetCases = ( dispatch({ type: 'FETCH_INIT', payload: 'cases' }); const response = await getCases({ - filterOptions, + filterOptions: { ...filterOptions, owner }, queryParams, signal: abortCtrlFetchCases.current.signal, }); @@ -207,7 +208,7 @@ export const useGetCases = ( } } }, - [toasts] + [owner, toasts] ); const dispatchUpdateCaseProperty = useCallback( diff --git a/x-pack/plugins/cases/public/containers/use_get_reporters.tsx b/x-pack/plugins/cases/public/containers/use_get_reporters.tsx index ed06f58008792..b3c2eff2c8e01 100644 --- a/x-pack/plugins/cases/public/containers/use_get_reporters.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_reporters.tsx @@ -12,6 +12,7 @@ import { User } from '../../common'; import { getReporters } from './api'; import * as i18n from './translations'; import { useToasts } from '../common/lib/kibana'; +import { useOwnerContext } from '../components/owner_context/use_owner_context'; interface ReportersState { reporters: string[]; @@ -31,7 +32,8 @@ export interface UseGetReporters extends ReportersState { fetchReporters: () => void; } -export const useGetReporters = (owner: string[]): UseGetReporters => { +export const useGetReporters = (): UseGetReporters => { + const owner = useOwnerContext(); const [reportersState, setReporterState] = useState<ReportersState>(initialData); const toasts = useToasts(); diff --git a/x-pack/plugins/cases/public/containers/use_get_tags.tsx b/x-pack/plugins/cases/public/containers/use_get_tags.tsx index dfd9667f17c96..362e7ebf8fbf3 100644 --- a/x-pack/plugins/cases/public/containers/use_get_tags.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_tags.tsx @@ -7,6 +7,7 @@ import { useEffect, useReducer, useRef, useCallback } from 'react'; import { useToasts } from '../common/lib/kibana'; +import { useOwnerContext } from '../components/owner_context/use_owner_context'; import { getTags } from './api'; import * as i18n from './translations'; @@ -51,7 +52,8 @@ const dataFetchReducer = (state: TagsState, action: Action): TagsState => { }; const initialData: string[] = []; -export const useGetTags = (owner: string[]): UseGetTags => { +export const useGetTags = (): UseGetTags => { + const owner = useOwnerContext(); const [state, dispatch] = useReducer(dataFetchReducer, { isLoading: true, isError: false, diff --git a/x-pack/plugins/cases/public/methods/get_all_cases.tsx b/x-pack/plugins/cases/public/methods/get_all_cases.tsx index 413af03264371..d3e7a924788f3 100644 --- a/x-pack/plugins/cases/public/methods/get_all_cases.tsx +++ b/x-pack/plugins/cases/public/methods/get_all_cases.tsx @@ -8,14 +8,10 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import React, { lazy, Suspense } from 'react'; import { AllCasesProps } from '../components/all_cases'; -import { OwnerProvider } from '../components/owner_context'; -import { Owner } from '../types'; const AllCasesLazy = lazy(() => import('../components/all_cases')); -export const getAllCasesLazy = (props: AllCasesProps & Owner) => ( - <OwnerProvider owner={props.owner}> - <Suspense fallback={<EuiLoadingSpinner />}> - <AllCasesLazy {...props} /> - </Suspense> - </OwnerProvider> +export const getAllCasesLazy = (props: AllCasesProps) => ( + <Suspense fallback={<EuiLoadingSpinner />}> + <AllCasesLazy {...props} /> + </Suspense> ); diff --git a/x-pack/plugins/cases/public/methods/get_configure_cases.tsx b/x-pack/plugins/cases/public/methods/get_configure_cases.tsx index 5c17f3ae2bb9a..96a3dbd55d7de 100644 --- a/x-pack/plugins/cases/public/methods/get_configure_cases.tsx +++ b/x-pack/plugins/cases/public/methods/get_configure_cases.tsx @@ -7,15 +7,11 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import React, { lazy, Suspense } from 'react'; -import { OwnerProvider } from '../components/owner_context'; import { ConfigureCasesProps } from '../components/configure_cases'; -import { Owner } from '../types'; const ConfigureCasesLazy = lazy(() => import('../components/configure_cases')); -export const getConfigureCasesLazy = (props: ConfigureCasesProps & Owner) => ( - <OwnerProvider owner={props.owner}> - <Suspense fallback={<EuiLoadingSpinner />}> - <ConfigureCasesLazy {...props} /> - </Suspense> - </OwnerProvider> +export const getConfigureCasesLazy = (props: ConfigureCasesProps) => ( + <Suspense fallback={<EuiLoadingSpinner />}> + <ConfigureCasesLazy {...props} /> + </Suspense> ); diff --git a/x-pack/plugins/cases/public/methods/get_create_case.tsx b/x-pack/plugins/cases/public/methods/get_create_case.tsx index 86fcb3e2d29a8..b030ed669b663 100644 --- a/x-pack/plugins/cases/public/methods/get_create_case.tsx +++ b/x-pack/plugins/cases/public/methods/get_create_case.tsx @@ -8,14 +8,10 @@ import React, { lazy, Suspense } from 'react'; import { EuiLoadingSpinner } from '@elastic/eui'; import { CreateCaseProps } from '../components/create'; -import { Owner } from '../types'; -import { OwnerProvider } from '../components/owner_context'; const CreateCaseLazy = lazy(() => import('../components/create')); -export const getCreateCaseLazy = (props: CreateCaseProps & Owner) => ( - <OwnerProvider owner={props.owner}> - <Suspense fallback={<EuiLoadingSpinner />}> - <CreateCaseLazy {...props} /> - </Suspense> - </OwnerProvider> +export const getCreateCaseLazy = (props: CreateCaseProps) => ( + <Suspense fallback={<EuiLoadingSpinner />}> + <CreateCaseLazy {...props} /> + </Suspense> ); diff --git a/x-pack/plugins/cases/public/methods/get_recent_cases.tsx b/x-pack/plugins/cases/public/methods/get_recent_cases.tsx index 1dc1be59d65e0..e87db9320ca3d 100644 --- a/x-pack/plugins/cases/public/methods/get_recent_cases.tsx +++ b/x-pack/plugins/cases/public/methods/get_recent_cases.tsx @@ -8,14 +8,10 @@ import { EuiLoadingSpinner } from '@elastic/eui'; import React, { lazy, Suspense } from 'react'; import { RecentCasesProps } from '../components/recent_cases'; -import { OwnerProvider } from '../components/owner_context'; -import { Owner } from '../types'; const RecentCasesLazy = lazy(() => import('../components/recent_cases')); -export const getRecentCasesLazy = (props: RecentCasesProps & Owner) => ( - <OwnerProvider owner={props.owner}> - <Suspense fallback={<EuiLoadingSpinner />}> - <RecentCasesLazy {...props} /> - </Suspense> - </OwnerProvider> +export const getRecentCasesLazy = (props: RecentCasesProps) => ( + <Suspense fallback={<EuiLoadingSpinner />}> + <RecentCasesLazy {...props} /> + </Suspense> ); diff --git a/x-pack/plugins/cases/public/types.ts b/x-pack/plugins/cases/public/types.ts index 1336b8f7dba46..2193832492aa2 100644 --- a/x-pack/plugins/cases/public/types.ts +++ b/x-pack/plugins/cases/public/types.ts @@ -44,12 +44,12 @@ export interface Owner { } export interface CasesUiStart { - getAllCases: (props: AllCasesProps & Owner) => ReactElement<AllCasesProps>; + getAllCases: (props: AllCasesProps) => ReactElement<AllCasesProps>; getAllCasesSelectorModal: ( - props: AllCasesSelectorModalProps & Owner + props: AllCasesSelectorModalProps ) => ReactElement<AllCasesSelectorModalProps>; getCaseView: (props: CaseViewProps) => ReactElement<CaseViewProps>; - getConfigureCases: (props: ConfigureCasesProps & Owner) => ReactElement<ConfigureCasesProps>; - getCreateCase: (props: CreateCaseProps & Owner) => ReactElement<CreateCaseProps>; - getRecentCases: (props: RecentCasesProps & Owner) => ReactElement<RecentCasesProps>; + getConfigureCases: (props: ConfigureCasesProps) => ReactElement<ConfigureCasesProps>; + getCreateCase: (props: CreateCaseProps) => ReactElement<CreateCaseProps>; + getRecentCases: (props: RecentCasesProps) => ReactElement<RecentCasesProps>; } From 935e2553283aed711d6080dfb19be350bf63fd67 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Fri, 14 May 2021 11:55:26 +0300 Subject: [PATCH 15/17] Fix bug --- .../public/cases/components/create/flyout.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx b/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx index 3e70b22825df5..1023bfc8b0206 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/flyout.tsx @@ -11,7 +11,8 @@ import { EuiFlyout, EuiFlyoutHeader, EuiTitle, EuiFlyoutBody } from '@elastic/eu import * as i18n from '../../translations'; import { useKibana } from '../../../common/lib/kibana'; -import { APP_ID, Case } from '../../../../../cases/common'; +import { Case } from '../../../../../cases/common'; +import { APP_ID } from '../../../../common/constants'; export interface CreateCaseModalProps { afterCaseCreated?: (theCase: Case) => Promise<void>; From 3b4634ea31cf8e840efecbd670c6a69a4e1dc3b7 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Fri, 14 May 2021 15:16:47 +0300 Subject: [PATCH 16/17] Fix types --- .../components/all_cases/index.test.tsx | 1 + .../components/configure_cases/index.test.tsx | 35 ++++++++++--------- .../public/components/create/index.test.tsx | 7 ++-- .../cases/public/components/create/tags.tsx | 4 +-- .../public/components/tag_list/index.tsx | 2 +- .../use_create_case_modal/index.test.tsx | 11 +++--- .../cases/public/containers/api.test.tsx | 6 ++-- .../configure/use_configure.test.tsx | 26 +++++++------- .../containers/use_get_reporters.test.tsx | 15 ++++---- .../public/containers/use_get_tags.test.tsx | 23 ++++-------- 10 files changed, 60 insertions(+), 70 deletions(-) diff --git a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx index 2abdbdea5cd77..5ed3215241de5 100644 --- a/x-pack/plugins/cases/public/components/all_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/all_cases/index.test.tsx @@ -53,6 +53,7 @@ describe('AllCasesGeneric', () => { onClick: jest.fn(), }, userCanCrud: true, + owner: [SECURITY_SOLUTION_OWNER], }; const dispatchResetIsDeleted = jest.fn(); diff --git a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx index 65f2755ef4545..0d9ede9bb7de8 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/index.test.tsx @@ -32,7 +32,7 @@ import { useConnectorsResponse, useActionTypesResponse, } from './__mock__'; -import { ConnectorTypes } from '../../../common'; +import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common'; jest.mock('../../common/lib/kibana'); jest.mock('../../containers/configure/use_connectors'); @@ -102,7 +102,7 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => ({ ...useConnectorsResponse, connectors: [] })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); }); @@ -157,7 +157,7 @@ describe('ConfigureCases', () => { })); useConnectorsMock.mockImplementation(() => ({ ...useConnectorsResponse, connectors: [] })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); }); @@ -204,7 +204,7 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); }); @@ -226,9 +226,12 @@ describe('ConfigureCases', () => { }); test('it disables correctly when the user cannot crud', () => { - const newWrapper = mount(<ConfigureCases userCanCrud={false} />, { - wrappingComponent: TestProviders, - }); + const newWrapper = mount( + <ConfigureCases userCanCrud={false} owner={[SECURITY_SOLUTION_OWNER]} />, + { + wrappingComponent: TestProviders, + } + ); expect(newWrapper.find('button[data-test-subj="dropdown-connectors"]').prop('disabled')).toBe( true @@ -288,7 +291,7 @@ describe('ConfigureCases', () => { })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); }); @@ -323,7 +326,7 @@ describe('ConfigureCases', () => { useActionTypesMock.mockImplementation(() => ({ ...useActionTypesResponse, loading: true })); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); expect(wrapper.find(Connectors).prop('isLoading')).toBe(true); @@ -347,7 +350,7 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); }); @@ -390,7 +393,7 @@ describe('ConfigureCases', () => { ...useConnectorsResponse, })); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); }); @@ -434,7 +437,7 @@ describe('ConfigureCases', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); }); @@ -478,7 +481,7 @@ describe('ConfigureCases', () => { }, })); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); @@ -526,7 +529,7 @@ describe('closure options', () => { useConnectorsMock.mockImplementation(() => useConnectorsResponse); useGetUrlSearchMock.mockImplementation(() => searchURL); - wrapper = mount(<ConfigureCases userCanCrud />, { + wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); }); @@ -575,7 +578,7 @@ describe('user interactions', () => { }); test('it show the add flyout when pressing the add connector button', () => { - const wrapper = mount(<ConfigureCases userCanCrud />, { + const wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); wrapper.find('button[data-test-subj="dropdown-connectors"]').simulate('click'); @@ -598,7 +601,7 @@ describe('user interactions', () => { }); test('it show the edit flyout when pressing the update connector button', () => { - const wrapper = mount(<ConfigureCases userCanCrud />, { + const wrapper = mount(<ConfigureCases userCanCrud owner={[SECURITY_SOLUTION_OWNER]} />, { wrappingComponent: TestProviders, }); wrapper diff --git a/x-pack/plugins/cases/public/components/create/index.test.tsx b/x-pack/plugins/cases/public/components/create/index.test.tsx index e82af8edc6337..350b971bb05fc 100644 --- a/x-pack/plugins/cases/public/components/create/index.test.tsx +++ b/x-pack/plugins/cases/public/components/create/index.test.tsx @@ -29,6 +29,7 @@ import { useGetFieldsByIssueTypeResponse, } from './mock'; import { CreateCase } from '.'; +import { SECURITY_SOLUTION_OWNER } from '../../../common'; jest.mock('../../containers/api'); jest.mock('../../containers/use_get_tags'); @@ -91,7 +92,7 @@ describe('CreateCase case', () => { it('it renders', async () => { const wrapper = mount( <TestProviders> - <CreateCase {...defaultProps} /> + <CreateCase {...defaultProps} owner={[SECURITY_SOLUTION_OWNER]} /> </TestProviders> ); @@ -102,7 +103,7 @@ describe('CreateCase case', () => { it('should call cancel on cancel click', async () => { const wrapper = mount( <TestProviders> - <CreateCase {...defaultProps} /> + <CreateCase {...defaultProps} owner={[SECURITY_SOLUTION_OWNER]} /> </TestProviders> ); @@ -113,7 +114,7 @@ describe('CreateCase case', () => { it('should redirect to new case when posting the case', async () => { const wrapper = mount( <TestProviders> - <CreateCase {...defaultProps} /> + <CreateCase {...defaultProps} owner={[SECURITY_SOLUTION_OWNER]} /> </TestProviders> ); diff --git a/x-pack/plugins/cases/public/components/create/tags.tsx b/x-pack/plugins/cases/public/components/create/tags.tsx index 59374d3963b58..ac0b67529e15a 100644 --- a/x-pack/plugins/cases/public/components/create/tags.tsx +++ b/x-pack/plugins/cases/public/components/create/tags.tsx @@ -9,7 +9,6 @@ import React, { memo, useMemo } from 'react'; import { Field, getUseField } from '../../common/shared_imports'; import { useGetTags } from '../../containers/use_get_tags'; -import { useOwnerContext } from '../owner_context/use_owner_context'; const CommonUseField = getUseField({ component: Field }); @@ -18,8 +17,7 @@ interface Props { } const TagsComponent: React.FC<Props> = ({ isLoading }) => { - const owner = useOwnerContext(); - const { tags: tagOptions, isLoading: isLoadingTags } = useGetTags(owner); + const { tags: tagOptions, isLoading: isLoadingTags } = useGetTags(); const options = useMemo( () => tagOptions.map((label) => ({ diff --git a/x-pack/plugins/cases/public/components/tag_list/index.tsx b/x-pack/plugins/cases/public/components/tag_list/index.tsx index ab4bb29d2ebba..f260593369679 100644 --- a/x-pack/plugins/cases/public/components/tag_list/index.tsx +++ b/x-pack/plugins/cases/public/components/tag_list/index.tsx @@ -63,7 +63,7 @@ export const TagList = React.memo( } }, [onSubmit, submit]); - const { tags: tagOptions } = useGetTags(owner); + const { tags: tagOptions } = useGetTags(); const [options, setOptions] = useState( tagOptions.map((label) => ({ label, diff --git a/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx b/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx index 2f8d139cd0a23..b227dd4b898b2 100644 --- a/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx +++ b/x-pack/plugins/cases/public/components/use_create_case_modal/index.test.tsx @@ -12,7 +12,6 @@ import { render } from '@testing-library/react'; import { useKibana } from '../../common/lib/kibana'; import { useCreateCaseModal, UseCreateCaseModalProps, UseCreateCaseModalReturnedValues } from '.'; import { TestProviders } from '../../common/mock'; -import { SECURITY_SOLUTION_OWNER } from '../../../common'; jest.mock('../../common/lib/kibana'); @@ -29,7 +28,7 @@ describe('useCreateCaseModal', () => { it('init', async () => { const { result } = renderHook<UseCreateCaseModalProps, UseCreateCaseModalReturnedValues>( - () => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), + () => useCreateCaseModal({ onCaseCreated }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, } @@ -40,7 +39,7 @@ describe('useCreateCaseModal', () => { it('opens the modal', async () => { const { result } = renderHook<UseCreateCaseModalProps, UseCreateCaseModalReturnedValues>( - () => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), + () => useCreateCaseModal({ onCaseCreated }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, } @@ -55,7 +54,7 @@ describe('useCreateCaseModal', () => { it('closes the modal', async () => { const { result } = renderHook<UseCreateCaseModalProps, UseCreateCaseModalReturnedValues>( - () => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), + () => useCreateCaseModal({ onCaseCreated }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, } @@ -73,7 +72,7 @@ describe('useCreateCaseModal', () => { const { result, rerender } = renderHook< UseCreateCaseModalProps, UseCreateCaseModalReturnedValues - >(() => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), { + >(() => useCreateCaseModal({ onCaseCreated }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, }); @@ -86,7 +85,7 @@ describe('useCreateCaseModal', () => { it('closes the modal when creating a case', async () => { const { result } = renderHook<UseCreateCaseModalProps, UseCreateCaseModalReturnedValues>( - () => useCreateCaseModal({ onCaseCreated, owner: SECURITY_SOLUTION_OWNER }), + () => useCreateCaseModal({ onCaseCreated }), { wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, } diff --git a/x-pack/plugins/cases/public/containers/api.test.tsx b/x-pack/plugins/cases/public/containers/api.test.tsx index d3469e1c8867e..5bd7bd3c2be72 100644 --- a/x-pack/plugins/cases/public/containers/api.test.tsx +++ b/x-pack/plugins/cases/public/containers/api.test.tsx @@ -127,7 +127,7 @@ describe('Case Configuration API', () => { }); test('check url, method, signal', async () => { await getCases({ - filterOptions: DEFAULT_FILTER_OPTIONS, + filterOptions: { ...DEFAULT_FILTER_OPTIONS, owner: [SECURITY_SOLUTION_OWNER] }, queryParams: DEFAULT_QUERY_PARAMS, signal: abortCtrl.signal, }); @@ -150,6 +150,7 @@ describe('Case Configuration API', () => { tags, status: CaseStatuses.open, search: 'hello', + owner: [SECURITY_SOLUTION_OWNER], }, queryParams: DEFAULT_QUERY_PARAMS, signal: abortCtrl.signal, @@ -177,6 +178,7 @@ describe('Case Configuration API', () => { tags: weirdTags, status: CaseStatuses.open, search: 'hello', + owner: [SECURITY_SOLUTION_OWNER], }, queryParams: DEFAULT_QUERY_PARAMS, signal: abortCtrl.signal, @@ -196,7 +198,7 @@ describe('Case Configuration API', () => { test('happy path', async () => { const resp = await getCases({ - filterOptions: DEFAULT_FILTER_OPTIONS, + filterOptions: { ...DEFAULT_FILTER_OPTIONS, owner: [SECURITY_SOLUTION_OWNER] }, queryParams: DEFAULT_QUERY_PARAMS, signal: abortCtrl.signal, }); diff --git a/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx b/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx index 094083d6a2c7c..4d2abbcaec4d4 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx @@ -14,7 +14,7 @@ import { } from './use_configure'; import { mappings, caseConfigurationCamelCaseResponseMock } from './mock'; import * as api from './api'; -import { ConnectorTypes, SECURITY_SOLUTION_OWNER } from '../../../common'; +import { ConnectorTypes } from '../../../common'; const mockErrorToast = jest.fn(); const mockSuccessToast = jest.fn(); @@ -50,7 +50,7 @@ describe('useConfigure', () => { test('init', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -68,7 +68,7 @@ describe('useConfigure', () => { test('fetch case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -100,7 +100,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -112,7 +112,7 @@ describe('useConfigure', () => { test('correctly sets mappings', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -125,7 +125,7 @@ describe('useConfigure', () => { test('set isLoading to true when fetching case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -138,7 +138,7 @@ describe('useConfigure', () => { test('persist case configuration', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -167,7 +167,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -193,7 +193,7 @@ describe('useConfigure', () => { await act(async () => { const { waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -222,7 +222,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -246,7 +246,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -267,7 +267,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); @@ -303,7 +303,7 @@ describe('useConfigure', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure(SECURITY_SOLUTION_OWNER) + useCaseConfigure() ); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx index 5d403a5a850ed..8345ddf107872 100644 --- a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx @@ -9,7 +9,6 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { useGetReporters, UseGetReporters } from './use_get_reporters'; import { reporters, respReporters } from './mock'; import * as api from './api'; -import { SECURITY_SOLUTION_OWNER } from '../../common'; jest.mock('./api'); jest.mock('../common/lib/kibana'); @@ -24,7 +23,7 @@ describe('useGetReporters', () => { it('init', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters([SECURITY_SOLUTION_OWNER]) + useGetReporters() ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -40,19 +39,17 @@ describe('useGetReporters', () => { it('calls getReporters api', async () => { const spyOnGetReporters = jest.spyOn(api, 'getReporters'); await act(async () => { - const { waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters([SECURITY_SOLUTION_OWNER]) - ); + const { waitForNextUpdate } = renderHook<string, UseGetReporters>(() => useGetReporters()); await waitForNextUpdate(); await waitForNextUpdate(); - expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); + expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal); }); }); it('fetch reporters', async () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters([SECURITY_SOLUTION_OWNER]) + useGetReporters() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -70,7 +67,7 @@ describe('useGetReporters', () => { const spyOnGetReporters = jest.spyOn(api, 'getReporters'); await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters([SECURITY_SOLUTION_OWNER]) + useGetReporters() ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -87,7 +84,7 @@ describe('useGetReporters', () => { await act(async () => { const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters([SECURITY_SOLUTION_OWNER]) + useGetReporters() ); await waitForNextUpdate(); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx index c7ed0d8563c51..3fecfb51b958c 100644 --- a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx @@ -9,7 +9,6 @@ import { renderHook, act } from '@testing-library/react-hooks'; import { useGetTags, UseGetTags } from './use_get_tags'; import { tags } from './mock'; import * as api from './api'; -import { SECURITY_SOLUTION_OWNER } from '../../common'; jest.mock('./api'); jest.mock('../common/lib/kibana'); @@ -23,9 +22,7 @@ describe('useGetTags', () => { it('init', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags([SECURITY_SOLUTION_OWNER]) - ); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); await waitForNextUpdate(); expect(result.current).toEqual({ tags: [], @@ -39,20 +36,16 @@ describe('useGetTags', () => { it('calls getTags api', async () => { const spyOnGetTags = jest.spyOn(api, 'getTags'); await act(async () => { - const { waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags([SECURITY_SOLUTION_OWNER]) - ); + const { waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); await waitForNextUpdate(); await waitForNextUpdate(); - expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); + expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal); }); }); it('fetch tags', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags([SECURITY_SOLUTION_OWNER]) - ); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); await waitForNextUpdate(); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -67,9 +60,7 @@ describe('useGetTags', () => { it('refetch tags', async () => { const spyOnGetTags = jest.spyOn(api, 'getTags'); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags([SECURITY_SOLUTION_OWNER]) - ); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); await waitForNextUpdate(); await waitForNextUpdate(); result.current.fetchTags(); @@ -84,9 +75,7 @@ describe('useGetTags', () => { }); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => - useGetTags([SECURITY_SOLUTION_OWNER]) - ); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); await waitForNextUpdate(); await waitForNextUpdate(); From 11b01b0112f1110928abf743e39c14ed70805bb4 Mon Sep 17 00:00:00 2001 From: Christos Nasikas <christos.nasikas@elastic.co> Date: Fri, 14 May 2021 15:38:34 +0300 Subject: [PATCH 17/17] Fix tests --- .../components/recent_cases/index.test.tsx | 1 - .../cases/public/containers/api.test.tsx | 3 + .../configure/use_configure.test.tsx | 86 +++++++++++++------ .../public/containers/use_get_cases.test.tsx | 70 +++++++++++---- .../containers/use_get_reporters.test.tsx | 37 +++++--- .../public/containers/use_get_tags.test.tsx | 25 ++++-- 6 files changed, 166 insertions(+), 56 deletions(-) diff --git a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx index e6610f6b27900..5893d5f8c5af4 100644 --- a/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx +++ b/x-pack/plugins/cases/public/components/recent_cases/index.test.tsx @@ -74,7 +74,6 @@ describe('RecentCases', () => { ); expect(useGetCasesMock).toBeCalledWith({ initialQueryParams: { perPage: 2 }, - initialFilterOptions: { owner: [SECURITY_SOLUTION_OWNER] }, }); }); diff --git a/x-pack/plugins/cases/public/containers/api.test.tsx b/x-pack/plugins/cases/public/containers/api.test.tsx index 5bd7bd3c2be72..bee6110c39a30 100644 --- a/x-pack/plugins/cases/public/containers/api.test.tsx +++ b/x-pack/plugins/cases/public/containers/api.test.tsx @@ -137,6 +137,7 @@ describe('Case Configuration API', () => { ...DEFAULT_QUERY_PARAMS, reporters: [], tags: [], + owner: [SECURITY_SOLUTION_OWNER], }, signal: abortCtrl.signal, }); @@ -163,6 +164,7 @@ describe('Case Configuration API', () => { tags: ['"coke"', '"pepsi"'], search: 'hello', status: CaseStatuses.open, + owner: [SECURITY_SOLUTION_OWNER], }, signal: abortCtrl.signal, }); @@ -191,6 +193,7 @@ describe('Case Configuration API', () => { tags: ['"("', '"\\"double\\""'], search: 'hello', status: CaseStatuses.open, + owner: [SECURITY_SOLUTION_OWNER], }, signal: abortCtrl.signal, }); diff --git a/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx b/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx index 4d2abbcaec4d4..d8d552ceb8b7a 100644 --- a/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx +++ b/x-pack/plugins/cases/public/containers/configure/use_configure.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import React from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; import { initialState, @@ -15,6 +16,7 @@ import { import { mappings, caseConfigurationCamelCaseResponseMock } from './mock'; import * as api from './api'; import { ConnectorTypes } from '../../../common'; +import { TestProviders } from '../../common/mock'; const mockErrorToast = jest.fn(); const mockSuccessToast = jest.fn(); @@ -49,8 +51,11 @@ describe('useConfigure', () => { test('init', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -67,8 +72,11 @@ describe('useConfigure', () => { test('fetch case configuration', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -99,8 +107,11 @@ describe('useConfigure', () => { const spyOnGetCaseConfigure = jest.spyOn(api, 'getCaseConfigure'); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -111,8 +122,11 @@ describe('useConfigure', () => { test('correctly sets mappings', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -124,8 +138,11 @@ describe('useConfigure', () => { test('set isLoading to true when fetching case configuration', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -137,8 +154,11 @@ describe('useConfigure', () => { test('persist case configuration', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -166,8 +186,11 @@ describe('useConfigure', () => { ); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -192,8 +215,11 @@ describe('useConfigure', () => { ); await act(async () => { - const { waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -221,8 +247,11 @@ describe('useConfigure', () => { ); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -245,8 +274,11 @@ describe('useConfigure', () => { ); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -266,8 +298,11 @@ describe('useConfigure', () => { }); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); @@ -302,8 +337,11 @@ describe('useConfigure', () => { }); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>(() => - useCaseConfigure() + const { result, waitForNextUpdate } = renderHook<string, ReturnUseCaseConfigure>( + () => useCaseConfigure(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/use_get_cases.test.tsx b/x-pack/plugins/cases/public/containers/use_get_cases.test.tsx index b07fec4984eb1..b3a6932c6971c 100644 --- a/x-pack/plugins/cases/public/containers/use_get_cases.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_cases.test.tsx @@ -5,8 +5,9 @@ * 2.0. */ +import React from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; -import { CaseStatuses } from '../../common'; +import { CaseStatuses, SECURITY_SOLUTION_OWNER } from '../../common'; import { DEFAULT_FILTER_OPTIONS, DEFAULT_QUERY_PARAMS, @@ -17,6 +18,7 @@ import { import { UpdateKey } from './types'; import { allCases, basicCase } from './mock'; import * as api from './api'; +import { TestProviders } from '../common/mock'; jest.mock('./api'); jest.mock('../common/lib/kibana'); @@ -30,7 +32,10 @@ describe('useGetCases', () => { it('init', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + await waitForNextUpdate(); expect(result.current).toEqual({ data: initialData, @@ -51,11 +56,13 @@ describe('useGetCases', () => { it('calls getCases with correct arguments', async () => { const spyOnGetCases = jest.spyOn(api, 'getCases'); await act(async () => { - const { waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + const { waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); expect(spyOnGetCases).toBeCalledWith({ - filterOptions: DEFAULT_FILTER_OPTIONS, + filterOptions: { ...DEFAULT_FILTER_OPTIONS, owner: [SECURITY_SOLUTION_OWNER] }, queryParams: DEFAULT_QUERY_PARAMS, signal: abortCtrl.signal, }); @@ -64,7 +71,9 @@ describe('useGetCases', () => { it('fetch cases', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -82,6 +91,7 @@ describe('useGetCases', () => { }); }); }); + it('dispatch update case property', async () => { const spyOnPatchCase = jest.spyOn(api, 'patchCase'); await act(async () => { @@ -92,7 +102,9 @@ describe('useGetCases', () => { refetchCasesStatus: jest.fn(), version: '99999', }; - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); result.current.dispatchUpdateCaseProperty(updateCase); @@ -109,7 +121,9 @@ describe('useGetCases', () => { it('refetch cases', async () => { const spyOnGetCases = jest.spyOn(api, 'getCases'); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); result.current.refetchCases(); @@ -119,7 +133,9 @@ describe('useGetCases', () => { it('set isLoading to true when refetching case', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); result.current.refetchCases(); @@ -135,7 +151,9 @@ describe('useGetCases', () => { }); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); @@ -154,6 +172,7 @@ describe('useGetCases', () => { }); }); }); + it('set filters', async () => { await act(async () => { const spyOnGetCases = jest.spyOn(api, 'getCases'); @@ -162,40 +181,61 @@ describe('useGetCases', () => { tags: ['new'], status: CaseStatuses.closed, }; - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + await waitForNextUpdate(); await waitForNextUpdate(); result.current.setFilters(newFilters); await waitForNextUpdate(); + expect(spyOnGetCases.mock.calls[1][0]).toEqual({ - filterOptions: { ...DEFAULT_FILTER_OPTIONS, ...newFilters }, + filterOptions: { + ...DEFAULT_FILTER_OPTIONS, + ...newFilters, + owner: [SECURITY_SOLUTION_OWNER], + }, queryParams: DEFAULT_QUERY_PARAMS, signal: abortCtrl.signal, }); }); }); + it('set query params', async () => { await act(async () => { const spyOnGetCases = jest.spyOn(api, 'getCases'); const newQueryParams = { page: 2, }; - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); + await waitForNextUpdate(); await waitForNextUpdate(); result.current.setQueryParams(newQueryParams); await waitForNextUpdate(); + expect(spyOnGetCases.mock.calls[1][0]).toEqual({ - filterOptions: DEFAULT_FILTER_OPTIONS, - queryParams: { ...DEFAULT_QUERY_PARAMS, ...newQueryParams }, + filterOptions: { ...DEFAULT_FILTER_OPTIONS, owner: [SECURITY_SOLUTION_OWNER] }, + queryParams: { + ...DEFAULT_QUERY_PARAMS, + ...newQueryParams, + }, signal: abortCtrl.signal, }); }); }); + it('set selected cases', async () => { await act(async () => { const selectedCases = [basicCase]; - const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases()); + const { result, waitForNextUpdate } = renderHook<string, UseGetCases>(() => useGetCases(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); result.current.setSelectedCases(selectedCases); diff --git a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx index 8345ddf107872..692c5237f58bf 100644 --- a/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_reporters.test.tsx @@ -5,10 +5,13 @@ * 2.0. */ +import React from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; import { useGetReporters, UseGetReporters } from './use_get_reporters'; import { reporters, respReporters } from './mock'; import * as api from './api'; +import { TestProviders } from '../common/mock'; +import { SECURITY_SOLUTION_OWNER } from '../../common'; jest.mock('./api'); jest.mock('../common/lib/kibana'); @@ -22,8 +25,11 @@ describe('useGetReporters', () => { it('init', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters() + const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>( + () => useGetReporters(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -39,17 +45,22 @@ describe('useGetReporters', () => { it('calls getReporters api', async () => { const spyOnGetReporters = jest.spyOn(api, 'getReporters'); await act(async () => { - const { waitForNextUpdate } = renderHook<string, UseGetReporters>(() => useGetReporters()); + const { waitForNextUpdate } = renderHook<string, UseGetReporters>(() => useGetReporters(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); - expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal); + expect(spyOnGetReporters).toBeCalledWith(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); }); }); it('fetch reporters', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters() + const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>( + () => useGetReporters(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -66,8 +77,11 @@ describe('useGetReporters', () => { it('refetch reporters', async () => { const spyOnGetReporters = jest.spyOn(api, 'getReporters'); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters() + const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>( + () => useGetReporters(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); @@ -83,8 +97,11 @@ describe('useGetReporters', () => { }); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>(() => - useGetReporters() + const { result, waitForNextUpdate } = renderHook<string, UseGetReporters>( + () => useGetReporters(), + { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + } ); await waitForNextUpdate(); await waitForNextUpdate(); diff --git a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx index 3fecfb51b958c..60d368aca0a04 100644 --- a/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx +++ b/x-pack/plugins/cases/public/containers/use_get_tags.test.tsx @@ -5,10 +5,13 @@ * 2.0. */ +import React from 'react'; import { renderHook, act } from '@testing-library/react-hooks'; import { useGetTags, UseGetTags } from './use_get_tags'; import { tags } from './mock'; import * as api from './api'; +import { TestProviders } from '../common/mock'; +import { SECURITY_SOLUTION_OWNER } from '../../common'; jest.mock('./api'); jest.mock('../common/lib/kibana'); @@ -22,7 +25,9 @@ describe('useGetTags', () => { it('init', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); expect(result.current).toEqual({ tags: [], @@ -36,16 +41,20 @@ describe('useGetTags', () => { it('calls getTags api', async () => { const spyOnGetTags = jest.spyOn(api, 'getTags'); await act(async () => { - const { waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); - expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal); + expect(spyOnGetTags).toBeCalledWith(abortCtrl.signal, [SECURITY_SOLUTION_OWNER]); }); }); it('fetch tags', async () => { await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); expect(result.current).toEqual({ @@ -60,7 +69,9 @@ describe('useGetTags', () => { it('refetch tags', async () => { const spyOnGetTags = jest.spyOn(api, 'getTags'); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate(); result.current.fetchTags(); @@ -75,7 +86,9 @@ describe('useGetTags', () => { }); await act(async () => { - const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags()); + const { result, waitForNextUpdate } = renderHook<string, UseGetTags>(() => useGetTags(), { + wrapper: ({ children }) => <TestProviders>{children}</TestProviders>, + }); await waitForNextUpdate(); await waitForNextUpdate();