mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Cases ]Expose the bulk get cases API from the cases UI client (#154235)
## Summary This PR exposes the bulk get cases API from the cases UI client. Fixes: https://github.com/elastic/kibana/issues/153926 ### Checklist Delete any items that are not applicable to this PR. - [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 ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
098c3fe2ed
commit
4cd0460f5a
8 changed files with 117 additions and 8 deletions
|
@ -15,10 +15,14 @@ import type {
|
|||
CasesFindResponse,
|
||||
CasesStatusResponse,
|
||||
CasesMetricsResponse,
|
||||
CasesBulkGetResponseCertainFields,
|
||||
CaseResponse,
|
||||
} from '../../common/api';
|
||||
import {
|
||||
CasesFindResponseRt,
|
||||
CasesStatusResponseRt,
|
||||
CasesResponseRt,
|
||||
getTypeForCertainFieldsFromArray,
|
||||
CasesMetricsResponseRt,
|
||||
} from '../../common/api';
|
||||
|
||||
|
@ -36,3 +40,13 @@ export const decodeCasesMetricsResponse = (metrics?: CasesMetricsResponse) =>
|
|||
CasesMetricsResponseRt.decode(metrics),
|
||||
fold(throwErrors(createToasterPlainError), identity)
|
||||
);
|
||||
|
||||
export const decodeCasesBulkGetResponse = <Field extends keyof CaseResponse = keyof CaseResponse>(
|
||||
res: CasesBulkGetResponseCertainFields<Field>,
|
||||
fields?: string[]
|
||||
) => {
|
||||
const typeToDecode = getTypeForCertainFieldsFromArray(CasesResponseRt, fields);
|
||||
pipe(typeToDecode.decode(res.cases), fold(throwErrors(createToasterPlainError), identity));
|
||||
|
||||
return res;
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
*/
|
||||
|
||||
import { httpServiceMock } from '@kbn/core/public/mocks';
|
||||
import { getCases, getCasesMetrics } from '.';
|
||||
import { allCases, allCasesSnake } from '../containers/mock';
|
||||
import { bulkGetCases, getCases, getCasesMetrics } from '.';
|
||||
import { allCases, allCasesSnake, casesSnake } from '../containers/mock';
|
||||
|
||||
describe('api', () => {
|
||||
beforeEach(() => {
|
||||
|
@ -47,4 +47,31 @@ describe('api', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulkGetCases', () => {
|
||||
const http = httpServiceMock.createStartContract({ basePath: '' });
|
||||
http.post.mockResolvedValue({ cases: [{ title: 'test' }], errors: [] });
|
||||
|
||||
it('should return the correct cases with a subset of fields', async () => {
|
||||
expect(await bulkGetCases({ http, params: { ids: ['test'], fields: ['title'] } })).toEqual({
|
||||
cases: [{ title: 'test' }],
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the correct cases with all fields', async () => {
|
||||
http.post.mockResolvedValueOnce({ cases: casesSnake, errors: [] });
|
||||
expect(await bulkGetCases({ http, params: { ids: ['test'] } })).toEqual({
|
||||
cases: casesSnake,
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should have been called with the correct path', async () => {
|
||||
await bulkGetCases({ http, params: { ids: ['test'], fields: ['title'] } });
|
||||
expect(http.post).toHaveBeenCalledWith('/internal/cases/_bulk_get', {
|
||||
body: '{"ids":["test"],"fields":["title"]}',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,8 +7,16 @@
|
|||
|
||||
import type { HttpStart } from '@kbn/core/public';
|
||||
import type { Cases, CasesStatus, CasesMetrics } from '../../common/ui';
|
||||
import { CASE_FIND_URL, CASE_METRICS_URL, CASE_STATUS_URL } from '../../common/constants';
|
||||
import {
|
||||
CASE_FIND_URL,
|
||||
CASE_METRICS_URL,
|
||||
CASE_STATUS_URL,
|
||||
INTERNAL_BULK_GET_CASES_URL,
|
||||
} from '../../common/constants';
|
||||
import type {
|
||||
CaseResponse,
|
||||
CasesBulkGetRequestCertainFields,
|
||||
CasesBulkGetResponseCertainFields,
|
||||
CasesFindRequest,
|
||||
CasesFindResponse,
|
||||
CasesMetricsRequest,
|
||||
|
@ -18,6 +26,7 @@ import type {
|
|||
} from '../../common/api';
|
||||
import { convertAllCasesToCamel, convertToCamelCase } from './utils';
|
||||
import {
|
||||
decodeCasesBulkGetResponse,
|
||||
decodeCasesFindResponse,
|
||||
decodeCasesMetricsResponse,
|
||||
decodeCasesStatusResponse,
|
||||
|
@ -58,3 +67,21 @@ export const getCasesMetrics = async ({
|
|||
const res = await http.get<CasesMetricsResponse>(CASE_METRICS_URL, { signal, query });
|
||||
return convertToCamelCase(decodeCasesMetricsResponse(res));
|
||||
};
|
||||
|
||||
export const bulkGetCases = async <Field extends keyof CaseResponse = keyof CaseResponse>({
|
||||
http,
|
||||
signal,
|
||||
params,
|
||||
}: HTTPService & { params: CasesBulkGetRequestCertainFields<Field> }): Promise<
|
||||
CasesBulkGetResponseCertainFields<Field>
|
||||
> => {
|
||||
const res = await http.post<CasesBulkGetResponseCertainFields<Field>>(
|
||||
INTERNAL_BULK_GET_CASES_URL,
|
||||
{
|
||||
body: JSON.stringify({ ...params }),
|
||||
signal,
|
||||
}
|
||||
);
|
||||
|
||||
return decodeCasesBulkGetResponse(res, params.fields);
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import { httpServiceMock } from '@kbn/core/public/mocks';
|
||||
import { createClientAPI } from '.';
|
||||
import { allCases, allCasesSnake } from '../../containers/mock';
|
||||
import { allCases, allCasesSnake, casesSnake } from '../../containers/mock';
|
||||
|
||||
describe('createClientAPI', () => {
|
||||
beforeEach(() => {
|
||||
|
@ -80,5 +80,33 @@ describe('createClientAPI', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulkGet', () => {
|
||||
const http = httpServiceMock.createStartContract({ basePath: '' });
|
||||
const api = createClientAPI({ http });
|
||||
http.post.mockResolvedValue({ cases: [{ title: 'test' }], errors: [] });
|
||||
|
||||
it('should return the correct cases with a subset of fields', async () => {
|
||||
expect(await api.cases.bulkGet({ ids: ['test'], fields: ['title'] })).toEqual({
|
||||
cases: [{ title: 'test' }],
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the correct cases with all fields', async () => {
|
||||
http.post.mockResolvedValueOnce({ cases: casesSnake, errors: [] });
|
||||
expect(await api.cases.bulkGet({ ids: ['test'], fields: ['title'] })).toEqual({
|
||||
cases: casesSnake,
|
||||
errors: [],
|
||||
});
|
||||
});
|
||||
|
||||
it('should have been called with the correct path', async () => {
|
||||
await api.cases.bulkGet({ ids: ['test'], fields: ['title'] });
|
||||
expect(http.post).toHaveBeenCalledWith('/internal/cases/_bulk_get', {
|
||||
body: '{"ids":["test"],"fields":["title"]}',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -15,7 +15,7 @@ import type {
|
|||
} from '../../../common/api';
|
||||
import { getCasesFromAlertsUrl } from '../../../common/api';
|
||||
import type { Cases, CasesStatus, CasesMetrics } from '../../../common/ui';
|
||||
import { getCases, getCasesMetrics, getCasesStatus } from '../../api';
|
||||
import { bulkGetCases, getCases, getCasesMetrics, getCasesStatus } from '../../api';
|
||||
import type { CasesUiStart } from '../../types';
|
||||
|
||||
export const createClientAPI = ({ http }: { http: HttpStart }): CasesUiStart['api'] => {
|
||||
|
@ -32,6 +32,7 @@ export const createClientAPI = ({ http }: { http: HttpStart }): CasesUiStart['ap
|
|||
getCasesStatus({ http, query, signal }),
|
||||
getCasesMetrics: (query: CasesMetricsRequest, signal?: AbortSignal): Promise<CasesMetrics> =>
|
||||
getCasesMetrics({ http, signal, query }),
|
||||
bulkGet: (params, signal?: AbortSignal) => bulkGetCases({ http, signal, params }),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -10,7 +10,12 @@ import type { CasesUiStart } from './types';
|
|||
|
||||
const apiMock: jest.Mocked<CasesUiStart['api']> = {
|
||||
getRelatedCases: jest.fn(),
|
||||
cases: { find: jest.fn(), getCasesMetrics: jest.fn(), getCasesStatus: jest.fn() },
|
||||
cases: {
|
||||
find: jest.fn(),
|
||||
getCasesMetrics: jest.fn(),
|
||||
getCasesStatus: jest.fn(),
|
||||
bulkGet: jest.fn(),
|
||||
},
|
||||
};
|
||||
|
||||
const uiMock: jest.Mocked<CasesUiStart['ui']> = {
|
||||
|
|
|
@ -25,6 +25,9 @@ import type { LicensingPluginStart } from '@kbn/licensing-plugin/public';
|
|||
import type { FilesSetup, FilesStart } from '@kbn/files-plugin/public';
|
||||
import type { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public';
|
||||
import type {
|
||||
CaseResponse,
|
||||
CasesBulkGetRequestCertainFields,
|
||||
CasesBulkGetResponseCertainFields,
|
||||
CasesByAlertId,
|
||||
CasesByAlertIDRequest,
|
||||
CasesFindRequest,
|
||||
|
@ -102,6 +105,10 @@ export interface CasesUiStart {
|
|||
find: (query: CasesFindRequest, signal?: AbortSignal) => Promise<Cases>;
|
||||
getCasesStatus: (query: CasesStatusRequest, signal?: AbortSignal) => Promise<CasesStatus>;
|
||||
getCasesMetrics: (query: CasesMetricsRequest, signal?: AbortSignal) => Promise<CasesMetrics>;
|
||||
bulkGet: <Field extends keyof CaseResponse = keyof CaseResponse>(
|
||||
params: CasesBulkGetRequestCertainFields<Field>,
|
||||
signal?: AbortSignal
|
||||
) => Promise<CasesBulkGetResponseCertainFields<Field>>;
|
||||
};
|
||||
};
|
||||
ui: {
|
||||
|
|
|
@ -66,8 +66,8 @@ export interface CasesSubClient {
|
|||
* Retrieves multiple cases with the specified IDs.
|
||||
*/
|
||||
bulkGet<Field extends keyof CaseResponse = keyof CaseResponse>(
|
||||
params: CasesBulkGetRequestCertainFields<Field | 'id' | 'version' | 'owner'>
|
||||
): Promise<CasesBulkGetResponseCertainFields<Field | 'id' | 'version' | 'owner'>>;
|
||||
params: CasesBulkGetRequestCertainFields<Field>
|
||||
): Promise<CasesBulkGetResponseCertainFields<Field>>;
|
||||
/**
|
||||
* Pushes a specific case to an external system.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue