mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Security Solution][Endpoint][Response Actions] Add automated tests for execute response action test cases (#155128)
This commit is contained in:
parent
92ce25d7c8
commit
241f71b346
3 changed files with 227 additions and 48 deletions
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { RESPONSE_ACTION_API_COMMANDS_NAMES } from '../service/response_actions/constants';
|
||||
import {
|
||||
EndpointActionListRequestSchema,
|
||||
NoParametersRequestSchema,
|
||||
|
@ -185,7 +186,7 @@ describe('actions schemas', () => {
|
|||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it.each(['isolate', 'unisolate', 'kill-process', 'suspend-process', 'running-processes'])(
|
||||
it.each(RESPONSE_ACTION_API_COMMANDS_NAMES)(
|
||||
'should work with commands query params with %s action',
|
||||
(command) => {
|
||||
expect(() => {
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* 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 type { AppContextTestRender } from '../../../../../common/mock/endpoint';
|
||||
import { createAppRootMockRenderer } from '../../../../../common/mock/endpoint';
|
||||
import {
|
||||
ConsoleManagerTestComponent,
|
||||
getConsoleManagerMockRenderResultQueriesAndActions,
|
||||
} from '../../../console/components/console_manager/mocks';
|
||||
import React from 'react';
|
||||
import { getEndpointConsoleCommands } from '../../lib/console_commands_definition';
|
||||
import { enterConsoleCommand } from '../../../console/mocks';
|
||||
import { getEndpointAuthzInitialState } from '../../../../../../common/endpoint/service/authz';
|
||||
import type { EndpointCapabilities } from '../../../../../../common/endpoint/service/response_actions/constants';
|
||||
import { ENDPOINT_CAPABILITIES } from '../../../../../../common/endpoint/service/response_actions/constants';
|
||||
import { useGetEndpointPendingActionsSummary } from '../../../../hooks/response_actions/use_get_endpoint_pending_actions_summary';
|
||||
import { useGetEndpointDetails } from '../../../../hooks';
|
||||
import { EndpointActionGenerator } from '../../../../../../common/endpoint/data_generators/endpoint_action_generator';
|
||||
import { EndpointMetadataGenerator } from '../../../../../../common/endpoint/data_generators/endpoint_metadata_generator';
|
||||
|
||||
jest.mock('../../../../hooks/response_actions/use_get_endpoint_pending_actions_summary');
|
||||
jest.mock('../../../../hooks');
|
||||
|
||||
const useGetEndpointPendingActionsSummaryMock = useGetEndpointPendingActionsSummary as jest.Mock;
|
||||
const useGetEndpointDetailsMock = useGetEndpointDetails as jest.Mock;
|
||||
|
||||
describe('When using processes action from response actions console', () => {
|
||||
let render: (
|
||||
capabilities?: EndpointCapabilities[]
|
||||
) => Promise<ReturnType<AppContextTestRender['render']>>;
|
||||
let renderResult: ReturnType<AppContextTestRender['render']>;
|
||||
let consoleManagerMockAccess: ReturnType<
|
||||
typeof getConsoleManagerMockRenderResultQueriesAndActions
|
||||
>;
|
||||
const agentId = 'a.b.c';
|
||||
|
||||
const pendingActionsMock = () => {
|
||||
useGetEndpointPendingActionsSummaryMock.mockReturnValue({
|
||||
data: {
|
||||
data: [
|
||||
new EndpointActionGenerator('seed').generateAgentPendingActionsSummary({
|
||||
agent_id: agentId,
|
||||
pending_actions: {
|
||||
isolate: 0,
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const endpointDetailsMock = () => {
|
||||
const endpointMetadata = new EndpointMetadataGenerator('seed').generateHostInfo({
|
||||
metadata: {
|
||||
'@timestamp': new Date('2023-04-20T09:37:40.309Z').getTime(),
|
||||
agent: {
|
||||
id: agentId,
|
||||
version: '8.8.0',
|
||||
},
|
||||
elastic: {
|
||||
agent: { id: agentId },
|
||||
},
|
||||
Endpoint: {
|
||||
state: {
|
||||
isolation: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
useGetEndpointDetailsMock.mockReturnValue({
|
||||
data: endpointMetadata,
|
||||
isFetching: false,
|
||||
isFetched: true,
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
const mockedContext = createAppRootMockRenderer();
|
||||
|
||||
render = async (capabilities: EndpointCapabilities[] = [...ENDPOINT_CAPABILITIES]) => {
|
||||
renderResult = mockedContext.render(
|
||||
<ConsoleManagerTestComponent
|
||||
registerConsoleProps={() => {
|
||||
return {
|
||||
consoleProps: {
|
||||
'data-test-subj': 'test',
|
||||
commands: getEndpointConsoleCommands({
|
||||
endpointAgentId: 'a.b.c',
|
||||
endpointCapabilities: [...capabilities],
|
||||
endpointPrivileges: {
|
||||
...getEndpointAuthzInitialState(),
|
||||
loading: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
consoleManagerMockAccess = getConsoleManagerMockRenderResultQueriesAndActions(renderResult);
|
||||
|
||||
await consoleManagerMockAccess.clickOnRegisterNewConsole();
|
||||
await consoleManagerMockAccess.openRunningConsole();
|
||||
|
||||
return renderResult;
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should show expected status output', async () => {
|
||||
pendingActionsMock();
|
||||
endpointDetailsMock();
|
||||
await render();
|
||||
enterConsoleCommand(renderResult, 'status');
|
||||
const statusResults = renderResult.getByTestId('agent-status-console-output');
|
||||
|
||||
expect(
|
||||
Array.from(statusResults.querySelectorAll('dt')).map((term) => term.textContent)
|
||||
).toEqual([
|
||||
'Agent status',
|
||||
'Platform',
|
||||
'Version',
|
||||
'Policy status',
|
||||
'Policy version',
|
||||
'Policy name',
|
||||
'Last active',
|
||||
]);
|
||||
|
||||
expect(
|
||||
Array.from(statusResults.querySelectorAll('dd')).map((detail) => detail.textContent)
|
||||
).toEqual([
|
||||
'Healthy',
|
||||
'Windows Server 2012R2',
|
||||
'8.8.0',
|
||||
'Success',
|
||||
'v3',
|
||||
'With Eventing',
|
||||
'Apr 20, 2023 @ 09:37:40.309',
|
||||
]);
|
||||
});
|
||||
});
|
|
@ -796,6 +796,10 @@ describe('Response actions history', () => {
|
|||
});
|
||||
|
||||
describe('Action status ', () => {
|
||||
beforeEach(() => {
|
||||
apiMocks = responseActionsHttpMocks(mockedContext.coreStart.http);
|
||||
});
|
||||
|
||||
const expandRows = () => {
|
||||
const { getAllByTestId } = renderResult;
|
||||
|
||||
|
@ -805,58 +809,84 @@ describe('Response actions history', () => {
|
|||
return outputs;
|
||||
};
|
||||
|
||||
it('shows completed status badge for successfully completed actions', async () => {
|
||||
useGetEndpointActionListMock.mockReturnValue({
|
||||
...getBaseMockedActionList(),
|
||||
data: await getActionListMock({ actionCount: 2 }),
|
||||
});
|
||||
render();
|
||||
it.each(RESPONSE_ACTION_API_COMMANDS_NAMES)(
|
||||
'shows completed status badge for successfully completed %s actions',
|
||||
async (command) => {
|
||||
useGetEndpointActionListMock.mockReturnValue({
|
||||
...getBaseMockedActionList(),
|
||||
data: await getActionListMock({ actionCount: 2, commands: [command] }),
|
||||
});
|
||||
if (command === 'get-file' || command === 'execute') {
|
||||
mockUseGetFileInfo = {
|
||||
isFetching: false,
|
||||
error: null,
|
||||
data: apiMocks.responseProvider.fileInfo(),
|
||||
};
|
||||
}
|
||||
|
||||
const outputs = expandRows();
|
||||
expect(outputs.map((n) => n.textContent)).toEqual([
|
||||
'isolate completed successfully',
|
||||
'isolate completed successfully',
|
||||
]);
|
||||
expect(
|
||||
renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent)
|
||||
).toEqual(['Successful', 'Successful']);
|
||||
});
|
||||
render();
|
||||
|
||||
it('shows Failed status badge for failed actions', async () => {
|
||||
useGetEndpointActionListMock.mockReturnValue({
|
||||
...getBaseMockedActionList(),
|
||||
data: await getActionListMock({ actionCount: 2, wasSuccessful: false, status: 'failed' }),
|
||||
});
|
||||
render();
|
||||
const outputs = expandRows();
|
||||
expect(outputs.map((n) => n.textContent)).toEqual([
|
||||
expect.stringContaining(`${command} completed successfully`),
|
||||
expect.stringContaining(`${command} completed successfully`),
|
||||
]);
|
||||
expect(
|
||||
renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent)
|
||||
).toEqual(['Successful', 'Successful']);
|
||||
}
|
||||
);
|
||||
|
||||
const outputs = expandRows();
|
||||
expect(outputs.map((n) => n.textContent)).toEqual(['isolate failed', 'isolate failed']);
|
||||
expect(
|
||||
renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent)
|
||||
).toEqual(['Failed', 'Failed']);
|
||||
});
|
||||
it.each(RESPONSE_ACTION_API_COMMANDS_NAMES)(
|
||||
'shows Failed status badge for failed %s actions',
|
||||
async (command) => {
|
||||
useGetEndpointActionListMock.mockReturnValue({
|
||||
...getBaseMockedActionList(),
|
||||
data: await getActionListMock({
|
||||
actionCount: 2,
|
||||
commands: [command],
|
||||
wasSuccessful: false,
|
||||
status: 'failed',
|
||||
}),
|
||||
});
|
||||
render();
|
||||
|
||||
it('shows Failed status badge for expired actions', async () => {
|
||||
useGetEndpointActionListMock.mockReturnValue({
|
||||
...getBaseMockedActionList(),
|
||||
data: await getActionListMock({
|
||||
actionCount: 2,
|
||||
isCompleted: false,
|
||||
isExpired: true,
|
||||
status: 'failed',
|
||||
}),
|
||||
});
|
||||
render();
|
||||
const outputs = expandRows();
|
||||
expect(outputs.map((n) => n.textContent)).toEqual([
|
||||
`${command} failed`,
|
||||
`${command} failed`,
|
||||
]);
|
||||
expect(
|
||||
renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent)
|
||||
).toEqual(['Failed', 'Failed']);
|
||||
}
|
||||
);
|
||||
|
||||
const outputs = expandRows();
|
||||
expect(outputs.map((n) => n.textContent)).toEqual([
|
||||
'isolate failed: action expired',
|
||||
'isolate failed: action expired',
|
||||
]);
|
||||
expect(
|
||||
renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent)
|
||||
).toEqual(['Failed', 'Failed']);
|
||||
});
|
||||
it.each(RESPONSE_ACTION_API_COMMANDS_NAMES)(
|
||||
'shows Failed status badge for expired %s actions',
|
||||
async (command) => {
|
||||
useGetEndpointActionListMock.mockReturnValue({
|
||||
...getBaseMockedActionList(),
|
||||
data: await getActionListMock({
|
||||
actionCount: 2,
|
||||
commands: [command],
|
||||
isCompleted: false,
|
||||
isExpired: true,
|
||||
status: 'failed',
|
||||
}),
|
||||
});
|
||||
render();
|
||||
|
||||
const outputs = expandRows();
|
||||
expect(outputs.map((n) => n.textContent)).toEqual([
|
||||
`${command} failed: action expired`,
|
||||
`${command} failed: action expired`,
|
||||
]);
|
||||
expect(
|
||||
renderResult.getAllByTestId(`${testPrefix}-column-status`).map((n) => n.textContent)
|
||||
).toEqual(['Failed', 'Failed']);
|
||||
}
|
||||
);
|
||||
|
||||
it('shows Pending status badge for pending actions', async () => {
|
||||
useGetEndpointActionListMock.mockReturnValue({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue