Skip to content

Commit

Permalink
[Discover] migrate remaining context files from js to ts
Browse files Browse the repository at this point in the history
  • Loading branch information
dimaanj committed May 3, 2021
1 parent 3cc6989 commit 6e26af1
Show file tree
Hide file tree
Showing 13 changed files with 368 additions and 223 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,71 +9,70 @@
import sinon from 'sinon';
import moment from 'moment';

import { IndexPatternsContract } from '../../../../../../data/public';
import { EsHitRecord, EsHitRecordList } from './context';

export function createIndexPatternsStub() {
return {
return ({
get: sinon.spy((indexPatternId) =>
Promise.resolve({
id: indexPatternId,
isTimeNanosBased: () => false,
popularizeField: () => {},
})
),
};
} as unknown) as IndexPatternsContract;
}

/**
* A stubbed search source with a `fetch` method that returns all of `_stubHits`.
*/
export function createSearchSourceStub(hits, timeField) {
const searchSourceStub = {
export function createSearchSourceStub(hits: Array<Partial<EsHitRecord>>, timeField?: string) {
const searchSourceStub: any = {
_stubHits: hits,
_stubTimeField: timeField,
_createStubHit: (timestamp, tiebreaker = 0) => ({
_createStubHit: (timestamp: number, tiebreaker = 0) => ({
[searchSourceStub._stubTimeField]: timestamp,
sort: [timestamp, tiebreaker],
}),
setParent: sinon.spy(() => searchSourceStub),
setField: sinon.spy(() => searchSourceStub),
removeField: sinon.spy(() => searchSourceStub),
getField: sinon.spy((key) => {
const previousSetCall = searchSourceStub.setField.withArgs(key).lastCall;
return previousSetCall ? previousSetCall.args[1] : null;
}),
fetch: sinon.spy(() =>
Promise.resolve({
hits: {
hits: searchSourceStub._stubHits,
total: searchSourceStub._stubHits.length,
},
})
),
};

searchSourceStub.setParent = sinon.spy(() => searchSourceStub);
searchSourceStub.setField = sinon.spy(() => searchSourceStub);
searchSourceStub.removeField = sinon.spy(() => searchSourceStub);

searchSourceStub.getField = sinon.spy((key) => {
const previousSetCall = searchSourceStub.setField.withArgs(key).lastCall;
return previousSetCall ? previousSetCall.args[1] : null;
});

searchSourceStub.fetch = sinon.spy(() =>
Promise.resolve({
hits: {
hits: searchSourceStub._stubHits,
total: searchSourceStub._stubHits.length,
},
})
);

return searchSourceStub;
}

/**
* A stubbed search source with a `fetch` method that returns a filtered set of `_stubHits`.
*/
export function createContextSearchSourceStub(hits, timeField = '@timestamp') {
const searchSourceStub = createSearchSourceStub(hits, timeField);
export function createContextSearchSourceStub(hits: EsHitRecordList, timeFieldName = '@timestamp') {
const searchSourceStub = createSearchSourceStub(hits, timeFieldName);

searchSourceStub.fetch = sinon.spy(() => {
const timeField = searchSourceStub._stubTimeField;
const timeField: keyof EsHitRecord = searchSourceStub._stubTimeField;
const lastQuery = searchSourceStub.setField.withArgs('query').lastCall.args[1];
const timeRange = lastQuery.query.bool.must.constant_score.filter.range[timeField];
const lastSort = searchSourceStub.setField.withArgs('sort').lastCall.args[1];
const sortDirection = lastSort[0][timeField].order;
const sortFunction =
sortDirection === 'asc'
? (first, second) => first[timeField] - second[timeField]
: (first, second) => second[timeField] - first[timeField];
? (first: any, second: any) => first[timeField] - second[timeField]
: (first: any, second: any) => second[timeField] - first[timeField];
const filteredHits = searchSourceStub._stubHits
.filter(
(hit) =>
(hit: EsHitRecord) =>
moment(hit[timeField]).isSameOrAfter(timeRange.gte) &&
moment(hit[timeField]).isSameOrBefore(timeRange.lte)
)
Expand All @@ -87,5 +86,5 @@ export function createContextSearchSourceStub(hits, timeField = '@timestamp') {
});
});

return searchSourceStub;
return searchSourceStub as sinon.SinonStub;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,41 @@
* Side Public License, v 1.
*/

import { createIndexPatternsStub, createSearchSourceStub } from './_stubs';
import { Dictionary } from 'lodash';

import { fetchAnchorProvider } from './anchor';
import { SortDirection } from '../../../../../../data/public';
import { createIndexPatternsStub, createSearchSourceStub } from './_stubs';
import { AnchorHitRecord, fetchAnchorProvider } from './anchor';

describe('context app', function () {
describe('function fetchAnchor', function () {
let fetchAnchor;
let searchSourceStub;
let fetchAnchor: (
indexPatternId: string,
anchorId: string,
sort: [Dictionary<SortDirection>, { [key: string]: SortDirection }]
) => Promise<AnchorHitRecord>;
let searchSourceStub: any;

describe('function fetchAnchor', function () {
beforeEach(() => {
searchSourceStub = createSearchSourceStub([{ _id: 'hit1' }]);
searchSourceStub = createSearchSourceStub([
{ _id: 'hit1', fields: [], sort: [], _source: {} },
]);
fetchAnchor = fetchAnchorProvider(createIndexPatternsStub(), searchSourceStub);
});

it('should use the `fetch` method of the SearchSource', function () {
return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(() => {
expect(searchSourceStub.fetch.calledOnce).toBe(true);
});
});

it('should configure the SearchSource to not inherit from the implicit root', function () {
return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(() => {
const setParentSpy = searchSourceStub.setParent;
expect(setParentSpy.calledOnce).toBe(true);
Expand All @@ -42,8 +50,8 @@ describe('context app', function () {

it('should set the SearchSource index pattern', function () {
return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(() => {
const setFieldSpy = searchSourceStub.setField;
expect(setFieldSpy.firstCall.args[1].id).toEqual('INDEX_PATTERN_ID');
Expand All @@ -52,8 +60,8 @@ describe('context app', function () {

it('should set the SearchSource version flag to true', function () {
return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(() => {
const setVersionSpy = searchSourceStub.setField.withArgs('version');
expect(setVersionSpy.calledOnce).toBe(true);
Expand All @@ -63,8 +71,8 @@ describe('context app', function () {

it('should set the SearchSource size to 1', function () {
return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(() => {
const setSizeSpy = searchSourceStub.setField.withArgs('size');
expect(setSizeSpy.calledOnce).toBe(true);
Expand All @@ -74,8 +82,8 @@ describe('context app', function () {

it('should set the SearchSource query to an ids query', function () {
return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(() => {
const setQuerySpy = searchSourceStub.setField.withArgs('query');
expect(setQuerySpy.calledOnce).toBe(true);
Expand All @@ -96,24 +104,27 @@ describe('context app', function () {

it('should set the SearchSource sort order', function () {
return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(() => {
const setSortSpy = searchSourceStub.setField.withArgs('sort');
expect(setSortSpy.calledOnce).toBe(true);
expect(setSortSpy.firstCall.args[1]).toEqual([{ '@timestamp': 'desc' }, { _doc: 'desc' }]);
expect(setSortSpy.firstCall.args[1]).toEqual([
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]);
});
});

it('should reject with an error when no hits were found', function () {
searchSourceStub._stubHits = [];

return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(
() => {
expect().fail('expected the promise to be rejected');
fail('expected the promise to be rejected');
},
(error) => {
expect(error).toBeInstanceOf(Error);
Expand All @@ -125,8 +136,8 @@ describe('context app', function () {
searchSourceStub._stubHits = [{ property1: 'value1' }, { property2: 'value2' }];

return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then((anchorDocument) => {
expect(anchorDocument).toHaveProperty('property1', 'value1');
expect(anchorDocument).toHaveProperty('$$_isAnchor', true);
Expand All @@ -135,9 +146,6 @@ describe('context app', function () {
});

describe('useNewFields API', () => {
let fetchAnchor;
let searchSourceStub;

beforeEach(() => {
searchSourceStub = createSearchSourceStub([{ _id: 'hit1' }]);
fetchAnchor = fetchAnchorProvider(createIndexPatternsStub(), searchSourceStub, true);
Expand All @@ -147,8 +155,8 @@ describe('context app', function () {
searchSourceStub._stubHits = [{ property1: 'value1' }, { property2: 'value2' }];

return fetchAnchor('INDEX_PATTERN_ID', 'id', [
{ '@timestamp': 'desc' },
{ _doc: 'desc' },
{ '@timestamp': SortDirection.desc },
{ _doc: SortDirection.desc },
]).then(() => {
const setFieldsSpy = searchSourceStub.setField.withArgs('fields');
const removeFieldsSpy = searchSourceStub.removeField.withArgs('fieldsFromSource');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,27 @@
* Side Public License, v 1.
*/

import _ from 'lodash';
import _, { Dictionary } from 'lodash';
import { i18n } from '@kbn/i18n';

export function fetchAnchorProvider(indexPatterns, searchSource, useNewFieldsApi = false) {
return async function fetchAnchor(indexPatternId, anchorId, sort) {
import { ISearchSource, IndexPatternsContract, SortDirection } from '../../../../../../data/public';
import { EsHitRecord } from './context';

export interface AnchorHitRecord extends EsHitRecord {
// eslint-disable-next-line @typescript-eslint/naming-convention
$$_isAnchor: boolean;
}

export function fetchAnchorProvider(
indexPatterns: IndexPatternsContract,
searchSource: ISearchSource,
useNewFieldsApi: boolean = false
) {
return async function fetchAnchor(
indexPatternId: string,
anchorId: string,
sort: [Dictionary<SortDirection>, { [key: string]: SortDirection }]
): Promise<AnchorHitRecord> {
const indexPattern = await indexPatterns.get(indexPatternId);
searchSource
.setParent(undefined)
Expand Down Expand Up @@ -46,7 +62,8 @@ export function fetchAnchorProvider(indexPatterns, searchSource, useNewFieldsApi

return {
..._.get(response, ['hits', 'hits', 0]),
// eslint-disable-next-line @typescript-eslint/naming-convention
$$_isAnchor: true,
};
} as AnchorHitRecord;
};
}
Loading

0 comments on commit 6e26af1

Please sign in to comment.