[Detection Engine][Exceptions] - Fix exception item update route (#159223)

## Summary

Addresses issue 159230
This commit is contained in:
Yara Tercero 2023-06-09 12:31:03 -07:00 committed by GitHub
parent e82005e0d6
commit f895c5c205
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 198 additions and 5 deletions

View file

@ -9,7 +9,7 @@
"operator": "included"
}
],
"item_id": "993f43f7-325d-4df3-9338-964e77c37053",
"item_id": "simple_list_item",
"name": "Test comments - exception list item",
"namespace_type": "single",
"tags": [],

View file

@ -59,7 +59,7 @@ export const updateOverwriteExceptionListItem = async ({
entries,
expire_time: expireTime,
immutable: undefined,
item_id: itemId,
item_id: itemId ?? exceptionListItem.item_id,
list_id: exceptionListItem.list_id,
list_type: 'item',
meta,
@ -72,7 +72,7 @@ export const updateOverwriteExceptionListItem = async ({
version: exceptionListItem._version ? parseInt(exceptionListItem._version, 10) : undefined,
},
{
id,
id: id ?? exceptionListItem.id,
overwrite: true,
version: _version,
}

View file

@ -13,12 +13,19 @@ import type {
} from '@kbn/securitysolution-io-ts-list-types';
import { EXCEPTION_LIST_URL, EXCEPTION_LIST_ITEM_URL } from '@kbn/securitysolution-list-constants';
import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '@kbn/lists-plugin/common/schemas/response/exception_list_item_schema.mock';
import { getCreateExceptionListItemMinimalSchemaMock } from '@kbn/lists-plugin/common/schemas/request/create_exception_list_item_schema.mock';
import {
getCreateExceptionListItemMinimalSchemaMock,
getCreateExceptionListItemSchemaMock,
} from '@kbn/lists-plugin/common/schemas/request/create_exception_list_item_schema.mock';
import { getCreateExceptionListMinimalSchemaMock } from '@kbn/lists-plugin/common/schemas/request/create_exception_list_schema.mock';
import { getUpdateMinimalExceptionListItemSchemaMock } from '@kbn/lists-plugin/common/schemas/request/update_exception_list_item_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils';
import {
deleteAllExceptions,
removeExceptionListItemServerGeneratedProperties,
removeExceptionListServerGeneratedProperties,
} from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
@ -31,6 +38,192 @@ export default ({ getService }: FtrProviderContext) => {
await deleteAllExceptions(supertest, log);
});
describe('regressions', () => {
it('updates an item via its item_id without side effects', async () => {
// create a simple exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// create a simple exception list item
await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(200);
const { body: items } = await supertest
.get(
`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${
getCreateExceptionListMinimalSchemaMock().list_id
}`
)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(items.total).to.eql(1);
const [item] = items.data;
const expectedId = item.id;
const expectedItemId = item.item_id;
// update an exception list item's name, specifying its item_id
const updatePayload: UpdateExceptionListItemSchema = {
...getUpdateMinimalExceptionListItemSchemaMock(),
name: 'some other name',
};
await supertest
.put(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(updatePayload)
.expect(200);
const { body: itemsAfterUpdate } = await supertest
.get(
`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${
getCreateExceptionListMinimalSchemaMock().list_id
}`
)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
// Validate that we have a single exception item with the expected properties
expect(itemsAfterUpdate.total).to.eql(1);
const [updatedItem] = itemsAfterUpdate.data;
expect(updatedItem.name).to.eql('some other name');
expect(updatedItem.id?.length).to.be.greaterThan(0);
expect(updatedItem.id).to.equal(expectedId);
expect(updatedItem.item_id?.length).to.be.greaterThan(0);
expect(updatedItem.item_id).to.equal(expectedItemId);
});
it('updates an item via its id without side effects', async () => {
// create a simple exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// create a simple exception list item
await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(200);
const { body: items } = await supertest
.get(
`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${
getCreateExceptionListMinimalSchemaMock().list_id
}`
)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(items.total).to.eql(1);
const [item] = items.data;
const expectedId = item.id;
const expectedItemId = item.item_id;
// update an exception list item's name, specifying its id
const { item_id: _, ...updateItemWithoutItemId } =
getUpdateMinimalExceptionListItemSchemaMock();
const updatePayload: UpdateExceptionListItemSchema = {
...updateItemWithoutItemId,
name: 'some other name',
id: expectedId,
};
await supertest
.put(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(updatePayload)
.expect(200);
const { body: itemsAfterUpdate } = await supertest
.get(
`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${
getCreateExceptionListMinimalSchemaMock().list_id
}`
)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
// Validate that we have a single exception item with the expected properties
expect(itemsAfterUpdate.total).to.eql(1);
const [updatedItem] = itemsAfterUpdate.data;
expect(updatedItem.name).to.eql('some other name');
expect(updatedItem.id?.length).to.be.greaterThan(0);
expect(updatedItem.id).to.equal(expectedId);
expect(updatedItem.item_id?.length).to.be.greaterThan(0);
expect(updatedItem.item_id).to.equal(expectedItemId);
});
it('preserves optional fields that are unspecified in the request, a la PATCH semantics', async () => {
// create a simple exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// create a simple exception list item
const { meta, ...createPayload } = {
...getCreateExceptionListItemSchemaMock(),
comments: [
{
comment: 'Im an old comment',
},
],
};
await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(createPayload)
.expect(200);
const { body: items } = await supertest
.get(`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${createPayload.list_id}`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(items.total).to.eql(1);
const [item] = items.data;
// Perform an update with only required fields. If any fields change on the item, then they're not really optional.
const { item_id: _, ...updatePayload } = {
...getUpdateMinimalExceptionListItemSchemaMock(),
id: item.id,
};
await supertest
.put(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(updatePayload)
.expect(200);
const { body: itemsAfterUpdate } = await supertest
.get(`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${createPayload.list_id}`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
// Validate that we have a single exception item with the expected properties
expect(itemsAfterUpdate.total).to.eql(1);
const [updatedItem] = itemsAfterUpdate.data;
expect(updatedItem.id).to.eql(item.id);
expect(removeExceptionListItemServerGeneratedProperties(updatedItem)).to.eql(
removeExceptionListItemServerGeneratedProperties(item)
);
});
});
it('should update a single exception list item property of name using an id', async () => {
// create a simple exception list
await supertest