fix case when both kql and filters are set and when opening timeline from graph

This commit is contained in:
alex prozorov 2025-04-09 15:09:49 +03:00
parent 7be44d7d1f
commit c29eea8f93
2 changed files with 79 additions and 6 deletions

View file

@ -24,6 +24,7 @@ import {
import * as previewAnnotations from '../../../.storybook/preview';
import { NOTIFICATIONS_ADD_ERROR_ACTION } from '../../../.storybook/constants';
import { USE_FETCH_GRAPH_DATA_REFRESH_ACTION } from '../mock/constants';
import { mockDataView } from '../mock/data_view.mock';
setProjectAnnotations(previewAnnotations);
@ -112,7 +113,7 @@ const isSearchBarVisible = (container: HTMLElement) => {
};
// FLAKY: https://github.com/elastic/kibana/issues/206646
describe.skip('GraphInvestigation Component', () => {
describe('GraphInvestigation Component', () => {
beforeEach(() => {
for (const key in actionMocks) {
if (Object.prototype.hasOwnProperty.call(actionMocks, key)) {
@ -274,7 +275,7 @@ describe.skip('GraphInvestigation Component', () => {
});
describe('investigateInTimeline', () => {
it('calls onInvestigateInTimeline action', () => {
it('empty query and no filters - calls onInvestigateInTimeline action with event.id', () => {
const onInvestigateInTimeline = jest.fn();
const { getByTestId } = renderStory({
onInvestigateInTimeline,
@ -323,7 +324,7 @@ describe.skip('GraphInvestigation Component', () => {
]);
});
it(`query doesn't include event id in filters input when onInvestigateInTimeline callback`, async () => {
it('query and no filters - calls onInvestigateInTimeline action with event.id in the query but not in the filters', async () => {
// Arrange
const onInvestigateInTimeline = jest.fn();
const { getByTestId } = renderStory({
@ -346,5 +347,62 @@ describe.skip('GraphInvestigation Component', () => {
});
expect(onInvestigateInTimeline.mock.calls[0][FILTERS_PARAM_IDX]).toEqual([]);
});
it('empty query and empty originEventIds - calls onInvestigateInTimeline with empty filters', () => {
const onInvestigateInTimeline = jest.fn();
const { getByTestId } = renderStory({
onInvestigateInTimeline,
showInvestigateInTimeline: true,
initialState: {
dataView: mockDataView,
originEventIds: [],
timeRange: {
from: 'now-15m',
to: 'now',
},
},
});
getByTestId(GRAPH_ACTIONS_INVESTIGATE_IN_TIMELINE_ID).click();
expect(onInvestigateInTimeline).toHaveBeenCalled();
expect(onInvestigateInTimeline.mock.calls[0][QUERY_PARAM_IDX]).toEqual({
query: '',
language: 'kuery',
});
// Should have empty filters since there are no originEventIds
expect(onInvestigateInTimeline.mock.calls[0][FILTERS_PARAM_IDX]).toEqual([]);
});
it('query and empty originEventIds - calls onInvestigateInTimeline with only the query', async () => {
const onInvestigateInTimeline = jest.fn();
const { getByTestId } = renderStory({
onInvestigateInTimeline,
showInvestigateInTimeline: true,
initialState: {
dataView: mockDataView,
originEventIds: [],
timeRange: {
from: 'now-15m',
to: 'now',
},
},
});
const queryInput = getByTestId('queryInput');
await userEvent.type(queryInput, 'host1');
const querySubmitBtn = getByTestId('querySubmitButton');
querySubmitBtn.click();
getByTestId(GRAPH_ACTIONS_INVESTIGATE_IN_TIMELINE_ID).click();
expect(onInvestigateInTimeline).toHaveBeenCalled();
// Query should remain unchanged since there are no originEventIds to add
expect(onInvestigateInTimeline.mock.calls[0][QUERY_PARAM_IDX]).toEqual({
query: 'host1',
language: 'kuery',
});
expect(onInvestigateInTimeline.mock.calls[0][FILTERS_PARAM_IDX]).toEqual([]);
});
});
});

View file

@ -140,14 +140,29 @@ export const GraphInvestigation = memo<GraphInvestigationProps>(
const query = { ...kquery };
let filters = [...searchFilters];
if ((query.query.trim() === '' || searchFilters.length > 0) && originEventIds.length > 0) {
// Case 1: Empty query with origin event IDs
if (query.query.trim() === '' && originEventIds.length > 0) {
filters = originEventIds.reduce<Filter[]>((acc, { id }) => {
return addFilter(dataView?.id ?? '', acc, EVENT_ID, id);
}, searchFilters);
}
// Case 2: Has query, no search filters, but has origin event IDs
else if (
query.query.trim() !== '' &&
searchFilters.length === 0 &&
originEventIds.length > 0
) {
query.query = `(${query.query})${originEventIds
.map(({ id }) => ` OR ${EVENT_ID}: "${id}"`)
.join('')}`;
}
// Case 3: Has query, has search filters, and has origin event IDs
else if (query.query.trim() !== '' && searchFilters.length > 0 && originEventIds.length > 0) {
// Apply both modifications from Case 1 and Case 2
filters = originEventIds.reduce<Filter[]>((acc, { id }) => {
return addFilter(dataView?.id ?? '', acc, EVENT_ID, id);
}, searchFilters);
if (query.query.trim() !== '' && searchFilters.length === 0 && originEventIds.length > 0) {
query.query = `(${query.query})${originEventIds
.map(({ id }) => ` OR ${EVENT_ID}: "${id}"`)
.join('')}`;