[Search] return full IKibanaSearchResponse from fetch$ (#98268)

* return full object from fetch$

* jest

* fun-ctional tests

* jest

* functional

* test

* test

* tesssst

* Update src/plugins/data/common/search/search_source/fetch/request_error.ts

Co-authored-by: Michael Dokolin <dokmic@gmail.com>

* Update src/plugins/data/common/search/expressions/esaggs/request_handler.test.ts

Co-authored-by: Michael Dokolin <dokmic@gmail.com>

* ts

* ts

* ts

* Revert "Update src/plugins/data/common/search/search_source/fetch/request_error.ts"

This reverts commit ab182e84ed.

Co-authored-by: Michael Dokolin <dokmic@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Liza Katz 2021-04-28 21:49:47 +03:00 committed by GitHub
parent 3f46d6f8a7
commit 02ac599569
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 124 additions and 82 deletions

View file

@ -355,7 +355,7 @@ export class SearchEmbeddable
this.updateOutput({ loading: true, error: undefined });
// Make the request, wait for the final result
const resp = await searchSource.fetch$({
const {rawResponse: resp} = await searchSource.fetch$({
sessionId: searchSessionId,
}).toPromise();

View file

@ -9,7 +9,7 @@ Fetch this source from Elasticsearch, returning an observable over the response(
<b>Signature:</b>
```typescript
fetch$(options?: ISearchOptions): Observable<estypes.SearchResponse<any>>;
fetch$(options?: ISearchOptions): Observable<IKibanaSearchResponse<estypes.SearchResponse<any>>>;
```
## Parameters
@ -20,5 +20,5 @@ fetch$(options?: ISearchOptions): Observable<estypes.SearchResponse<any>>;
<b>Returns:</b>
`Observable<estypes.SearchResponse<any>>`
`Observable<IKibanaSearchResponse<estypes.SearchResponse<any>>>`

View file

@ -233,7 +233,7 @@ export const SearchExamplesApp = ({
}
setRequest(searchSource.getSearchRequestBody());
const res = await searchSource.fetch$().toPromise();
const { rawResponse: res } = await searchSource.fetch$().toPromise();
setResponse(res);
const message = <EuiText>Searched {res.hits.total} documents.</EuiText>;

View file

@ -101,7 +101,7 @@ export const getTermsBucketAgg = () =>
nestedSearchSource.setField('aggs', filterAgg);
const response = await nestedSearchSource
const { rawResponse: response } = await nestedSearchSource
.fetch$({
abortSignal,
sessionId: searchSessionId,

View file

@ -11,7 +11,7 @@ import type { Filter } from '../../../es_query';
import type { IndexPattern } from '../../../index_patterns';
import type { IAggConfigs } from '../../aggs';
import type { ISearchSource } from '../../search_source';
import { searchSourceCommonMock } from '../../search_source/mocks';
import { searchSourceCommonMock, searchSourceInstanceMock } from '../../search_source/mocks';
import { handleRequest, RequestHandlerParams } from './request_handler';
@ -20,12 +20,20 @@ jest.mock('../../tabify', () => ({
}));
import { tabifyAggResponse } from '../../tabify';
import { of } from 'rxjs';
describe('esaggs expression function - public', () => {
let mockParams: MockedKeys<RequestHandlerParams>;
beforeEach(() => {
jest.clearAllMocks();
searchSourceInstanceMock.fetch$ = jest.fn().mockReturnValue(
of({
rawResponse: {},
})
);
mockParams = {
abortSignal: (jest.fn() as unknown) as jest.Mocked<AbortSignal>,
aggs: ({

View file

@ -111,7 +111,7 @@ export const handleRequest = async ({
inspectorAdapters.requests?.reset();
const response = await requestSearchSource
const { rawResponse: response } = await requestSearchSource
.fetch$({
abortSignal,
sessionId: searchSessionId,

View file

@ -20,11 +20,13 @@ describe('pollSearch', () => {
resolve({
isRunning: false,
isPartial: finishWithError,
rawResponse: {},
});
} else {
resolve({
isRunning: true,
isPartial: true,
rawResponse: {},
});
}
});

View file

@ -6,8 +6,8 @@
* Side Public License, v 1.
*/
import type { estypes } from '@elastic/elasticsearch';
import { KbnError } from '../../../../../kibana_utils/common';
import { IKibanaSearchResponse } from '../../types';
import { SearchError } from './types';
/**
@ -16,9 +16,9 @@ import { SearchError } from './types';
* @param {Object} resp - optional HTTP response
*/
export class RequestFailure extends KbnError {
public resp?: estypes.SearchResponse<any>;
constructor(err: SearchError | null = null, resp?: estypes.SearchResponse<any>) {
super(`Request to Elasticsearch failed: ${JSON.stringify(resp || err?.message)}`);
public resp?: IKibanaSearchResponse;
constructor(err: SearchError | null = null, resp?: IKibanaSearchResponse) {
super(`Request to Elasticsearch failed: ${JSON.stringify(resp?.rawResponse || err?.message)}`);
this.resp = resp;
}

View file

@ -6,8 +6,8 @@
* Side Public License, v 1.
*/
import type { estypes } from '@elastic/elasticsearch';
import { GetConfigFn } from '../../../types';
import { IKibanaSearchResponse } from '../../types';
/**
* @internal
@ -24,10 +24,7 @@ export interface FetchHandlers {
* Callback which can be used to hook into responses, modify them, or perform
* side effects like displaying UI errors on the client.
*/
onResponse: (
request: SearchRequest,
response: estypes.SearchResponse<any>
) => estypes.SearchResponse<any>;
onResponse: (request: SearchRequest, response: IKibanaSearchResponse) => IKibanaSearchResponse;
}
export interface SearchError {

View file

@ -903,18 +903,26 @@ describe('SearchSource', () => {
expect(next).toBeCalledTimes(2);
expect(complete).toBeCalledTimes(1);
expect(next.mock.calls[0]).toMatchInlineSnapshot(`
Array [
Object {
Array [
Object {
"isPartial": true,
"isRunning": true,
"rawResponse": Object {
"test": 1,
},
]
},
]
`);
expect(next.mock.calls[1]).toMatchInlineSnapshot(`
Array [
Object {
Array [
Object {
"isPartial": false,
"isRunning": false,
"rawResponse": Object {
"test": 2,
},
]
},
]
`);
});
@ -958,13 +966,9 @@ describe('SearchSource', () => {
expect(next).toBeCalledTimes(1);
expect(error).toBeCalledTimes(1);
expect(complete).toBeCalledTimes(0);
expect(next.mock.calls[0]).toMatchInlineSnapshot(`
Array [
Object {
"test": 1,
},
]
`);
expect(next.mock.calls[0][0].rawResponse).toStrictEqual({
test: 1,
});
expect(error.mock.calls[0][0]).toBe(undefined);
});
});
@ -1174,7 +1178,7 @@ describe('SearchSource', () => {
expect(fetchSub.next).toHaveBeenCalledTimes(3);
expect(fetchSub.complete).toHaveBeenCalledTimes(1);
expect(fetchSub.error).toHaveBeenCalledTimes(0);
expect(resp).toStrictEqual({ other: 5 });
expect(resp.rawResponse).toStrictEqual({ other: 5 });
expect(typesRegistry.get('avg').postFlightRequest).toHaveBeenCalledTimes(3);
});

View file

@ -271,7 +271,9 @@ export class SearchSource {
* Fetch this source from Elasticsearch, returning an observable over the response(s)
* @param options
*/
fetch$(options: ISearchOptions = {}) {
fetch$(
options: ISearchOptions = {}
): Observable<IKibanaSearchResponse<estypes.SearchResponse<any>>> {
const { getConfig } = this.dependencies;
const syncSearchByDefault = getConfig(UI_SETTINGS.COURIER_BATCH_SEARCHES);
@ -308,7 +310,11 @@ export class SearchSource {
* @deprecated Use fetch$ instead
*/
fetch(options: ISearchOptions = {}) {
return this.fetch$(options).toPromise();
return this.fetch$(options)
.toPromise()
.then((r) => {
return r.rawResponse as estypes.SearchResponse<any>;
});
}
/**
@ -341,7 +347,7 @@ export class SearchSource {
* PRIVATE APIS
******/
private inspectSearch(s$: Observable<estypes.SearchResponse<any>>, options: ISearchOptions) {
private inspectSearch(s$: Observable<IKibanaSearchResponse<any>>, options: ISearchOptions) {
const { id, title, description, adapter } = options.inspector || { title: '' };
const requestResponder = adapter?.start(title, {
@ -384,7 +390,7 @@ export class SearchSource {
last(undefined, null),
tap((finalResponse) => {
if (finalResponse) {
requestResponder?.stats(getResponseInspectorStats(finalResponse, this));
requestResponder?.stats(getResponseInspectorStats(finalResponse.rawResponse, this));
requestResponder?.ok({ json: finalResponse });
}
}),
@ -424,8 +430,8 @@ export class SearchSource {
);
}
}
return response;
}
return response;
}
/**
@ -477,7 +483,7 @@ export class SearchSource {
}
});
}),
map(({ rawResponse }) => onResponse(searchRequest, rawResponse))
map((response) => onResponse(searchRequest, response))
);
}

View file

@ -12,7 +12,7 @@ import type { IKibanaSearchResponse } from './types';
* @returns true if response had an error while executing in ES
*/
export const isErrorResponse = (response?: IKibanaSearchResponse) => {
return !response || (!response.isRunning && response.isPartial);
return !response || !response.rawResponse || (!response.isRunning && response.isPartial);
};
/**

View file

@ -2446,7 +2446,7 @@ export class SearchSource {
createChild(options?: {}): SearchSource;
createCopy(): SearchSource;
destroy(): void;
fetch$(options?: ISearchOptions): Observable<estypes.SearchResponse<any>>;
fetch$(options?: ISearchOptions): Observable<IKibanaSearchResponse<estypes.SearchResponse<any>>>;
// @deprecated
fetch(options?: ISearchOptions): Promise<estypes.SearchResponse<any>>;
getField<K extends keyof SearchSourceFields>(field: K, recurse?: boolean): SearchSourceFields[K];

View file

@ -12,7 +12,7 @@ import { handleResponse } from './handle_response';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { notificationServiceMock } from '../../../../../core/public/notifications/notifications_service.mock';
import { setNotifications } from '../../services';
import { SearchResponse } from 'elasticsearch';
import { IKibanaSearchResponse } from 'src/plugins/data/common';
jest.mock('@kbn/i18n', () => {
return {
@ -33,8 +33,10 @@ describe('handleResponse', () => {
test('should notify if timed out', () => {
const request = { body: {} };
const response = {
timed_out: true,
} as SearchResponse<any>;
rawResponse: {
timed_out: true,
},
} as IKibanaSearchResponse<any>;
const result = handleResponse(request, response);
expect(result).toBe(response);
expect(notifications.toasts.addWarning).toBeCalled();
@ -46,13 +48,15 @@ describe('handleResponse', () => {
test('should notify if shards failed', () => {
const request = { body: {} };
const response = {
_shards: {
failed: 1,
total: 2,
successful: 1,
skipped: 1,
rawResponse: {
_shards: {
failed: 1,
total: 2,
successful: 1,
skipped: 1,
},
},
} as SearchResponse<any>;
} as IKibanaSearchResponse<any>;
const result = handleResponse(request, response);
expect(result).toBe(response);
expect(notifications.toasts.addWarning).toBeCalled();
@ -63,7 +67,9 @@ describe('handleResponse', () => {
test('returns the response', () => {
const request = {};
const response = {} as SearchResponse<any>;
const response = {
rawResponse: {},
} as IKibanaSearchResponse<any>;
const result = handleResponse(request, response);
expect(result).toBe(response);
});

View file

@ -9,14 +9,15 @@
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiSpacer } from '@elastic/eui';
import type { estypes } from '@elastic/elasticsearch';
import { IKibanaSearchResponse } from 'src/plugins/data/common';
import { ShardFailureOpenModalButton } from '../../ui/shard_failure_modal';
import { toMountPoint } from '../../../../kibana_react/public';
import { getNotifications } from '../../services';
import { SearchRequest } from '..';
export function handleResponse(request: SearchRequest, response: estypes.SearchResponse<any>) {
if (response.timed_out) {
export function handleResponse(request: SearchRequest, response: IKibanaSearchResponse) {
const { rawResponse } = response;
if (rawResponse.timed_out) {
getNotifications().toasts.addWarning({
title: i18n.translate('data.search.searchSource.fetch.requestTimedOutNotificationMessage', {
defaultMessage: 'Data might be incomplete because your request timed out',
@ -24,12 +25,12 @@ export function handleResponse(request: SearchRequest, response: estypes.SearchR
});
}
if (response._shards && response._shards.failed) {
if (rawResponse._shards && rawResponse._shards.failed) {
const title = i18n.translate('data.search.searchSource.fetch.shardsFailedNotificationMessage', {
defaultMessage: '{shardsFailed} of {shardsTotal} shards failed',
values: {
shardsFailed: response._shards.failed,
shardsTotal: response._shards.total,
shardsFailed: rawResponse._shards.failed,
shardsTotal: rawResponse._shards.total,
},
});
const description = i18n.translate(
@ -43,7 +44,7 @@ export function handleResponse(request: SearchRequest, response: estypes.SearchR
<>
{description}
<EuiSpacer size="s" />
<ShardFailureOpenModalButton request={request.body} response={response} title={title} />
<ShardFailureOpenModalButton request={request.body} response={rawResponse} title={title} />
</>
);

View file

@ -144,7 +144,7 @@ describe('SearchInterceptor', () => {
describe('search', () => {
test('Observable should resolve if fetch is successful', async () => {
const mockResponse: any = { result: 200 };
const mockResponse: any = { rawResponse: {} };
fetchMock.mockResolvedValueOnce(mockResponse);
const mockRequest: IEsSearchRequest = {
params: {},
@ -233,6 +233,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: true,
isRunning: false,
rawResponse: {},
id: 1,
},
},
@ -255,6 +256,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: false,
isRunning: false,
rawResponse: {},
id: 1,
},
},
@ -281,6 +283,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: true,
isRunning: true,
rawResponse: {},
id: 1,
},
},
@ -289,6 +292,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: false,
isRunning: false,
rawResponse: {},
id: 1,
},
},
@ -325,6 +329,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: false,
isRunning: false,
rawResponse: {},
id: 1,
},
},
@ -349,6 +354,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: true,
isRunning: true,
rawResponse: {},
id: 1,
},
},
@ -357,6 +363,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: false,
isRunning: false,
rawResponse: {},
id: 1,
},
},
@ -389,6 +396,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: true,
isRunning: true,
rawResponse: {},
id: 1,
},
},
@ -433,6 +441,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: true,
isRunning: true,
rawResponse: {},
id: 1,
},
},
@ -441,6 +450,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: false,
isRunning: false,
rawResponse: {},
id: 1,
},
},
@ -511,7 +521,10 @@ describe('SearchInterceptor', () => {
sessionId,
});
await searchInterceptor.search(mockRequest, { sessionId }).toPromise();
await searchInterceptor
.search(mockRequest, { sessionId })
.toPromise()
.catch(() => {});
expect(fetchMock.mock.calls[0][0]).toEqual(
expect.objectContaining({
options: { sessionId, isStored: true, isRestore: true, strategy: 'ese' },
@ -527,7 +540,10 @@ describe('SearchInterceptor', () => {
const sessionId = 'sid';
setup(null);
await searchInterceptor.search(mockRequest, { sessionId }).toPromise();
await searchInterceptor
.search(mockRequest, { sessionId })
.toPromise()
.catch(() => {});
expect(fetchMock.mock.calls[0][0]).toEqual(
expect.not.objectContaining({
options: { sessionId },
@ -548,6 +564,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: true,
isRunning: true,
rawResponse: {},
id: 1,
},
},
@ -556,6 +573,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: false,
isRunning: false,
rawResponse: {},
id: 1,
},
},
@ -792,6 +810,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: true,
isRunning: true,
rawResponse: {},
id: 1,
},
},
@ -838,6 +857,7 @@ describe('SearchInterceptor', () => {
value: {
isPartial: true,
isRunning: false,
rawResponse: {},
id: 1,
},
},

View file

@ -251,7 +251,7 @@ export class SearchService implements Plugin<ISearchSetup, ISearchStart> {
private registerSearchStrategy = <
SearchStrategyRequest extends IKibanaSearchRequest = IEsSearchRequest,
SearchStrategyResponse extends IKibanaSearchResponse = IEsSearchResponse
SearchStrategyResponse extends IKibanaSearchResponse<any> = IEsSearchResponse
>(
name: string,
strategy: ISearchStrategy<SearchStrategyRequest, SearchStrategyResponse>

View file

@ -431,7 +431,7 @@ function discoverController($route, $scope) {
},
})
.toPromise()
.then(onResults)
.then(({ rawResponse }) => onResults(rawResponse))
.catch((error) => {
// If the request was aborted then no need to surface this error in the UI
if (error instanceof Error && error.name === 'AbortError') return;

View file

@ -325,7 +325,7 @@ export class SearchEmbeddable
try {
// Make the request
const resp = await searchSource
const { rawResponse: resp } = await searchSource
.fetch$({
abortSignal: this.abortController.signal,
sessionId: searchSessionId,

View file

@ -167,9 +167,8 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
const abortController = new AbortController();
registerCancelCallback(() => abortController.abort());
let resp;
try {
resp = await searchSource
const { rawResponse: resp } = await searchSource
.fetch$({
abortSignal: abortController.signal,
sessionId: searchSessionId,
@ -182,6 +181,7 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
},
})
.toPromise();
return resp;
} catch (error) {
if (isSearchSourceAbortError(error)) {
throw new DataRequestAbortError();
@ -194,8 +194,6 @@ export class AbstractESSource extends AbstractVectorSource implements IESSource
})
);
}
return resp;
}
async makeSearchSource(

View file

@ -27,20 +27,20 @@ export default function ({ getPageObjects, getService }) {
});
it('should request documents when zoomed to smaller regions showing less data', async () => {
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
// Allow a range of hits to account for variances in browser window size.
expect(response.hits.hits.length).to.be.within(30, 40);
});
it('should request clusters when zoomed to larger regions showing lots of data', async () => {
await PageObjects.maps.setView(20, -90, 2);
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(17);
});
it('should request documents when query narrows data', async () => {
await PageObjects.maps.setAndSubmitQuery('bytes > 19000');
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.hits.hits.length).to.equal(75);
});
});

View file

@ -23,7 +23,7 @@ export default function ({ getPageObjects, getService }) {
it('should only fetch geo_point field and nothing else when source does not have data driven styling', async () => {
await PageObjects.maps.loadSavedMap('document example');
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
const firstHit = response.hits.hits[0];
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
expect(firstHit.fields).to.only.have.keys(['geo.coordinates']);
@ -31,7 +31,7 @@ export default function ({ getPageObjects, getService }) {
it('should only fetch geo_point field and data driven styling fields', async () => {
await PageObjects.maps.loadSavedMap('document example with data driven styles');
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
const firstHit = response.hits.hits[0];
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
expect(firstHit.fields).to.only.have.keys(['bytes', 'geo.coordinates', 'hour_of_day']);
@ -39,7 +39,7 @@ export default function ({ getPageObjects, getService }) {
it('should format date fields as epoch_millis when data driven styling is applied to a date field', async () => {
await PageObjects.maps.loadSavedMap('document example with data driven styles on date field');
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
const firstHit = response.hits.hits[0];
expect(firstHit).to.only.have.keys(['_id', '_index', '_score', 'fields']);
expect(firstHit.fields).to.only.have.keys(['@timestamp', 'bytes', 'geo.coordinates']);

View file

@ -83,7 +83,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should apply container state (time, query, filters) to embeddable when loaded', async () => {
const response = await PageObjects.maps.getResponseFromDashboardPanel(
const { rawResponse: response } = await PageObjects.maps.getResponseFromDashboardPanel(
'geo grid vector grid example'
);
expect(response.aggregations.gridSplit.buckets.length).to.equal(6);
@ -95,12 +95,12 @@ export default function ({ getPageObjects, getService }) {
await filterBar.selectIndexPattern('meta_for_geo_shapes*');
await filterBar.addFilter('shape_name', 'is', 'alpha'); // runtime fields do not have autocomplete
const gridResponse = await PageObjects.maps.getResponseFromDashboardPanel(
const { rawResponse: gridResponse } = await PageObjects.maps.getResponseFromDashboardPanel(
'geo grid vector grid example'
);
expect(gridResponse.aggregations.gridSplit.buckets.length).to.equal(1);
const joinResponse = await PageObjects.maps.getResponseFromDashboardPanel(
const { rawResponse: joinResponse } = await PageObjects.maps.getResponseFromDashboardPanel(
'join example',
'meta_for_geo_shapes*.runtime_shape_name'
);

View file

@ -141,7 +141,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should apply query to geotile_grid aggregation request', async () => {
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(1);
});
});
@ -152,7 +152,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should contain geotile_grid aggregation elasticsearch request', async () => {
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(4);
});
@ -204,7 +204,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should apply query to geotile_grid aggregation request', async () => {
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(1);
});
});
@ -215,7 +215,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should contain geotile_grid aggregation elasticsearch request', async () => {
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(4);
});
@ -244,7 +244,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should contain geotile_grid aggregation elasticsearch request', async () => {
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.gridSplit.buckets.length).to.equal(13);
});
});

View file

@ -24,7 +24,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should request source clusters for destination locations', async () => {
const response = await PageObjects.maps.getResponse();
const { rawResponse: response } = await PageObjects.maps.getResponse();
expect(response.aggregations.destSplit.buckets.length).to.equal(2);
});

View file

@ -121,7 +121,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should not apply query to source and apply query to join', async () => {
const joinResponse = await PageObjects.maps.getResponse(
const { rawResponse: joinResponse } = await PageObjects.maps.getResponse(
'meta_for_geo_shapes*.runtime_shape_name'
);
expect(joinResponse.aggregations.join.buckets.length).to.equal(2);
@ -138,7 +138,7 @@ export default function ({ getPageObjects, getService }) {
});
it('should apply query to join request', async () => {
const joinResponse = await PageObjects.maps.getResponse(
const { rawResponse: joinResponse } = await PageObjects.maps.getResponse(
'meta_for_geo_shapes*.runtime_shape_name'
);
expect(joinResponse.aggregations.join.buckets.length).to.equal(1);