-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding unique key, adding test case.
- Loading branch information
1 parent
288122b
commit a458aae
Showing
4 changed files
with
325 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
139 changes: 139 additions & 0 deletions
139
graylog2-web-interface/src/components/events/bulk-replay/__tests__/BulkEventReplay.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import * as React from 'react'; | ||
import { render, screen, waitFor } from 'wrappedTestingLibrary'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { PluginManifest } from 'graylog-web-plugin/plugin'; | ||
|
||
import type { Event } from 'components/events/events/types'; | ||
import { usePlugin } from 'views/test/testPlugins'; | ||
import MenuItem from 'components/bootstrap/menuitem/MenuItem'; | ||
|
||
import events from './events.fixtures'; | ||
|
||
import BulkEventReplay from '../BulkEventReplay'; | ||
|
||
const initialEventIds = [ | ||
'01JH007XPDF710TPJZT8K2CN3W', | ||
'01JH006340WP7HQ5E7P71Q9HHX', | ||
'01JH0029TS9PX5ED87TZ1RVRT2', | ||
]; | ||
|
||
jest.mock('components/events/bulk-replay/ReplaySearch', () => ({ event }: { event: Event }) => <span>Replaying search for event {event.id}</span>); | ||
|
||
const markEventAsInvestigated = async (eventId: string) => { | ||
const markAsInvestigatedButton = await screen.findByRole('button', { name: new RegExp(`mark event "${eventId}" as investigated`, 'i') }); | ||
|
||
return userEvent.click(markAsInvestigatedButton); | ||
}; | ||
|
||
const removeEvent = async (eventId: string) => { | ||
const removeEventButton = await screen.findByRole('button', { name: new RegExp(`remove event "${eventId}" from list`, 'i') }); | ||
|
||
return userEvent.click(removeEventButton); | ||
}; | ||
|
||
const expectReplayingEvent = (eventId: string) => screen.findByText(new RegExp(`replaying search for event ${eventId}`, 'i')); | ||
|
||
const eventByIndex = (index: number) => events[initialEventIds[index]].event; | ||
const eventMessage = (index: number) => eventByIndex(index).message; | ||
|
||
const SUT = (props: Partial<React.ComponentProps<typeof BulkEventReplay>>) => ( | ||
<BulkEventReplay events={events} initialEventIds={initialEventIds} onClose={() => {}} {...props} /> | ||
); | ||
|
||
const bulkAction = jest.fn(); | ||
const testPlugin = new PluginManifest({}, { | ||
'views.components.eventActions': [{ | ||
key: 'test-bulk-action', | ||
component: ({ events: _events }) => ( | ||
<MenuItem onClick={() => bulkAction(_events)}>Test Action</MenuItem> | ||
), | ||
useCondition: () => true, | ||
isBulk: true, | ||
}], | ||
}); | ||
|
||
describe('BulkEventReplay', () => { | ||
usePlugin(testPlugin); | ||
|
||
it('calls `onClose` when close button is clicked', async () => { | ||
const onClose = jest.fn(); | ||
render(<SUT onClose={onClose} />); | ||
const closeButton = await screen.findByRole('button', { name: 'Close' }); | ||
userEvent.click(closeButton); | ||
|
||
await waitFor(() => { | ||
expect(onClose).toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
it('renders list of selected events', async () => { | ||
render(<SUT />); | ||
await screen.findByText(eventMessage(0)); | ||
await screen.findByText(eventMessage(1)); | ||
await screen.findByText(eventMessage(2)); | ||
|
||
await expectReplayingEvent(initialEventIds[0]); | ||
}); | ||
|
||
it('clicking delete button removes event from list', async () => { | ||
render(<SUT />); | ||
await removeEvent(initialEventIds[0]); | ||
|
||
await screen.findByText(eventMessage(1)); | ||
await expectReplayingEvent(initialEventIds[1]); | ||
|
||
expect(screen.queryByText(eventMessage(0))).not.toBeInTheDocument(); | ||
}); | ||
|
||
it('marking events as investigated jumps to next one', async () => { | ||
render(<SUT />); | ||
await markEventAsInvestigated(initialEventIds[0]); | ||
|
||
await expectReplayingEvent(initialEventIds[1]); | ||
|
||
await markEventAsInvestigated(initialEventIds[1]); | ||
await expectReplayingEvent(initialEventIds[2]); | ||
|
||
await markEventAsInvestigated(initialEventIds[2]); | ||
await screen.findByText('You are done investigating all events. You can now select a bulk action to apply to all remaining events, or close the page to return to the events list.'); | ||
}); | ||
|
||
it('allows jumping to specific events', async () => { | ||
render(<SUT />); | ||
await expectReplayingEvent(initialEventIds[0]); | ||
|
||
userEvent.click(await screen.findByText(eventMessage(1))); | ||
|
||
await expectReplayingEvent(initialEventIds[1]); | ||
|
||
userEvent.click(await screen.findByText(eventMessage(0))); | ||
|
||
await expectReplayingEvent(initialEventIds[0]); | ||
}); | ||
|
||
it('skips removed event when jumping to next one', async () => { | ||
render(<SUT />); | ||
await removeEvent(initialEventIds[1]); | ||
await markEventAsInvestigated(initialEventIds[0]); | ||
await expectReplayingEvent(initialEventIds[2]); | ||
}); | ||
|
||
it('skips event marked as investigated when jumping to next one', async () => { | ||
render(<SUT />); | ||
await markEventAsInvestigated(initialEventIds[1]); | ||
await markEventAsInvestigated(initialEventIds[0]); | ||
await expectReplayingEvent(initialEventIds[2]); | ||
}); | ||
|
||
it('bulk actions get current list of events', async () => { | ||
render(<SUT />); | ||
await removeEvent(initialEventIds[1]); | ||
|
||
userEvent.click(await screen.findByRole('button', { name: /bulk actions/i })); | ||
userEvent.click(await screen.findByRole('menuitem', { name: /test action/i })); | ||
|
||
await waitFor(() => { | ||
expect(bulkAction).toHaveBeenCalledWith([eventByIndex(0), eventByIndex(2)]); | ||
}); | ||
}); | ||
}); |
182 changes: 182 additions & 0 deletions
182
graylog2-web-interface/src/components/events/bulk-replay/__tests__/events.fixtures.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
export default { | ||
'01JH006340WP7HQ5E7P71Q9HHX': { | ||
event: { | ||
id: '01JH006340WP7HQ5E7P71Q9HHX', | ||
event_definition_type: 'aggregation-v1', | ||
event_definition_id: '66d719128a7ffa68df52fd7f', | ||
origin_context: null, | ||
timestamp: '2025-01-07T09:05:23.262Z', | ||
timestamp_processing: '2025-01-07T09:05:29.216Z', | ||
timerange_start: '2025-01-07T09:04:23.262Z', | ||
timerange_end: '2025-01-07T09:05:23.262Z', | ||
streams: [ | ||
'000000000000000000000002', | ||
], | ||
source_streams: [ | ||
'66e962c1b3a0040a1570faf9', | ||
'000000000000000000000001', | ||
], | ||
message: 'Error Rate: count()=4758.0', | ||
source: 'church', | ||
key_tuple: [ | ||
'foo', | ||
'hey there!', | ||
], | ||
key: 'foo|hey there!', | ||
priority: 3, | ||
scores: { | ||
raw_risk: 6, | ||
normalized_risk: 6, | ||
}, | ||
associated_assets: [], | ||
alert: false, | ||
fields: { | ||
mightyalert: 'foo', | ||
secondkey: 'hey there!', | ||
}, | ||
group_by_fields: {}, | ||
replay_info: { | ||
timerange_start: '2025-01-07T09:04:23.262Z', | ||
timerange_end: '2025-01-07T09:05:23.262Z', | ||
query: '', | ||
streams: [ | ||
'66e962c1b3a0040a1570faf9', | ||
'000000000000000000000001', | ||
], | ||
filters: [ | ||
{ | ||
type: 'inlineQueryString', | ||
title: 'Index Actions', | ||
id: 'd1057daf-f0e0-4159-ae00-e7e340629bb3', | ||
description: '', | ||
queryString: 'action:index', | ||
negation: false, | ||
disabled: false, | ||
}, | ||
], | ||
}, | ||
}, | ||
index_name: 'gl-events_13', | ||
index_type: 'message', | ||
}, | ||
'01JH0029TS9PX5ED87TZ1RVRT2': { | ||
event: { | ||
id: '01JH0029TS9PX5ED87TZ1RVRT2', | ||
event_definition_type: 'aggregation-v1', | ||
event_definition_id: '66d719128a7ffa68df52fd7f', | ||
origin_context: null, | ||
timestamp: '2025-01-07T09:03:23.262Z', | ||
timestamp_processing: '2025-01-07T09:03:25.017Z', | ||
timerange_start: '2025-01-07T09:02:23.262Z', | ||
timerange_end: '2025-01-07T09:03:23.262Z', | ||
streams: [ | ||
'000000000000000000000002', | ||
], | ||
source_streams: [ | ||
'66e962c1b3a0040a1570faf9', | ||
'000000000000000000000001', | ||
], | ||
message: 'Error Rate: count()=4760.0', | ||
source: 'church', | ||
key_tuple: [ | ||
'foo', | ||
'hey there!', | ||
], | ||
key: 'foo|hey there!', | ||
priority: 3, | ||
scores: { | ||
raw_risk: 6, | ||
normalized_risk: 6, | ||
}, | ||
associated_assets: [], | ||
alert: false, | ||
fields: { | ||
mightyalert: 'foo', | ||
secondkey: 'hey there!', | ||
}, | ||
group_by_fields: {}, | ||
replay_info: { | ||
timerange_start: '2025-01-07T09:02:23.262Z', | ||
timerange_end: '2025-01-07T09:03:23.262Z', | ||
query: '', | ||
streams: [ | ||
'66e962c1b3a0040a1570faf9', | ||
'000000000000000000000001', | ||
], | ||
filters: [ | ||
{ | ||
type: 'inlineQueryString', | ||
title: 'Index Actions', | ||
id: 'd1057daf-f0e0-4159-ae00-e7e340629bb3', | ||
description: '', | ||
queryString: 'action:index', | ||
negation: false, | ||
disabled: false, | ||
}, | ||
], | ||
}, | ||
}, | ||
index_name: 'gl-events_13', | ||
index_type: 'message', | ||
}, | ||
'01JH007XPDF710TPJZT8K2CN3W': { | ||
event: { | ||
id: '01JH007XPDF710TPJZT8K2CN3W', | ||
event_definition_type: 'aggregation-v1', | ||
event_definition_id: '66d719128a7ffa68df52fd7f', | ||
origin_context: null, | ||
timestamp: '2025-01-07T09:06:23.262Z', | ||
timestamp_processing: '2025-01-07T09:06:29.197Z', | ||
timerange_start: '2025-01-07T09:05:23.262Z', | ||
timerange_end: '2025-01-07T09:06:23.262Z', | ||
streams: [ | ||
'000000000000000000000002', | ||
], | ||
source_streams: [ | ||
'66e962c1b3a0040a1570faf9', | ||
'000000000000000000000001', | ||
], | ||
message: 'Error Rate: count()=4718.0', | ||
source: 'church', | ||
key_tuple: [ | ||
'foo', | ||
'hey there!', | ||
], | ||
key: 'foo|hey there!', | ||
priority: 3, | ||
scores: { | ||
raw_risk: 6, | ||
normalized_risk: 6, | ||
}, | ||
associated_assets: [], | ||
alert: false, | ||
fields: { | ||
mightyalert: 'foo', | ||
secondkey: 'hey there!', | ||
}, | ||
group_by_fields: {}, | ||
replay_info: { | ||
timerange_start: '2025-01-07T09:05:23.262Z', | ||
timerange_end: '2025-01-07T09:06:23.262Z', | ||
query: '', | ||
streams: [ | ||
'66e962c1b3a0040a1570faf9', | ||
'000000000000000000000001', | ||
], | ||
filters: [ | ||
{ | ||
type: 'inlineQueryString', | ||
title: 'Index Actions', | ||
id: 'd1057daf-f0e0-4159-ae00-e7e340629bb3', | ||
description: '', | ||
queryString: 'action:index', | ||
negation: false, | ||
disabled: false, | ||
}, | ||
], | ||
}, | ||
}, | ||
index_name: 'gl-events_13', | ||
index_type: 'message', | ||
}, | ||
}; |