Skip to content

Commit

Permalink
[Security Solution][Notes] - ensures that notes are always sorted fro…
Browse files Browse the repository at this point in the history
…m newest to oldest in expandable flyout notes tab (#188400)
  • Loading branch information
PhilippeOberti committed Jul 19, 2024
1 parent 80ea217 commit d58de3d
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
selectDeleteNotesStatus,
selectFetchNotesByDocumentIdsError,
selectFetchNotesByDocumentIdsStatus,
selectNotesByDocumentId,
selectSortedNotesByDocumentId,
} from '../../../../notes/store/notes.slice';
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
import { useUserPrivileges } from '../../../../common/components/user_privileges';
Expand Down Expand Up @@ -90,7 +90,12 @@ export const NotesList = memo(({ eventId }: NotesListProps) => {
const fetchStatus = useSelector((state: State) => selectFetchNotesByDocumentIdsStatus(state));
const fetchError = useSelector((state: State) => selectFetchNotesByDocumentIdsError(state));

const notes: Note[] = useSelector((state: State) => selectNotesByDocumentId(state, eventId));
const notes: Note[] = useSelector((state: State) =>
selectSortedNotesByDocumentId(state, {
documentId: eventId,
sort: { field: 'created', direction: 'desc' },
})
);

const createStatus = useSelector((state: State) => selectCreateNoteStatus(state));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
userSelectedRow,
userSelectedRowForDeletion,
userSortedNotes,
selectSortedNotesByDocumentId,
} from './notes.slice';
import type { NotesState } from './notes.slice';
import { mockGlobalState } from '../../common/mock';
Expand Down Expand Up @@ -515,6 +516,63 @@ describe('notesSlice', () => {
expect(selectNotesByDocumentId(mockGlobalState, 'wrong-document-id')).toHaveLength(0);
});

it('should return all notes sorted dor an existing document id', () => {
const oldestNote = {
eventId: '1', // should be a valid id based on mockTimelineData
noteId: '1',
note: 'note-1',
timelineId: 'timeline-1',
created: 1663882629000,
createdBy: 'elastic',
updated: 1663882629000,
updatedBy: 'elastic',
version: 'version',
};
const newestNote = {
...oldestNote,
noteId: '2',
created: 1663882689000,
};

const state = {
...mockGlobalState,
notes: {
...mockGlobalState.notes,
entities: {
'1': oldestNote,
'2': newestNote,
},
ids: ['1', '2'],
},
};

const ascResult = selectSortedNotesByDocumentId(state, {
documentId: '1',
sort: { field: 'created', direction: 'asc' },
});
expect(ascResult[0]).toEqual(oldestNote);
expect(ascResult[1]).toEqual(newestNote);

const descResult = selectSortedNotesByDocumentId(state, {
documentId: '1',
sort: { field: 'created', direction: 'desc' },
});
expect(descResult[0]).toEqual(newestNote);
expect(descResult[1]).toEqual(oldestNote);
});

it('should also return no notes if document id does not exist', () => {
expect(
selectSortedNotesByDocumentId(mockGlobalState, {
documentId: 'wrong-document-id',
sort: {
field: 'created',
direction: 'desc',
},
})
).toHaveLength(0);
});

it('should select notes pagination', () => {
const state = {
...mockGlobalState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,35 @@ export const selectFetchNotesError = (state: State) => state.notes.error.fetchNo
export const selectFetchNotesStatus = (state: State) => state.notes.status.fetchNotes;

export const selectNotesByDocumentId = createSelector(
[selectAllNotes, (state, documentId) => documentId],
[selectAllNotes, (state: State, documentId: string) => documentId],
(notes, documentId) => notes.filter((note) => note.eventId === documentId)
);

export const selectSortedNotesByDocumentId = createSelector(
[
selectAllNotes,
(
state: State,
{
documentId,
sort,
}: { documentId: string; sort: { field: keyof Note; direction: 'asc' | 'desc' } }
) => ({ documentId, sort }),
],
(notes, { documentId, sort }) => {
const { field, direction } = sort;
return notes
.filter((note: Note) => note.eventId === documentId)
.sort((first: Note, second: Note) => {
const a = first[field];
const b = second[field];
if (a == null) return 1;
if (b == null) return -1;
return direction === 'asc' ? (a > b ? 1 : -1) : a > b ? -1 : 1;
});
}
);

export const {
userSelectedPage,
userSelectedPerPage,
Expand Down

0 comments on commit d58de3d

Please sign in to comment.