Allowing deletion of collections (#91926)
This commit is contained in:
parent
eea6f82e4e
commit
a108469ec7
|
@ -8,43 +8,12 @@
|
|||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import { SavedObjectsClientContract } from 'src/core/server';
|
||||
import { CaseType } from '../../../../common/api';
|
||||
import { buildCaseUserActionItem } from '../../../services/user_actions/helpers';
|
||||
import { RouteDeps } from '../types';
|
||||
import { wrapError } from '../utils';
|
||||
import { CASES_URL } from '../../../../common/constants';
|
||||
import { CaseServiceSetup } from '../../../services';
|
||||
|
||||
async function unremovableCases({
|
||||
caseService,
|
||||
client,
|
||||
ids,
|
||||
force,
|
||||
}: {
|
||||
caseService: CaseServiceSetup;
|
||||
client: SavedObjectsClientContract;
|
||||
ids: string[];
|
||||
force: boolean | undefined;
|
||||
}): Promise<string[]> {
|
||||
// if the force flag was included then we can skip checking whether the cases are collections and go ahead
|
||||
// and delete them
|
||||
if (force) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const cases = await caseService.getCases({ caseIds: ids, client });
|
||||
const parentCases = cases.saved_objects.filter(
|
||||
/**
|
||||
* getCases will return an array of saved_objects and some can be successful cases where as others
|
||||
* might have failed to find the ID. If it fails to find it, it will set the error field but not
|
||||
* the attributes so check that we didn't receive an error.
|
||||
*/
|
||||
(caseObj) => !caseObj.error && caseObj.attributes.type === CaseType.collection
|
||||
);
|
||||
|
||||
return parentCases.map((parentCase) => parentCase.id);
|
||||
}
|
||||
|
||||
async function deleteSubCases({
|
||||
caseService,
|
||||
client,
|
||||
|
@ -84,25 +53,12 @@ export function initDeleteCasesApi({ caseService, router, userActionService }: R
|
|||
validate: {
|
||||
query: schema.object({
|
||||
ids: schema.arrayOf(schema.string()),
|
||||
force: schema.maybe(schema.boolean()),
|
||||
}),
|
||||
},
|
||||
},
|
||||
async (context, request, response) => {
|
||||
try {
|
||||
const client = context.core.savedObjects.client;
|
||||
const unremovable = await unremovableCases({
|
||||
caseService,
|
||||
client,
|
||||
ids: request.query.ids,
|
||||
force: request.query.force,
|
||||
});
|
||||
|
||||
if (unremovable.length > 0) {
|
||||
return response.badRequest({
|
||||
body: `Case IDs: [${unremovable.join(' ,')}] are not removable`,
|
||||
});
|
||||
}
|
||||
await Promise.all(
|
||||
request.query.ids.map((id) =>
|
||||
caseService.deleteCase({
|
||||
|
|
|
@ -10,7 +10,17 @@ import { FtrProviderContext } from '../../../common/ftr_provider_context';
|
|||
|
||||
import { CASES_URL } from '../../../../../plugins/case/common/constants';
|
||||
import { postCaseReq, postCommentUserReq } from '../../../common/lib/mock';
|
||||
import { deleteCases, deleteCasesUserActions, deleteComments } from '../../../common/lib/utils';
|
||||
import {
|
||||
createCaseAction,
|
||||
createSubCase,
|
||||
deleteAllCaseItems,
|
||||
deleteCaseAction,
|
||||
deleteCases,
|
||||
deleteCasesUserActions,
|
||||
deleteComments,
|
||||
} from '../../../common/lib/utils';
|
||||
import { getSubCaseDetailsUrl } from '../../../../../plugins/case/common/api/helpers';
|
||||
import { CollectionWithSubCaseResponse } from '../../../../../plugins/case/common/api';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext): void => {
|
||||
|
@ -79,5 +89,64 @@ export default ({ getService }: FtrProviderContext): void => {
|
|||
.send()
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
describe('sub cases', () => {
|
||||
let actionID: string;
|
||||
before(async () => {
|
||||
actionID = await createCaseAction(supertest);
|
||||
});
|
||||
after(async () => {
|
||||
await deleteCaseAction(supertest, actionID);
|
||||
});
|
||||
afterEach(async () => {
|
||||
await deleteAllCaseItems(es);
|
||||
});
|
||||
|
||||
it('should delete the sub cases when deleting a collection', async () => {
|
||||
const { newSubCaseInfo: caseInfo } = await createSubCase({ supertest, actionID });
|
||||
expect(caseInfo.subCase?.id).to.not.eql(undefined);
|
||||
|
||||
const { body } = await supertest
|
||||
.delete(`${CASES_URL}?ids=["${caseInfo.id}"]`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send()
|
||||
.expect(204);
|
||||
|
||||
expect(body).to.eql({});
|
||||
await supertest
|
||||
.get(getSubCaseDetailsUrl(caseInfo.id, caseInfo.subCase!.id))
|
||||
.send()
|
||||
.expect(404);
|
||||
});
|
||||
|
||||
it(`should delete a sub case's comments when that case gets deleted`, async () => {
|
||||
const { newSubCaseInfo: caseInfo } = await createSubCase({ supertest, actionID });
|
||||
expect(caseInfo.subCase?.id).to.not.eql(undefined);
|
||||
|
||||
// there should be two comments on the sub case now
|
||||
const {
|
||||
body: patchedCaseWithSubCase,
|
||||
}: { body: CollectionWithSubCaseResponse } = await supertest
|
||||
.post(`${CASES_URL}/${caseInfo.id}/comments`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.query({ subCaseID: caseInfo.subCase!.id })
|
||||
.send(postCommentUserReq)
|
||||
.expect(200);
|
||||
|
||||
const subCaseCommentUrl = `${CASES_URL}/${patchedCaseWithSubCase.id}/comments/${
|
||||
patchedCaseWithSubCase.subCase!.comments![1].id
|
||||
}`;
|
||||
// make sure we can get the second comment
|
||||
await supertest.get(subCaseCommentUrl).set('kbn-xsrf', 'true').send().expect(200);
|
||||
|
||||
await supertest
|
||||
.delete(`${CASES_URL}?ids=["${caseInfo.id}"]`)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.send()
|
||||
.expect(204);
|
||||
|
||||
await supertest.get(subCaseCommentUrl).set('kbn-xsrf', 'true').send().expect(404);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue