diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/draft_timeline.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/draft_timeline.ts index f084afa62d6af2..dafb08124b0e5b 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/draft_timeline.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/draft_timeline.ts @@ -6,21 +6,21 @@ */ import expect from '@kbn/expect'; +import { TIMELINE_DRAFT_URL } from '@kbn/security-solution-plugin/common/constants'; +import TestAgent from 'supertest/lib/agent'; +import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; -import { FtrProviderContext } from '../../../../../api_integration/ftr_provider_context'; - -export default function ({ getService }: FtrProviderContext) { - const kibanaServer = getService('kibanaServer'); - const supertest = getService('supertest'); +export default function ({ getService }: FtrProviderContextWithSpaces) { + const utils = getService('securitySolutionUtils'); + let supertest: TestAgent; describe('Draft timeline - Saved Objects', () => { - before(() => kibanaServer.savedObjects.cleanStandardList()); - after(() => kibanaServer.savedObjects.cleanStandardList()); + before(async () => (supertest = await utils.createSuperTest())); describe('Clean draft timelines', () => { it('returns a draft timeline if none exists', async () => { const response = await supertest - .post('/api/timeline/_draft') + .post(TIMELINE_DRAFT_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ @@ -36,7 +36,7 @@ export default function ({ getService }: FtrProviderContext) { it('returns a draft timeline template if none exists', async () => { const response = await supertest - .post('/api/timeline/_draft') + .post(TIMELINE_DRAFT_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ @@ -60,7 +60,7 @@ export default function ({ getService }: FtrProviderContext) { it('returns a cleaned draft timeline if another one already exists', async () => { const response = await supertest - .post('/api/timeline/_draft') + .post(TIMELINE_DRAFT_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ @@ -114,7 +114,7 @@ export default function ({ getService }: FtrProviderContext) { expect(noteIds).to.have.length(1, 'should have one note'); const cleanDraftTimelineRequest = await supertest - .post('/api/timeline/_draft') + .post(TIMELINE_DRAFT_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/notes.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/notes.ts index 027c0a20262a81..4596297f9411a9 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/notes.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/notes.ts @@ -7,26 +7,26 @@ import expect from '@kbn/expect'; import { v4 as uuidv4 } from 'uuid'; -import { Note } from '@kbn/security-solution-plugin/common/api/timeline'; -import { createNote, deleteAllNotes } from './helpers'; -import { FtrProviderContext } from '../../../../../api_integration/ftr_provider_context'; - -export default function ({ getService }: FtrProviderContext) { - const kibanaServer = getService('kibanaServer'); - const supertest = getService('supertest'); - - // Failing: See https://github.com/elastic/kibana/issues/196492 - describe.skip('Note - Saved Objects', () => { - const es = getService('es'); - - before(() => kibanaServer.savedObjects.cleanStandardList()); - after(() => kibanaServer.savedObjects.cleanStandardList()); +import { GetNotesResult, Note } from '@kbn/security-solution-plugin/common/api/timeline'; +import { NOTE_URL } from '@kbn/security-solution-plugin/common/constants'; +import TestAgent from 'supertest/lib/agent'; +import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; +import { createNote, deleteNotes } from '../../utils/notes'; + +export default function ({ getService }: FtrProviderContextWithSpaces) { + const utils = getService('securitySolutionUtils'); + let supertest: TestAgent; + + describe('Note - Saved Objects', () => { + before(async () => { + supertest = await utils.createSuperTest(); + }); describe('create a note', () => { it('should return a timelineId, noteId and version', async () => { const myNote = 'world test'; const response = await supertest - .patch('/api/note') + .patch(NOTE_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ @@ -44,10 +44,10 @@ export default function ({ getService }: FtrProviderContext) { expect(version).to.not.be.empty(); }); - it('if noteId exist update note and return existing noteId and new version', async () => { + it('should update note and return existing noteId and new version if noteId exist', async () => { const myNote = 'world test'; const response = await supertest - .patch('/api/note') + .patch(NOTE_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ @@ -61,7 +61,7 @@ export default function ({ getService }: FtrProviderContext) { const myNewNote = 'new world test'; const responseToTest = await supertest - .patch('/api/note') + .patch(NOTE_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ @@ -78,7 +78,7 @@ export default function ({ getService }: FtrProviderContext) { describe('get notes', () => { beforeEach(async () => { - await deleteAllNotes(es); + await deleteNotes(supertest); }); const eventId1 = uuidv4(); @@ -117,11 +117,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get(`/api/note?documentIds=${eventId1}`) + .get(`${NOTE_URL}?documentIds=${eventId1}`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(2); notes.forEach((note: Note) => expect(note.eventId).to.be(eventId1)); @@ -172,11 +171,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get(`/api/note?documentIds=${eventId1}&documentIds=${eventId2}`) + .get(`${NOTE_URL}?documentIds=${eventId1}&documentIds=${eventId2}`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(4); notes.forEach((note: Note) => { @@ -214,11 +212,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get(`/api/note?savedObjectIds=${timelineId1}`) + .get(`${NOTE_URL}?savedObjectIds=${timelineId1}`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(2); notes.forEach((note: Note) => expect(note.timelineId).to.be(timelineId1)); @@ -269,11 +266,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get(`/api/note?savedObjectIds=${timelineId1}&savedObjectIds=${timelineId2}`) + .get(`${NOTE_URL}?savedObjectIds=${timelineId1}&savedObjectIds=${timelineId2}`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(4); notes.forEach((note: Note) => { @@ -298,16 +294,15 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note') + .get(NOTE_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount } = response.body; + const { totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(4); }); - it('should retrieve notes considering perPage query parameter', async () => { + it('should retrieve notes considering perPage and page query parameters', async () => { await Promise.all([ createNote(supertest, { text: 'first note' }), createNote(supertest, { text: 'second note' }), @@ -315,31 +310,13 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?perPage=1') - .set('kbn-xsrf', 'true') - .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; - - expect(totalCount).to.be(3); - expect(notes.length).to.be(1); - }); - - it('should retrieve considering page query parameter', async () => { - await createNote(supertest, { text: 'first note' }); - await createNote(supertest, { text: 'second note' }); - await createNote(supertest, { text: 'third note' }); - - const response = await supertest - .get('/api/note?perPage=1&page=2') + .get(`${NOTE_URL}?perPage=1`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(3); expect(notes.length).to.be(1); - expect(notes[0].note).to.be('second note'); }); it('should retrieve considering search query parameter', async () => { @@ -358,11 +335,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?search=event') + .get(`${NOTE_URL}?search=event`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount } = response.body; + const { totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(2); }); @@ -376,11 +352,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?sortField=eventId') + .get(`${NOTE_URL}?sortField=eventId`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(3); expect(notes[0].eventId).to.be('1'); @@ -396,11 +371,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?sortField=eventId&sortOrder=desc') + .get(`${NOTE_URL}?sortField=eventId&sortOrder=desc`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(3); expect(notes[0].eventId).to.be('3'); @@ -408,21 +382,22 @@ export default function ({ getService }: FtrProviderContext) { expect(notes[2].eventId).to.be('1'); }); - // TODO figure out why this test is failing on CI but not locally - it.skip('should retrieve all notes that have been created by a specific user', async () => { - await Promise.all([ - createNote(supertest, { text: 'first note' }), - createNote(supertest, { text: 'second note' }), - ]); - - const response = await supertest - .get('/api/note?userFilter=elastic') - .set('kbn-xsrf', 'true') - .set('elastic-api-version', '2023-10-31'); - - const { totalCount } = response.body; - - expect(totalCount).to.be(2); + // skipped https://github.com/elastic/kibana/issues/196896 + describe('@skipInServerless', () => { + it('should retrieve all notes that have been created by a specific user', async () => { + await Promise.all([ + createNote(supertest, { text: 'first note' }), + createNote(supertest, { text: 'second note' }), + ]); + + const response = await supertest + .get(`${NOTE_URL}?userFilter=elastic`) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', '2023-10-31'); + const { totalCount } = response.body as GetNotesResult; + + expect(totalCount).to.be(2); + }); }); it('should return nothing if no notes have been created by that user', async () => { @@ -432,11 +407,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?userFilter=user1') + .get(`${NOTE_URL}?userFilter=user1`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount } = response.body; + const { totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(0); }); @@ -457,11 +431,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?associatedFilter=document_only') + .get(`${NOTE_URL}?associatedFilter=document_only`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(1); expect(notes[0].eventId).to.be(eventId1); @@ -483,11 +456,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?associatedFilter=saved_object_only') + .get(`${NOTE_URL}?associatedFilter=saved_object_only`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(1); expect(notes[0].timelineId).to.be(timelineId1); @@ -509,11 +481,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?associatedFilter=document_and_saved_object') + .get(`${NOTE_URL}?associatedFilter=document_and_saved_object`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(1); expect(notes[0].eventId).to.be(eventId1); @@ -536,11 +507,10 @@ export default function ({ getService }: FtrProviderContext) { ]); const response = await supertest - .get('/api/note?associatedFilter=orphan') + .get(`${NOTE_URL}?associatedFilter=orphan`) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31'); - - const { totalCount, notes } = response.body; + const { notes, totalCount } = response.body as GetNotesResult; expect(totalCount).to.be(1); expect(notes[0].eventId).to.be(''); diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/pinned_events.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/pinned_events.ts index 9506e7345a00e9..183c56fc2d8f36 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/pinned_events.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/pinned_events.ts @@ -6,21 +6,21 @@ */ import expect from '@kbn/expect'; +import { PINNED_EVENT_URL } from '@kbn/security-solution-plugin/common/constants'; +import TestAgent from 'supertest/lib/agent'; +import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; -import { FtrProviderContext } from '../../../../../api_integration/ftr_provider_context'; - -export default function ({ getService }: FtrProviderContext) { - const kibanaServer = getService('kibanaServer'); - const supertest = getService('supertest'); +export default function ({ getService }: FtrProviderContextWithSpaces) { + const utils = getService('securitySolutionUtils'); + let supertest: TestAgent; describe('Pinned Events - Saved Objects', () => { - before(() => kibanaServer.savedObjects.cleanStandardList()); - after(() => kibanaServer.savedObjects.cleanStandardList()); + before(async () => (supertest = await utils.createSuperTest())); - describe('Pinned an event', () => { + describe('pin an event', () => { it('return a timelineId, pinnedEventId and version', async () => { const response = await supertest - .patch('/api/pinned_event') + .patch(PINNED_EVENT_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ @@ -38,10 +38,10 @@ export default function ({ getService }: FtrProviderContext) { }); }); - describe('Unpinned an event', () => { + describe('unpin an event', () => { it('returns null', async () => { const response = await supertest - .patch('/api/pinned_event') + .patch(PINNED_EVENT_URL) .set('elastic-api-version', '2023-10-31') .set('kbn-xsrf', 'true') .send({ @@ -53,7 +53,7 @@ export default function ({ getService }: FtrProviderContext) { response.body.data && response.body.data.persistPinnedEventOnTimeline; const responseToTest = await supertest - .patch('/api/pinned_event') + .patch(PINNED_EVENT_URL) .set('kbn-xsrf', 'true') .set('elastic-api-version', '2023-10-31') .send({ diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/timeline.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/timeline.ts index 3206c14eee04dc..8029fce1c7b90b 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/timeline.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/timeline.ts @@ -10,17 +10,17 @@ import { TimelineResponse, TimelineTypeEnum, } from '@kbn/security-solution-plugin/common/api/timeline'; -import { FtrProviderContext } from '../../../../../api_integration/ftr_provider_context'; +import { TIMELINE_URL } from '@kbn/security-solution-plugin/common/constants'; +import TestAgent from 'supertest/lib/agent'; +import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; +import { createBasicTimeline } from '../../utils/timelines'; -import { createBasicTimeline } from './helpers'; - -export default function ({ getService }: FtrProviderContext) { - const kibanaServer = getService('kibanaServer'); - const supertest = getService('supertest'); +export default function ({ getService }: FtrProviderContextWithSpaces) { + const utils = getService('securitySolutionUtils'); + let supertest: TestAgent; describe('Timeline - Saved Objects', () => { - beforeEach(() => kibanaServer.savedObjects.cleanStandardList()); - afterEach(() => kibanaServer.savedObjects.cleanStandardList()); + before(async () => (supertest = await utils.createSuperTest())); describe('Persist a timeline', () => { it('Create a timeline just with a title', async () => { @@ -136,7 +136,7 @@ export default function ({ getService }: FtrProviderContext) { sort: { columnId: '@timestamp', sortDirection: 'desc' }, }; - const response = await supertest.post('/api/timeline').set('kbn-xsrf', 'true').send({ + const response = await supertest.post(TIMELINE_URL).set('kbn-xsrf', 'true').send({ timelineId: null, version: null, timeline: timelineObject, @@ -178,7 +178,7 @@ export default function ({ getService }: FtrProviderContext) { const newTitle = 'new title'; const responseToTest = await supertest - .patch('/api/timeline') + .patch(TIMELINE_URL) .set('kbn-xsrf', 'true') .send({ timelineId: savedObjectId, @@ -383,7 +383,7 @@ export default function ({ getService }: FtrProviderContext) { const { savedObjectId } = response.body.data && response.body.data.persistTimeline.timeline; const responseToTest = await supertest - .delete('/api/timeline') + .delete(TIMELINE_URL) .set('kbn-xsrf', 'true') .send({ savedObjectIds: [savedObjectId], @@ -407,7 +407,7 @@ export default function ({ getService }: FtrProviderContext) { : ''; const responseToTest = await supertest - .delete('/api/timeline') + .delete(TIMELINE_URL) .set('kbn-xsrf', 'true') .send({ savedObjectIds: [savedObjectId1, savedObjectId2], diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/import_timelines.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/import_timelines.ts index 90f56e82a310af..375d52a26bde29 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/import_timelines.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/import_timelines.ts @@ -6,17 +6,20 @@ */ import expect from '@kbn/expect'; - import { TIMELINE_IMPORT_URL } from '@kbn/security-solution-plugin/common/constants'; - +import TestAgent from 'supertest/lib/agent'; import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; -import { deleteAllTimelines } from '../utils'; +import { deleteTimelines } from '../../utils/timelines'; export default ({ getService }: FtrProviderContextWithSpaces): void => { - const supertest = getService('supertest'); - const es = getService('es'); + const utils = getService('securitySolutionUtils'); + let supertest: TestAgent; describe('import timelines', () => { + before(async () => { + supertest = await utils.createSuperTest(); + }); + describe('creating a timeline', () => { const getTimeline = () => { return Buffer.from( @@ -135,15 +138,14 @@ export default ({ getService }: FtrProviderContextWithSpaces): void => { }) ); }; - beforeEach(async () => {}); afterEach(async () => { - await deleteAllTimelines(es); + await deleteTimelines(supertest); }); it("if it doesn't exists", async () => { const { body } = await supertest - .post(`${TIMELINE_IMPORT_URL}`) + .post(TIMELINE_IMPORT_URL) .set('kbn-xsrf', 'true') .attach('file', getTimeline(), 'timelines.ndjson') .expect(200); @@ -257,12 +259,12 @@ export default ({ getService }: FtrProviderContextWithSpaces): void => { }; afterEach(async () => { - await deleteAllTimelines(es); + await deleteTimelines(supertest); }); it("if it doesn't exists", async () => { const { body } = await supertest - .post(`${TIMELINE_IMPORT_URL}`) + .post(TIMELINE_IMPORT_URL) .set('kbn-xsrf', 'true') .attach('file', getTimelineTemplate(), 'timelines.ndjson') .expect(200); @@ -376,17 +378,17 @@ export default ({ getService }: FtrProviderContextWithSpaces): void => { }; afterEach(async () => { - await deleteAllTimelines(es); + await deleteTimelines(supertest); }); it("if it doesn't exists", async () => { await supertest - .post(`${TIMELINE_IMPORT_URL}`) + .post(TIMELINE_IMPORT_URL) .set('kbn-xsrf', 'true') .attach('file', getTimelineTemplate(1), 'timelines.ndjson') .expect(200); const { body } = await supertest - .post(`${TIMELINE_IMPORT_URL}`) + .post(TIMELINE_IMPORT_URL) .set('kbn-xsrf', 'true') .attach('file', getTimelineTemplate(2), 'timelines.ndjson') .expect(200); diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/install_prepackaged_timelines.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/install_prepackaged_timelines.ts index 58c9442b12159f..656abe74c525c0 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/install_prepackaged_timelines.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/install_prepackaged_timelines.ts @@ -6,19 +6,23 @@ */ import expect from '@kbn/expect'; - import { TIMELINE_PREPACKAGED_URL } from '@kbn/security-solution-plugin/common/constants'; +import TestAgent from 'supertest/lib/agent'; import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; -import { deleteAllTimelines } from '../utils'; +import { deleteTimelines } from '../../utils/timelines'; export default ({ getService }: FtrProviderContextWithSpaces): void => { - const supertest = getService('supertest'); - const es = getService('es'); + const utils = getService('securitySolutionUtils'); + let supertest: TestAgent; describe('install_prepackaged_timelines', () => { + before(async () => { + supertest = await utils.createSuperTest(); + }); + describe('creating prepackaged rules', () => { afterEach(async () => { - await deleteAllTimelines(es); + await deleteTimelines(supertest); }); it('should contain timelines_installed, and timelines_updated', async () => { diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline.ts index db5abd723f6f60..5a0b79174293f3 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline.ts @@ -7,24 +7,25 @@ import expect from '@kbn/expect'; import { SavedTimeline, TimelineTypeEnum } from '@kbn/security-solution-plugin/common/api/timeline'; - +import { TIMELINE_URL, TIMELINES_URL } from '@kbn/security-solution-plugin/common/constants'; +import TestAgent from 'supertest/lib/agent'; import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; -import { - createBasicTimeline, - createBasicTimelineTemplate, -} from '../../saved_objects/tests/helpers'; +import { createBasicTimeline, createBasicTimelineTemplate } from '../../utils/timelines'; export default function ({ getService }: FtrProviderContextWithSpaces) { - const supertest = getService('supertest'); + const utils = getService('securitySolutionUtils'); const esArchiver = getService('esArchiver'); + let supertest: TestAgent; describe('Timeline', () => { + before(async () => (supertest = await utils.createSuperTest())); + describe('timelines', () => { it('Make sure that we get Timeline data', async () => { const titleToSaved = 'hello timeline'; await createBasicTimeline(supertest, titleToSaved); - const resp = await supertest.get('/api/timelines').set('kbn-xsrf', 'true'); + const resp = await supertest.get(TIMELINES_URL).set('kbn-xsrf', 'true'); const timelines = resp.body.timeline; @@ -36,7 +37,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { await createBasicTimeline(supertest, titleToSaved); const resp = await supertest - .get('/api/timelines?page_size=1&page_index=1') + .get(`${TIMELINES_URL}?page_size=1&page_index=1`) .set('kbn-xsrf', 'true'); const timelines = resp.body.timeline; @@ -49,7 +50,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { await createBasicTimelineTemplate(supertest, titleToSaved); const resp = await supertest - .get('/api/timelines?timeline_type=template') + .get(`${TIMELINES_URL}?timeline_type=template`) .set('kbn-xsrf', 'true'); const templates: SavedTimeline[] = resp.body.timeline; @@ -79,7 +80,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('should return outcome exactMatch when the id is unchanged', async () => { const resp = await supertest - .get('/api/timeline/resolve') + .get(`${TIMELINE_URL}/resolve`) .query({ id: '8dc70950-1012-11ec-9ad3-2d7c6600c0f7' }); expect(resp.body.data.outcome).to.be('exactMatch'); expect(resp.body.data.alias_target_id).to.be(undefined); @@ -89,7 +90,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { describe('notes', () => { it('should return notes with eventId', async () => { const resp = await supertest - .get('/api/timeline/resolve') + .get(`${TIMELINE_URL}/resolve`) .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); expect(resp.body.data.timeline.notes[0].eventId).to.be('Edo00XsBEVtyvU-8LGNe'); @@ -97,7 +98,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('should return notes with the timelineId matching request id', async () => { const resp = await supertest - .get('/api/timeline/resolve') + .get(`${TIMELINE_URL}/resolve`) .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); expect(resp.body.data.timeline.notes[0].timelineId).to.be( @@ -112,7 +113,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { describe('pinned events', () => { it('should pinned events with eventId', async () => { const resp = await supertest - .get('/api/timeline/resolve') + .get(`${TIMELINE_URL}/resolve`) .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); expect(resp.body.data.timeline.pinnedEventsSaveObject[0].eventId).to.be( @@ -125,7 +126,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('should return pinned events with the timelineId matching request id', async () => { const resp = await supertest - .get('/api/timeline/resolve') + .get(`${TIMELINE_URL}/resolve`) .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); expect(resp.body.data.timeline.pinnedEventsSaveObject[0].timelineId).to.be( diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline_details.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline_details.ts index 7d127ab7c0f96f..e614f7d30d14fb 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline_details.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline_details.ts @@ -13,7 +13,6 @@ import { TimelineKpiStrategyResponse, } from '@kbn/security-solution-plugin/common/search_strategy'; import TestAgent from 'supertest/lib/agent'; - import { BsearchService } from '@kbn/ftr-common-functional-services'; import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; import { timelineDetailsFilebeatExpectedResults as EXPECTED_DATA } from '../mocks/timeline_details'; @@ -33,15 +32,16 @@ const EXPECTED_KPI_COUNTS = { export default function ({ getService }: FtrProviderContextWithSpaces) { const esArchiver = getService('esArchiver'); const utils = getService('securitySolutionUtils'); + let supertest: TestAgent; + let bsearch: BsearchService; describe('@skipInServerless Timeline Details', () => { - let supertest: TestAgent; - let bsearch: BsearchService; before(async () => { supertest = await utils.createSuperTest(); bsearch = await utils.createBsearch(); await esArchiver.load('x-pack/test/functional/es_archives/filebeat/default'); }); + after( async () => await esArchiver.unload('x-pack/test/functional/es_archives/filebeat/default') ); diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline_migrations.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline_migrations.ts index 4aafce9938ae17..2e8a8fd4aaa942 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline_migrations.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/tests/timeline_migrations.ts @@ -16,6 +16,8 @@ import { BarePinnedEventWithoutExternalRefs, TimelineWithoutExternalRefs, } from '@kbn/security-solution-plugin/common/api/timeline'; +import { TIMELINE_URL } from '@kbn/security-solution-plugin/common/constants'; +import TestAgent from 'supertest/lib/agent'; import type { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces'; import { getSavedObjectFromES } from '../../../utils'; @@ -32,9 +34,14 @@ interface PinnedEventWithoutTimelineId { } export default function ({ getService }: FtrProviderContextWithSpaces) { - const supertest = getService('supertest'); + const utils = getService('securitySolutionUtils'); + let supertest: TestAgent; describe('@skipInServerless Timeline migrations', () => { + before(async () => { + supertest = await utils.createSuperTest(); + }); + const esArchiver = getService('esArchiver'); const es = getService('es'); const kibanaServer = getService('kibanaServer'); @@ -151,7 +158,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('preserves the eventId in the saved object after migration', async () => { const resp = await supertest - .get('/api/timeline') + .get(TIMELINE_URL) .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); expect(resp.body.data.getOneTimeline.notes[0].eventId).to.be('Edo00XsBEVtyvU-8LGNe'); @@ -159,7 +166,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('returns the timelineId in the response', async () => { const resp = await supertest - .get('/api/timeline') + .get(TIMELINE_URL) .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); expect(resp.body.data.getOneTimeline.notes[0].timelineId).to.be( @@ -188,7 +195,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('preserves the title in the saved object after migration', async () => { const resp = await supertest - .get('/api/timeline') + .get(TIMELINE_URL) .query({ id: '8dc70950-1012-11ec-9ad3-2d7c6600c0f7' }); expect(resp.body.data.getOneTimeline.title).to.be('Awesome Timeline'); @@ -196,7 +203,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('returns the savedQueryId in the response', async () => { const resp = await supertest - .get('/api/timeline') + .get(TIMELINE_URL) .query({ id: '8dc70950-1012-11ec-9ad3-2d7c6600c0f7' }); expect(resp.body.data.getOneTimeline.savedQueryId).to.be("It's me"); @@ -228,7 +235,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('preserves the eventId in the saved object after migration', async () => { const resp = await supertest - .get('/api/timeline') + .get(TIMELINE_URL) .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); expect(resp.body.data.getOneTimeline.pinnedEventsSaveObject[0].eventId).to.be( @@ -241,7 +248,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) { it('returns the timelineId in the response', async () => { const resp = await supertest - .get('/api/timeline') + .get(TIMELINE_URL) .query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' }); expect(resp.body.data.getOneTimeline.pinnedEventsSaveObject[0].timelineId).to.be( diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/utils/delete_all_timelines.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/utils/delete_all_timelines.ts deleted file mode 100644 index 291cd269580b07..00000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/utils/delete_all_timelines.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 type { Client } from '@elastic/elasticsearch'; -import { SECURITY_SOLUTION_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; - -/** - * Remove all timelines from the security solution savedObjects index - * @param es The ElasticSearch handle - */ -export const deleteAllTimelines = async (es: Client): Promise => { - await es.deleteByQuery({ - index: SECURITY_SOLUTION_SAVED_OBJECT_INDEX, - q: 'type:siem-ui-timeline', - wait_for_completion: true, - refresh: true, - body: {}, - }); -}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/utils/index.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/utils/index.ts deleted file mode 100644 index d43b824d2b4280..00000000000000 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/utils/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * 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. - */ - -export * from './delete_all_timelines'; -export * from './wait_for'; diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/utils/notes.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/utils/notes.ts new file mode 100644 index 00000000000000..84db87aefb8f79 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/utils/notes.ts @@ -0,0 +1,60 @@ +/* + * 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 type SuperTest from 'supertest'; +import { + GetNotesResult, + Note, + PersistNoteRouteRequestBody, +} from '@kbn/security-solution-plugin/common/api/timeline'; +import { NOTE_URL } from '@kbn/security-solution-plugin/common/constants'; + +/** + * Deletes the first 100 notes (the getNotes endpoints is paginated and defaults to 10 is nothing is provided) + * This works in ess, serverless and on the MKI environments as it avoids having to look at hidden indexes. + */ +export const deleteNotes = async (supertest: SuperTest.Agent): Promise => { + const response = await supertest + .get(`${NOTE_URL}?perPage=100`) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', '2023-10-31'); + const { notes } = response.body as GetNotesResult; + + await supertest + .delete(NOTE_URL) + .set('kbn-xsrf', 'true') + .send({ + noteIds: notes.map((note: Note) => note.noteId), + }); +}; + +/** + * Create a note that can be attached to a document only, a saved object only, both or none + * + * @param supertest + * @param note + * documentId is the document (alert, event...) id we want to associate the note with + * savedObjectId is the id of the saved object (most likely a timeline id) we want to associate the note with + */ +export const createNote = async ( + supertest: SuperTest.Agent, + note: { + documentId?: string; + savedObjectId?: string; + text: string; + } +) => + await supertest + .patch(NOTE_URL) + .set('kbn-xsrf', 'true') + .send({ + note: { + eventId: note.documentId || '', + timelineId: note.savedObjectId || '', + note: note.text, + }, + } as PersistNoteRouteRequestBody); diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/helpers.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/utils/timelines.ts similarity index 50% rename from x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/helpers.ts rename to x-pack/test/security_solution_api_integration/test_suites/investigation/utils/timelines.ts index 5bf4d61c8b5959..4a5d849e8565d7 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/investigation/saved_objects/tests/helpers.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/investigation/utils/timelines.ts @@ -8,17 +8,36 @@ import type SuperTest from 'supertest'; import { v4 as uuidv4 } from 'uuid'; import { - PersistNoteRouteRequestBody, + GetTimelinesResponse, + SavedTimelineWithSavedObjectId, TimelineTypeEnum, } from '@kbn/security-solution-plugin/common/api/timeline'; -import { NOTE_URL } from '@kbn/security-solution-plugin/common/constants'; -import type { Client } from '@elastic/elasticsearch'; -import { SECURITY_SOLUTION_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server'; -import { noteSavedObjectType } from '@kbn/security-solution-plugin/server/lib/timeline/saved_object_mappings'; +import { TIMELINE_URL } from '@kbn/security-solution-plugin/common/constants'; + +/** + * Deletes the first 100 timelines. + * This works in ess, serverless and on the MKI environments as it avoids having to look at hidden indexes. + */ +export const deleteTimelines = async (supertest: SuperTest.Agent): Promise => { + const response = await supertest + .get('/api/timelines') + .set('kbn-xsrf', 'true') + .set('elastic-api-version', '2023-10-31'); + const { timeline: timelines } = response.body as GetTimelinesResponse; + + await supertest + .delete(TIMELINE_URL) + .set('kbn-xsrf', 'true') + .send({ + savedObjectIds: timelines.map( + (timeline: SavedTimelineWithSavedObjectId) => timeline.savedObjectId + ), + }); +}; export const createBasicTimeline = async (supertest: SuperTest.Agent, titleToSaved: string) => await supertest - .post('/api/timeline') + .post(TIMELINE_URL) .set('kbn-xsrf', 'true') .send({ timelineId: null, @@ -33,7 +52,7 @@ export const createBasicTimelineTemplate = async ( titleToSaved: string ) => await supertest - .post('/api/timeline') + .post(TIMELINE_URL) .set('kbn-xsrf', 'true') .send({ timelineId: null, @@ -45,36 +64,3 @@ export const createBasicTimelineTemplate = async ( timelineType: TimelineTypeEnum.template, }, }); - -export const deleteAllNotes = async (es: Client): Promise => { - await es.deleteByQuery({ - index: SECURITY_SOLUTION_SAVED_OBJECT_INDEX, - q: `type:${noteSavedObjectType}`, - wait_for_completion: true, - refresh: true, - body: {}, - }); -}; - -export const createNote = async ( - supertest: SuperTest.Agent, - note: { - documentId?: string; - savedObjectId?: string; - text: string; - } -) => - await supertest - .patch(NOTE_URL) - .set('kbn-xsrf', 'true') - .send({ - note: { - eventId: note.documentId || '', - timelineId: note.savedObjectId || '', - created: Date.now(), - createdBy: 'elastic', - updated: Date.now(), - updatedBy: 'elastic', - note: note.text, - }, - } as PersistNoteRouteRequestBody); diff --git a/x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/utils/wait_for.ts b/x-pack/test/security_solution_api_integration/test_suites/investigation/utils/wait_for.ts similarity index 100% rename from x-pack/test/security_solution_api_integration/test_suites/investigation/timeline/utils/wait_for.ts rename to x-pack/test/security_solution_api_integration/test_suites/investigation/utils/wait_for.ts