Skip to content

Commit

Permalink
[SecuritySolution][Timelines/Notes] Updating API tests (#208218)
Browse files Browse the repository at this point in the history
## Summary

In this PR we're updating some API tests to use the OpenAPI-generated
types and we're unksipping a bunch of tests on ESS.

### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: Elastic Machine <[email protected]>
  • Loading branch information
janmonschke and elasticmachine authored Jan 27, 2025
1 parent b84c65c commit 91268e8
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const persistFavoriteRoute = (router: SecuritySolutionPluginRouter) => {
path: TIMELINE_FAVORITE_URL,
security: {
authz: {
requiredPrivileges: ['timeline_read'],
requiredPrivileges: ['timeline_write'],
},
},
access: 'public',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,26 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
before(async () => {
const superTest = await utils.createSuperTestWithUser(users.secNotesAllUser);
const {
body: { noteId },
body: {
note: { noteId },
},
} = await createNote(superTest, { text: 'test', documentId: '123' });
getNoteId = () => noteId;
});

canWriteOrReadUsers.forEach((user) => {
it(`user "${user.username}" can read notes`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await getNote(superTest, getNoteId()).expect(200);
const getNoteResponse = await getNote(superTest, getNoteId());
expect(getNoteResponse.status).to.be(200);
});
});

cannotAccessUsers.forEach((user) => {
it(`user "${user.username}" cannot read notes`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await getNote(superTest, getNoteId()).expect(403);
const getNoteResponse = await getNote(superTest, getNoteId());
expect(getNoteResponse.status).to.be(403);
});
});
});
Expand Down Expand Up @@ -96,22 +100,26 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
before(async () => {
const superTest = await utils.createSuperTestWithUser(users.secNotesAllUser);
const {
body: { noteId },
body: {
note: { noteId },
},
} = await createNote(superTest, { text: 'test', documentId: '123' });
getNoteId = () => noteId;
});

canWriteUsers.forEach((user) => {
it(`user "${user.username}" can delete notes`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await deleteNote(superTest, getNoteId()).expect(200);
const deleteNoteRequest = await deleteNote(superTest, getNoteId());
expect(deleteNoteRequest.status).to.be(200);
});
});

cannotWriteUsers.forEach((user) => {
it(`user "${user.username}" cannot delete notes`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await deleteNote(superTest, getNoteId()).expect(403);
const deleteNoteRequest = await deleteNote(superTest, getNoteId());
expect(deleteNoteRequest.status).to.be(403);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@
*/

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 { TimelineTypeEnum } from '@kbn/security-solution-plugin/common/api/timeline';
import TestAgent from 'supertest/lib/agent';
import { FtrProviderContextWithSpaces } from '../../../../ftr_provider_context_with_spaces';
import { createBasicTimeline, createBasicTimelineTemplate } from '../../utils/timelines';
import {
createBasicTimeline,
createBasicTimelineTemplate,
getTimelines,
resolveTimeline,
} from '../../utils/timelines';

export default function ({ getService }: FtrProviderContextWithSpaces) {
const utils = getService('securitySolutionUtils');
Expand All @@ -25,9 +29,9 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
const titleToSaved = 'hello timeline';
await createBasicTimeline(supertest, titleToSaved);

const resp = await supertest.get(TIMELINES_URL).set('kbn-xsrf', 'true');

const timelines = resp.body.timeline;
const {
body: { timeline: timelines },
} = await getTimelines(supertest);

expect(timelines.length).to.greaterThan(0);
});
Expand All @@ -36,11 +40,9 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
const titleToSaved = 'hello timeline';
await createBasicTimeline(supertest, titleToSaved);

const resp = await supertest
.get(`${TIMELINES_URL}?page_size=1&page_index=1`)
.set('kbn-xsrf', 'true');

const timelines = resp.body.timeline;
const {
body: { timeline: timelines },
} = await getTimelines(supertest, { page_size: '1', page_index: '1' });

expect(timelines.length).to.equal(1);
});
Expand All @@ -49,11 +51,9 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
const titleToSaved = 'hello timeline template';
await createBasicTimelineTemplate(supertest, titleToSaved);

const resp = await supertest
.get(`${TIMELINES_URL}?timeline_type=template`)
.set('kbn-xsrf', 'true');

const templates: SavedTimeline[] = resp.body.timeline;
const {
body: { timeline: templates },
} = await getTimelines(supertest, { timeline_type: 'template' });

expect(templates.length).to.greaterThan(0);
expect(
Expand All @@ -65,7 +65,7 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
* Migration of saved object not working to current serverless version
* https://github.com/elastic/kibana/issues/196483
* */
describe.skip('resolve timeline', () => {
describe('@skipInServerless resolve timeline', () => {
before(async () => {
await esArchiver.load(
'x-pack/test/functional/es_archives/security_solution/timelines/7.15.0'
Expand All @@ -79,60 +79,49 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
});

it('should return outcome exactMatch when the id is unchanged', async () => {
const resp = await supertest
.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);
expect(resp.body.data.timeline.title).to.be('Awesome Timeline');
const resp = await resolveTimeline(supertest, '8dc70950-1012-11ec-9ad3-2d7c6600c0f7');
expect(resp.body.outcome).to.be('exactMatch');
expect(resp.body.alias_target_id).to.be(undefined);
expect(resp.body.timeline.title).to.be('Awesome Timeline');
});

describe('notes', () => {
it('should return notes with eventId', async () => {
const resp = await supertest
.get(`${TIMELINE_URL}/resolve`)
.query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' });

expect(resp.body.data.timeline.notes[0].eventId).to.be('Edo00XsBEVtyvU-8LGNe');
const resp = await resolveTimeline(supertest, '6484cc90-126e-11ec-83d2-db1096c73738');
expect(resp.body.timeline.notes![0].eventId).to.be('Edo00XsBEVtyvU-8LGNe');
});

it('should return notes with the timelineId matching request id', async () => {
const resp = await supertest
.get(`${TIMELINE_URL}/resolve`)
.query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' });
const resp = await resolveTimeline(supertest, '6484cc90-126e-11ec-83d2-db1096c73738');

expect(resp.body.data.timeline.notes[0].timelineId).to.be(
expect(resp.body.timeline.notes![0].timelineId).to.be(
'6484cc90-126e-11ec-83d2-db1096c73738'
);
expect(resp.body.data.timeline.notes[1].timelineId).to.be(
expect(resp.body.timeline.notes![1].timelineId).to.be(
'6484cc90-126e-11ec-83d2-db1096c73738'
);
});
});

describe('pinned events', () => {
it('should pinned events with eventId', async () => {
const resp = await supertest
.get(`${TIMELINE_URL}/resolve`)
.query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' });
const resp = await resolveTimeline(supertest, '6484cc90-126e-11ec-83d2-db1096c73738');

expect(resp.body.data.timeline.pinnedEventsSaveObject[0].eventId).to.be(
expect(resp.body.timeline.pinnedEventsSaveObject![0].eventId).to.be(
'DNo00XsBEVtyvU-8LGNe'
);
expect(resp.body.data.timeline.pinnedEventsSaveObject[1].eventId).to.be(
expect(resp.body.timeline.pinnedEventsSaveObject![1].eventId).to.be(
'Edo00XsBEVtyvU-8LGNe'
);
});

it('should return pinned events with the timelineId matching request id', async () => {
const resp = await supertest
.get(`${TIMELINE_URL}/resolve`)
.query({ id: '6484cc90-126e-11ec-83d2-db1096c73738' });
const resp = await resolveTimeline(supertest, '6484cc90-126e-11ec-83d2-db1096c73738');

expect(resp.body.data.timeline.pinnedEventsSaveObject[0].timelineId).to.be(
expect(resp.body.timeline.pinnedEventsSaveObject![0].timelineId).to.be(
'6484cc90-126e-11ec-83d2-db1096c73738'
);
expect(resp.body.data.timeline.pinnedEventsSaveObject[1].timelineId).to.be(
expect(resp.body.timeline.pinnedEventsSaveObject![1].timelineId).to.be(
'6484cc90-126e-11ec-83d2-db1096c73738'
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
copyTimeline,
resolveTimeline,
installPrepackedTimelines,
unPinEvent,
} from '../../utils/timelines';
import * as users from '../../../../config/privileges/users';
import { roles } from '../../../../config/privileges/roles';
Expand Down Expand Up @@ -63,14 +64,16 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
canWriteOrReadUsers.forEach((user) => {
it(`user "${user.username}" can read timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await getTimelines(superTest).expect(200);
const getTimelinesResponse = await getTimelines(superTest);
expect(getTimelinesResponse.status).to.be(200);
});
});

cannotAccessUsers.forEach((user) => {
it(`user "${user.username}" cannot read timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await getTimelines(superTest).expect(403);
const getTimelinesResponse = await getTimelines(superTest);
expect(getTimelinesResponse.status).to.be(403);
});
});
});
Expand All @@ -87,14 +90,16 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
canWriteOrReadUsers.forEach((user) => {
it(`user "${user.username}" can resolve timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await resolveTimeline(superTest, getTimelineId()).expect(200);
const resolveTimelineResponse = await resolveTimeline(superTest, getTimelineId());
expect(resolveTimelineResponse.status).to.be(200);
});
});

cannotAccessUsers.forEach((user) => {
it(`user "${user.username}" cannot resolve timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await resolveTimeline(superTest, getTimelineId()).expect(403);
const resolveTimelineResponse = await resolveTimeline(superTest, getTimelineId());
expect(resolveTimelineResponse.status).to.be(403);
});
});
});
Expand All @@ -107,7 +112,8 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
const createResponse = await createBasicTimeline(superTest, 'test timeline');
expect(createResponse.status).to.be(200);

await deleteTimeline(superTest, createResponse.body.savedObjectId).expect(200);
const deleteResponse = await deleteTimeline(superTest, createResponse.body.savedObjectId);
expect(deleteResponse.status).to.be(200);
});
});

Expand All @@ -131,7 +137,8 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {

it(`user "${user.username}" cannot delete timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await deleteTimeline(superTest, getTimelineToDeleteId()).expect(403);
const deleteResponse = await deleteTimeline(superTest, getTimelineToDeleteId());
expect(deleteResponse.status).to.be(403);
});
});
});
Expand Down Expand Up @@ -185,18 +192,23 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
canWriteUsers.forEach((user) => {
it(`user "${user.username}" can favorite/unfavorite timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await favoriteTimeline(superTest, getTimelineId()).expect(200);
const favoriteTimelineRequest = await favoriteTimeline(superTest, getTimelineId());
expect(favoriteTimelineRequest.status).to.be(200);
expect(favoriteTimelineRequest.body.favorite).to.have.length(1);

// unfavorite
await favoriteTimeline(superTest, getTimelineId()).expect(200);
const unFavoriteTimelineRequest = await favoriteTimeline(superTest, getTimelineId());
expect(unFavoriteTimelineRequest.status).to.be(200);
expect(unFavoriteTimelineRequest.body.favorite).to.have.length(0);
});
});

cannotWriteUsers.forEach((user) => {
it(`user "${user.username}" cannot favorite/unfavorite timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);

await favoriteTimeline(superTest, getTimelineId()).expect(403);
const favoriteTimelineRequest = await favoriteTimeline(superTest, getTimelineId());
expect(favoriteTimelineRequest.status).to.be(403);
});
});
});
Expand All @@ -214,18 +226,28 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
canWriteUsers.forEach((user) => {
it(`user "${user.username}" can pin/unpin events`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await pinEvent(superTest, getTimelineId(), eventId).expect(200);
const pinEventResponse = await pinEvent(superTest, getTimelineId(), eventId);
expect(pinEventResponse.status).to.be(200);
expect('pinnedEventId' in pinEventResponse.body).to.be(true);

// unpin
await pinEvent(superTest, getTimelineId(), eventId).expect(200);
const unPinEventResponse = await unPinEvent(
superTest,
getTimelineId(),
eventId,
'pinnedEventId' in pinEventResponse.body ? pinEventResponse.body.pinnedEventId : ''
);
expect(unPinEventResponse.status).to.be(200);
expect(unPinEventResponse.body).to.eql({ unpinned: true });
});
});

cannotWriteUsers.forEach((user) => {
it(`user "${user.username}" cannot pin/unpin events`, async () => {
const superTest = await utils.createSuperTestWithUser(user);

await pinEvent(superTest, getTimelineId(), eventId).expect(403);
const pinEventResponse = await pinEvent(superTest, getTimelineId(), eventId);
expect(pinEventResponse.status).to.be(403);
});
});
});
Expand All @@ -242,15 +264,25 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
it(`user "${user.username}" can copy timeline`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
const timeline = getTimeline();
await copyTimeline(superTest, timeline.savedObjectId, timeline).expect(200);
const copyTimelineResponse = await copyTimeline(
superTest,
timeline.savedObjectId,
timeline
);
expect(copyTimelineResponse.status).to.be(200);
});
});

cannotWriteUsers.forEach((user) => {
it(`user "${user.username}" cannot copy timeline`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
const timeline = getTimeline();
await copyTimeline(superTest, timeline.savedObjectId, timeline).expect(403);
const copyTimelineResponse = await copyTimeline(
superTest,
timeline.savedObjectId,
timeline
);
expect(copyTimelineResponse.status).to.be(403);
});
});
});
Expand All @@ -259,14 +291,16 @@ export default function ({ getService }: FtrProviderContextWithSpaces) {
canWriteUsers.forEach((user) => {
it(`user "${user.username}" can install prepackaged timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await installPrepackedTimelines(superTest).expect(200);
const installTimelinesResponse = await installPrepackedTimelines(superTest);
expect(installTimelinesResponse.status).to.be(200);
});
});

cannotWriteUsers.forEach((user) => {
it(`user "${user.username}" cannot install prepackaged timelines`, async () => {
const superTest = await utils.createSuperTestWithUser(user);
await installPrepackedTimelines(superTest).expect(403);
const installTimelinesResponse = await installPrepackedTimelines(superTest);
expect(installTimelinesResponse.status).to.be(403);
});
});
});
Expand Down
Loading

0 comments on commit 91268e8

Please sign in to comment.