Skip to content

Commit

Permalink
fix custom chart actions
Browse files Browse the repository at this point in the history
  • Loading branch information
angorayc committed Apr 6, 2023
1 parent 3164b53 commit 8bd7b3d
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 35 deletions.
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 @@ -280,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 @@ -307,14 +308,14 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> =
isChartEmbeddablesEnabled ? (
<VisualizationEmbeddable
data-test-subj="embeddable-matrix-histogram"
extraOptions={extraVisualizationOptions}
getLensAttributes={getLensAttributes}
height={CHART_HEIGHT}
id={`${id}-embeddable`}
inspectTitle={title as string}
lensAttributes={lensAttributes}
stackByField={selectedStackByOption.value}
timerange={timerange}
extraOptions={extraVisualizationOptions}
/>
) : (
<MatrixHistogramChartContent
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 8bd7b3d

Please sign in to comment.