diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.test.tsx
index 291ebdcd3ac4c..4a1ed7c791350 100644
--- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.test.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.test.tsx
@@ -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');
@@ -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,
@@ -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(, {
wrappingComponent: TestProviders,
@@ -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(, {
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', () => {
diff --git a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx
index d8e75ceafb5e3..82ef731321cb7 100644
--- a/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/matrix_histogram/index.tsx
@@ -280,6 +280,7 @@ export const MatrixHistogramComponent: React.FC =
=
isChartEmbeddablesEnabled ? (
=
lensAttributes={lensAttributes}
stackByField={selectedStackByOption.value}
timerange={timerange}
- extraOptions={extraVisualizationOptions}
/>
) : (
{
+export const VisualizationActions = jest.fn((props: VisualizationActionsProps) => {
const { title, className } = props;
+
return (
{title}
);
-};
+});
diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/actions.test.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/actions.test.tsx
index 924f3ea80dcca..aa168343cdb90 100644
--- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/actions.test.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/actions.test.tsx
@@ -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,
@@ -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');
@@ -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;
@@ -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();
@@ -123,6 +130,25 @@ describe('VisualizationActions', () => {
store = createStore(myState, SUB_PLUGINS_REDUCER, kibanaObservable, storage);
});
+ test('Should generate attributes', () => {
+ render(
+
+
+
+ );
+ 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(
@@ -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);
});
diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/actions.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/actions.tsx
index 029f7545d3a42..0825aacfee410 100644
--- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/actions.tsx
+++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/actions.tsx
@@ -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 {
@@ -41,8 +42,10 @@ const Wrapper = styled.div`
`;
const VisualizationActionsComponent: React.FC = ({
+ applyGlobalQueriesAndFilters = true,
className,
extraActions,
+ extraOptions,
getLensAttributes,
inputId = InputsModelId.global,
inspectIndex = 0,
@@ -52,7 +55,8 @@ const VisualizationActionsComponent: React.FC = ({
onCloseInspect,
queryId,
timerange,
- title,
+ title: inspectTitle,
+ scopeId = SourcererScopeName.default,
stackByField,
withDefaultActions = true,
}) => {
@@ -71,9 +75,13 @@ const VisualizationActionsComponent: React.FC = ({
};
const attributes = useLensAttributes({
- lensAttributes,
+ applyGlobalQueriesAndFilters,
+ extraOptions,
getLensAttributes,
+ lensAttributes,
+ scopeId,
stackByField,
+ title: '',
});
const dataTestSubj = `stat-${queryId}`;
@@ -250,7 +258,7 @@ const VisualizationActionsComponent: React.FC = ({
inputId={inputId}
request={request}
response={response}
- title={title}
+ title={inspectTitle}
/>
)}
diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap
index b25fced257c67..626e61fe0399a 100644
--- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap
+++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/__snapshots__/dns_top_domains.test.ts.snap
@@ -43,7 +43,7 @@ Object {
"e8842815-2a45-4c74-86de-c19a391e2424": Object {
"dataType": "string",
"isBucketed": true,
- "label": "Top values of dns.question.registered_domain",
+ "label": "Top values of event.dataset",
"operationType": "terms",
"params": Object {
"accuracyMode": true,
@@ -61,7 +61,7 @@ Object {
"size": 10,
},
"scale": "ordinal",
- "sourceField": "dns.question.registered_domain",
+ "sourceField": "event.dataset",
},
},
"incompleteColumns": Object {},
diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts
index 87aae1a44dd3d..24f611eb4ebf6 100644
--- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts
+++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_attributes/network/dns_top_domains.ts
@@ -9,7 +9,10 @@ import { TOP_VALUE, UNIQUE_COUNT } from '../../translations';
import type { LensAttributes, GetLensAttributes } from '../../types';
/* Exported from Kibana Saved Object */
-export const getDnsTopDomainsLensAttributes: GetLensAttributes = (stackByField, extraOptions) =>
+export const getDnsTopDomainsLensAttributes: GetLensAttributes = (
+ stackByField = 'dns.question.registered_domain',
+ extraOptions
+) =>
({
title: 'Top domains by dns.question.registered_domain',
visualizationType: 'lnsXY',
@@ -98,11 +101,11 @@ export const getDnsTopDomainsLensAttributes: GetLensAttributes = (stackByField,
'b1c3efc6-c886-4fba-978f-3b6bb5e7948a': {
columns: {
'e8842815-2a45-4c74-86de-c19a391e2424': {
- label: TOP_VALUE('dns.question.registered_domain'),
+ label: TOP_VALUE(stackByField),
dataType: 'string',
operationType: 'terms',
scale: 'ordinal',
- sourceField: 'dns.question.registered_domain',
+ sourceField: stackByField,
isBucketed: true,
params: {
size: 10,
diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts b/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts
index 732d23967e68c..732db46bf1cb2 100644
--- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts
+++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/types.ts
@@ -30,8 +30,10 @@ export interface UseLensAttributesProps {
}
export interface VisualizationActionsProps {
+ applyGlobalQueriesAndFilters?: boolean;
className?: string;
extraActions?: Action[];
+ extraOptions?: ExtraOptions;
getLensAttributes?: GetLensAttributes;
inputId?: InputsModelId.global | InputsModelId.timeline;
inspectIndex?: number;
@@ -40,6 +42,7 @@ export interface VisualizationActionsProps {
lensAttributes?: LensAttributes | null;
onCloseInspect?: () => void;
queryId: string;
+ scopeId?: SourcererScopeName;
stackByField?: string;
timerange: { from: string; to: string };
title: React.ReactNode;