mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
## Summary As outlined in https://github.com/elastic/ingest-dev/issues/419, clearing the first filter within the Timeline Query Builder would result in all the remaining `and`'d filters being cleared as well. This PR fixes that issues, and adds testing to catch a future regressions. Before:  After:  ### Checklist Use ~~strikethroughs~~ to remove checklist items you don't feel are applicable to this PR. - [x] This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) - IE11 needs this fix to be applicable: https://github.com/elastic/ingest-dev/issues/263 - [ ] ~Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md)~ - [ ] ~[Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials~ - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios - [ ] ~This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist)~ ### For maintainers - [ ] ~This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~ - [ ] ~This includes a feature addition or change that requires a release note and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~
This commit is contained in:
parent
b403fe3d22
commit
acf4b798cf
2 changed files with 358 additions and 1 deletions
|
@ -1000,6 +1000,14 @@ const removeProvider = (providerId: string, timeline: TimelineModel) => {
|
|||
const providerIndex = timeline.dataProviders.findIndex(p => p.id === providerId);
|
||||
return [
|
||||
...timeline.dataProviders.slice(0, providerIndex),
|
||||
...(timeline.dataProviders[providerIndex].and.length
|
||||
? [
|
||||
{
|
||||
...timeline.dataProviders[providerIndex].and.slice(0, 1)[0],
|
||||
and: [...timeline.dataProviders[providerIndex].and.slice(1)],
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...timeline.dataProviders.slice(providerIndex + 1),
|
||||
];
|
||||
};
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
import { cloneDeep, set } from 'lodash/fp';
|
||||
|
||||
import { ColumnHeader } from '../../components/timeline/body/column_headers/column_header';
|
||||
import { IS_OPERATOR, DataProvider } from '../../components/timeline/data_providers/data_provider';
|
||||
import {
|
||||
IS_OPERATOR,
|
||||
DataProvider,
|
||||
DataProvidersAnd,
|
||||
} from '../../components/timeline/data_providers/data_provider';
|
||||
import { defaultColumnHeaderType } from '../../components/timeline/body/column_headers/default_headers';
|
||||
import {
|
||||
DEFAULT_COLUMN_MIN_WIDTH,
|
||||
|
@ -1706,5 +1710,350 @@ describe('Timeline', () => {
|
|||
};
|
||||
expect(update).toEqual(expected);
|
||||
});
|
||||
|
||||
test('should remove only first provider and not nested andProvider', () => {
|
||||
const dataProviders: DataProvider[] = [
|
||||
{
|
||||
and: [],
|
||||
id: '111',
|
||||
name: 'data provider 1',
|
||||
enabled: true,
|
||||
queryMatch: {
|
||||
field: '',
|
||||
value: '',
|
||||
operator: IS_OPERATOR,
|
||||
},
|
||||
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
},
|
||||
{
|
||||
and: [],
|
||||
id: '222',
|
||||
name: 'data provider 2',
|
||||
enabled: true,
|
||||
queryMatch: {
|
||||
field: '',
|
||||
value: '',
|
||||
operator: IS_OPERATOR,
|
||||
},
|
||||
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
},
|
||||
{
|
||||
and: [],
|
||||
id: '333',
|
||||
name: 'data provider 3',
|
||||
enabled: true,
|
||||
queryMatch: {
|
||||
field: '',
|
||||
value: '',
|
||||
operator: IS_OPERATOR,
|
||||
},
|
||||
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
},
|
||||
];
|
||||
|
||||
const multiDataProviderMock = set('foo.dataProviders', dataProviders, timelineByIdMock);
|
||||
|
||||
const andDataProvider: DataProvidersAnd = {
|
||||
id: '211',
|
||||
name: 'And Data Provider',
|
||||
enabled: true,
|
||||
queryMatch: {
|
||||
field: '',
|
||||
value: '',
|
||||
operator: IS_OPERATOR,
|
||||
},
|
||||
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
};
|
||||
|
||||
const nestedMultiAndDataProviderMock = set(
|
||||
'foo.dataProviders[1].and',
|
||||
[andDataProvider],
|
||||
multiDataProviderMock
|
||||
);
|
||||
|
||||
const update = removeTimelineProvider({
|
||||
id: 'foo',
|
||||
providerId: '222',
|
||||
timelineById: nestedMultiAndDataProviderMock,
|
||||
});
|
||||
expect(update).toEqual(
|
||||
set(
|
||||
'foo.dataProviders',
|
||||
[
|
||||
nestedMultiAndDataProviderMock.foo.dataProviders[0],
|
||||
{ ...andDataProvider, and: [] },
|
||||
nestedMultiAndDataProviderMock.foo.dataProviders[2],
|
||||
],
|
||||
timelineByIdMock
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
test('should remove only the first provider and keep multiple nested andProviders', () => {
|
||||
const multiDataProvider: DataProvider[] = [
|
||||
{
|
||||
and: [
|
||||
{
|
||||
enabled: true,
|
||||
id: 'socket_closed-MSoH7GoB9v5HJNSHRYj1-user_name-root',
|
||||
name: 'root',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'user.name',
|
||||
value: 'root',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
{
|
||||
enabled: true,
|
||||
id: 'executed-yioH7GoB9v5HJNSHKnp5-auditd_result-success',
|
||||
name: 'success',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'auditd.result',
|
||||
value: 'success',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
],
|
||||
enabled: true,
|
||||
excluded: false,
|
||||
id: 'hosts-table-hostName-suricata-iowa',
|
||||
name: 'suricata-iowa',
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'host.name',
|
||||
value: 'suricata-iowa',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const multiDataProviderMock = set('foo.dataProviders', multiDataProvider, timelineByIdMock);
|
||||
|
||||
const update = removeTimelineProvider({
|
||||
id: 'foo',
|
||||
providerId: 'hosts-table-hostName-suricata-iowa',
|
||||
timelineById: multiDataProviderMock,
|
||||
});
|
||||
|
||||
expect(update).toEqual(
|
||||
set(
|
||||
'foo.dataProviders',
|
||||
[
|
||||
{
|
||||
enabled: true,
|
||||
id: 'socket_closed-MSoH7GoB9v5HJNSHRYj1-user_name-root',
|
||||
name: 'root',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'user.name',
|
||||
value: 'root',
|
||||
operator: ':',
|
||||
},
|
||||
and: [
|
||||
{
|
||||
enabled: true,
|
||||
id: 'executed-yioH7GoB9v5HJNSHKnp5-auditd_result-success',
|
||||
name: 'success',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'auditd.result',
|
||||
value: 'success',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
timelineByIdMock
|
||||
)
|
||||
);
|
||||
});
|
||||
test('should remove only the first AND provider when the first AND is deleted, and there are multiple andProviders', () => {
|
||||
const multiDataProvider: DataProvider[] = [
|
||||
{
|
||||
and: [
|
||||
{
|
||||
enabled: true,
|
||||
id: 'socket_closed-MSoH7GoB9v5HJNSHRYj1-user_name-root',
|
||||
name: 'root',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'user.name',
|
||||
value: 'root',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
{
|
||||
enabled: true,
|
||||
id: 'executed-yioH7GoB9v5HJNSHKnp5-auditd_result-success',
|
||||
name: 'success',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'auditd.result',
|
||||
value: 'success',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
],
|
||||
enabled: true,
|
||||
excluded: false,
|
||||
id: 'hosts-table-hostName-suricata-iowa',
|
||||
name: 'suricata-iowa',
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'host.name',
|
||||
value: 'suricata-iowa',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const multiDataProviderMock = set('foo.dataProviders', multiDataProvider, timelineByIdMock);
|
||||
|
||||
const update = removeTimelineProvider({
|
||||
andProviderId: 'socket_closed-MSoH7GoB9v5HJNSHRYj1-user_name-root',
|
||||
id: 'foo',
|
||||
providerId: 'hosts-table-hostName-suricata-iowa',
|
||||
timelineById: multiDataProviderMock,
|
||||
});
|
||||
|
||||
expect(update).toEqual(
|
||||
set(
|
||||
'foo.dataProviders',
|
||||
[
|
||||
{
|
||||
and: [
|
||||
{
|
||||
enabled: true,
|
||||
id: 'executed-yioH7GoB9v5HJNSHKnp5-auditd_result-success',
|
||||
name: 'success',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'auditd.result',
|
||||
value: 'success',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
],
|
||||
enabled: true,
|
||||
excluded: false,
|
||||
id: 'hosts-table-hostName-suricata-iowa',
|
||||
name: 'suricata-iowa',
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'host.name',
|
||||
value: 'suricata-iowa',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
],
|
||||
timelineByIdMock
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
test('should remove only the second AND provider when the second AND is deleted, and there are multiple andProviders', () => {
|
||||
const multiDataProvider: DataProvider[] = [
|
||||
{
|
||||
and: [
|
||||
{
|
||||
enabled: true,
|
||||
id: 'socket_closed-MSoH7GoB9v5HJNSHRYj1-user_name-root',
|
||||
name: 'root',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'user.name',
|
||||
value: 'root',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
{
|
||||
enabled: true,
|
||||
id: 'executed-yioH7GoB9v5HJNSHKnp5-auditd_result-success',
|
||||
name: 'success',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'auditd.result',
|
||||
value: 'success',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
],
|
||||
enabled: true,
|
||||
excluded: false,
|
||||
id: 'hosts-table-hostName-suricata-iowa',
|
||||
name: 'suricata-iowa',
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'host.name',
|
||||
value: 'suricata-iowa',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const multiDataProviderMock = set('foo.dataProviders', multiDataProvider, timelineByIdMock);
|
||||
|
||||
const update = removeTimelineProvider({
|
||||
andProviderId: 'executed-yioH7GoB9v5HJNSHKnp5-auditd_result-success',
|
||||
id: 'foo',
|
||||
providerId: 'hosts-table-hostName-suricata-iowa',
|
||||
timelineById: multiDataProviderMock,
|
||||
});
|
||||
|
||||
expect(update).toEqual(
|
||||
set(
|
||||
'foo.dataProviders',
|
||||
[
|
||||
{
|
||||
and: [
|
||||
{
|
||||
enabled: true,
|
||||
id: 'socket_closed-MSoH7GoB9v5HJNSHRYj1-user_name-root',
|
||||
name: 'root',
|
||||
excluded: false,
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'user.name',
|
||||
value: 'root',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
],
|
||||
enabled: true,
|
||||
excluded: false,
|
||||
id: 'hosts-table-hostName-suricata-iowa',
|
||||
name: 'suricata-iowa',
|
||||
kqlQuery: '',
|
||||
queryMatch: {
|
||||
field: 'host.name',
|
||||
value: 'suricata-iowa',
|
||||
operator: ':',
|
||||
},
|
||||
},
|
||||
],
|
||||
timelineByIdMock
|
||||
)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue