import { omit } from 'lodash' ; import getPort from 'get-port' ; import http from 'http' ; import expect from '@kbn/expect' ; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey' ; import type { TransportResult } from '@elastic/elasticsearch' ; import type { Client } from '@elastic/elasticsearch' ; import type SuperTest from 'supertest' ; import { ObjectRemover as ActionsRemover } from '../../../alerting_api_integration/common/lib' ; import { CASES_URL , CASE_CONFIGURE_CONNECTORS_URL , CASE_CONFIGURE_URL , CASE_REPORTERS_URL , CASE_STATUS_URL , CASE_TAGS_URL , SUB_CASES_PATCH_DEL_URL , } from '../../../../plugins/cases/common/constants' ; import { CasesConfigureRequest , CasesConfigureResponse , CaseConnector , ConnectorTypes , CasePostRequest , CaseResponse , SubCasesFindResponse , CaseStatuses , SubCasesResponse , CasesResponse , CasesFindResponse , CommentRequest , CaseUserActionResponse , SubCaseResponse , CommentResponse , CasesPatchRequest , AllCommentsResponse , CommentPatchRequest , CasesConfigurePatch , CasesStatusResponse , CasesConfigurationsResponse , CaseUserActionsResponse , AlertResponse , ConnectorMappings , CasesByAlertId , CaseResolveResponse , CaseMetricsResponse , } from '../../../../plugins/cases/common/api' ; import { getPostCaseRequest , postCollectionReq , postCommentGenAlertReq } from './mock' ; import { getCaseUserActionUrl , getSubCasesUrl } from '../../../../plugins/cases/common/api/helpers' ; import { ContextTypeGeneratedAlertType } from '../../../../plugins/cases/server/connectors' ; import { SignalHit } from '../../../../plugins/security_solution/server/lib/detection_engine/signals/types' ; import { ActionResult , FindActionResult } from '../../../../plugins/actions/server/types' ; import { User } from './authentication/types' ; import { superUser } from './authentication/users' ; import { ESCasesConfigureAttributes } from '../../../../plugins/cases/server/services/configure/types' ; import { ESCaseAttributes } from '../../../../plugins/cases/server/services/cases/types' ; import { getServiceNowServer } from '../../../alerting_api_integration/common/fixtures/plugins/actions_simulators/server/plugin' ; function toArray < T > ( input ) { if ( Array . isArray ( input ) ) { return input ; } return [ input ] ; } /**
 * Query Elasticsearch for a set of signals within a set of indices
 */ export const getSignalsWithES = async ( { es , indices , ids , } ) : Promise < Map < string , Map < string , estypes . SearchHit < SignalHit > > > > => { const signals = await es . search ( { index : indices , body : { size : 10000 , query : { bool : { filter : [ { ids : { values : toArray ( ids ) , } , } , ] , } , } , } , } , { meta : true } ) ; return signals . body . hits . hits . reduce ( ( acc , hit ) => { let indexMap = acc . get ( hit . _index ) ; if ( indexMap === undefined ) { indexMap = new Map < string , estypes . SearchHit < SignalHit > > ( [ [ hit . _id , hit ] ] ) ; } else { indexMap . set ( hit . _id , hit ) ; } acc . set ( hit . _index , indexMap ) ; return acc ; } , new Map < string , Map < string , estypes . SearchHit < SignalHit > > > ( ) ) ; } ; interface SetStatusCasesParams { id : string ; version : string ; status : CaseStatuses ; } /**
 * Sets the status of some cases or sub cases. The cases field must be all of one type.
 */ export const setStatus = async ( { supertest , cases , type , } ) : Promise < CasesResponse | SubCasesResponse > => { const url = type === 'case' ? CASES_URL : SUB_CASES_PATCH_DEL_URL ; const patchFields = type === 'case' ? { cases } : { subCases : cases } ; const { body } = await supertest . patch ( url ) . set ( 'kbn-xsrf' , 'true' ) . send ( patchFields ) . expect ( 200 ) ; return body ; } ; /**
 * Variable to easily access the default comment for the createSubCase function.
 */ export const defaultCreateSubComment = postCommentGenAlertReq ; /**
 * Variable to easily access the default comment for the createSubCase function.
 */ export const defaultCreateSubPost = postCollectionReq ; /**
 * Response structure for the createSubCase and createSubCaseComment functions.
 */ export interface CreateSubCaseResp { newSubCaseInfo : CaseResponse ; modifiedSubCases ? : SubCasesResponse ; } /**
 * Creates a sub case using the actions API. If a caseID isn't passed in then it will create
 * the collection as well. To create a sub case a comment must be created so it uses a default
 * generated alert style comment which can be overridden.
 */ export const createSubCase = async ( args ) : Promise < CreateSubCaseResp > => { return createSubCaseComment ( { ... args , forceNewSubCase : true } ) ; } ; /**
 * Add case as a connector
 */ export const createCaseAction = async ( supertest ) => { const { body : createdAction } = await supertest . post ( '/api/actions/connector' ) . set ( 'kbn-xsrf' , 'foo' ) . send ( { name : 'A case connector' , connector_type_id : '.case' , config : { } , } ) . expect ( 200 ) ; return createdAction . id ; } ; /**
 * Remove a connector
 */ export const deleteCaseAction = async ( supertest , id ) => { await supertest . delete ( `/api/actions/connector/${ id }` ) . set ( 'kbn-xsrf' , 'foo' ) ; } ; /**
 * Creates a sub case using the actions APIs. This will handle forcing a creation of a new sub case even if one exists
 * if the forceNewSubCase parameter is set to true.
 */ export const createSubCaseComment = async ( { supertest , caseID , comment = defaultCreateSubComment , caseInfo = defaultCreateSubPost , forceNewSubCase = false , actionID , } ) : Promise < CreateSubCaseResp > => { let actionIDToUse ; if ( actionID === undefined ) { actionIDToUse = await createCaseAction ( supertest ) ; } else { actionIDToUse = actionID ; } let collectionID ; if ( ! caseID ) { collectionID = ( await supertest . post ( CASES_URL ) . set ( 'kbn-xsrf' , 'true' ) . send ( caseInfo ) . expect ( 200 ) ) . body . id ; } else { collectionID = caseID ; } let closedSubCases ; if ( forceNewSubCase ) { const { body : subCasesResp } = await supertest . get ( `${ getSubCasesUrl ( collectionID ) }/_find` ) . expect ( 200 ) ; const nonClosed = subCasesResp . subCases . filter ( ( subCase ) => subCase . status !== CaseStatuses . closed ) ; if ( nonClosed . length > 0 ) { closedSubCases = ( await supertest . patch ( SUB_CASES_PATCH_DEL_URL ) . set ( 'kbn-xsrf' , 'true' ) . send ( { subCases : nonClosed . map ( ( subCase ) => ( { id : subCase . id , version : subCase . version , status : CaseStatuses . closed , } ) ) , } ) . expect ( 200 ) ) . body ; } } const caseConnector = await supertest . post ( `/api/actions/connector/${ actionIDToUse }/_execute` ) . set ( 'kbn-xsrf' , 'foo' ) . send ( { params : { subAction : 'addComment' , subActionParams : { caseId : collectionID , comment , } , } , } ) . expect ( 200 ) ; expect ( caseConnector . body . status ) . to . eql ( 'ok' ) ; return { newSubCaseInfo : caseConnector . body . data , modifiedSubCases : closedSubCases } ; } ; type ConfigRequestParams = Partial < CaseConnector > & { overrides ? : Record < string , unknown > ; } ; export const getConfigurationRequest = ( { id = 'none' , name = 'none' , type = ConnectorTypes . none , fields = null , overrides , } = { } ) : CasesConfigureRequest => { return { connector : { id , name , type , fields , } as CaseConnector , closure_type : 'close-by-user' , owner : 'securitySolutionFixture' , ... overrides , } ; } ; export const getConfigurationOutput = ( update = false , overwrite = { } ) : Partial < CasesConfigureResponse > => { return { ... getConfigurationRequest ( ) , error : null , mappings : [ ] , created_by : { email : null , full_name : null , username : 'elastic' } , updated_by : update ? { email : null , full_name : null , username : 'elastic' } : null , ... overwrite , } ; } ; export const getServiceNowConnector = ( ) => ( { name : 'ServiceNow Connector' , connector_type_id : '.servicenow' , secrets : { username : 'admin' , password : 'password' , } , config : { apiUrl : 'http://some.non.existent.com' , usesTableApi : false , } , } ) ; export const getJiraConnector = ( ) => ( { name : 'Jira Connector' , connector_type_id : '.jira' , secrets : { email : 'elastic@elastic.co' , apiToken : 'token' , } , config : { apiUrl : 'http://some.non.existent.com' , projectKey : 'pkey' , } , } ) ; export const getMappings = ( ) => [ { source : 'title' , target : 'name' , actionType : 'overwrite' , } , { source : 'description' , target : 'description' , actionType : 'overwrite' , } , { source : 'comments' , target : 'comments' , actionType : 'append' , } , ] ; export const getResilientConnector = ( ) => ( { name : 'Resilient Connector' , connector_type_id : '.resilient' , secrets : { apiKeyId : 'id' , apiKeySecret : 'secret' , } , config : { apiUrl : 'http://some.non.existent.com' , orgId : 'pkey' , } , } ) ; export const getServiceNowSIRConnector = ( ) => ( { name : 'ServiceNow Connector' , connector_type_id : '.servicenow-sir' , secrets : { username : 'admin' , password : 'password' , } , config : { apiUrl : 'http://some.non.existent.com' , usesTableApi : false , } , } ) ; export const getWebhookConnector = ( ) => ( { name : 'A generic Webhook action' , connector_type_id : '.webhook' , secrets : { user : 'user' , password : 'password' , } , config : { headers : { 'Content-Type' : 'text/plain' , } , url : 'http://some.non.existent.com' , } , } ) ; interface CommonSavedObjectAttributes { id ? : string | null ; created_at ? : string | null ; updated_at ? : string | null ; version ? : string | null ; [ key ] : unknown ; } const savedObjectCommonAttributes = [ 'created_at' , 'updated_at' , 'version' , 'id' ] ; const removeServerGeneratedPropertiesFromObject = < T extends object , K extends keyof T > ( object , keys ) : Omit < T , K > => { return omit < T , K > ( object , keys ) ; } ; export const removeServerGeneratedPropertiesFromSavedObject = < T extends CommonSavedObjectAttributes > ( attributes , keys = [ ] ) : Omit < T , typeof savedObjectCommonAttributes [ number ] | typeof keys [ number ] > => { return removeServerGeneratedPropertiesFromObject ( attributes , [ ... savedObjectCommonAttributes , ... keys , ] ) ; } ; export const removeServerGeneratedPropertiesFromUserAction = ( attributes ) => { const keysToRemove = [ 'action_id' , 'created_at' ] ; return removeServerGeneratedPropertiesFromObject < CaseUserActionResponse , typeof keysToRemove [ number ] > ( attributes , keysToRemove ) ; } ; export const removeServerGeneratedPropertiesFromSubCase = ( subCase ) => { if ( ! subCase ) { return ; } return removeServerGeneratedPropertiesFromSavedObject < SubCaseResponse > ( subCase , [ 'closed_at' , 'comments' , ] ) ; } ; export const removeServerGeneratedPropertiesFromCase = ( theCase ) : Partial < CaseResponse > => { return removeServerGeneratedPropertiesFromSavedObject < CaseResponse > ( theCase , [ 'closed_at' ] ) ; } ; export const removeServerGeneratedPropertiesFromComments = ( comments ) : Array < Partial < CommentResponse > > | undefined => { return comments ?. map ( ( comment ) => { return removeServerGeneratedPropertiesFromSavedObject < CommentResponse > ( comment , [ ] ) ; } ) ; } ; export const deleteAllCaseItems = async ( es ) => { await Promise . all ( [ deleteCasesByESQuery ( es ) , deleteSubCases ( es ) , deleteCasesUserActions ( es ) , deleteComments ( es ) , deleteConfiguration ( es ) , deleteMappings ( es ) , ] ) ; } ; export const deleteCasesUserActions = async ( es ) : Promise < void > => { await es . deleteByQuery ( { index : '.kibana' , q : 'type:cases-user-actions' , wait_for_completion : true , refresh : true , body : { } , conflicts : 'proceed' , } ) ; } ; export const deleteCasesByESQuery = async ( es ) : Promise < void > => { await es . deleteByQuery ( { index : '.kibana' , q : 'type:cases' , wait_for_completion : true , refresh : true , body : { } , conflicts : 'proceed' , } ) ; } ; /**
 * Deletes all sub cases in the .kibana index. This uses ES to perform the delete and does
 * not go through the case API.
 */ export const deleteSubCases = async ( es ) : Promise < void > => { await es . deleteByQuery ( { index : '.kibana' , q : 'type:cases-sub-case' , wait_for_completion : true , refresh : true , body : { } , conflicts : 'proceed' , } ) ; } ; export const deleteComments = async ( es ) : Promise < void > => { await es . deleteByQuery ( { index : '.kibana' , q : 'type:cases-comments' , wait_for_completion : true , refresh : true , body : { } , conflicts : 'proceed' , } ) ; } ; export const deleteConfiguration = async ( es ) : Promise < void > => { await es . deleteByQuery ( { index : '.kibana' , q : 'type:cases-configure' , wait_for_completion : true , refresh : true , body : { } , conflicts : 'proceed' , } ) ; } ; export const deleteMappings = async ( es ) : Promise < void > => { await es . deleteByQuery ( { index : '.kibana' , q : 'type:cases-connector-mappings' , wait_for_completion : true , refresh : true , body : { } , conflicts : 'proceed' , } ) ; } ; export const superUserSpace1Auth = getAuthWithSuperUser ( ) ; /**
 * Returns an auth object with the specified space and user set as super user. The result can be passed to other utility
 * functions.
 */ export function getAuthWithSuperUser ( space = 'space1' ) { return { user : superUser , space } ; } /**
 * Converts the space into the appropriate string for use by the actions remover utility object.
 */ export function getActionsSpace ( space ) { return space ?? 'default' ; } export const getSpaceUrlPrefix = ( spaceId ) => { return spaceId && spaceId !== 'default' ? `/s/${ spaceId }` : `` ; } ; interface OwnerEntity { owner : string ; } export const ensureSavedObjectIsAuthorized = ( entities , numberOfExpectedCases , owners ) => { expect ( entities . length ) . to . eql ( numberOfExpectedCases ) ; entities . forEach ( ( entity ) => expect ( owners . includes ( entity . owner ) ) . to . be ( true ) ) ; } ; interface ConnectorMappingsSavedObject { 'cases-connector-mappings' : ConnectorMappings ; } /**
 * Returns connector mappings saved objects from Elasticsearch directly.
 */ export const getConnectorMappingsFromES = async ( { es } ) => { const mappings = await es . search ( { index : '.kibana' , body : { query : { term : { type : { value : 'cases-connector-mappings' , } , } , } , } , } , { meta : true } ) ; return mappings ; } ; interface ConfigureSavedObject { 'cases-configure' : ESCasesConfigureAttributes ; } /**
 * Returns configure saved objects from Elasticsearch directly.
 */ export const getConfigureSavedObjectsFromES = async ( { es } ) => { const configure = await es . search ( { index : '.kibana' , body : { query : { term : { type : { value : 'cases-configure' , } , } , } , } , } , { meta : true } ) ; return configure ; } ; export const getCaseSavedObjectsFromES = async ( { es } ) => { const configure = await es . search ( { index : '.kibana' , body : { query : { term : { type : { value : 'cases' , } , } , } , } , } , { meta : true } ) ; return configure ; } ; export const createCaseWithConnector = async ( { supertest , configureReq = { } , serviceNowSimulatorURL , actionsRemover , auth = { user : superUser , space : null } , createCaseReq = getPostCaseRequest ( ) , } ) : Promise < { postedCase : CaseResponse ; connector : CreateConnectorResponse ; configuration : CasesConfigureResponse ; } > => { const connector = await createConnector ( { supertest , req : { ... getServiceNowConnector ( ) , config : { apiUrl : serviceNowSimulatorURL } , } , auth , } ) ; actionsRemover . add ( auth . space ?? 'default' , connector . id , 'action' , 'actions' ) ; const configuration = await createConfiguration ( supertest , { ... getConfigurationRequest ( { id : connector . id , name : connector . name , type : connector . connector_type_id as ConnectorTypes , } ) , ... configureReq , } , 200 , auth ) ; const postedCase = await createCase ( supertest , { ... createCaseReq , connector : { id : connector . id , name : connector . name , type : connector . connector_type_id , fields : { urgency : '2' , impact : '2' , severity : '2' , category : 'software' , subcategory : 'os' , } , } as CaseConnector , } , 200 , auth ) ; return { postedCase , connector , configuration } ; } ; export const createCase = async ( supertest , params , expectedHttpCode = 200 , auth = { user : superUser , space : null } ) : Promise < CaseResponse > => { const { body : theCase } = await supertest . post ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . send ( params ) . expect ( expectedHttpCode ) ; return theCase ; } ; /**
 * Sends a delete request for the specified case IDs.
 */ export const deleteCases = async ( { supertest , caseIDs , expectedHttpCode = 204 , auth = { user : superUser , space : null } , } ) => { const { body } = await supertest . delete ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }` ) . auth ( auth . user . username , auth . user . password ) . query ( { ids : JSON . stringify ( caseIDs ) } ) . set ( 'kbn-xsrf' , 'true' ) . send ( ) . expect ( expectedHttpCode ) ; return body ; } ; export const createComment = async ( { supertest , caseId , params , auth = { user : superUser , space : null } , expectedHttpCode = 200 , } ) : Promise < CaseResponse > => { const { body : theCase } = await supertest . post ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/${ caseId }/comments` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . send ( params ) . expect ( expectedHttpCode ) ; return theCase ; } ; export const updateCase = async ( { supertest , params , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CaseResponse [ ] > => { const { body : cases } = await supertest . patch ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . send ( params ) . expect ( expectedHttpCode ) ; return cases ; } ; export const getCaseUserActions = async ( { supertest , caseID , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CaseUserActionsResponse > => { const { body : userActions } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ getCaseUserActionUrl ( caseID ) }` ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return userActions ; } ; export const deleteComment = async ( { supertest , caseId , commentId , expectedHttpCode = 204 , auth = { user : superUser , space : null } , } ) : Promise < { } | Error > => { const { body : comment } = await supertest . delete ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/${ caseId }/comments/${ commentId }` ) . set ( 'kbn-xsrf' , 'true' ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) . send ( ) ; return comment ; } ; export const deleteAllComments = async ( { supertest , caseId , expectedHttpCode = 204 , auth = { user : superUser , space : null } , } ) : Promise < { } | Error > => { const { body : comment } = await supertest . delete ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/${ caseId }/comments` ) . set ( 'kbn-xsrf' , 'true' ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) . send ( ) ; return comment ; } ; export const getAllComments = async ( { supertest , caseId , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < AllCommentsResponse > => { const { body : comments } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/${ caseId }/comments` ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return comments ; } ; export const getComment = async ( { supertest , caseId , commentId , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CommentResponse > => { const { body : comment } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/${ caseId }/comments/${ commentId }` ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return comment ; } ; export const updateComment = async ( { supertest , caseId , req , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CaseResponse > => { const { body : res } = await supertest . patch ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/${ caseId }/comments` ) . set ( 'kbn-xsrf' , 'true' ) . send ( req ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return res ; } ; export const getConfiguration = async ( { supertest , query = { owner : 'securitySolutionFixture' } , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CasesConfigurationsResponse > => { const { body : configuration } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASE_CONFIGURE_URL }` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . query ( query ) . expect ( expectedHttpCode ) ; return configuration ; } ; export const createConfiguration = async ( supertest , req = getConfigurationRequest ( ) , expectedHttpCode = 200 , auth = { user : superUser , space : null } ) : Promise < CasesConfigureResponse > => { const { body : configuration } = await supertest . post ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASE_CONFIGURE_URL }` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . send ( req ) . expect ( expectedHttpCode ) ; return configuration ; } ; export type CreateConnectorResponse = Omit < ActionResult , 'actionTypeId' > & { connector_type_id : string ; } ; export const createConnector = async ( { supertest , req , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CreateConnectorResponse > => { const { body : connector } = await supertest . post ( `${ getSpaceUrlPrefix ( auth . space ) }/api/actions/connector` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . send ( req ) . expect ( expectedHttpCode ) ; return connector ; } ; export const getCaseConnectors = async ( { supertest , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < FindActionResult [ ] > => { const { body : connectors } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASE_CONFIGURE_CONNECTORS_URL }/_find` ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return connectors ; } ; export const updateConfiguration = async ( supertest , id , req , expectedHttpCode = 200 , auth = { user : superUser , space : null } ) : Promise < CasesConfigureResponse > => { const { body : configuration } = await supertest . patch ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASE_CONFIGURE_URL }/${ id }` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . send ( req ) . expect ( expectedHttpCode ) ; return configuration ; } ; export const getAllCasesStatuses = async ( { supertest , expectedHttpCode = 200 , auth = { user : superUser , space : null } , query = { } , } ) : Promise < CasesStatusResponse > => { const { body : statuses } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASE_STATUS_URL }` ) . auth ( auth . user . username , auth . user . password ) . query ( { ... query } ) . expect ( expectedHttpCode ) ; return statuses ; } ; export const getCase = async ( { supertest , caseId , includeComments = false , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CaseResponse > => { const { body : theCase } = await supertest . get ( `${ getSpaceUrlPrefix ( auth ?. space ) }${ CASES_URL }/${ caseId }?includeComments=${ includeComments }` ) . set ( 'kbn-xsrf' , 'true' ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return theCase ; } ; export const getCaseMetrics = async ( { supertest , caseId , features , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CaseMetricsResponse > => { const { body : metricsResponse } = await supertest . get ( `${ getSpaceUrlPrefix ( auth ?. space ) }${ CASES_URL }/metrics/${ caseId }` ) . query ( { features : JSON . stringify ( features ) } ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return metricsResponse ; } ; export const resolveCase = async ( { supertest , caseId , includeComments = false , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CaseResolveResponse > => { const { body : theResolvedCase } = await supertest . get ( `${ getSpaceUrlPrefix ( auth ?. space ) }${ CASES_URL }/${ caseId }/resolve?includeComments=${ includeComments }` ) . set ( 'kbn-xsrf' , 'true' ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return theResolvedCase ; } ; export const findCases = async ( { supertest , query = { } , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CasesFindResponse > => { const { body : res } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/_find` ) . auth ( auth . user . username , auth . user . password ) . query ( { sortOrder : 'asc' , ... query } ) . set ( 'kbn-xsrf' , 'true' ) . send ( ) . expect ( expectedHttpCode ) ; return res ; } ; export const getCasesByAlert = async ( { supertest , alertID , query = { } , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CasesByAlertId > => { const { body : res } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/alerts/${ alertID }` ) . auth ( auth . user . username , auth . user . password ) . query ( query ) . expect ( expectedHttpCode ) ; return res ; } ; export const getTags = async ( { supertest , query = { } , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CasesFindResponse > => { const { body : res } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASE_TAGS_URL }` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . query ( { ... query } ) . expect ( expectedHttpCode ) ; return res ; } ; export const getReporters = async ( { supertest , query = { } , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CasesFindResponse > => { const { body : res } = await supertest . get ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASE_REPORTERS_URL }` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . query ( { ... query } ) . expect ( expectedHttpCode ) ; return res ; } ; export const pushCase = async ( { supertest , caseId , connectorId , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < CaseResponse > => { const { body : res } = await supertest . post ( `${ getSpaceUrlPrefix ( auth . space ) }${ CASES_URL }/${ caseId }/connector/${ connectorId }/_push` ) . auth ( auth . user . username , auth . user . password ) . set ( 'kbn-xsrf' , 'true' ) . send ( { } ) . expect ( expectedHttpCode ) ; return res ; } ; export const getAlertsAttachedToCase = async ( { supertest , caseId , expectedHttpCode = 200 , auth = { user : superUser , space : null } , } ) : Promise < AlertResponse > => { const { body : theCase } = await supertest . get ( `${ getSpaceUrlPrefix ( auth ?. space ) }${ CASES_URL }/${ caseId }/alerts` ) . auth ( auth . user . username , auth . user . password ) . expect ( expectedHttpCode ) ; return theCase ; } ; export const getServiceNowSimulationServer = async ( ) : Promise < { server : http . Server ; url : string ; } > => { const server = await getServiceNowServer ( ) ; const port = await getPort ( { port : getPort . makeRange ( 9000 , 9100 ) } ) ; if ( ! server . listening ) { server . listen ( port ) ; } const url = `http://localhost:${ port }` ; return { server , url } ; } ;