[Security Solution][lists] Adds tests for exception lists and items part 2 (#74815)

## Summary

This is the basics of end to end tests, so there could be a lot more, but this ties to cover the basics of the tests.

Test with:
```ts
node scripts/functional_tests --config x-pack/test/lists_api_integration/security_and_spaces/config.ts
```

Adds these tests for the route counter parts:
* create_exception_list_items.ts
* create_exception_lists.ts
* delete_exception_list_items.ts
* delete_exception_lists.ts
* find_exception_list_items.ts
* find_exception_lists.ts
* read_exception_list_items.ts
* read_exception_lists.ts
* update_exception_list_items.ts
* update_exception_lists.ts

Fixes a few minor strings, other tests, but no large bugs found with these tests

### Checklist

- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
This commit is contained in:
Frank Hassanabad 2020-08-12 22:32:05 -06:00 committed by GitHub
parent e2ef219a7c
commit db357a212d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 1444 additions and 46 deletions

View file

@ -8,6 +8,7 @@ import {
COMMENTS,
DESCRIPTION,
ENTRIES,
ITEM_ID,
ITEM_TYPE,
LIST_ID,
META,
@ -32,3 +33,26 @@ export const getCreateExceptionListItemSchemaMock = (): CreateExceptionListItemS
tags: TAGS,
type: ITEM_TYPE,
});
/**
* Useful for end to end testing
*/
export const getCreateExceptionListItemMinimalSchemaMock = (): CreateExceptionListItemSchema => ({
description: DESCRIPTION,
entries: ENTRIES,
item_id: ITEM_ID,
list_id: LIST_ID,
name: NAME,
type: ITEM_TYPE,
});
/**
* Useful for end to end testing
*/
export const getCreateExceptionListItemMinimalSchemaMockWithoutId = (): CreateExceptionListItemSchema => ({
description: DESCRIPTION,
entries: ENTRIES,
list_id: LIST_ID,
name: NAME,
type: ITEM_TYPE,
});

View file

@ -7,6 +7,7 @@
import {
DESCRIPTION,
ENDPOINT_TYPE,
LIST_ID,
META,
NAME,
NAMESPACE_TYPE,
@ -26,3 +27,22 @@ export const getCreateExceptionListSchemaMock = (): CreateExceptionListSchema =>
type: ENDPOINT_TYPE,
version: VERSION,
});
/**
* Useful for end to end testing
*/
export const getCreateExceptionListMinimalSchemaMock = (): CreateExceptionListSchema => ({
description: DESCRIPTION,
list_id: LIST_ID,
name: NAME,
type: ENDPOINT_TYPE,
});
/**
* Useful for end to end testing
*/
export const getCreateExceptionListMinimalSchemaMockWithoutId = (): CreateExceptionListSchema => ({
description: DESCRIPTION,
name: NAME,
type: ENDPOINT_TYPE,
});

View file

@ -9,6 +9,7 @@ import {
DESCRIPTION,
ENTRIES,
ID,
ITEM_ID,
ITEM_TYPE,
LIST_ITEM_ID,
META,
@ -34,3 +35,15 @@ export const getUpdateExceptionListItemSchemaMock = (): UpdateExceptionListItemS
tags: TAGS,
type: ITEM_TYPE,
});
/**
* Useful for end to end tests and other mechanisms which want to fill in the values
* after doing a get of the structure.
*/
export const getUpdateMinimalExceptionListItemSchemaMock = (): UpdateExceptionListItemSchema => ({
description: DESCRIPTION,
entries: ENTRIES,
item_id: ITEM_ID,
name: NAME,
type: ITEM_TYPE,
});

View file

@ -20,3 +20,14 @@ export const getUpdateExceptionListSchemaMock = (): UpdateExceptionListSchema =>
tags: ['malware'],
type: 'endpoint',
});
/**
* Useful for end to end tests and other mechanisms which want to fill in the values
* after doing a get of the structure.
*/
export const getUpdateMinimalExceptionListSchemaMock = (): UpdateExceptionListSchema => ({
description: DESCRIPTION,
list_id: LIST_ID,
name: NAME,
type: 'endpoint',
});

View file

@ -7,8 +7,11 @@ import {
COMMENTS,
DATE_NOW,
DESCRIPTION,
ELASTIC_USER,
ENTRIES,
ITEM_ID,
ITEM_TYPE,
LIST_ID,
META,
NAME,
NAMESPACE_TYPE,
@ -38,3 +41,24 @@ export const getExceptionListItemSchemaMock = (): ExceptionListItemSchema => ({
updated_at: DATE_NOW,
updated_by: USER,
});
/**
* This is useful for end to end tests where we remove the auto generated parts for comparisons
* such as created_at, updated_at, and id.
*/
export const getExceptionListItemResponseMockWithoutAutoGeneratedValues = (): Partial<
ExceptionListItemSchema
> => ({
_tags: [],
comments: [],
created_by: ELASTIC_USER,
description: DESCRIPTION,
entries: ENTRIES,
item_id: ITEM_ID,
list_id: LIST_ID,
name: NAME,
namespace_type: 'single',
tags: [],
type: ITEM_TYPE,
updated_by: ELASTIC_USER,
});

View file

@ -7,9 +7,12 @@
import {
DATE_NOW,
DESCRIPTION,
ELASTIC_USER,
ENDPOINT_TYPE,
IMMUTABLE,
LIST_ID,
META,
NAME,
TIE_BREAKER,
USER,
VERSION,
@ -18,6 +21,7 @@ import {
import { ENDPOINT_LIST_ID } from '../..';
import { ExceptionListSchema } from './exception_list_schema';
export const getExceptionListSchemaMock = (): ExceptionListSchema => ({
_tags: ['endpoint', 'process', 'malware', 'os:linux'],
_version: _VERSION,
@ -37,3 +41,23 @@ export const getExceptionListSchemaMock = (): ExceptionListSchema => ({
updated_by: 'user_name',
version: VERSION,
});
/**
* This is useful for end to end tests where we remove the auto generated parts for comparisons
* such as created_at, updated_at, and id.
*/
export const getExceptionResponseMockWithoutAutoGeneratedValues = (): Partial<
ExceptionListSchema
> => ({
_tags: [],
created_by: ELASTIC_USER,
description: DESCRIPTION,
immutable: IMMUTABLE,
list_id: LIST_ID,
name: NAME,
namespace_type: 'single',
tags: [],
type: ENDPOINT_TYPE,
updated_by: ELASTIC_USER,
version: VERSION,
});

View file

@ -57,7 +57,7 @@ export const createExceptionListItemRoute = (router: IRouter): void => {
});
if (exceptionList == null) {
return siemResponse.error({
body: `list id: "${listId}" does not exist`,
body: `exception list id: "${listId}" does not exist`,
statusCode: 404,
});
} else {

View file

@ -62,7 +62,7 @@ export const findExceptionListItemRoute = (router: IRouter): void => {
});
if (exceptionListItems == null) {
return siemResponse.error({
body: `list id: "${listId}" does not exist`,
body: `exception list id: "${listId}" does not exist`,
statusCode: 404,
});
}

View file

@ -54,39 +54,46 @@ export const updateExceptionListItemRoute = (router: IRouter): void => {
namespace_type: namespaceType,
tags,
} = request.body;
const exceptionLists = getExceptionListClient(context);
const exceptionListItem = await exceptionLists.updateExceptionListItem({
_tags,
_version,
comments,
description,
entries,
id,
itemId,
meta,
name,
namespaceType,
tags,
type,
});
if (exceptionListItem == null) {
if (id != null) {
return siemResponse.error({
body: `list item id: "${id}" not found`,
statusCode: 404,
});
} else {
return siemResponse.error({
body: `list item item_id: "${itemId}" not found`,
statusCode: 404,
});
}
if (id == null && itemId == null) {
return siemResponse.error({
body: 'either id or item_id need to be defined',
statusCode: 404,
});
} else {
const [validated, errors] = validate(exceptionListItem, exceptionListItemSchema);
if (errors != null) {
return siemResponse.error({ body: errors, statusCode: 500 });
const exceptionLists = getExceptionListClient(context);
const exceptionListItem = await exceptionLists.updateExceptionListItem({
_tags,
_version,
comments,
description,
entries,
id,
itemId,
meta,
name,
namespaceType,
tags,
type,
});
if (exceptionListItem == null) {
if (id != null) {
return siemResponse.error({
body: `exception list item id: "${id}" does not exist`,
statusCode: 404,
});
} else {
return siemResponse.error({
body: `exception list item item_id: "${itemId}" does not exist`,
statusCode: 404,
});
}
} else {
return response.ok({ body: validated ?? {} });
const [validated, errors] = validate(exceptionListItem, exceptionListItemSchema);
if (errors != null) {
return siemResponse.error({ body: errors, statusCode: 500 });
} else {
return response.ok({ body: validated ?? {} });
}
}
}
} catch (err) {

View file

@ -15,7 +15,7 @@ import {
updateExceptionListSchema,
} from '../../common/schemas';
import { getExceptionListClient } from './utils';
import { getErrorMessageExceptionList, getExceptionListClient } from './utils';
export const updateExceptionListRoute = (router: IRouter): void => {
router.put(
@ -50,7 +50,7 @@ export const updateExceptionListRoute = (router: IRouter): void => {
const exceptionLists = getExceptionListClient(context);
if (id == null && listId == null) {
return siemResponse.error({
body: `either id or list_id need to be defined`,
body: 'either id or list_id need to be defined',
statusCode: 404,
});
} else {
@ -69,7 +69,7 @@ export const updateExceptionListRoute = (router: IRouter): void => {
});
if (list == null) {
return siemResponse.error({
body: `exception list id: "${id}" not found`,
body: getErrorMessageExceptionList({ id, listId }),
statusCode: 404,
});
} else {

View file

@ -12,10 +12,10 @@ export const getErrorMessageExceptionList = ({
listId: string | undefined;
}): string => {
if (id != null) {
return `Exception list id: "${id}" does not exist`;
return `exception list id: "${id}" does not exist`;
} else if (listId != null) {
return `Exception list list_id: "${listId}" does not exist`;
return `exception list list_id: "${listId}" does not exist`;
} else {
return 'Exception list does not exist';
return 'exception list does not exist';
}
};

View file

@ -12,10 +12,10 @@ export const getErrorMessageExceptionListItem = ({
itemId: string | undefined;
}): string => {
if (id != null) {
return `Exception list item id: "${id}" does not exist`;
return `exception list item id: "${id}" does not exist`;
} else if (itemId != null) {
return `Exception list item list_id: "${itemId}" does not exist`;
return `exception list item item_id: "${itemId}" does not exist`;
} else {
return 'Exception list item does not exist';
return 'exception list item does not exist';
}
};

View file

@ -0,0 +1,119 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { ExceptionListItemSchema } from '../../../../plugins/lists/common';
import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock';
import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import {
getCreateExceptionListItemMinimalSchemaMock,
getCreateExceptionListItemMinimalSchemaMockWithoutId,
} from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock';
import {
EXCEPTION_LIST_ITEM_URL,
EXCEPTION_LIST_URL,
} from '../../../../plugins/lists/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
removeListItemServerGeneratedProperties,
removeExceptionListItemServerGeneratedProperties,
} from '../../utils';
import { deleteAllExceptions } from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const es = getService('es');
describe('create_exception_list_items', () => {
describe('validation errors', () => {
it('should give a 404 error that the exception list must exist first before being able to add a list item to the exception list', async () => {
const { body } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(404);
expect(body).to.eql({
message: 'exception list id: "some-list-id" does not exist',
status_code: 404,
});
});
});
describe('creating exception list items', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should create a simple exception list item with a list item id', async () => {
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(200);
const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(getExceptionListItemResponseMockWithoutAutoGeneratedValues());
});
it('should create a simple exception list item without an id', async () => {
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMockWithoutId())
.expect(200);
const bodyToCompare = removeListItemServerGeneratedProperties(body);
const outputList: Partial<ExceptionListItemSchema> = {
...getExceptionListItemResponseMockWithoutAutoGeneratedValues(),
item_id: body.item_id,
};
expect(bodyToCompare).to.eql(outputList);
});
it('should cause a 409 conflict if we attempt to create the same exception list item twice', async () => {
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(409);
expect(body).to.eql({
message: 'exception list item id: "some-list-item-id" already exists',
status_code: 409,
});
});
});
});
};

View file

@ -0,0 +1,77 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { ExceptionListSchema } from '../../../../plugins/lists/common';
import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock';
import {
getCreateExceptionListMinimalSchemaMock,
getCreateExceptionListMinimalSchemaMockWithoutId,
} from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const es = getService('es');
describe('create_exception_lists', () => {
describe('creating exception lists', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should create a simple exception list', async () => {
const { body } = await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(getExceptionResponseMockWithoutAutoGeneratedValues());
});
it('should create a simple exception list without a list_id', async () => {
const { body } = await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMockWithoutId())
.expect(200);
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
const outputtedList: Partial<ExceptionListSchema> = {
...getExceptionResponseMockWithoutAutoGeneratedValues(),
list_id: bodyToCompare.list_id,
};
expect(bodyToCompare).to.eql(outputtedList);
});
it('should cause a 409 conflict if we attempt to create the same list_id twice', async () => {
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(409);
expect(body).to.eql({
message: 'exception list id: "some-list-id" already exists',
status_code: 409,
});
});
});
});
};

View file

@ -0,0 +1,119 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { ExceptionListItemSchema } from '../../../../plugins/lists/common';
import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock';
import {
getCreateExceptionListItemMinimalSchemaMock,
getCreateExceptionListItemMinimalSchemaMockWithoutId,
} from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock';
import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
EXCEPTION_LIST_URL,
EXCEPTION_LIST_ITEM_URL,
} from '../../../../plugins/lists/common/constants';
import { deleteAllExceptions, removeExceptionListItemServerGeneratedProperties } from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const es = getService('es');
describe('delete_exception_list_items', () => {
describe('delete exception list items', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should delete a single exception list item by its item_id', async () => {
// create an exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// create an exception list item
await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(200);
// delete the exception list item by its item_id
const { body } = await supertest
.delete(
`${EXCEPTION_LIST_ITEM_URL}?item_id=${
getCreateExceptionListItemMinimalSchemaMock().item_id
}`
)
.set('kbn-xsrf', 'true')
.expect(200);
const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(getExceptionListItemResponseMockWithoutAutoGeneratedValues());
});
it('should delete a single exception list item using an auto generated id', async () => {
// create an exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// create an exception list item
const { body: bodyWithCreatedList } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMockWithoutId())
.expect(200);
// delete that exception list item by its auto-generated id
const { body } = await supertest
.delete(`${EXCEPTION_LIST_ITEM_URL}?id=${bodyWithCreatedList.id}`)
.set('kbn-xsrf', 'true')
.expect(200);
const outputtedList: Partial<ExceptionListItemSchema> = {
...getExceptionListItemResponseMockWithoutAutoGeneratedValues(),
item_id: body.item_id,
};
const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputtedList);
});
it('should return an error if the id does not exist when trying to delete it', async () => {
const { body } = await supertest
.delete(`${EXCEPTION_LIST_ITEM_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.expect(404);
expect(body).to.eql({
message: 'exception list item id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist',
status_code: 404,
});
});
it('should return an error if the item_id does not exist when trying to delete it', async () => {
const { body } = await supertest
.delete(`${EXCEPTION_LIST_ITEM_URL}?item_id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.expect(404);
expect(body).to.eql({
message:
'exception list item item_id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist',
status_code: 404,
});
});
});
});
};

View file

@ -0,0 +1,98 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { ExceptionListSchema } from '../../../../plugins/lists/common';
import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock';
import {
getCreateExceptionListMinimalSchemaMock,
getCreateExceptionListMinimalSchemaMockWithoutId,
} from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants';
import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const es = getService('es');
describe('delete_exception_lists', () => {
describe('delete exception lists', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should delete a single exception list by its list_id', async () => {
// create an exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// delete the exception list by its list id
const { body } = await supertest
.delete(
`${EXCEPTION_LIST_URL}?list_id=${getCreateExceptionListMinimalSchemaMock().list_id}`
)
.set('kbn-xsrf', 'true')
.expect(200);
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(getExceptionResponseMockWithoutAutoGeneratedValues());
});
it('should delete a single exception list using an auto generated id', async () => {
// create an exception list
const { body: bodyWithCreatedList } = await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMockWithoutId())
.expect(200);
// delete that list by its auto-generated id
const { body } = await supertest
.delete(`${EXCEPTION_LIST_URL}?id=${bodyWithCreatedList.id}`)
.set('kbn-xsrf', 'true')
.expect(200);
const outputtedList: Partial<ExceptionListSchema> = {
...getExceptionResponseMockWithoutAutoGeneratedValues(),
list_id: body.list_id,
};
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputtedList);
});
it('should return an error if the id does not exist when trying to delete it', async () => {
const { body } = await supertest
.delete(`${EXCEPTION_LIST_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.expect(404);
expect(body).to.eql({
message: 'exception list id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist',
status_code: 404,
});
});
it('should return an error if the list_id does not exist when trying to delete it', async () => {
const { body } = await supertest
.delete(`${EXCEPTION_LIST_URL}?list_id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.expect(404);
expect(body).to.eql({
message: 'exception list list_id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist',
status_code: 404,
});
});
});
});
};

View file

@ -96,8 +96,9 @@ export default ({ getService }: FtrProviderContext): void => {
.set('kbn-xsrf', 'true')
.expect(200)
.parse(binaryToString);
expect(body.toString()).to.eql('127.0.0.2\n127.0.0.1\n');
const bodyString = body.toString();
expect(bodyString.includes('127.0.0.1')).to.be(true);
expect(bodyString.includes('127.0.0.2')).to.be(true);
});
});
});

View file

@ -0,0 +1,105 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock';
import { getCreateExceptionListItemMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock';
import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
EXCEPTION_LIST_URL,
EXCEPTION_LIST_ITEM_URL,
} from '../../../../plugins/lists/common/constants';
import { deleteAllExceptions, removeExceptionListItemServerGeneratedProperties } from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('find_exception_list_items', () => {
describe('find exception list items', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should return an empty find body correctly if no exception list items are loaded', async () => {
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.get(
`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${
getCreateExceptionListMinimalSchemaMock().list_id
}`
)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql({
data: [],
page: 1,
per_page: 20,
total: 0,
});
});
it('should return 404 if given a list_id that does not exist', async () => {
const { body } = await supertest
.get(`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=non_exist`)
.set('kbn-xsrf', 'true')
.send()
.expect(404);
expect(body).to.eql({
message: 'exception list id: "non_exist" does not exist',
status_code: 404,
});
});
it('should return a single exception list item when a single exception list item is loaded from a find with defaults added', async () => {
// add the exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// add a single exception list item
await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(200);
// query the single exception list from _find
const { body } = await supertest
.get(
`${EXCEPTION_LIST_ITEM_URL}/_find?list_id=${
getCreateExceptionListMinimalSchemaMock().list_id
}`
)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
body.data = [removeExceptionListItemServerGeneratedProperties(body.data[0])];
expect(body).to.eql({
data: [getExceptionListItemResponseMockWithoutAutoGeneratedValues()],
page: 1,
per_page: 20,
total: 1,
});
});
});
});
};

View file

@ -0,0 +1,67 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock';
import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants';
import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('find_exception_lists', () => {
describe('find exception lists', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should return an empty find body correctly if no exception lists are loaded', async () => {
const { body } = await supertest
.get(`${EXCEPTION_LIST_URL}/_find`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql({
data: [],
page: 1,
per_page: 20,
total: 0,
});
});
it('should return a single exception list when a single exception list is loaded from a find with defaults added', async () => {
// add a single exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// query the single exception list from _find
const { body } = await supertest
.get(`${EXCEPTION_LIST_URL}/_find`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
body.data = [removeExceptionListServerGeneratedProperties(body.data[0])];
expect(body).to.eql({
data: [getExceptionResponseMockWithoutAutoGeneratedValues()],
page: 1,
per_page: 20,
total: 1,
});
});
});
});
};

View file

@ -45,7 +45,7 @@ export default ({ getService }: FtrProviderContext): void => {
});
});
describe('importing rules with an index', () => {
describe('importing lists with an index', () => {
beforeEach(async () => {
await createListsIndex(supertest);
});

View file

@ -23,5 +23,15 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
loadTestFile(require.resolve('./find_list_items'));
loadTestFile(require.resolve('./import_list_items'));
loadTestFile(require.resolve('./export_list_items'));
loadTestFile(require.resolve('./create_exception_lists'));
loadTestFile(require.resolve('./create_exception_list_items'));
loadTestFile(require.resolve('./read_exception_lists'));
loadTestFile(require.resolve('./read_exception_list_items'));
loadTestFile(require.resolve('./update_exception_lists'));
loadTestFile(require.resolve('./update_exception_list_items'));
loadTestFile(require.resolve('./delete_exception_lists'));
loadTestFile(require.resolve('./delete_exception_list_items'));
loadTestFile(require.resolve('./find_exception_lists'));
loadTestFile(require.resolve('./find_exception_list_items'));
});
};

View file

@ -0,0 +1,159 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock';
import {
getCreateExceptionListItemMinimalSchemaMock,
getCreateExceptionListItemMinimalSchemaMockWithoutId,
} from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock';
import { ExceptionListItemSchema } from '../../../../plugins/lists/common';
import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
EXCEPTION_LIST_URL,
EXCEPTION_LIST_ITEM_URL,
} from '../../../../plugins/lists/common/constants';
import { deleteAllExceptions, removeExceptionListItemServerGeneratedProperties } from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const es = getService('es');
describe('read_exception_list_items', () => {
describe('reading exception list items', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should be able to read a single exception list items using item_id', async () => {
// create a simple exception list to read
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(200);
const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(getExceptionListItemResponseMockWithoutAutoGeneratedValues());
});
it('should be able to read a single exception list item using id', async () => {
// create a simple exception list to read
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// create a simple exception list item to read
const { body: createListBody } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.get(`${EXCEPTION_LIST_ITEM_URL}?id=${createListBody.id}`)
.set('kbn-xsrf', 'true')
.expect(200);
const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(getExceptionListItemResponseMockWithoutAutoGeneratedValues());
});
it('should be able to read a single list item with an auto-generated id', async () => {
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// create a simple exception list item to read
const { body: createListBody } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMockWithoutId())
.expect(200);
const { body } = await supertest
.get(`${EXCEPTION_LIST_ITEM_URL}?id=${createListBody.id}`)
.set('kbn-xsrf', 'true')
.expect(200);
const outputtedList: Partial<ExceptionListItemSchema> = {
...getExceptionListItemResponseMockWithoutAutoGeneratedValues(),
item_id: body.item_id,
};
const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputtedList);
});
it('should be able to read a single list item with an auto-generated item_id', async () => {
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// create a simple exception list item to read
const { body: createListBody } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListItemMinimalSchemaMockWithoutId())
.expect(200);
const { body } = await supertest
.get(`${EXCEPTION_LIST_ITEM_URL}?item_id=${createListBody.item_id}`)
.set('kbn-xsrf', 'true')
.expect(200);
const outputtedList: Partial<ExceptionListItemSchema> = {
...getExceptionListItemResponseMockWithoutAutoGeneratedValues(),
item_id: body.item_id,
};
const bodyToCompare = removeExceptionListItemServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputtedList);
});
it('should return 404 if given a fake id', async () => {
const { body } = await supertest
.get(`${EXCEPTION_LIST_ITEM_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.expect(404);
expect(body).to.eql({
status_code: 404,
message: 'exception list item id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist',
});
});
it('should return 404 if given a fake list_id', async () => {
const { body } = await supertest
.get(`${EXCEPTION_LIST_ITEM_URL}?item_id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.expect(404);
expect(body).to.eql({
status_code: 404,
message:
'exception list item item_id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist',
});
});
});
});
};

View file

@ -0,0 +1,112 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { ExceptionListSchema } from '../../../../plugins/lists/common';
import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock';
import {
getCreateExceptionListMinimalSchemaMock,
getCreateExceptionListMinimalSchemaMockWithoutId,
} from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants';
import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const es = getService('es');
describe('read_exception_lists', () => {
describe('reading exception lists', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should be able to read a single exception list using list_id', async () => {
// create a simple exception list to read
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.get(`${EXCEPTION_LIST_URL}?list_id=${getCreateExceptionListMinimalSchemaMock().list_id}`)
.set('kbn-xsrf', 'true')
.expect(200);
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(getExceptionResponseMockWithoutAutoGeneratedValues());
});
it('should be able to read a single exception list using id', async () => {
// create a simple exception list to read
const { body: createListBody } = await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
const { body } = await supertest
.get(`${EXCEPTION_LIST_URL}?id=${createListBody.id}`)
.set('kbn-xsrf', 'true')
.expect(200);
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(getExceptionResponseMockWithoutAutoGeneratedValues());
});
it('should be able to read a single list with an auto-generated list_id', async () => {
// create a simple exception list to read
const { body: createListBody } = await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMockWithoutId())
.expect(200);
const { body } = await supertest
.get(`${EXCEPTION_LIST_URL}?list_id=${createListBody.list_id}`)
.set('kbn-xsrf', 'true')
.expect(200);
const outputtedList: Partial<ExceptionListSchema> = {
...getExceptionResponseMockWithoutAutoGeneratedValues(),
list_id: body.list_id,
};
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputtedList);
});
it('should return 404 if given a fake id', async () => {
const { body } = await supertest
.get(`${EXCEPTION_LIST_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.expect(404);
expect(body).to.eql({
status_code: 404,
message: 'exception list id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist',
});
});
it('should return 404 if given a fake list_id', async () => {
const { body } = await supertest
.get(`${EXCEPTION_LIST_URL}?list_id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.expect(404);
expect(body).to.eql({
status_code: 404,
message: 'exception list list_id: "c1e1b359-7ac1-4e96-bc81-c683c092436f" does not exist',
});
});
});
});
};

View file

@ -0,0 +1,168 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { getExceptionListItemResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_item_schema.mock';
import { getCreateExceptionListItemMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_item_schema.mock';
import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
EXCEPTION_LIST_URL,
EXCEPTION_LIST_ITEM_URL,
} from '../../../../plugins/lists/common/constants';
import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils';
import {
UpdateExceptionListItemSchema,
ExceptionListItemSchema,
} from '../../../../plugins/lists/common/schemas';
import { getUpdateMinimalExceptionListItemSchemaMock } from '../../../../plugins/lists/common/schemas/request/update_exception_list_item_schema.mock';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const es = getService('es');
describe('update_exception_list_items', () => {
describe('update exception list items', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should update a single exception list item property of name using an id', 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);
// update a exception list item's name
const updatedList: UpdateExceptionListItemSchema = {
...getUpdateMinimalExceptionListItemSchemaMock(),
name: 'some other name',
};
const { body } = await supertest
.put(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(200);
const outputList: Partial<ExceptionListItemSchema> = {
...getExceptionListItemResponseMockWithoutAutoGeneratedValues(),
name: 'some other name',
};
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputList);
});
it('should update a single exception list item property of name using an auto-generated item_id', async () => {
// create a simple exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// eslint-disable-next-line @typescript-eslint/naming-convention
const { item_id, ...itemNoId } = getCreateExceptionListItemMinimalSchemaMock();
// create a simple exception list item
const { body: createListBody } = await supertest
.post(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(itemNoId)
.expect(200);
// update a exception list item's name
const updatedList: UpdateExceptionListItemSchema = {
...getUpdateMinimalExceptionListItemSchemaMock(),
item_id: createListBody.item_id,
name: 'some other name',
};
const { body } = await supertest
.put(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(200);
const outputList: Partial<ExceptionListItemSchema> = {
...getExceptionListItemResponseMockWithoutAutoGeneratedValues(),
name: 'some other name',
item_id: body.item_id,
};
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputList);
});
it('should give a 404 if it is given a fake exception list item id', async () => {
const updatedList: UpdateExceptionListItemSchema = {
...getUpdateMinimalExceptionListItemSchemaMock(),
id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d',
};
delete updatedList.item_id;
const { body } = await supertest
.put(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(404);
expect(body).to.eql({
status_code: 404,
message: 'exception list item id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" does not exist',
});
});
it('should give a 404 if it is given a fake item_id', async () => {
const updatedList: UpdateExceptionListItemSchema = {
...getUpdateMinimalExceptionListItemSchemaMock(),
item_id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d',
};
const { body } = await supertest
.put(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(404);
expect(body).to.eql({
status_code: 404,
message:
'exception list item item_id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" does not exist',
});
});
it('should give a 404 if both id and list_id is null', async () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { item_id, ...listNoId } = getUpdateMinimalExceptionListItemSchemaMock();
const { body } = await supertest
.put(EXCEPTION_LIST_ITEM_URL)
.set('kbn-xsrf', 'true')
.send(listNoId)
.expect(404);
expect(body).to.eql({
status_code: 404,
message: 'either id or item_id need to be defined',
});
});
});
});
};

View file

@ -0,0 +1,182 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import expect from '@kbn/expect';
import { getExceptionResponseMockWithoutAutoGeneratedValues } from '../../../../plugins/lists/common/schemas/response/exception_list_schema.mock';
import { getCreateExceptionListMinimalSchemaMock } from '../../../../plugins/lists/common/schemas/request/create_exception_list_schema.mock';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { EXCEPTION_LIST_URL } from '../../../../plugins/lists/common/constants';
import { deleteAllExceptions, removeExceptionListServerGeneratedProperties } from '../../utils';
import {
UpdateExceptionListSchema,
ExceptionListSchema,
} from '../../../../plugins/lists/common/schemas';
import { getUpdateMinimalExceptionListSchemaMock } from '../../../../plugins/lists/common/schemas/request/update_exception_list_schema.mock';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const es = getService('es');
describe('update_exception_lists', () => {
describe('update exception lists', () => {
afterEach(async () => {
await deleteAllExceptions(es);
});
it('should update a single exception list property of name using an id', async () => {
// create a simple exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// update a exception list's name
const updatedList: UpdateExceptionListSchema = {
...getUpdateMinimalExceptionListSchemaMock(),
name: 'some other name',
};
const { body } = await supertest
.put(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(200);
const outputList: Partial<ExceptionListSchema> = {
...getExceptionResponseMockWithoutAutoGeneratedValues(),
name: 'some other name',
version: 2,
};
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputList);
});
it('should update a single exception list property of name using an auto-generated list_id', async () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { list_id, ...listNoId } = getCreateExceptionListMinimalSchemaMock();
// create a simple exception list
const { body: createListBody } = await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(listNoId)
.expect(200);
// update a exception list's name
const updatedList: UpdateExceptionListSchema = {
...getUpdateMinimalExceptionListSchemaMock(),
id: createListBody.id,
name: 'some other name',
};
const { body } = await supertest
.put(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(200);
const outputList: Partial<ExceptionListSchema> = {
...getExceptionResponseMockWithoutAutoGeneratedValues(),
name: 'some other name',
list_id: body.list_id,
version: 2,
};
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputList);
});
it('should change the version of a list when it updates two properties', async () => {
// create a simple exception list
await supertest
.post(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(getCreateExceptionListMinimalSchemaMock())
.expect(200);
// update a simple exception list property of name and description
// update a exception list's name
const updatedList: UpdateExceptionListSchema = {
...getUpdateMinimalExceptionListSchemaMock(),
name: 'some other name',
description: 'some other description',
};
const { body } = await supertest
.put(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(200);
const outputList: Partial<ExceptionListSchema> = {
...getExceptionResponseMockWithoutAutoGeneratedValues(),
name: 'some other name',
description: 'some other description',
version: 2,
};
const bodyToCompare = removeExceptionListServerGeneratedProperties(body);
expect(bodyToCompare).to.eql(outputList);
});
it('should give a 404 if it is given a fake id', async () => {
const updatedList: UpdateExceptionListSchema = {
...getUpdateMinimalExceptionListSchemaMock(),
id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d',
};
delete updatedList.list_id;
const { body } = await supertest
.put(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(404);
expect(body).to.eql({
status_code: 404,
message: 'exception list id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" does not exist',
});
});
it('should give a 404 if it is given a fake list_id', async () => {
const updatedList: UpdateExceptionListSchema = {
...getUpdateMinimalExceptionListSchemaMock(),
list_id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d',
};
const { body } = await supertest
.put(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(updatedList)
.expect(404);
expect(body).to.eql({
status_code: 404,
message: 'exception list list_id: "5096dec6-b6b9-4d8d-8f93-6c2602079d9d" does not exist',
});
});
it('should give a 404 if both id and list_id is null', async () => {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { list_id, ...listNoId } = getUpdateMinimalExceptionListSchemaMock();
const { body } = await supertest
.put(EXCEPTION_LIST_URL)
.set('kbn-xsrf', 'true')
.send(listNoId)
.expect(404);
expect(body).to.eql({
status_code: 404,
message: 'either id or list_id need to be defined',
});
});
});
});
};

View file

@ -6,8 +6,13 @@
import { SuperTest } from 'supertest';
import supertestAsPromised from 'supertest-as-promised';
import { Client } from '@elastic/elasticsearch';
import { ListItemSchema } from '../../plugins/lists/common/schemas';
import {
ListItemSchema,
ExceptionListSchema,
ExceptionListItemSchema,
} from '../../plugins/lists/common/schemas';
import { ListSchema } from '../../plugins/lists/common';
import { LIST_INDEX } from '../../plugins/lists/common/constants';
@ -83,6 +88,30 @@ export const removeListItemServerGeneratedProperties = (
return removedProperties;
};
/**
* This will remove server generated properties such as date times, etc...
* @param list List to pass in to remove typical server generated properties
*/
export const removeExceptionListItemServerGeneratedProperties = (
list: Partial<ExceptionListItemSchema>
): Partial<ExceptionListItemSchema> => {
/* eslint-disable-next-line @typescript-eslint/naming-convention */
const { created_at, updated_at, id, tie_breaker_id, _version, ...removedProperties } = list;
return removedProperties;
};
/**
* This will remove server generated properties such as date times, etc...
* @param list List to pass in to remove typical server generated properties
*/
export const removeExceptionListServerGeneratedProperties = (
list: Partial<ExceptionListSchema>
): Partial<ExceptionListSchema> => {
/* eslint-disable-next-line @typescript-eslint/naming-convention */
const { created_at, updated_at, id, tie_breaker_id, _version, ...removedProperties } = list;
return removedProperties;
};
// Similar to ReactJs's waitFor from here: https://testing-library.com/docs/dom-testing-library/api-async#waitfor
export const waitFor = async (
functionToTest: () => Promise<boolean>,
@ -124,3 +153,32 @@ export const binaryToString = (res: any, callback: any): void => {
callback(null, Buffer.from(res.data));
});
};
/**
* Remove all exceptions from the .kibana index
* This will retry 20 times before giving up and hopefully still not interfere with other tests
* @param es The ElasticSearch handle
*/
export const deleteAllExceptions = async (es: Client, retryCount = 20): Promise<void> => {
if (retryCount > 0) {
try {
await es.deleteByQuery({
index: '.kibana',
q: 'type:exception-list or type:exception-list-agnostic',
wait_for_completion: true,
refresh: true,
body: {},
});
} catch (err) {
// eslint-disable-next-line no-console
console.log(
`Failure trying to deleteAllExceptions, retries left are: ${retryCount - 1}`,
err
);
await deleteAllExceptions(es, retryCount - 1);
}
} else {
// eslint-disable-next-line no-console
console.log('Could not deleteAllExceptions, no retries are left');
}
};