diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/__snapshots__/page_view.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/endpoint/__snapshots__/page_view.test.tsx.snap index 6d8ea6b346ef..096df5ceab25 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/__snapshots__/page_view.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/__snapshots__/page_view.test.tsx.snap @@ -2,11 +2,11 @@ exports[`PageView component should display body header custom element 1`] = ` .c0.endpoint--isListView { - padding: 0 70px 0 24px; + padding: 0 24px; } .c0.endpoint--isListView .endpoint-header { - padding: 24px 0; + padding: 24px; margin-bottom: 0; } @@ -22,7 +22,7 @@ exports[`PageView component should display body header custom element 1`] = ` } .c0 .endpoint-navTabs { - margin-left: 24px; + margin-left: 12px; } props.theme.eui.euiSizeL}; + padding: 0 ${(props) => props.theme.eui.euiSizeL}; .endpoint-header { - padding: ${(props) => props.theme.eui.euiSizeL} 0; + padding: ${(props) => props.theme.eui.euiSizeL}; margin-bottom: 0; } .endpoint-page-content { @@ -44,7 +43,7 @@ const StyledEuiPage = styled(EuiPage)` } } .endpoint-navTabs { - margin-left: ${(props) => props.theme.eui.euiSizeL}; + margin-left: ${(props) => props.theme.eui.euiSizeM}; } `; diff --git a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.tsx b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.tsx index fde3f6f8b222..a9c6660ba9c6 100644 --- a/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.tsx +++ b/x-pack/plugins/security_solution/public/common/utils/timeline/use_show_timeline.tsx @@ -7,7 +7,7 @@ import { useState, useEffect } from 'react'; import { useRouteSpy } from '../route/use_route_spy'; -const hideTimelineForRoutes = [`/cases/configure`]; +const hideTimelineForRoutes = [`/cases/configure`, '/management']; export const useShowTimeline = () => { const [{ pageName, pathName }] = useRouteSpy(); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 224411c5f7ec..7bc101b89147 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -34,6 +34,12 @@ describe('when on the hosts page', () => { render = () => mockedContext.render(); }); + it('should NOT display timeline', async () => { + const renderResult = render(); + const timelineFlyout = await renderResult.queryByTestId('flyoutOverlay'); + expect(timelineFlyout).toBeNull(); + }); + it('should show a table', async () => { const renderResult = render(); const table = await renderResult.findByTestId('hostListTable'); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer.ts index 75e7808ea30b..b3b74c2ca9da 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_details/reducer.ts @@ -78,13 +78,20 @@ export const policyDetailsReducer: ImmutableReducer { let http: ReturnType; @@ -59,76 +61,7 @@ describe('ingest service', () => { describe('sendGetEndpointSecurityPackage()', () => { it('should query EPM with category=security', async () => { - http.get.mockResolvedValue({ - response: [ - { - name: 'endpoint', - title: 'Elastic Endpoint', - version: '0.5.0', - description: 'This is the Elastic Endpoint package.', - type: 'solution', - download: '/epr/endpoint/endpoint-0.5.0.tar.gz', - path: '/package/endpoint/0.5.0', - icons: [ - { - src: '/package/endpoint/0.5.0/img/logo-endpoint-64-color.svg', - size: '16x16', - type: 'image/svg+xml', - }, - ], - status: 'installed', - savedObject: { - type: 'epm-packages', - id: 'endpoint', - attributes: { - installed: [ - { id: '826759f0-7074-11ea-9bc8-6b38f4d29a16', type: 'dashboard' }, - { id: '1cfceda0-728b-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, - { id: '1e525190-7074-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, - { id: '55387750-729c-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, - { id: '92b1edc0-706a-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, - { id: 'a3a3bd10-706b-11ea-9bc8-6b38f4d29a16', type: 'map' }, - { id: 'logs-endpoint.alerts', type: 'index-template' }, - { id: 'events-endpoint', type: 'index-template' }, - { id: 'logs-endpoint.events.file', type: 'index-template' }, - { id: 'logs-endpoint.events.library', type: 'index-template' }, - { id: 'metrics-endpoint.metadata', type: 'index-template' }, - { id: 'metrics-endpoint.metadata_mirror', type: 'index-template' }, - { id: 'logs-endpoint.events.network', type: 'index-template' }, - { id: 'metrics-endpoint.policy', type: 'index-template' }, - { id: 'logs-endpoint.events.process', type: 'index-template' }, - { id: 'logs-endpoint.events.registry', type: 'index-template' }, - { id: 'logs-endpoint.events.security', type: 'index-template' }, - { id: 'metrics-endpoint.telemetry', type: 'index-template' }, - ], - es_index_patterns: { - alerts: 'logs-endpoint.alerts-*', - events: 'events-endpoint-*', - file: 'logs-endpoint.events.file-*', - library: 'logs-endpoint.events.library-*', - metadata: 'metrics-endpoint.metadata-*', - metadata_mirror: 'metrics-endpoint.metadata_mirror-*', - network: 'logs-endpoint.events.network-*', - policy: 'metrics-endpoint.policy-*', - process: 'logs-endpoint.events.process-*', - registry: 'logs-endpoint.events.registry-*', - security: 'logs-endpoint.events.security-*', - telemetry: 'metrics-endpoint.telemetry-*', - }, - name: 'endpoint', - version: '0.5.0', - internal: false, - removable: false, - }, - references: [], - updated_at: '2020-06-24T14:41:23.098Z', - version: 'Wzc0LDFd', - score: 0, - }, - }, - ], - success: true, - }); + http.get.mockReturnValue(apiPathMockResponseProviders[INGEST_API_EPM_PACKAGES]()); await sendGetEndpointSecurityPackage(http); expect(http.get).toHaveBeenCalledWith('/api/ingest_manager/epm/packages', { query: { category: 'security' }, diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_list/test_mock_utils.ts b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_list/test_mock_utils.ts index 0f0d1cb1b559..46f84d296bd4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_list/test_mock_utils.ts +++ b/x-pack/plugins/security_solution/public/management/pages/policy/store/policy_list/test_mock_utils.ts @@ -16,6 +16,82 @@ import { const generator = new EndpointDocGenerator('policy-list'); +/** + * a list of API paths response mock providers + */ +export const apiPathMockResponseProviders = { + [INGEST_API_EPM_PACKAGES]: () => + Promise.resolve({ + response: [ + { + name: 'endpoint', + title: 'Elastic Endpoint', + version: '0.5.0', + description: 'This is the Elastic Endpoint package.', + type: 'solution', + download: '/epr/endpoint/endpoint-0.5.0.tar.gz', + path: '/package/endpoint/0.5.0', + icons: [ + { + src: '/package/endpoint/0.5.0/img/logo-endpoint-64-color.svg', + size: '16x16', + type: 'image/svg+xml', + }, + ], + status: 'installed' as InstallationStatus, + savedObject: { + type: 'epm-packages', + id: 'endpoint', + attributes: { + installed: [ + { id: '826759f0-7074-11ea-9bc8-6b38f4d29a16', type: 'dashboard' }, + { id: '1cfceda0-728b-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, + { id: '1e525190-7074-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, + { id: '55387750-729c-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, + { id: '92b1edc0-706a-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, + { id: 'a3a3bd10-706b-11ea-9bc8-6b38f4d29a16', type: 'map' }, + { id: 'logs-endpoint.alerts', type: 'index-template' }, + { id: 'events-endpoint', type: 'index-template' }, + { id: 'logs-endpoint.events.file', type: 'index-template' }, + { id: 'logs-endpoint.events.library', type: 'index-template' }, + { id: 'metrics-endpoint.metadata', type: 'index-template' }, + { id: 'metrics-endpoint.metadata_mirror', type: 'index-template' }, + { id: 'logs-endpoint.events.network', type: 'index-template' }, + { id: 'metrics-endpoint.policy', type: 'index-template' }, + { id: 'logs-endpoint.events.process', type: 'index-template' }, + { id: 'logs-endpoint.events.registry', type: 'index-template' }, + { id: 'logs-endpoint.events.security', type: 'index-template' }, + { id: 'metrics-endpoint.telemetry', type: 'index-template' }, + ] as AssetReference[], + es_index_patterns: { + alerts: 'logs-endpoint.alerts-*', + events: 'events-endpoint-*', + file: 'logs-endpoint.events.file-*', + library: 'logs-endpoint.events.library-*', + metadata: 'metrics-endpoint.metadata-*', + metadata_mirror: 'metrics-endpoint.metadata_mirror-*', + network: 'logs-endpoint.events.network-*', + policy: 'metrics-endpoint.policy-*', + process: 'logs-endpoint.events.process-*', + registry: 'logs-endpoint.events.registry-*', + security: 'logs-endpoint.events.security-*', + telemetry: 'metrics-endpoint.telemetry-*', + }, + name: 'endpoint', + version: '0.5.0', + internal: false, + removable: false, + }, + references: [], + updated_at: '2020-06-24T14:41:23.098Z', + version: 'Wzc0LDFd', + }, + }, + ], + success: true, + }), +}; + /** * It sets the mock implementation on the necessary http methods to support the policy list view * @param mockedHttpService @@ -38,76 +114,8 @@ export const setPolicyListApiMockImplementation = ( }); } - if (path === INGEST_API_EPM_PACKAGES) { - return Promise.resolve({ - response: [ - { - name: 'endpoint', - title: 'Elastic Endpoint', - version: '0.5.0', - description: 'This is the Elastic Endpoint package.', - type: 'solution', - download: '/epr/endpoint/endpoint-0.5.0.tar.gz', - path: '/package/endpoint/0.5.0', - icons: [ - { - src: '/package/endpoint/0.5.0/img/logo-endpoint-64-color.svg', - size: '16x16', - type: 'image/svg+xml', - }, - ], - status: 'installed' as InstallationStatus, - savedObject: { - type: 'epm-packages', - id: 'endpoint', - attributes: { - installed: [ - { id: '826759f0-7074-11ea-9bc8-6b38f4d29a16', type: 'dashboard' }, - { id: '1cfceda0-728b-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, - { id: '1e525190-7074-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, - { id: '55387750-729c-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, - { id: '92b1edc0-706a-11ea-9bc8-6b38f4d29a16', type: 'visualization' }, - { id: 'a3a3bd10-706b-11ea-9bc8-6b38f4d29a16', type: 'map' }, - { id: 'logs-endpoint.alerts', type: 'index-template' }, - { id: 'events-endpoint', type: 'index-template' }, - { id: 'logs-endpoint.events.file', type: 'index-template' }, - { id: 'logs-endpoint.events.library', type: 'index-template' }, - { id: 'metrics-endpoint.metadata', type: 'index-template' }, - { id: 'metrics-endpoint.metadata_mirror', type: 'index-template' }, - { id: 'logs-endpoint.events.network', type: 'index-template' }, - { id: 'metrics-endpoint.policy', type: 'index-template' }, - { id: 'logs-endpoint.events.process', type: 'index-template' }, - { id: 'logs-endpoint.events.registry', type: 'index-template' }, - { id: 'logs-endpoint.events.security', type: 'index-template' }, - { id: 'metrics-endpoint.telemetry', type: 'index-template' }, - ] as AssetReference[], - es_index_patterns: { - alerts: 'logs-endpoint.alerts-*', - events: 'events-endpoint-*', - file: 'logs-endpoint.events.file-*', - library: 'logs-endpoint.events.library-*', - metadata: 'metrics-endpoint.metadata-*', - metadata_mirror: 'metrics-endpoint.metadata_mirror-*', - network: 'logs-endpoint.events.network-*', - policy: 'metrics-endpoint.policy-*', - process: 'logs-endpoint.events.process-*', - registry: 'logs-endpoint.events.registry-*', - security: 'logs-endpoint.events.security-*', - telemetry: 'metrics-endpoint.telemetry-*', - }, - name: 'endpoint', - version: '0.5.0', - internal: false, - removable: false, - }, - references: [], - updated_at: '2020-06-24T14:41:23.098Z', - version: 'Wzc0LDFd', - }, - }, - ], - success: true, - }); + if (apiPathMockResponseProviders[path]) { + return apiPathMockResponseProviders[path](); } } return Promise.reject(new Error(`MOCK: unknown policy list api: ${path}`)); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx index 315e3d29b6df..984639f0f599 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.test.tsx @@ -9,8 +9,9 @@ import { mount } from 'enzyme'; import { PolicyDetails } from './policy_details'; import { EndpointDocGenerator } from '../../../../../common/endpoint/generate_data'; -import { createAppRootMockRenderer } from '../../../../common/mock/endpoint'; +import { AppContextTestRender, createAppRootMockRenderer } from '../../../../common/mock/endpoint'; import { getPolicyDetailPath, getPoliciesPath } from '../../../common/routing'; +import { apiPathMockResponseProviders } from '../store/policy_list/test_mock_utils'; describe('Policy Details', () => { type FindReactWrapperResponse = ReturnType['find']>; @@ -19,29 +20,50 @@ describe('Policy Details', () => { const policyListPathUrl = getPoliciesPath(); const sleep = (ms = 100) => new Promise((wakeup) => setTimeout(wakeup, ms)); const generator = new EndpointDocGenerator(); - const { history, AppWrapper, coreStart } = createAppRootMockRenderer(); - const http = coreStart.http; - const render = (ui: Parameters[0]) => mount(ui, { wrappingComponent: AppWrapper }); + let history: AppContextTestRender['history']; + let coreStart: AppContextTestRender['coreStart']; + let middlewareSpy: AppContextTestRender['middlewareSpy']; + let http: typeof coreStart.http; + let render: (ui: Parameters[0]) => ReturnType; let policyDatasource: ReturnType; let policyView: ReturnType; - beforeEach(() => jest.clearAllMocks()); + beforeEach(() => { + const appContextMockRenderer = createAppRootMockRenderer(); + const AppWrapper = appContextMockRenderer.AppWrapper; + + ({ history, coreStart, middlewareSpy } = appContextMockRenderer); + render = (ui) => mount(ui, { wrappingComponent: AppWrapper }); + http = coreStart.http; + }); afterEach(() => { if (policyView) { policyView.unmount(); } + jest.clearAllMocks(); }); describe('when displayed with invalid id', () => { + let releaseApiFailure: () => void; beforeEach(() => { - http.get.mockReturnValue(Promise.reject(new Error('policy not found'))); + http.get.mockImplementationOnce(async () => { + await new Promise((_, reject) => { + releaseApiFailure = reject.bind(null, new Error('policy not found')); + }); + }); history.push(policyDetailsPathUrl); policyView = render(); }); - it('should show loader followed by error message', () => { + it('should NOT display timeline', async () => { + expect(policyView.find('flyoutOverlay')).toHaveLength(0); + }); + + it('should show loader followed by error message', async () => { expect(policyView.find('EuiLoadingSpinner').length).toBe(1); + releaseApiFailure(); + await middlewareSpy.waitForAction('serverFailedToReturnPolicyDetailsData'); policyView.update(); const callout = policyView.find('EuiCallOut'); expect(callout).toHaveLength(1); @@ -76,14 +98,25 @@ describe('Policy Details', () => { success: true, }); } + + // Get package data + // Used in tests that route back to the list + if (apiPathMockResponseProviders[path]) { + asyncActions = asyncActions.then(async () => sleep()); + return apiPathMockResponseProviders[path](); + } } - return Promise.reject(new Error('unknown API call!')); + return Promise.reject(new Error(`unknown API call (not MOCKED): ${path}`)); }); history.push(policyDetailsPathUrl); policyView = render(); }); + it('should NOT display timeline', async () => { + expect(policyView.find('flyoutOverlay')).toHaveLength(0); + }); + it('should display back to list button and policy title', () => { policyView.update(); const pageHeaderLeft = policyView.find( diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx index acce5c8f7835..32de3c93ac98 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_list.test.tsx @@ -23,6 +23,12 @@ describe('when on the policies page', () => { render = () => mockedContext.render(); }); + it('should NOT display timeline', async () => { + const renderResult = render(); + const timelineFlyout = await renderResult.queryByTestId('flyoutOverlay'); + expect(timelineFlyout).toBeNull(); + }); + it('should show the empty state', async () => { const renderResult = render(); const table = await renderResult.findByTestId('emptyPolicyTable');