[SIEM] [Cases] Case API tests (#65777)

This commit is contained in:
Steph Milovic 2020-05-11 14:27:02 -06:00 committed by GitHub
parent 56c46ae1de
commit 2082648678
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1580 additions and 33 deletions

View file

@ -0,0 +1,76 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../../plugins/case/common/constants';
import { postCaseReq, postCommentReq } from '../../../../common/lib/mock';
import { deleteCases, deleteCasesUserActions, deleteComments } from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('delete_comment', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteCasesUserActions(es);
});
it('should delete a comment', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body: comment } = await supertest
.delete(`${CASES_URL}/${postedCase.id}/comments/${patchedCase.comments[0].id}`)
.set('kbn-xsrf', 'true')
.send();
expect(comment).to.eql({});
});
it('unhappy path - 404s when comment belongs to different case', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body } = await supertest
.delete(`${CASES_URL}/fake-id/comments/${patchedCase.comments[0].id}`)
.set('kbn-xsrf', 'true')
.send()
.expect(404);
expect(body.message).to.eql(
`This comment ${patchedCase.comments[0].id} does not exist in fake-id).`
);
});
it('unhappy path - 404s when comment is not there', async () => {
await supertest
.delete(`${CASES_URL}/fake-id/comments/fake-id`)
.set('kbn-xsrf', 'true')
.send()
.expect(404);
});
});
};

View file

@ -0,0 +1,93 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../../plugins/case/common/constants';
import { postCaseReq, postCommentReq } from '../../../../common/lib/mock';
import { deleteCases, deleteCasesUserActions, deleteComments } from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('find_comments', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteCasesUserActions(es);
});
it('should find all case comment', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
// post 2 comments
await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body: caseComments } = await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/_find`)
.set('kbn-xsrf', 'true')
.send();
expect(caseComments.comments).to.eql(patchedCase.comments);
});
it('should filter case comments', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
// post 2 comments
await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send({ comment: 'unique' });
const { body: caseComments } = await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/_find?search=unique`)
.set('kbn-xsrf', 'true')
.send();
expect(caseComments.comments).to.eql([patchedCase.comments[1]]);
});
it('unhappy path - 400s when query is bad', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/_find?perPage=true`)
.set('kbn-xsrf', 'true')
.send()
.expect(400);
});
});
};

View file

@ -0,0 +1,53 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../../plugins/case/common/constants';
import { postCaseReq, postCommentReq } from '../../../../common/lib/mock';
import { deleteCases, deleteCasesUserActions, deleteComments } from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('get_comment', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteCasesUserActions(es);
});
it('should get a comment', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body: comment } = await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/${patchedCase.comments[0].id}`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(comment).to.eql(patchedCase.comments[0]);
});
it('unhappy path - 404s when comment is not there', async () => {
await supertest
.get(`${CASES_URL}/fake-id/comments/fake-comment`)
.set('kbn-xsrf', 'true')
.send()
.expect(404);
});
});
};

View file

@ -0,0 +1,123 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../../plugins/case/common/constants';
import { defaultUser, postCaseReq, postCommentReq } from '../../../../common/lib/mock';
import { deleteCases, deleteCasesUserActions, deleteComments } from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('patch_comment', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteCasesUserActions(es);
});
it('should patch a comment', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const newComment = 'Well I decided to update my comment. So what? Deal with it.';
const { body } = await supertest
.patch(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send({
id: patchedCase.comments[0].id,
version: patchedCase.comments[0].version,
comment: newComment,
});
expect(body.comments[0].comment).to.eql(newComment);
expect(body.updated_by).to.eql(defaultUser);
});
it('unhappy path - 404s when comment is not there', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
await supertest
.patch(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send({
id: 'id',
version: 'version',
comment: 'comment',
})
.expect(404);
});
it('unhappy path - 404s when case is not there', async () => {
await supertest
.patch(`${CASES_URL}/fake-id/comments`)
.set('kbn-xsrf', 'true')
.send({
id: 'id',
version: 'version',
comment: 'comment',
})
.expect(404);
});
it('unhappy path - 400s when patch body is bad', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
await supertest
.patch(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send({
id: patchedCase.comments[0].id,
version: patchedCase.comments[0].version,
comment: true,
})
.expect(400);
});
it('unhappy path - 409s when conflict', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const newComment = 'Well I decided to update my comment. So what? Deal with it.';
await supertest
.patch(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send({
id: patchedCase.comments[0].id,
version: 'version-mismatch',
comment: newComment,
})
.expect(409);
});
});
};

View file

@ -0,0 +1,57 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../../plugins/case/common/constants';
import { defaultUser, postCaseReq, postCommentReq } from '../../../../common/lib/mock';
import { deleteCases, deleteCasesUserActions, deleteComments } from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('post_comment', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteCasesUserActions(es);
});
it('should post a comment', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
expect(patchedCase.comments[0].comment).to.eql(postCommentReq.comment);
expect(patchedCase.updated_by).to.eql(defaultUser);
});
it('unhappy path - 400s when post body is bad', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send({
bad: 'comment',
})
.expect(400);
});
});
};

View file

@ -0,0 +1,76 @@
/*
* 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 { FtrProviderContext } from '../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../plugins/case/common/constants';
import { postCaseReq, postCommentReq } from '../../../common/lib/mock';
import { deleteCases, deleteCasesUserActions, deleteComments } from '../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('delete_cases', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteCasesUserActions(es);
});
it('should delete a case', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body } = await supertest
.delete(`${CASES_URL}?ids=["${postedCase.id}"]`)
.set('kbn-xsrf', 'true')
.send()
.expect(204);
expect(body).to.eql({});
});
it(`should delete a case's comments when that case gets deleted`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/${patchedCase.comments[0].id}`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
await supertest
.delete(`${CASES_URL}?ids=["${postedCase.id}"]`)
.set('kbn-xsrf', 'true')
.send()
.expect(204);
await supertest
.get(`${CASES_URL}/${postedCase.id}/comments/${patchedCase.comments[0].id}`)
.set('kbn-xsrf', 'true')
.send()
.expect(404);
});
it('unhappy path - 404s when case is not there', async () => {
await supertest
.delete(`${CASES_URL}?ids=["fake-id"]`)
.set('kbn-xsrf', 'true')
.send()
.expect(404);
});
});
};

View file

@ -0,0 +1,158 @@
/*
* 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 { FtrProviderContext } from '../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../plugins/case/common/constants';
import { postCaseReq, postCommentReq, findCasesResp } from '../../../common/lib/mock';
import { deleteCases, deleteComments, deleteCasesUserActions } from '../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('find_cases', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteCasesUserActions(es);
});
it('should return empty response', async () => {
const { body } = await supertest
.get(`${CASES_URL}/_find`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql(findCasesResp);
});
it('should return cases', async () => {
const { body: a } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body: b } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body: c } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body } = await supertest
.get(`${CASES_URL}/_find?sortOrder=asc`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql({
...findCasesResp,
total: 3,
cases: [a, b, c],
count_open_cases: 3,
});
});
it('filters by tags', async () => {
await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send({ ...postCaseReq, tags: ['unique'] });
const { body } = await supertest
.get(`${CASES_URL}/_find?sortOrder=asc&tags=unique`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql({
...findCasesResp,
total: 1,
cases: [postedCase],
count_open_cases: 1,
});
});
it('correctly counts comments', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
// post 2 comments
await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body } = await supertest
.get(`${CASES_URL}/_find?sortOrder=asc`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql({
...findCasesResp,
total: 1,
cases: [
{
...patchedCase,
comments: [],
totalComment: 2,
},
],
count_open_cases: 1,
});
});
it('correctly counts open/closed', async () => {
await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
status: 'closed',
},
],
})
.expect(200);
const { body } = await supertest
.get(`${CASES_URL}/_find?sortOrder=asc`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.count_open_cases).to.eql(1);
expect(body.count_closed_cases).to.eql(1);
});
it('unhappy path - 400s when bad query supplied', async () => {
await supertest
.get(`${CASES_URL}/_find?perPage=true`)
.set('kbn-xsrf', 'true')
.send()
.expect(400);
});
});
};

View file

@ -0,0 +1,52 @@
/*
* 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 { FtrProviderContext } from '../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../plugins/case/common/constants';
import {
postCaseReq,
postCaseResp,
removeServerGeneratedPropertiesFromCase,
} from '../../../common/lib/mock';
import { deleteCases } from '../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('get_case', () => {
afterEach(async () => {
await deleteCases(es);
});
it('should return a case', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
const data = removeServerGeneratedPropertiesFromCase(body);
expect(data).to.eql(postCaseResp(postedCase.id));
});
it('unhappy path - 404s when case is not there', async () => {
await supertest
.get(`${CASES_URL}/fake-id`)
.set('kbn-xsrf', 'true')
.send()
.expect(404);
});
});
};

View file

@ -0,0 +1,139 @@
/*
* 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 { FtrProviderContext } from '../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../plugins/case/common/constants';
import {
defaultUser,
postCaseReq,
postCaseResp,
removeServerGeneratedPropertiesFromCase,
} from '../../../common/lib/mock';
import { deleteCases, deleteCasesUserActions } from '../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('patch_cases', () => {
afterEach(async () => {
await deleteCases(es);
await deleteCasesUserActions(es);
});
it('should patch a case', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body: patchedCases } = await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
status: 'closed',
},
],
})
.expect(200);
const data = removeServerGeneratedPropertiesFromCase(patchedCases[0]);
expect(data).to.eql({
...postCaseResp(postedCase.id),
closed_by: defaultUser,
status: 'closed',
updated_by: defaultUser,
});
});
it('unhappy path - 404s when case is not there', async () => {
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: 'not-real',
version: 'version',
status: 'closed',
},
],
})
.expect(404);
});
it('unhappy path - 406s when excess data sent', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
badKey: 'closed',
},
],
})
.expect(406);
});
it('unhappy path - 400s when bad data sent', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
status: true,
},
],
})
.expect(400);
});
it('unhappy path - 409s when conflict', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
await supertest
.patch(`${CASES_URL}`)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: 'version',
status: 'closed',
},
],
})
.expect(409);
});
});
};

View file

@ -0,0 +1,46 @@
/*
* 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 { FtrProviderContext } from '../../../common/ftr_provider_context';
import { CASES_URL } from '../../../../../plugins/case/common/constants';
import {
postCaseReq,
postCaseResp,
removeServerGeneratedPropertiesFromCase,
} from '../../../common/lib/mock';
import { deleteCases } from '../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('post_case', () => {
afterEach(async () => {
await deleteCases(es);
});
it('should post a case', async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const data = removeServerGeneratedPropertiesFromCase(postedCase);
expect(data).to.eql(postCaseResp(postedCase.id));
});
it('unhappy path - 400s when bad query supplied', async () => {
await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send({ ...postCaseReq, badKey: true })
.expect(400);
});
});
};

View file

@ -0,0 +1,161 @@
/*
* 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 { FtrProviderContext } from '../../../common/ftr_provider_context';
import { CASE_CONFIGURE_URL, CASES_URL } from '../../../../../plugins/case/common/constants';
import { postCaseReq, defaultUser, postCommentReq } from '../../../common/lib/mock';
import {
deleteCases,
deleteCasesUserActions,
deleteComments,
deleteConfiguration,
getConfiguration,
} from '../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('push_case', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteConfiguration(es);
await deleteCasesUserActions(es);
});
it('should push a case', async () => {
const { body: configure } = await supertest
.post(CASE_CONFIGURE_URL)
.set('kbn-xsrf', 'true')
.send(getConfiguration())
.expect(200);
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body } = await supertest
.post(`${CASES_URL}/${postedCase.id}/_push`)
.set('kbn-xsrf', 'true')
.send({
connector_id: configure.connector_id,
connector_name: configure.connector_name,
external_id: 'external_id',
external_title: 'external_title',
external_url: 'external_url',
})
.expect(200);
expect(body.connector_id).to.eql(configure.connector_id);
expect(body.external_service.pushed_by).to.eql(defaultUser);
});
it('pushes a comment appropriately', async () => {
const { body: configure } = await supertest
.post(CASE_CONFIGURE_URL)
.set('kbn-xsrf', 'true')
.send(getConfiguration())
.expect(200);
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
await supertest
.post(`${CASES_URL}/${postedCase.id}/_push`)
.set('kbn-xsrf', 'true')
.send({
connector_id: configure.connector_id,
connector_name: configure.connector_name,
external_id: 'external_id',
external_title: 'external_title',
external_url: 'external_url',
})
.expect(200);
await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body } = await supertest
.post(`${CASES_URL}/${postedCase.id}/_push`)
.set('kbn-xsrf', 'true')
.send({
connector_id: configure.connector_id,
connector_name: configure.connector_name,
external_id: 'external_id',
external_title: 'external_title',
external_url: 'external_url',
})
.expect(200);
expect(body.comments[0].pushed_by).to.eql(defaultUser);
});
it('unhappy path - 404s when case does not exist', async () => {
await supertest
.post(`${CASES_URL}/fake-id/_push`)
.set('kbn-xsrf', 'true')
.send({
connector_id: 'connector_id',
connector_name: 'connector_name',
external_id: 'external_id',
external_title: 'external_title',
external_url: 'external_url',
})
.expect(404);
});
it('unhappy path - 400s when bad data supplied', async () => {
await supertest
.post(`${CASES_URL}/fake-id/_push`)
.set('kbn-xsrf', 'true')
.send({
badKey: 'connector_id',
})
.expect(400);
});
it('unhappy path = 409s when case is closed', async () => {
const { body: configure } = await supertest
.post(CASE_CONFIGURE_URL)
.set('kbn-xsrf', 'true')
.send(getConfiguration())
.expect(200);
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
status: 'closed',
},
],
})
.expect(200);
await supertest
.post(`${CASES_URL}/${postedCase.id}/_push`)
.set('kbn-xsrf', 'true')
.send({
connector_id: configure.connector_id,
connector_name: configure.connector_name,
external_id: 'external_id',
external_title: 'external_title',
external_url: 'external_url',
})
.expect(409);
});
});
};

View file

@ -0,0 +1,40 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASES_URL, CASE_REPORTERS_URL } from '../../../../../../plugins/case/common/constants';
import { defaultUser, postCaseReq } from '../../../../common/lib/mock';
import { deleteCases } from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('get_reporters', () => {
afterEach(async () => {
await deleteCases(es);
});
it('should return reporters', async () => {
await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq)
.expect(200);
const { body } = await supertest
.get(CASE_REPORTERS_URL)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql([defaultUser]);
});
});
};

View file

@ -0,0 +1,59 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASES_URL, CASE_STATUS_URL } from '../../../../../../plugins/case/common/constants';
import { postCaseReq } from '../../../../common/lib/mock';
import { deleteCases } from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('get_status', () => {
afterEach(async () => {
await deleteCases(es);
});
it('should return case statuses', async () => {
await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
status: 'closed',
},
],
})
.expect(200);
const { body } = await supertest
.get(CASE_STATUS_URL)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql({
count_open_cases: 1,
count_closed_cases: 1,
});
});
});
};

View file

@ -0,0 +1,43 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASES_URL, CASE_TAGS_URL } from '../../../../../../plugins/case/common/constants';
import { postCaseReq } from '../../../../common/lib/mock';
import { deleteCases } from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('get_tags', () => {
afterEach(async () => {
await deleteCases(es);
});
it('should return case tags', async () => {
await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send({ ...postCaseReq, tags: ['unique'] });
const { body } = await supertest
.get(CASE_TAGS_URL)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body).to.eql(['defacement', 'unique']);
});
});
};

View file

@ -0,0 +1,307 @@
/*
* 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 { FtrProviderContext } from '../../../../common/ftr_provider_context';
import { CASE_CONFIGURE_URL, CASES_URL } from '../../../../../../plugins/case/common/constants';
import { defaultUser, postCaseReq, postCommentReq } from '../../../../common/lib/mock';
import {
deleteCases,
deleteCasesUserActions,
deleteComments,
deleteConfiguration,
getConfiguration,
} from '../../../../common/lib/utils';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const es = getService('es');
describe('get_all_user_actions', () => {
afterEach(async () => {
await deleteCases(es);
await deleteComments(es);
await deleteConfiguration(es);
await deleteCasesUserActions(es);
});
it(`on new case, user action: 'create' should be called with actionFields: ['description', 'status', 'tags', 'title']`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(1);
expect(body[0].action_field).to.eql(['description', 'status', 'tags', 'title']);
expect(body[0].action).to.eql('create');
expect(body[0].old_value).to.eql(null);
expect(body[0].new_value).to.eql(JSON.stringify(postCaseReq));
});
it(`on close case, user action: 'update' should be called with actionFields: ['status']`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
status: 'closed',
},
],
})
.expect(200);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(2);
expect(body[1].action_field).to.eql(['status']);
expect(body[1].action).to.eql('update');
expect(body[1].old_value).to.eql('open');
expect(body[1].new_value).to.eql('closed');
});
it(`on update case connector, user action: 'update' should be called with actionFields: ['connector_id']`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const newConnectorId = '12345';
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
connector_id: newConnectorId,
},
],
})
.expect(200);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(2);
expect(body[1].action_field).to.eql(['connector_id']);
expect(body[1].action).to.eql('update');
expect(body[1].old_value).to.eql('none');
expect(body[1].new_value).to.eql(newConnectorId);
});
it(`on update tags, user action: 'add' and 'delete' should be called with actionFields: ['tags']`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
tags: ['cool', 'neat'],
},
],
})
.expect(200);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(3);
expect(body[1].action_field).to.eql(['tags']);
expect(body[1].action).to.eql('add');
expect(body[1].old_value).to.eql(null);
expect(body[1].new_value).to.eql('cool, neat');
expect(body[2].action_field).to.eql(['tags']);
expect(body[2].action).to.eql('delete');
expect(body[2].old_value).to.eql(null);
expect(body[2].new_value).to.eql('defacement');
});
it(`on update title, user action: 'update' should be called with actionFields: ['title']`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const newTitle = 'Such a great title';
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
title: newTitle,
},
],
})
.expect(200);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(2);
expect(body[1].action_field).to.eql(['title']);
expect(body[1].action).to.eql('update');
expect(body[1].old_value).to.eql(postCaseReq.title);
expect(body[1].new_value).to.eql(newTitle);
});
it(`on update description, user action: 'update' should be called with actionFields: ['description']`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const newDesc = 'Such a great description';
await supertest
.patch(CASES_URL)
.set('kbn-xsrf', 'true')
.send({
cases: [
{
id: postedCase.id,
version: postedCase.version,
description: newDesc,
},
],
})
.expect(200);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(2);
expect(body[1].action_field).to.eql(['description']);
expect(body[1].action).to.eql('update');
expect(body[1].old_value).to.eql(postCaseReq.description);
expect(body[1].new_value).to.eql(newDesc);
});
it(`on new comment, user action: 'create' should be called with actionFields: ['comments']`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(2);
expect(body[1].action_field).to.eql(['comment']);
expect(body[1].action).to.eql('create');
expect(body[1].old_value).to.eql(null);
expect(body[1].new_value).to.eql(postCommentReq.comment);
});
it(`on update comment, user action: 'update' should be called with actionFields: ['comments']`, async () => {
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
const { body: patchedCase } = await supertest
.post(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send(postCommentReq);
const newComment = 'Well I decided to update my comment. So what? Deal with it.';
await supertest
.patch(`${CASES_URL}/${postedCase.id}/comments`)
.set('kbn-xsrf', 'true')
.send({
id: patchedCase.comments[0].id,
version: patchedCase.comments[0].version,
comment: newComment,
});
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(3);
expect(body[2].action_field).to.eql(['comment']);
expect(body[2].action).to.eql('update');
expect(body[2].old_value).to.eql(postCommentReq.comment);
expect(body[2].new_value).to.eql(newComment);
});
it(`on new push to service, user action: 'push-to-service' should be called with actionFields: ['pushed']`, async () => {
const { body: configure } = await supertest
.post(CASE_CONFIGURE_URL)
.set('kbn-xsrf', 'true')
.send(getConfiguration())
.expect(200);
const { body: postedCase } = await supertest
.post(CASES_URL)
.set('kbn-xsrf', 'true')
.send(postCaseReq);
await supertest
.post(`${CASES_URL}/${postedCase.id}/_push`)
.set('kbn-xsrf', 'true')
.send({
connector_id: configure.connector_id,
connector_name: configure.connector_name,
external_id: 'external_id',
external_title: 'external_title',
external_url: 'external_url',
})
.expect(200);
const { body } = await supertest
.get(`${CASES_URL}/${postedCase.id}/user_actions`)
.set('kbn-xsrf', 'true')
.send()
.expect(200);
expect(body.length).to.eql(2);
expect(body[1].action_field).to.eql(['pushed']);
expect(body[1].action).to.eql('push-to-service');
expect(body[1].old_value).to.eql(null);
const newValue = JSON.parse(body[1].new_value);
expect(newValue.connector_id).to.eql(configure.connector_id);
expect(newValue.pushed_by).to.eql(defaultUser);
});
});
};

View file

@ -12,9 +12,24 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
// Fastest ciGroup for the moment.
this.tags('ciGroup2');
loadTestFile(require.resolve('./cases/comments/delete_comment'));
loadTestFile(require.resolve('./cases/comments/find_comments'));
loadTestFile(require.resolve('./cases/comments/get_comment'));
loadTestFile(require.resolve('./cases/comments/patch_comment'));
loadTestFile(require.resolve('./cases/comments/post_comment'));
loadTestFile(require.resolve('./cases/delete_cases'));
loadTestFile(require.resolve('./cases/find_cases'));
loadTestFile(require.resolve('./cases/get_case'));
loadTestFile(require.resolve('./cases/patch_cases'));
loadTestFile(require.resolve('./cases/post_case'));
loadTestFile(require.resolve('./cases/push_case'));
loadTestFile(require.resolve('./cases/reporters/get_reporters'));
loadTestFile(require.resolve('./cases/status/get_status'));
loadTestFile(require.resolve('./cases/tags/get_tags'));
loadTestFile(require.resolve('./cases/user_actions/get_all_user_actions'));
loadTestFile(require.resolve('./configure/get_configure'));
loadTestFile(require.resolve('./configure/post_configure'));
loadTestFile(require.resolve('./configure/patch_configure'));
loadTestFile(require.resolve('./configure/get_connectors'));
loadTestFile(require.resolve('./configure/patch_configure'));
loadTestFile(require.resolve('./configure/post_configure'));
});
};

View file

@ -0,0 +1,50 @@
/*
* 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 {
CasePostRequest,
CaseResponse,
CasesFindResponse,
} from '../../../../plugins/case/common/api';
export const defaultUser = { email: null, full_name: null, username: 'elastic' };
export const postCaseReq: CasePostRequest = {
description: 'This is a brand new case of a bad meanie defacing data',
title: 'Super Bad Security Issue',
tags: ['defacement'],
};
export const postCommentReq: { comment: string } = {
comment: 'This is a cool comment',
};
export const postCaseResp = (id: string): Partial<CaseResponse> => ({
...postCaseReq,
id,
comments: [],
totalComment: 0,
connector_id: 'none',
closed_by: null,
created_by: defaultUser,
external_service: null,
status: 'open',
updated_by: null,
});
export const removeServerGeneratedPropertiesFromCase = (
config: Partial<CaseResponse>
): Partial<CaseResponse> => {
const { closed_at, created_at, updated_at, version, ...rest } = config;
return rest;
};
export const findCasesResp: CasesFindResponse = {
page: 1,
per_page: 20,
total: 0,
cases: [],
count_open_cases: 0,
count_closed_cases: 0,
};

View file

@ -30,6 +30,36 @@ export const removeServerGeneratedPropertiesFromConfigure = (
return rest;
};
export const deleteCasesUserActions = async (es: Client): Promise<void> => {
await es.deleteByQuery({
index: '.kibana',
q: 'type:cases-user-actions',
wait_for_completion: true,
refresh: true,
body: {},
});
};
export const deleteCases = async (es: Client): Promise<void> => {
await es.deleteByQuery({
index: '.kibana',
q: 'type:cases',
wait_for_completion: true,
refresh: true,
body: {},
});
};
export const deleteComments = async (es: Client): Promise<void> => {
await es.deleteByQuery({
index: '.kibana',
q: 'type:cases-comments',
wait_for_completion: true,
refresh: true,
body: {},
});
};
export const deleteConfiguration = async (es: Client): Promise<void> => {
await es.deleteByQuery({
index: '.kibana',
@ -39,34 +69,3 @@ export const deleteConfiguration = async (es: Client): Promise<void> => {
body: {},
});
};
export const getConnector = () => ({
name: 'ServiceNow Connector',
actionTypeId: '.servicenow',
secrets: {
username: 'admin',
password: 'admin',
},
config: {
apiUrl: 'localhost',
casesConfiguration: {
mapping: [
{
source: 'title',
target: 'short_description',
actionType: 'overwrite',
},
{
source: 'description',
target: 'description',
actionType: 'overwrite',
},
{
source: 'comments',
target: 'comments',
actionType: 'append',
},
],
},
},
});