Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SecuritySolution] Fix DNS histogram query #154548

Merged
merged 6 commits into from
Apr 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ import { useMatrixHistogramCombined } from '../../containers/matrix_histogram';
import { MatrixHistogramType } from '../../../../common/search_strategy/security_solution';
import { TestProviders } from '../../mock';
import { mockRuntimeMappings } from '../../containers/source/mock';
import { dnsTopDomainsLensAttributes } from '../visualization_actions/lens_attributes/network/dns_top_domains';
import { getDnsTopDomainsLensAttributes } from '../visualization_actions/lens_attributes/network/dns_top_domains';
import { useQueryToggle } from '../../containers/query_toggle';
import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features';
import type { ExperimentalFeatures } from '../../../../common/experimental_features';
import { allowedExperimentalValues } from '../../../../common/experimental_features';
import { VisualizationActions } from '../visualization_actions/actions';

jest.mock('../../containers/query_toggle');

Expand Down Expand Up @@ -61,19 +62,23 @@ describe('Matrix Histogram Component', () => {

const mockMatrixOverTimeHistogramProps = {
defaultIndex: ['defaultIndex'],
defaultStackByOption: { text: 'text', value: 'value' },
defaultStackByOption: {
text: 'dns.question.registered_domain',
value: 'dns.question.registered_domain',
},
endDate: '2019-07-18T20:00:00.000Z',
errorMessage: 'error',
histogramType: MatrixHistogramType.alerts,
id: 'mockId',
indexNames: [],
isInspected: false,
isPtrIncluded: false,
isPtrIncluded: true,
setQuery: jest.fn(),
skip: false,
sourceId: 'default',
stackByField: 'mockStackByField',
stackByOptions: [{ text: 'text', value: 'value' }],
stackByOptions: [
{ text: 'dns.question.registered_domain', value: 'dns.question.registered_domain' },
],
startDate: '2019-07-18T19:00: 00.000Z',
subtitle: 'mockSubtitle',
totalCount: -1,
Expand Down Expand Up @@ -192,7 +197,7 @@ describe('Matrix Histogram Component', () => {
test("it doesn't render Inspect button by default", () => {
const testProps = {
...mockMatrixOverTimeHistogramProps,
lensAttributes: dnsTopDomainsLensAttributes,
getLensAttributes: getDnsTopDomainsLensAttributes,
};
wrapper = mount(<MatrixHistogram {...testProps} />, {
wrappingComponent: TestProviders,
Expand All @@ -202,25 +207,48 @@ describe('Matrix Histogram Component', () => {
});

describe('VisualizationActions', () => {
test('it renders VisualizationActions if lensAttributes is provided', () => {
const testProps = {
...mockMatrixOverTimeHistogramProps,
lensAttributes: dnsTopDomainsLensAttributes,
};
const testProps = {
...mockMatrixOverTimeHistogramProps,
getLensAttributes: jest.fn().mockReturnValue(getDnsTopDomainsLensAttributes()),
};
beforeEach(() => {
wrapper = mount(<MatrixHistogram {...testProps} />, {
wrappingComponent: TestProviders,
});
});
test('it renders VisualizationActions if getLensAttributes is provided', () => {
expect(wrapper.find('[data-test-subj="visualizationActions"]').exists()).toBe(true);
expect(wrapper.find('[data-test-subj="visualizationActions"]').prop('className')).toEqual(
'histogram-viz-actions'
);
});

test('it VisualizationActions with correct properties', () => {
expect((VisualizationActions as unknown as jest.Mock).mock.calls[0][0]).toEqual(
expect.objectContaining({
className: 'histogram-viz-actions',
extraOptions: {
dnsIsPtrIncluded: testProps.isPtrIncluded,
},
getLensAttributes: testProps.getLensAttributes,
lensAttributes: undefined,
isInspectButtonDisabled: true,
queryId: testProps.id,
stackByField: testProps.defaultStackByOption.value,
timerange: {
from: testProps.startDate,
to: testProps.endDate,
},
title: testProps.title,
})
);
});
});

describe('toggle query', () => {
const testProps = {
...mockMatrixOverTimeHistogramProps,
lensAttributes: dnsTopDomainsLensAttributes,
getLensAttributes: getDnsTopDomainsLensAttributes,
};

test('toggleQuery updates toggleStatus', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> =
]);

const timerange = useMemo(() => ({ from: startDate, to: endDate }), [startDate, endDate]);
const extraVisualizationOptions = useMemo(
() => ({ dnsIsPtrIncluded: isPtrIncluded ?? false }),
[isPtrIncluded]
);
if (hideHistogram) {
return null;
}
Expand Down Expand Up @@ -276,6 +280,7 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> =
<EuiFlexItem grow={false}>
<VisualizationActions
className="histogram-viz-actions"
extraOptions={extraVisualizationOptions}
getLensAttributes={getLensAttributes}
isInspectButtonDisabled={filterQuery === undefined}
lensAttributes={lensAttributes}
Expand Down Expand Up @@ -303,6 +308,7 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> =
isChartEmbeddablesEnabled ? (
<VisualizationEmbeddable
data-test-subj="embeddable-matrix-histogram"
extraOptions={extraVisualizationOptions}
stephmilovic marked this conversation as resolved.
Show resolved Hide resolved
getLensAttributes={getLensAttributes}
height={CHART_HEIGHT}
id={`${id}-embeddable`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
import React from 'react';
import type { VisualizationActionsProps } from '../types';

export const VisualizationActions = (props: VisualizationActionsProps) => {
export const VisualizationActions = jest.fn((props: VisualizationActionsProps) => {
const { title, className } = props;

return (
<div data-test-subj="visualizationActions" className={className}>
{title}
</div>
);
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import type { Action } from '@kbn/ui-actions-plugin/public';

import { dnsTopDomainsLensAttributes } from './lens_attributes/network/dns_top_domains';
import { getDnsTopDomainsLensAttributes } from './lens_attributes/network/dns_top_domains';
import { VisualizationActions } from './actions';
import {
createSecuritySolutionStorageMock,
Expand All @@ -27,6 +27,9 @@ import { CASES_FEATURE_ID } from '../../../../common/constants';
import { mockCasesContract } from '@kbn/cases-plugin/public/mocks';
import { allCasesCapabilities, allCasesPermissions } from '../../../cases_test_utils';
import { InputsModelId } from '../../store/inputs/constants';
import type { VisualizationActionsProps } from './types';
import * as useLensAttributesModule from './use_lens_attributes';
import { SourcererScopeName } from '../../store/sourcerer/model';

jest.mock('react-router-dom', () => {
const actual = jest.requireActual('react-router-dom');
Expand All @@ -43,6 +46,7 @@ jest.mock('../../utils/route/use_route_spy', () => {
useRouteSpy: jest.fn(() => [{ pageName: 'network', detailName: '', tabName: 'dns' }]),
};
});

describe('VisualizationActions', () => {
const refetch = jest.fn();
const state: State = mockGlobalState;
Expand All @@ -58,16 +62,19 @@ describe('VisualizationActions', () => {
refetch,
state: state.inputs,
};
const spyUseLensAttributes = jest.spyOn(useLensAttributesModule, 'useLensAttributes');

let store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage);
const props = {
lensAttributes: dnsTopDomainsLensAttributes,
const props: VisualizationActionsProps = {
getLensAttributes: getDnsTopDomainsLensAttributes,
queryId: 'networkDnsHistogramQuery',
timerange: {
from: '2022-03-06T16:00:00.000Z',
to: '2022-03-07T15:59:59.999Z',
},
title: 'mock networkDnsHistogram',
extraOptions: { dnsIsPtrIncluded: true },
stackByField: 'dns.question.registered_domain',
};
const mockNavigateToPrefilledEditor = jest.fn();
const mockGetCreateCaseFlyoutOpen = jest.fn();
Expand Down Expand Up @@ -123,6 +130,25 @@ describe('VisualizationActions', () => {
store = createStore(myState, SUB_PLUGINS_REDUCER, kibanaObservable, storage);
});

test('Should generate attributes', () => {
render(
<TestProviders store={store}>
<VisualizationActions {...props} />
</TestProviders>
);
expect(spyUseLensAttributes.mock.calls[0][0]).toEqual(
expect.objectContaining({
applyGlobalQueriesAndFilters: true,
extraOptions: props.extraOptions,
getLensAttributes: props.getLensAttributes,
lensAttributes: props.lensAttributes,
scopeId: SourcererScopeName.default,
stackByField: props.stackByField,
title: '',
})
);
});

test('Should render VisualizationActions button', () => {
const { container } = render(
<TestProviders store={store}>
Expand Down Expand Up @@ -156,21 +182,13 @@ describe('VisualizationActions', () => {

fireEvent.click(screen.getByText('Open in Lens'));
expect(mockNavigateToPrefilledEditor.mock.calls[0][0].timeRange).toEqual(props.timerange);
expect(mockNavigateToPrefilledEditor.mock.calls[0][0].attributes.title).toEqual(
props.lensAttributes.title
);
expect(mockNavigateToPrefilledEditor.mock.calls[0][0].attributes.title).toEqual('');
expect(mockNavigateToPrefilledEditor.mock.calls[0][0].attributes.references).toEqual([
{
id: 'security-solution',
name: 'indexpattern-datasource-current-indexpattern',
type: 'index-pattern',
},
{
id: 'security-solution',
name: 'indexpattern-datasource-layer-b1c3efc6-c886-4fba-978f-3b6bb5e7948a',
type: 'index-pattern',
},
{ id: 'security-solution', name: 'filter-index-pattern-0', type: 'index-pattern' },
]);
expect(mockNavigateToPrefilledEditor.mock.calls[0][1].openInNewTab).toEqual(true);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
OPEN_IN_LENS,
} from './translations';
import { VISUALIZATION_ACTIONS_BUTTON_CLASS } from './utils';
import { SourcererScopeName } from '../../store/sourcerer/model';

const Wrapper = styled.div`
&.viz-actions {
Expand All @@ -41,8 +42,10 @@ const Wrapper = styled.div`
`;

const VisualizationActionsComponent: React.FC<VisualizationActionsProps> = ({
applyGlobalQueriesAndFilters = true,
className,
extraActions,
extraOptions,
getLensAttributes,
inputId = InputsModelId.global,
inspectIndex = 0,
Expand All @@ -52,7 +55,8 @@ const VisualizationActionsComponent: React.FC<VisualizationActionsProps> = ({
onCloseInspect,
queryId,
timerange,
title,
title: inspectTitle,
scopeId = SourcererScopeName.default,
stackByField,
withDefaultActions = true,
}) => {
Expand All @@ -71,9 +75,13 @@ const VisualizationActionsComponent: React.FC<VisualizationActionsProps> = ({
};

const attributes = useLensAttributes({
lensAttributes,
applyGlobalQueriesAndFilters,
extraOptions,
getLensAttributes,
lensAttributes,
scopeId,
stackByField,
title: '',
});

const dataTestSubj = `stat-${queryId}`;
Expand Down Expand Up @@ -250,7 +258,7 @@ const VisualizationActionsComponent: React.FC<VisualizationActionsProps> = ({
inputId={inputId}
request={request}
response={response}
title={title}
title={inspectTitle}
/>
)}
</Wrapper>
Expand Down
Loading