Skip to content

Commit

Permalink
unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
angorayc committed Aug 4, 2020
1 parent 86bf9e4 commit e03918d
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ export interface Note {
request: FrameworkRequest,
noteId: string | null,
version: string | null,
note: SavedNote
note: SavedNote,
overideOwner: boolean
) => Promise<ResponseNote>;
convertSavedObjectToSavedNote: (
savedObject: unknown,
Expand Down Expand Up @@ -137,7 +138,7 @@ export const persistNote = async (
noteId: string | null,
version: string | null,
note: SavedNote,
overideNote: boolean = true
overideOwner: boolean = true
): Promise<ResponseNote> => {
try {
const savedObjectsClient = request.context.core.savedObjects.client;
Expand All @@ -164,7 +165,7 @@ export const persistNote = async (
note: convertSavedObjectToSavedNote(
await savedObjectsClient.create(
noteSavedObjectType,
overideNote ? pickSavedNote(noteId, note, request.user) : note
overideOwner ? pickSavedNote(noteId, note, request.user) : note
),
timelineVersionSavedObject != null ? timelineVersionSavedObject : undefined
),
Expand All @@ -181,7 +182,7 @@ export const persistNote = async (
await savedObjectsClient.update(
noteSavedObjectType,
noteId,
overideNote ? pickSavedNote(noteId, note, request.user) : note,
overideOwner ? pickSavedNote(noteId, note, request.user) : note,
{
version: existingNote.version || undefined,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
TimelineStatusActions,
} from './utils/common';
import { createTimelines } from './utils/create_timelines';
import { DEFAULT_ERROR } from './utils/failure_cases';

export const createTimelinesRoute = (
router: IRouter,
Expand Down Expand Up @@ -85,7 +86,7 @@ export const createTimelinesRoute = (
return siemResponse.error(
compareTimelinesStatus.checkIsFailureCases(TimelineStatusActions.create) || {
statusCode: 405,
body: 'update timeline error',
body: DEFAULT_ERROR,
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('import timelines', () => {
let mockPersistTimeline: jest.Mock;
let mockPersistPinnedEventOnTimeline: jest.Mock;
let mockPersistNote: jest.Mock;
let mockGetNote: jest.Mock;
let mockGetTupleDuplicateErrorsAndUniqueTimeline: jest.Mock;

beforeEach(() => {
Expand All @@ -69,6 +70,7 @@ describe('import timelines', () => {
mockPersistTimeline = jest.fn();
mockPersistPinnedEventOnTimeline = jest.fn();
mockPersistNote = jest.fn();
mockGetNote = jest.fn();
mockGetTupleDuplicateErrorsAndUniqueTimeline = jest.fn();

jest.doMock('../create_timelines_stream_from_ndjson', () => {
Expand Down Expand Up @@ -113,6 +115,37 @@ describe('import timelines', () => {
jest.doMock('../../note/saved_object', () => {
return {
persistNote: mockPersistNote,
getNote: mockGetNote
.mockResolvedValueOnce({
noteId: 'd2649d40-6bc5-11ea-86f0-5db0048c6086',
version: 'WzExNjQsMV0=',
eventId: undefined,
note: 'original note',
created: '1584830796960',
createdBy: 'original author A',
updated: '1584830796960',
updatedBy: 'original author A',
})
.mockResolvedValueOnce({
noteId: '73ac2370-6bc2-11ea-a90b-f5341fb7a189',
version: 'WzExMjgsMV0=',
eventId: 'ZaAi8nAB5OldxqFfdhke',
note: 'original event note',
created: '1584830796960',
createdBy: 'original author B',
updated: '1584830796960',
updatedBy: 'original author B',
})
.mockResolvedValue({
noteId: 'f7b71620-6bc2-11ea-a0b6-33c7b2a78885',
version: 'WzExMzUsMV0=',
eventId: 'ZaAi8nAB5OldxqFfdhke',
note: 'event note2',
created: '1584830796960',
createdBy: 'angela',
updated: '1584830796960',
updatedBy: 'angela',
}),
};
});

Expand Down Expand Up @@ -213,6 +246,14 @@ describe('import timelines', () => {
);
});

test('should Check if note exists', async () => {
const mockRequest = getImportTimelinesRequest();
await server.inject(mockRequest, context);
expect(mockGetNote.mock.calls[0][1]).toEqual(
mockUniqueParsedObjects[0].globalNotes[0].noteId
);
});

test('should Create notes', async () => {
const mockRequest = getImportTimelinesRequest();
await server.inject(mockRequest, context);
Expand All @@ -237,34 +278,69 @@ describe('import timelines', () => {
expect(mockPersistNote.mock.calls[0][2]).toEqual(mockCreatedTimeline.version);
});

test('should provide new notes when Creating notes for a timeline', async () => {
test('should provide new notes with original author info when Creating notes for a timeline', async () => {
const mockRequest = getImportTimelinesRequest();
await server.inject(mockRequest, context);
expect(mockPersistNote.mock.calls[0][3]).toEqual({
eventId: undefined,
note: mockUniqueParsedObjects[0].globalNotes[0].note,
note: 'original note',
created: '1584830796960',
createdBy: 'original author A',
updated: '1584830796960',
updatedBy: 'original author A',
timelineId: mockCreatedTimeline.savedObjectId,
});
expect(mockPersistNote.mock.calls[1][3]).toEqual({
eventId: mockUniqueParsedObjects[0].eventNotes[0].eventId,
note: 'original event note',
created: '1584830796960',
createdBy: 'original author B',
updated: '1584830796960',
updatedBy: 'original author B',
timelineId: mockCreatedTimeline.savedObjectId,
});
expect(mockPersistNote.mock.calls[2][3]).toEqual({
eventId: mockUniqueParsedObjects[0].eventNotes[1].eventId,
note: 'event note2',
created: '1584830796960',
createdBy: 'angela',
updated: '1584830796960',
updatedBy: 'angela',
timelineId: mockCreatedTimeline.savedObjectId,
});
});

test('should keep current author if note does not exist when Creating notes for a timeline', async () => {
mockGetNote.mockReset();
mockGetNote.mockRejectedValue(new Error());

const mockRequest = getImportTimelinesRequest();
await server.inject(mockRequest, context);
expect(mockPersistNote.mock.calls[0][3]).toEqual({
created: mockUniqueParsedObjects[0].globalNotes[0].created,
createdBy: mockUniqueParsedObjects[0].globalNotes[0].createdBy,
updated: mockUniqueParsedObjects[0].globalNotes[0].updated,
updatedBy: mockUniqueParsedObjects[0].globalNotes[0].updatedBy,
eventId: undefined,
note: mockUniqueParsedObjects[0].globalNotes[0].note,
timelineId: mockCreatedTimeline.savedObjectId,
});
expect(mockPersistNote.mock.calls[1][3]).toEqual({
eventId: mockUniqueParsedObjects[0].eventNotes[0].eventId,
note: mockUniqueParsedObjects[0].eventNotes[0].note,
created: mockUniqueParsedObjects[0].eventNotes[0].created,
createdBy: mockUniqueParsedObjects[0].eventNotes[0].createdBy,
updated: mockUniqueParsedObjects[0].eventNotes[0].updated,
updatedBy: mockUniqueParsedObjects[0].eventNotes[0].updatedBy,
eventId: mockUniqueParsedObjects[0].eventNotes[0].eventId,
note: mockUniqueParsedObjects[0].eventNotes[0].note,
timelineId: mockCreatedTimeline.savedObjectId,
});
expect(mockPersistNote.mock.calls[2][3]).toEqual({
eventId: mockUniqueParsedObjects[0].eventNotes[1].eventId,
note: mockUniqueParsedObjects[0].eventNotes[1].note,
created: mockUniqueParsedObjects[0].eventNotes[1].created,
createdBy: mockUniqueParsedObjects[0].eventNotes[1].createdBy,
updated: mockUniqueParsedObjects[0].eventNotes[1].updated,
updatedBy: mockUniqueParsedObjects[0].eventNotes[1].updatedBy,
eventId: mockUniqueParsedObjects[0].eventNotes[1].eventId,
note: mockUniqueParsedObjects[0].eventNotes[1].note,
timelineId: mockCreatedTimeline.savedObjectId,
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,44 +45,56 @@ export const savePinnedEvents = (
)
);

const getNewNote = async (
frameworkRequest: FrameworkRequest,
note: NoteResult,
timelineSavedObjectId: string,
overrideOwner: boolean
): Promise<SavedNote> => {
let savedNote = note;
try {
savedNote = await noteLib.getNote(frameworkRequest, note.noteId);
// eslint-disable-next-line no-empty
} catch (e) {}
return overrideOwner
? {
eventId: note.eventId,
note: note.note,
timelineId: timelineSavedObjectId,
}
: {
eventId: savedNote.eventId,
note: savedNote.note,
created: savedNote.created,
createdBy: savedNote.createdBy,
updated: savedNote.updated,
updatedBy: savedNote.updatedBy,
timelineId: timelineSavedObjectId,
};
};

export const saveNotes = async (
frameworkRequest: FrameworkRequest,
timelineSavedObjectId: string,
timelineVersion?: string | null,
existingNoteIds?: string[],
newNotes?: NoteResult[],
overideNotes: boolean = true
overrideOwner: boolean = true
) => {
return Promise.all(
newNotes?.map(async (note) => {
let savedNote = note;

try {
savedNote = await noteLib.getNote(frameworkRequest, note.noteId);
// eslint-disable-next-line no-empty
} catch (e) {}

const newNote: SavedNote = overideNotes
? {
eventId: note.eventId,
note: note.note,
timelineId: timelineSavedObjectId,
}
: {
eventId: savedNote.eventId,
note: savedNote.note,
created: savedNote.created,
createdBy: savedNote.createdBy,
updated: savedNote.updated,
updatedBy: savedNote.updatedBy,
timelineId: timelineSavedObjectId,
};
const newNote = await getNewNote(
frameworkRequest,
note,
timelineSavedObjectId,
overrideOwner
);
return noteLib.persistNote(
frameworkRequest,
overideNotes ? existingNoteIds?.find((nId) => nId === note.noteId) ?? null : null,
overrideOwner ? existingNoteIds?.find((nId) => nId === note.noteId) ?? null : null,
timelineVersion ?? null,
newNote,
overideNotes
overrideOwner
);
}) ?? []
);
Expand All @@ -93,7 +105,7 @@ interface CreateTimelineProps {
timeline: SavedTimeline;
timelineSavedObjectId?: string | null;
timelineVersion?: string | null;
overideNotes?: boolean;
overrideNotesOwner?: boolean;
pinnedEventIds?: string[] | null;
notes?: NoteResult[];
existingNoteIds?: string[];
Expand All @@ -114,7 +126,7 @@ export const createTimelines = async ({
notes = [],
existingNoteIds = [],
isImmutable,
overideNotes = true,
overrideNotesOwner = true,
}: CreateTimelineProps): Promise<ResponseTimeline> => {
const responseTimeline = await saveTimelines(
frameworkRequest,
Expand Down Expand Up @@ -145,7 +157,7 @@ export const createTimelines = async ({
newTimelineVersion,
existingNoteIds,
notes,
overideNotes
overrideNotesOwner
),
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const NOT_ALLOW_UPDATE_TIMELINE_TYPE_ERROR_MESSAGE =
'You cannot convert a Timeline template to a timeline, or a timeline to a Timeline template.';
export const UPDAT_TIMELINE_VIA_IMPORT_NOT_ALLOWED_ERROR_MESSAGE =
'You cannot update a timeline via imports. Use the UI to modify existing timelines.';
export const DEFAULT_ERROR = `Something has gone wrong. We didn't handle something properly. To help us fix this, please upload your file to https://discuss.elastic.co/c/security/siem.`;

const isUpdatingStatus = (
isHandlingTemplateTimeline: boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { createPromiseFromStreams } from '../../../../../../../../src/legacy/uti
import { getTupleDuplicateErrorsAndUniqueTimeline } from './get_timelines_from_stream';
import { CompareTimelinesStatus } from './compare_timelines_status';
import { TimelineStatusActions } from './common';
import { DEFAULT_ERROR } from './failure_cases';

export type ImportedTimeline = SavedTimeline & {
savedObjectId: string | null;
Expand Down Expand Up @@ -78,7 +79,6 @@ export const timelineSavedObjectOmittedFields = [
];

const CHUNK_PARSED_OBJECT_SIZE = 10;
const DEFAULT_IMPORT_ERROR = `Something has gone wrong. We didn't handle something properly. To help us fix this, please upload your file to https://discuss.elastic.co/c/security/siem.`;

export const importTimelines = async (
file: Readable,
Expand Down Expand Up @@ -163,7 +163,7 @@ export const importTimelines = async (
pinnedEventIds: isTemplateTimeline ? null : pinnedEventIds,
notes: isTemplateTimeline ? globalNotes : [...globalNotes, ...eventNotes],
isImmutable,
overideNotes: false,
overrideNotesOwner: false,
});

resolve({
Expand All @@ -177,7 +177,7 @@ export const importTimelines = async (
const errorMessage = compareTimelinesStatus.checkIsFailureCases(
TimelineStatusActions.createViaImport
);
const message = errorMessage?.body ?? DEFAULT_IMPORT_ERROR;
const message = errorMessage?.body ?? DEFAULT_ERROR;

resolve(
createBulkErrorObject({
Expand All @@ -197,7 +197,7 @@ export const importTimelines = async (
notes: globalNotes,
existingNoteIds: compareTimelinesStatus.timelineInput.data?.noteIds,
isImmutable,
overideNotes: false,
overrideNotesOwner: false,
});

resolve({
Expand All @@ -210,7 +210,7 @@ export const importTimelines = async (
TimelineStatusActions.updateViaImport
);

const message = errorMessage?.body ?? DEFAULT_IMPORT_ERROR;
const message = errorMessage?.body ?? DEFAULT_ERROR;

resolve(
createBulkErrorObject({
Expand Down

0 comments on commit e03918d

Please sign in to comment.