mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Cases] Add import/export functionality (#110148)
* Working export but not import * Adding user action import flag * Adding a few integration tests * Adding connector test * Finishing integration tests * Removing connector after each test to restore original state * Bumping migration version for comment so Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
65eb7b930a
commit
2567c4f5fb
10 changed files with 369 additions and 7 deletions
|
@ -21,7 +21,7 @@ import {
|
|||
createCaseCommentSavedObjectType,
|
||||
caseConfigureSavedObjectType,
|
||||
caseConnectorMappingsSavedObjectType,
|
||||
caseSavedObjectType,
|
||||
createCaseSavedObjectType,
|
||||
caseUserActionSavedObjectType,
|
||||
subCaseSavedObjectType,
|
||||
} from './saved_object_types';
|
||||
|
@ -94,7 +94,7 @@ export class CasePlugin {
|
|||
);
|
||||
core.savedObjects.registerType(caseConfigureSavedObjectType);
|
||||
core.savedObjects.registerType(caseConnectorMappingsSavedObjectType);
|
||||
core.savedObjects.registerType(caseSavedObjectType);
|
||||
core.savedObjects.registerType(createCaseSavedObjectType(core, this.log));
|
||||
core.savedObjects.registerType(caseUserActionSavedObjectType);
|
||||
|
||||
this.log.debug(
|
||||
|
|
|
@ -5,11 +5,22 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { SavedObjectsType } from 'src/core/server';
|
||||
import {
|
||||
CoreSetup,
|
||||
Logger,
|
||||
SavedObject,
|
||||
SavedObjectsExportTransformContext,
|
||||
SavedObjectsType,
|
||||
} from 'src/core/server';
|
||||
import { CASE_SAVED_OBJECT } from '../../common';
|
||||
import { ESCaseAttributes } from '../services/cases/types';
|
||||
import { handleExport } from './import_export/export';
|
||||
import { caseMigrations } from './migrations';
|
||||
|
||||
export const caseSavedObjectType: SavedObjectsType = {
|
||||
export const createCaseSavedObjectType = (
|
||||
coreSetup: CoreSetup,
|
||||
logger: Logger
|
||||
): SavedObjectsType => ({
|
||||
name: CASE_SAVED_OBJECT,
|
||||
hidden: true,
|
||||
namespaceType: 'single',
|
||||
|
@ -144,4 +155,14 @@ export const caseSavedObjectType: SavedObjectsType = {
|
|||
},
|
||||
},
|
||||
migrations: caseMigrations,
|
||||
};
|
||||
management: {
|
||||
importableAndExportable: true,
|
||||
defaultSearchField: 'title',
|
||||
icon: 'folderExclamation',
|
||||
getTitle: (savedObject: SavedObject<ESCaseAttributes>) => savedObject.attributes.title,
|
||||
onExport: async (
|
||||
context: SavedObjectsExportTransformContext,
|
||||
objects: Array<SavedObject<ESCaseAttributes>>
|
||||
) => handleExport({ context, objects, coreSetup, logger }),
|
||||
},
|
||||
});
|
||||
|
|
|
@ -109,5 +109,8 @@ export const createCaseCommentSavedObjectType = ({
|
|||
},
|
||||
},
|
||||
},
|
||||
migrations: () => createCommentsMigrations(migrationDeps),
|
||||
migrations: createCommentsMigrations(migrationDeps),
|
||||
management: {
|
||||
importableAndExportable: true,
|
||||
},
|
||||
});
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
CoreSetup,
|
||||
Logger,
|
||||
SavedObject,
|
||||
SavedObjectsClientContract,
|
||||
SavedObjectsExportTransformContext,
|
||||
} from 'kibana/server';
|
||||
import {
|
||||
CaseUserActionAttributes,
|
||||
CASE_COMMENT_SAVED_OBJECT,
|
||||
CASE_SAVED_OBJECT,
|
||||
CASE_USER_ACTION_SAVED_OBJECT,
|
||||
CommentAttributes,
|
||||
MAX_DOCS_PER_PAGE,
|
||||
SAVED_OBJECT_TYPES,
|
||||
} from '../../../common';
|
||||
import { createCaseError, defaultSortField } from '../../common';
|
||||
import { ESCaseAttributes } from '../../services/cases/types';
|
||||
|
||||
export async function handleExport({
|
||||
context,
|
||||
objects,
|
||||
coreSetup,
|
||||
logger,
|
||||
}: {
|
||||
context: SavedObjectsExportTransformContext;
|
||||
objects: Array<SavedObject<ESCaseAttributes>>;
|
||||
coreSetup: CoreSetup;
|
||||
logger: Logger;
|
||||
}): Promise<Array<SavedObject<ESCaseAttributes | CommentAttributes | CaseUserActionAttributes>>> {
|
||||
try {
|
||||
if (objects.length <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const [{ savedObjects }] = await coreSetup.getStartServices();
|
||||
const savedObjectsClient = savedObjects.getScopedClient(context.request, {
|
||||
includedHiddenTypes: SAVED_OBJECT_TYPES,
|
||||
});
|
||||
|
||||
const caseIds = objects.map((caseObject) => caseObject.id);
|
||||
const attachmentsAndUserActionsForCases = await getAttachmentsAndUserActionsForCases(
|
||||
savedObjectsClient,
|
||||
caseIds
|
||||
);
|
||||
|
||||
return [...objects, ...attachmentsAndUserActionsForCases.flat()];
|
||||
} catch (error) {
|
||||
throw createCaseError({
|
||||
message: `Failed to retrieve associated objects for exporting of cases: ${error}`,
|
||||
error,
|
||||
logger,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function getAttachmentsAndUserActionsForCases(
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
caseIds: string[]
|
||||
): Promise<Array<SavedObject<CommentAttributes | CaseUserActionAttributes>>> {
|
||||
const [attachments, userActions] = await Promise.all([
|
||||
getAssociatedObjects<CommentAttributes>({
|
||||
savedObjectsClient,
|
||||
caseIds,
|
||||
sortField: defaultSortField,
|
||||
type: CASE_COMMENT_SAVED_OBJECT,
|
||||
}),
|
||||
getAssociatedObjects<CaseUserActionAttributes>({
|
||||
savedObjectsClient,
|
||||
caseIds,
|
||||
sortField: 'action_at',
|
||||
type: CASE_USER_ACTION_SAVED_OBJECT,
|
||||
}),
|
||||
]);
|
||||
|
||||
return [...attachments, ...userActions];
|
||||
}
|
||||
|
||||
async function getAssociatedObjects<T>({
|
||||
savedObjectsClient,
|
||||
caseIds,
|
||||
sortField,
|
||||
type,
|
||||
}: {
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
caseIds: string[];
|
||||
sortField: string;
|
||||
type: string;
|
||||
}): Promise<Array<SavedObject<T>>> {
|
||||
const references = caseIds.map((id) => ({ type: CASE_SAVED_OBJECT, id }));
|
||||
|
||||
const finder = savedObjectsClient.createPointInTimeFinder<T>({
|
||||
type,
|
||||
hasReferenceOperator: 'OR',
|
||||
hasReference: references,
|
||||
perPage: MAX_DOCS_PER_PAGE,
|
||||
sortField,
|
||||
sortOrder: 'asc',
|
||||
});
|
||||
|
||||
let result: Array<SavedObject<T>> = [];
|
||||
for await (const findResults of finder.find()) {
|
||||
result = result.concat(findResults.saved_objects);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export { caseSavedObjectType } from './cases';
|
||||
export { createCaseSavedObjectType } from './cases';
|
||||
export { subCaseSavedObjectType } from './sub_case';
|
||||
export { caseConfigureSavedObjectType } from './configure';
|
||||
export { createCaseCommentSavedObjectType } from './comments';
|
||||
|
|
|
@ -49,4 +49,7 @@ export const caseUserActionSavedObjectType: SavedObjectsType = {
|
|||
},
|
||||
},
|
||||
migrations: userActionsMigrations,
|
||||
management: {
|
||||
importableAndExportable: true,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{"attributes":{"closed_at":null,"closed_by":null,"connector":{"fields":[],"name":"none","type":".none"},"created_at":"2021-08-26T19:48:01.292Z","created_by":{"email":null,"full_name":null,"username":"elastic"},"description":"a description","external_service":null,"owner":"securitySolution","settings":{"syncAlerts":true},"status":"open","tags":["some tags"],"title":"A case to export","type":"individual","updated_at":"2021-08-26T19:48:30.151Z","updated_by":{"email":null,"full_name":null,"username":"elastic"}},"coreMigrationVersion":"8.0.0","id":"85541260-06a6-11ec-b3f9-3d05c48a7d46","migrationVersion":{"cases":"7.15.0"},"references":[],"type":"cases","updated_at":"2021-08-26T19:48:30.162Z","version":"WzM0NDEsMV0="}
|
||||
{"attributes":{"action":"create","action_at":"2021-08-26T19:48:01.292Z","action_by":{"email":null,"full_name":null,"username":"elastic"},"action_field":["description","status","tags","title","connector","settings","owner"],"new_value":"{\"type\":\"individual\",\"title\":\"A case to export\",\"tags\":[\"some tags\"],\"description\":\"a description\",\"connector\":{\"id\":\"none\",\"name\":\"none\",\"type\":\".none\",\"fields\":null},\"settings\":{\"syncAlerts\":true},\"owner\":\"securitySolution\"}","old_value":null,"owner":"securitySolution"},"coreMigrationVersion":"8.0.0","id":"8cb85070-06a6-11ec-b3f9-3d05c48a7d46","migrationVersion":{"cases-user-actions":"7.14.0"},"references":[{"id":"85541260-06a6-11ec-b3f9-3d05c48a7d46","name":"associated-cases","type":"cases"}],"score":null,"sort":[1630007281292,7288],"type":"cases-user-actions","updated_at":"2021-08-26T19:48:13.687Z","version":"WzIzODIsMV0="}
|
||||
{"attributes":{"associationType":"case","comment":"A comment for my case","created_at":"2021-08-26T19:48:30.151Z","created_by":{"email":null,"full_name":null,"username":"elastic"},"owner":"securitySolution","pushed_at":null,"pushed_by":null,"type":"user","updated_at":null,"updated_by":null},"coreMigrationVersion":"8.0.0","id":"9687c220-06a6-11ec-b3f9-3d05c48a7d46","migrationVersion":{"cases-comments":"7.16.0"},"references":[{"id":"85541260-06a6-11ec-b3f9-3d05c48a7d46","name":"associated-cases","type":"cases"}],"score":null,"sort":[1630007310151,9470],"type":"cases-comments","updated_at":"2021-08-26T19:48:30.161Z","version":"WzM0NDIsMV0="}
|
||||
{"attributes":{"action":"create","action_at":"2021-08-26T19:48:30.151Z","action_by":{"email":null,"full_name":null,"username":"elastic"},"action_field":["comment"],"new_value":"{\"comment\":\"A comment for my case\",\"type\":\"user\",\"owner\":\"securitySolution\"}","old_value":null,"owner":"securitySolution"},"coreMigrationVersion":"8.0.0","id":"9710c840-06a6-11ec-b3f9-3d05c48a7d46","migrationVersion":{"cases-user-actions":"7.14.0"},"references":[{"id":"85541260-06a6-11ec-b3f9-3d05c48a7d46","name":"associated-cases","type":"cases"},{"id":"9687c220-06a6-11ec-b3f9-3d05c48a7d46","name":"associated-cases-comments","type":"cases-comments"}],"score":null,"sort":[1630007310151,9542],"type":"cases-user-actions","updated_at":"2021-08-26T19:48:31.044Z","version":"WzM1MTIsMV0="}
|
||||
{"excludedObjects":[],"excludedObjectsCount":0,"exportedCount":4,"missingRefCount":0,"missingReferences":[]}
|
|
@ -0,0 +1,6 @@
|
|||
{"attributes":{"actionTypeId":".jira","config":{"apiUrl":"https://cases-testing.atlassian.net","projectKey":"TPN"},"isMissingSecrets":true,"name":"A jira connector"},"coreMigrationVersion":"8.0.0","id":"1cd34740-06ad-11ec-babc-0b08808e8e01","migrationVersion":{"action":"7.14.0"},"references":[],"type":"action","updated_at":"2021-08-26T20:35:12.447Z","version":"WzM1ODQsMV0="}
|
||||
{"attributes":{"closed_at":null,"closed_by":null,"connector":{"fields":[],"name":"none","type":".none"},"created_at":"2021-08-26T20:35:42.131Z","created_by":{"email":null,"full_name":null,"username":"elastic"},"description":"super description","external_service":{"connector_name":"A jira connector","external_id":"10125","external_title":"TPN-118","external_url":"https://cases-testing.atlassian.net/browse/TPN-118","pushed_at":"2021-08-26T20:35:44.302Z","pushed_by":{"email":null,"full_name":null,"username":"elastic"}},"owner":"securitySolution","settings":{"syncAlerts":true},"status":"open","tags":["other tags"],"title":"A case with a connector","type":"individual","updated_at":"2021-08-26T20:36:35.536Z","updated_by":{"email":null,"full_name":null,"username":"elastic"}},"coreMigrationVersion":"8.0.0","id":"2e85c3f0-06ad-11ec-babc-0b08808e8e01","migrationVersion":{"cases":"7.15.0"},"references":[{"id":"1cd34740-06ad-11ec-babc-0b08808e8e01","name":"pushConnectorId","type":"action"}],"type":"cases","updated_at":"2021-08-26T20:36:35.537Z","version":"WzM1OTIsMV0="}
|
||||
{"attributes":{"action":"create","action_at":"2021-08-26T20:35:42.131Z","action_by":{"email":null,"full_name":null,"username":"elastic"},"action_field":["description","status","tags","title","connector","settings","owner"],"new_value":"{\"type\":\"individual\",\"title\":\"A case with a connector\",\"tags\":[\"other tags\"],\"description\":\"super description\",\"connector\":{\"id\":\"1cd34740-06ad-11ec-babc-0b08808e8e01\",\"name\":\"A jira connector\",\"type\":\".jira\",\"fields\":{\"issueType\":\"10002\",\"parent\":null,\"priority\":\"High\"}},\"settings\":{\"syncAlerts\":true},\"owner\":\"securitySolution\"}","old_value":null,"owner":"securitySolution"},"coreMigrationVersion":"8.0.0","id":"2e9db8c0-06ad-11ec-babc-0b08808e8e01","migrationVersion":{"cases-user-actions":"7.14.0"},"references":[{"id":"2e85c3f0-06ad-11ec-babc-0b08808e8e01","name":"associated-cases","type":"cases"}],"score":null,"sort":[1630010142131,4024],"type":"cases-user-actions","updated_at":"2021-08-26T20:35:42.284Z","version":"WzM1ODksMV0="}
|
||||
{"attributes":{"action":"push-to-service","action_at":"2021-08-26T20:35:44.302Z","action_by":{"email":null,"full_name":null,"username":"elastic"},"action_field":["pushed"],"new_value":"{\"pushed_at\":\"2021-08-26T20:35:44.302Z\",\"pushed_by\":{\"username\":\"elastic\",\"full_name\":null,\"email\":null},\"connector_id\":\"1cd34740-06ad-11ec-babc-0b08808e8e01\",\"connector_name\":\"A jira connector\",\"external_id\":\"10125\",\"external_title\":\"TPN-118\",\"external_url\":\"https://cases-testing.atlassian.net/browse/TPN-118\"}","old_value":null,"owner":"securitySolution"},"coreMigrationVersion":"8.0.0","id":"2fd1cbf0-06ad-11ec-babc-0b08808e8e01","migrationVersion":{"cases-user-actions":"7.14.0"},"references":[{"id":"2e85c3f0-06ad-11ec-babc-0b08808e8e01","name":"associated-cases","type":"cases"}],"score":null,"sort":[1630010144302,4029],"type":"cases-user-actions","updated_at":"2021-08-26T20:35:44.303Z","version":"WzM1OTAsMV0="}
|
||||
{"attributes":{"action":"update","action_at":"2021-08-26T20:36:35.536Z","action_by":{"email":null,"full_name":null,"username":"elastic"},"action_field":["connector"],"new_value":"{\"id\":\"none\",\"name\":\"none\",\"type\":\".none\",\"fields\":null}","old_value":"{\"id\":\"1cd34740-06ad-11ec-babc-0b08808e8e01\",\"name\":\"A jira connector\",\"type\":\".jira\",\"fields\":{\"issueType\":\"10002\",\"parent\":null,\"priority\":\"High\"}}","owner":"securitySolution"},"coreMigrationVersion":"8.0.0","id":"4ee9b250-06ad-11ec-babc-0b08808e8e01","migrationVersion":{"cases-user-actions":"7.14.0"},"references":[{"id":"2e85c3f0-06ad-11ec-babc-0b08808e8e01","name":"associated-cases","type":"cases"}],"score":null,"sort":[1630010195536,4033],"type":"cases-user-actions","updated_at":"2021-08-26T20:36:36.469Z","version":"WzM1OTMsMV0="}
|
||||
{"excludedObjects":[],"excludedObjectsCount":0,"exportedCount":5,"missingRefCount":0,"missingReferences":[]}
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import expect from '@kbn/expect';
|
||||
import { join } from 'path';
|
||||
import { ObjectRemover as ActionsRemover } from '../../../../../alerting_api_integration/common/lib';
|
||||
import {
|
||||
deleteAllCaseItems,
|
||||
createCase,
|
||||
createComment,
|
||||
findCases,
|
||||
getCaseUserActions,
|
||||
} from '../../../../common/lib/utils';
|
||||
import { getPostCaseRequest, postCommentUserReq } from '../../../../common/lib/mock';
|
||||
import { FtrProviderContext } from '../../../../common/ftr_provider_context';
|
||||
import {
|
||||
AttributesTypeUser,
|
||||
CommentsResponse,
|
||||
CASES_URL,
|
||||
CaseType,
|
||||
} from '../../../../../../plugins/cases/common';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ({ getService }: FtrProviderContext): void => {
|
||||
const supertest = getService('supertest');
|
||||
const es = getService('es');
|
||||
|
||||
describe('import and export cases', () => {
|
||||
const actionsRemover = new ActionsRemover(supertest);
|
||||
|
||||
afterEach(async () => {
|
||||
await deleteAllCaseItems(es);
|
||||
await actionsRemover.removeAll();
|
||||
});
|
||||
|
||||
it('exports a case with its associated user actions and comments', async () => {
|
||||
const caseRequest = getPostCaseRequest();
|
||||
const postedCase = await createCase(supertest, caseRequest);
|
||||
await createComment({
|
||||
supertest,
|
||||
caseId: postedCase.id,
|
||||
params: postCommentUserReq,
|
||||
});
|
||||
|
||||
const { text } = await supertest
|
||||
.post(`/api/saved_objects/_export`)
|
||||
.send({
|
||||
type: ['cases'],
|
||||
excludeExportDetails: true,
|
||||
includeReferencesDeep: true,
|
||||
})
|
||||
.set('kbn-xsrf', 'true');
|
||||
|
||||
const objects = ndjsonToObject(text);
|
||||
|
||||
expect(objects).to.have.length(4);
|
||||
|
||||
// should be the case
|
||||
expect(objects[0].attributes.title).to.eql(caseRequest.title);
|
||||
expect(objects[0].attributes.description).to.eql(caseRequest.description);
|
||||
expect(objects[0].attributes.connector.type).to.eql(caseRequest.connector.type);
|
||||
expect(objects[0].attributes.connector.name).to.eql(caseRequest.connector.name);
|
||||
expect(objects[0].attributes.connector.fields).to.eql([]);
|
||||
expect(objects[0].attributes.settings).to.eql(caseRequest.settings);
|
||||
|
||||
// should be two user actions
|
||||
expect(objects[1].attributes.action).to.eql('create');
|
||||
|
||||
const parsedCaseNewValue = JSON.parse(objects[1].attributes.new_value);
|
||||
const {
|
||||
connector: { id: ignoreParsedId, ...restParsedConnector },
|
||||
...restParsedCreateCase
|
||||
} = parsedCaseNewValue;
|
||||
|
||||
const {
|
||||
connector: { id: ignoreConnectorId, ...restConnector },
|
||||
...restCreateCase
|
||||
} = caseRequest;
|
||||
|
||||
expect(restParsedCreateCase).to.eql({ ...restCreateCase, type: CaseType.individual });
|
||||
expect(restParsedConnector).to.eql(restConnector);
|
||||
|
||||
expect(objects[1].attributes.old_value).to.eql(null);
|
||||
expect(includesAllRequiredFields(objects[1].attributes.action_field)).to.eql(true);
|
||||
|
||||
// should be the comment
|
||||
expect(objects[2].attributes.comment).to.eql(postCommentUserReq.comment);
|
||||
expect(objects[2].attributes.type).to.eql(postCommentUserReq.type);
|
||||
|
||||
expect(objects[3].attributes.action).to.eql('create');
|
||||
expect(JSON.parse(objects[3].attributes.new_value)).to.eql(postCommentUserReq);
|
||||
expect(objects[3].attributes.old_value).to.eql(null);
|
||||
expect(objects[3].attributes.action_field).to.eql(['comment']);
|
||||
});
|
||||
|
||||
it('imports a case with a comment and user actions', async () => {
|
||||
await supertest
|
||||
.post('/api/saved_objects/_import')
|
||||
.query({ overwrite: true })
|
||||
.attach(
|
||||
'file',
|
||||
join(
|
||||
__dirname,
|
||||
'../../../../common/fixtures/saved_object_exports/single_case_user_actions_one_comment.ndjson'
|
||||
)
|
||||
)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
|
||||
const findResponse = await findCases({ supertest, query: {} });
|
||||
expect(findResponse.total).to.eql(1);
|
||||
expect(findResponse.cases[0].title).to.eql('A case to export');
|
||||
expect(findResponse.cases[0].description).to.eql('a description');
|
||||
|
||||
const { body: commentsResponse }: { body: CommentsResponse } = await supertest
|
||||
.get(`${CASES_URL}/${findResponse.cases[0].id}/comments/_find`)
|
||||
.send()
|
||||
.expect(200);
|
||||
|
||||
const comment = (commentsResponse.comments[0] as unknown) as AttributesTypeUser;
|
||||
expect(comment.comment).to.eql('A comment for my case');
|
||||
|
||||
const userActions = await getCaseUserActions({
|
||||
supertest,
|
||||
caseID: findResponse.cases[0].id,
|
||||
});
|
||||
|
||||
expect(userActions).to.have.length(2);
|
||||
expect(userActions[0].action).to.eql('create');
|
||||
expect(includesAllRequiredFields(userActions[0].action_field)).to.eql(true);
|
||||
|
||||
expect(userActions[1].action).to.eql('create');
|
||||
expect(userActions[1].action_field).to.eql(['comment']);
|
||||
expect(userActions[1].old_value).to.eql(null);
|
||||
expect(JSON.parse(userActions[1].new_value!)).to.eql({
|
||||
comment: 'A comment for my case',
|
||||
type: 'user',
|
||||
owner: 'securitySolution',
|
||||
});
|
||||
});
|
||||
|
||||
it('imports a case with a connector', async () => {
|
||||
await supertest
|
||||
.post('/api/saved_objects/_import')
|
||||
.query({ overwrite: true })
|
||||
.attach(
|
||||
'file',
|
||||
join(
|
||||
__dirname,
|
||||
'../../../../common/fixtures/saved_object_exports/single_case_with_connector_update_to_none.ndjson'
|
||||
)
|
||||
)
|
||||
.set('kbn-xsrf', 'true')
|
||||
.expect(200);
|
||||
|
||||
actionsRemover.add('default', '1cd34740-06ad-11ec-babc-0b08808e8e01', 'action', 'actions');
|
||||
|
||||
const findResponse = await findCases({ supertest, query: {} });
|
||||
expect(findResponse.total).to.eql(1);
|
||||
expect(findResponse.cases[0].title).to.eql('A case with a connector');
|
||||
expect(findResponse.cases[0].description).to.eql('super description');
|
||||
|
||||
const userActions = await getCaseUserActions({
|
||||
supertest,
|
||||
caseID: findResponse.cases[0].id,
|
||||
});
|
||||
|
||||
expect(userActions).to.have.length(3);
|
||||
expect(userActions[0].action).to.eql('create');
|
||||
expect(includesAllRequiredFields(userActions[0].action_field)).to.eql(true);
|
||||
|
||||
expect(userActions[1].action).to.eql('push-to-service');
|
||||
expect(userActions[1].action_field).to.eql(['pushed']);
|
||||
expect(userActions[1].old_value).to.eql(null);
|
||||
|
||||
const parsedPushNewValue = JSON.parse(userActions[1].new_value!);
|
||||
expect(parsedPushNewValue.connector_name).to.eql('A jira connector');
|
||||
expect(parsedPushNewValue.connector_id).to.eql('1cd34740-06ad-11ec-babc-0b08808e8e01');
|
||||
|
||||
expect(userActions[2].action).to.eql('update');
|
||||
expect(userActions[2].action_field).to.eql(['connector']);
|
||||
|
||||
const parsedUpdateNewValue = JSON.parse(userActions[2].new_value!);
|
||||
expect(parsedUpdateNewValue.id).to.eql('none');
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const ndjsonToObject = (input: string) => {
|
||||
return input.split('\n').map((str) => JSON.parse(str));
|
||||
};
|
||||
|
||||
const includesAllRequiredFields = (actionFields: string[]): boolean => {
|
||||
const requiredFields = [
|
||||
'description',
|
||||
'status',
|
||||
'tags',
|
||||
'title',
|
||||
'connector',
|
||||
'settings',
|
||||
'owner',
|
||||
];
|
||||
|
||||
return requiredFields.every((field) => actionFields.includes(field));
|
||||
};
|
|
@ -20,6 +20,7 @@ export default ({ loadTestFile }: FtrProviderContext): void => {
|
|||
loadTestFile(require.resolve('./alerts/get_cases'));
|
||||
loadTestFile(require.resolve('./alerts/get_alerts_attached_to_case'));
|
||||
loadTestFile(require.resolve('./cases/delete_cases'));
|
||||
loadTestFile(require.resolve('./cases/import_export'));
|
||||
loadTestFile(require.resolve('./cases/find_cases'));
|
||||
loadTestFile(require.resolve('./cases/get_case'));
|
||||
loadTestFile(require.resolve('./cases/patch_cases'));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue