Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SIEM][Exceptions] - ExceptionsViewer UI component part 2 #68294

Merged
merged 35 commits into from
Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
24ed91f
moved and_or_badge to common folder and added tests
yctercero Jun 2, 2020
629b832
updated references to new and_or_badge location
yctercero Jun 2, 2020
335a720
built out exception item component for viewer
yctercero Jun 2, 2020
dd2b8c8
added exception item component stories for easy testing
yctercero Jun 2, 2020
990d656
updated text to use i18n in spots missed
yctercero Jun 2, 2020
bac11c9
added tests for exception detail component and updated braking tests
yctercero Jun 2, 2020
9496085
finished adding tests and fixing lint issue
yctercero Jun 3, 2020
f3a1fba
fixed test timestamps to be UTC
yctercero Jun 3, 2020
a8a68fa
fix failing test that was passing locally
yctercero Jun 3, 2020
f0aeda8
tests
yctercero Jun 3, 2020
b19237f
fix dates
yctercero Jun 3, 2020
3a31452
fixes per feedback
yctercero Jun 3, 2020
7ad2a23
Merge branch 'master' of github.com:yctercero/kibana into all-exc-view
yctercero Jun 3, 2020
053c5d7
cleanup
yctercero Jun 3, 2020
c24c1ff
updated tests
yctercero Jun 3, 2020
8b91e10
Merge branch 'master' of github.com:yctercero/kibana into all-exc-view
yctercero Jun 4, 2020
878547e
updated translations to use securitySolution after rename
yctercero Jun 4, 2020
410ecb9
Merge branch 'all-exc-view' of https://github.com/yctercero/kibana in…
yctercero Jun 4, 2020
bc7b81e
updated useExceptionList hook to use different refresh pattern, updat…
yctercero Jun 4, 2020
798b1dd
moved exception item component into its own folder
yctercero Jun 4, 2020
29810e7
added search bar, toggle, and buttons
yctercero Jun 4, 2020
da467bf
added exceptions viewer component
yctercero Jun 4, 2020
c953d0f
Merge branch 'master' of github.com:yctercero/kibana into exceptions-…
yctercero Jun 4, 2020
32f66d2
fix merge issue
yctercero Jun 4, 2020
8de7469
some cleanup
yctercero Jun 4, 2020
c333567
modified list scripts for help with testing
yctercero Jun 5, 2020
8a51155
added exceptions hook for general api usage, updated exception item
yctercero Jun 8, 2020
9196387
updated per feedback to allow for different filtering
yctercero Jun 8, 2020
3117815
Merge branch 'master' of github.com:yctercero/kibana into exceptions-…
yctercero Jun 8, 2020
aea3b16
temp disabled complexity linter for rules/details/index, this file is…
yctercero Jun 8, 2020
854892a
cleanup
yctercero Jun 8, 2020
5303cc9
updated hook tests and clean up
yctercero Jun 8, 2020
6027cbb
updated and added more tests, cleaned up linter issues and per page s…
yctercero Jun 9, 2020
2f8eb18
update typing
yctercero Jun 9, 2020
77fd167
Merge branch 'master' into exceptions-viewer-2
elasticmachine Jun 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions x-pack/plugins/lists/public/exceptions/hooks/use_api.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { useMemo } from 'react';

import * as Api from '../api';
import { HttpStart } from '../../../../../../src/core/public';
import { ExceptionListItemSchema, ExceptionListSchema } from '../../../common/schemas';
import { ApiCallMemoProps } from '../types';

export interface ExceptionsApi {
deleteExceptionItem: (arg: ApiCallMemoProps) => Promise<void>;
deleteExceptionList: (arg: ApiCallMemoProps) => Promise<void>;
getExceptionItem: (
arg: ApiCallMemoProps & { onSuccess: (arg: ExceptionListItemSchema) => void }
) => Promise<void>;
getExceptionList: (
arg: ApiCallMemoProps & { onSuccess: (arg: ExceptionListSchema) => void }
) => Promise<void>;
}
Comment on lines +14 to +23
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice way of exposing the list API's! Makes for a clean separation of concerns between usage in hooks, and exposing the plugin's API as a whole 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, the other way felt strange and saw this pattern elsewhere.


export const useApi = (http: HttpStart): ExceptionsApi => {
return useMemo(
(): ExceptionsApi => ({
async deleteExceptionItem({
id,
namespaceType,
onSuccess,
onError,
}: ApiCallMemoProps): Promise<void> {
const abortCtrl = new AbortController();

try {
await Api.deleteExceptionListItemById({
http,
id,
namespaceType,
signal: abortCtrl.signal,
});
onSuccess();
} catch (error) {
onError(error);
}
},
async deleteExceptionList({
id,
namespaceType,
onSuccess,
onError,
}: ApiCallMemoProps): Promise<void> {
const abortCtrl = new AbortController();

try {
await Api.deleteExceptionListById({
http,
id,
namespaceType,
signal: abortCtrl.signal,
});
onSuccess();
} catch (error) {
onError(error);
}
},
async getExceptionItem({
id,
namespaceType,
onSuccess,
onError,
}: ApiCallMemoProps & { onSuccess: (arg: ExceptionListItemSchema) => void }): Promise<void> {
const abortCtrl = new AbortController();

try {
const item = await Api.fetchExceptionListItemById({
http,
id,
namespaceType,
signal: abortCtrl.signal,
});
onSuccess(item);
} catch (error) {
onError(error);
}
},
async getExceptionList({
id,
namespaceType,
onSuccess,
onError,
}: ApiCallMemoProps & { onSuccess: (arg: ExceptionListSchema) => void }): Promise<void> {
const abortCtrl = new AbortController();

try {
const list = await Api.fetchExceptionListById({
http,
id,
namespaceType,
signal: abortCtrl.signal,
});
onSuccess(list);
} catch (error) {
onError(error);
}
},
}),
[http]
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import * as api from '../api';
import { createKibanaCoreStartMock } from '../../common/mocks/kibana_core';
import { getExceptionListSchemaMock } from '../../../common/schemas/response/exception_list_schema.mock';
import { getExceptionListItemSchemaMock } from '../../../common/schemas/response/exception_list_item_schema.mock';
import { ExceptionListAndItems, UseExceptionListProps } from '../types';
import { ExceptionListItemSchema } from '../../../common/schemas';
import { ExceptionList, UseExceptionListProps } from '../types';

import { ReturnExceptionListAndItems, useExceptionList } from './use_exception_list';

Expand All @@ -34,15 +35,23 @@ describe('useExceptionList', () => {
>(() =>
useExceptionList({
http: mockKibanaHttpService,
id: 'myListId',
namespaceType: 'single',
lists: [{ id: 'myListId', namespaceType: 'single' }],
onError: onErrorMock,
})
);
await waitForNextUpdate();

expect(result.current).toEqual([true, null, result.current[2]]);
expect(typeof result.current[2]).toEqual('function');
expect(result.current).toEqual([
true,
[],
[],
{
page: 1,
perPage: 20,
total: 0,
},
null,
]);
});
});

Expand All @@ -54,27 +63,32 @@ describe('useExceptionList', () => {
>(() =>
useExceptionList({
http: mockKibanaHttpService,
id: 'myListId',
namespaceType: 'single',
lists: [{ id: 'myListId', namespaceType: 'single' }],
onError: onErrorMock,
})
);
await waitForNextUpdate();
await waitForNextUpdate();

const expectedResult: ExceptionListAndItems = {
...getExceptionListSchemaMock(),
exceptionItems: {
items: [{ ...getExceptionListItemSchemaMock() }],
pagination: {
page: 1,
perPage: 20,
total: 1,
},
},
};
const expectedListResult: ExceptionList[] = [
{ ...getExceptionListSchemaMock(), totalItems: 1 },
];

const expectedListItemsResult: ExceptionListItemSchema[] = [
{ ...getExceptionListItemSchemaMock() },
];

expect(result.current).toEqual([false, expectedResult, result.current[2]]);
expect(result.current).toEqual([
false,
expectedListResult,
expectedListItemsResult,
{
page: 1,
perPage: 20,
total: 1,
},
result.current[4],
]);
});
});

Expand All @@ -86,22 +100,20 @@ describe('useExceptionList', () => {
UseExceptionListProps,
ReturnExceptionListAndItems
>(
({ filterOptions, http, id, namespaceType, pagination, onError }) =>
useExceptionList({ filterOptions, http, id, namespaceType, onError, pagination }),
({ filterOptions, http, lists, pagination, onError }) =>
useExceptionList({ filterOptions, http, lists, onError, pagination }),
{
initialProps: {
http: mockKibanaHttpService,
id: 'myListId',
namespaceType: 'single',
lists: [{ id: 'myListId', namespaceType: 'single' }],
onError: onErrorMock,
},
}
);
await waitForNextUpdate();
rerender({
http: mockKibanaHttpService,
id: 'newListId',
namespaceType: 'single',
lists: [{ id: 'newListId', namespaceType: 'single' }],
onError: onErrorMock,
});
await waitForNextUpdate();
Expand All @@ -121,14 +133,19 @@ describe('useExceptionList', () => {
>(() =>
useExceptionList({
http: mockKibanaHttpService,
id: 'myListId',
namespaceType: 'single',
lists: [{ id: 'myListId', namespaceType: 'single' }],
onError: onErrorMock,
})
);
await waitForNextUpdate();
await waitForNextUpdate();
result.current[2]();

expect(typeof result.current[4]).toEqual('function');

if (result.current[4] != null) {
result.current[4]();
}

await waitForNextUpdate();

expect(spyOnfetchExceptionListById).toHaveBeenCalledTimes(2);
Expand All @@ -147,8 +164,7 @@ describe('useExceptionList', () => {
() =>
useExceptionList({
http: mockKibanaHttpService,
id: 'myListId',
namespaceType: 'single',
lists: [{ id: 'myListId', namespaceType: 'single' }],
onError: onErrorMock,
})
);
Expand All @@ -170,8 +186,7 @@ describe('useExceptionList', () => {
() =>
useExceptionList({
http: mockKibanaHttpService,
id: 'myListId',
namespaceType: 'single',
lists: [{ id: 'myListId', namespaceType: 'single' }],
onError: onErrorMock,
})
);
Expand Down
Loading