mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[ML] Tests for ML annotations feature. (#27994)
Adds unit/integration tests for various parts of the code base affected by the annotations feature.
This commit is contained in:
parent
3496dff912
commit
99f99291ef
15 changed files with 711 additions and 1 deletions
|
@ -0,0 +1,135 @@
|
|||
{
|
||||
"job_id": "farequote",
|
||||
"job_type": "anomaly_detector",
|
||||
"job_version": "7.0.0",
|
||||
"description": "",
|
||||
"create_time": 1546418356716,
|
||||
"finished_time": 1546418359427,
|
||||
"established_model_memory": 42102,
|
||||
"analysis_config": {
|
||||
"bucket_span": "15m",
|
||||
"summary_count_field_name": "doc_count",
|
||||
"detectors": [
|
||||
{
|
||||
"detector_description": "count",
|
||||
"function": "count",
|
||||
"detector_index": 0
|
||||
}
|
||||
],
|
||||
"influencers": []
|
||||
},
|
||||
"analysis_limits": {
|
||||
"model_memory_limit": "10mb",
|
||||
"categorization_examples_limit": 4
|
||||
},
|
||||
"data_description": {
|
||||
"time_field": "@timestamp",
|
||||
"time_format": "epoch_ms"
|
||||
},
|
||||
"model_plot_config": {
|
||||
"enabled": true
|
||||
},
|
||||
"model_snapshot_retention_days": 1,
|
||||
"custom_settings": {
|
||||
"created_by": "single-metric-wizard"
|
||||
},
|
||||
"model_snapshot_id": "1546418359",
|
||||
"model_snapshot_min_version": "6.4.0",
|
||||
"results_index_name": "shared",
|
||||
"data_counts": {
|
||||
"job_id": "farequote",
|
||||
"processed_record_count": 479,
|
||||
"processed_field_count": 479,
|
||||
"input_bytes": 21554,
|
||||
"input_field_count": 479,
|
||||
"invalid_date_count": 0,
|
||||
"missing_field_count": 0,
|
||||
"out_of_order_timestamp_count": 0,
|
||||
"empty_bucket_count": 0,
|
||||
"sparse_bucket_count": 0,
|
||||
"bucket_count": 478,
|
||||
"earliest_record_timestamp": 1454804096000,
|
||||
"latest_record_timestamp": 1455234298000,
|
||||
"last_data_time": 1546418357578,
|
||||
"input_record_count": 479
|
||||
},
|
||||
"model_size_stats": {
|
||||
"job_id": "farequote",
|
||||
"result_type": "model_size_stats",
|
||||
"model_bytes": 42102,
|
||||
"total_by_field_count": 3,
|
||||
"total_over_field_count": 0,
|
||||
"total_partition_field_count": 2,
|
||||
"bucket_allocation_failures_count": 0,
|
||||
"memory_status": "ok",
|
||||
"log_time": 1546418359000,
|
||||
"timestamp": 1455232500000
|
||||
},
|
||||
"datafeed_config": {
|
||||
"datafeed_id": "datafeed-farequote",
|
||||
"job_id": "farequote",
|
||||
"query_delay": "115823ms",
|
||||
"indices": [
|
||||
"farequote"
|
||||
],
|
||||
"types": [],
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{
|
||||
"query_string": {
|
||||
"query": "*",
|
||||
"fields": [],
|
||||
"type": "best_fields",
|
||||
"default_operator": "or",
|
||||
"max_determinized_states": 10000,
|
||||
"enable_position_increments": true,
|
||||
"fuzziness": "AUTO",
|
||||
"fuzzy_prefix_length": 0,
|
||||
"fuzzy_max_expansions": 50,
|
||||
"phrase_slop": 0,
|
||||
"analyze_wildcard": true,
|
||||
"escape": false,
|
||||
"auto_generate_synonyms_phrase_query": true,
|
||||
"fuzzy_transpositions": true,
|
||||
"boost": 1
|
||||
}
|
||||
}
|
||||
],
|
||||
"adjust_pure_negative": true,
|
||||
"boost": 1
|
||||
}
|
||||
},
|
||||
"aggregations": {
|
||||
"buckets": {
|
||||
"date_histogram": {
|
||||
"field": "@timestamp",
|
||||
"interval": 900000,
|
||||
"offset": 0,
|
||||
"order": {
|
||||
"_key": "asc"
|
||||
},
|
||||
"keyed": false,
|
||||
"min_doc_count": 0
|
||||
},
|
||||
"aggregations": {
|
||||
"@timestamp": {
|
||||
"max": {
|
||||
"field": "@timestamp"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scroll_size": 1000,
|
||||
"chunking_config": {
|
||||
"mode": "manual",
|
||||
"time_span": "900000000ms"
|
||||
},
|
||||
"delayed_data_check_config": {
|
||||
"enabled": true
|
||||
},
|
||||
"state": "stopped"
|
||||
},
|
||||
"state": "closed"
|
||||
}
|
23
x-pack/plugins/ml/common/types/annotations.test.ts
Normal file
23
x-pack/plugins/ml/common/types/annotations.test.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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 { ANNOTATION_TYPE } from '../constants/annotations';
|
||||
|
||||
import { isAnnotation, isAnnotations } from './annotations';
|
||||
|
||||
describe('Types: Annotations', () => {
|
||||
test('Minimal integrity check.', () => {
|
||||
const annotation = {
|
||||
job_id: 'id',
|
||||
annotation: 'Annotation text',
|
||||
timestamp: 0,
|
||||
type: ANNOTATION_TYPE.ANNOTATION,
|
||||
};
|
||||
|
||||
expect(isAnnotation(annotation)).toBe(true);
|
||||
expect(isAnnotations([annotation])).toBe(true);
|
||||
});
|
||||
});
|
15
x-pack/plugins/ml/common/types/jobs.test.js
Normal file
15
x-pack/plugins/ml/common/types/jobs.test.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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 jobConfigFarequote from './__mocks__/job_config_farequote';
|
||||
import { isMlJob, isMlJobs } from './jobs';
|
||||
|
||||
describe('Types: Jobs', () => {
|
||||
test('Minimal integrity check.', () => {
|
||||
expect(isMlJob(jobConfigFarequote)).toBe(true);
|
||||
expect(isMlJobs([jobConfigFarequote])).toBe(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
[
|
||||
{
|
||||
"timestamp": 1455026177994,
|
||||
"end_timestamp": 1455041968976,
|
||||
"annotation": "Major spike.",
|
||||
"job_id": "farequote",
|
||||
"type": "annotation",
|
||||
"create_time": 1546417097181,
|
||||
"create_username": "<user unknown>",
|
||||
"modified_time": 1546417097181,
|
||||
"modified_username": "<user unknown>",
|
||||
"_id": "KCCkDWgB_ZdQ1MFDSYPi"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,126 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AnnotationsTable Initialization with annotations prop. 1`] = `
|
||||
<EuiInMemoryTable
|
||||
className="eui-textOverflowWrap"
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"field": "annotation",
|
||||
"name": "Annotation",
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"dataType": "date",
|
||||
"field": "timestamp",
|
||||
"name": "From",
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"dataType": "date",
|
||||
"field": "end_timestamp",
|
||||
"name": "To",
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"dataType": "date",
|
||||
"field": "create_time",
|
||||
"name": "Creation date",
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"field": "create_username",
|
||||
"name": "Created by",
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"dataType": "date",
|
||||
"field": "modified_time",
|
||||
"name": "Last modified date",
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"field": "modified_username",
|
||||
"name": "Last modified by",
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"align": "right",
|
||||
"name": "View",
|
||||
"render": [Function],
|
||||
"width": "60px",
|
||||
},
|
||||
]
|
||||
}
|
||||
compressed={true}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"_id": "KCCkDWgB_ZdQ1MFDSYPi",
|
||||
"annotation": "Major spike.",
|
||||
"create_time": 1546417097181,
|
||||
"create_username": "<user unknown>",
|
||||
"end_timestamp": 1455041968976,
|
||||
"job_id": "farequote",
|
||||
"modified_time": 1546417097181,
|
||||
"modified_username": "<user unknown>",
|
||||
"timestamp": 1455026177994,
|
||||
"type": "annotation",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={
|
||||
Object {
|
||||
"pageSizeOptions": Array [
|
||||
5,
|
||||
10,
|
||||
25,
|
||||
],
|
||||
}
|
||||
}
|
||||
responsive={true}
|
||||
rowProps={[Function]}
|
||||
sorting={
|
||||
Object {
|
||||
"sort": Object {
|
||||
"direction": "asc",
|
||||
"field": "timestamp",
|
||||
},
|
||||
}
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`AnnotationsTable Initialization with job config prop. 1`] = `
|
||||
<EuiFlexGroup
|
||||
alignItems="stretch"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="spaceAround"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiLoadingSpinner
|
||||
size="l"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
||||
|
||||
exports[`AnnotationsTable Minimal initialization without props. 1`] = `
|
||||
<EuiCallOut
|
||||
color="primary"
|
||||
iconType="iInCircle"
|
||||
size="m"
|
||||
title="No annotations created for this job"
|
||||
/>
|
||||
`;
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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 jobConfig from '../../../../common/types/__mocks__/job_config_farequote';
|
||||
|
||||
import ngMock from 'ng_mock';
|
||||
import expect from 'expect.js';
|
||||
import sinon from 'sinon';
|
||||
|
||||
import { ml } from '../../../services/ml_api_service';
|
||||
|
||||
describe('ML - <ml-annotation-table>', () => {
|
||||
let $scope;
|
||||
let $compile;
|
||||
|
||||
beforeEach(ngMock.module('kibana'));
|
||||
beforeEach(() => {
|
||||
ngMock.inject(function ($injector) {
|
||||
$compile = $injector.get('$compile');
|
||||
const $rootScope = $injector.get('$rootScope');
|
||||
$scope = $rootScope.$new();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
$scope.$destroy();
|
||||
});
|
||||
|
||||
it('Plain initialization doesn\'t throw an error', () => {
|
||||
expect(() => {
|
||||
$compile('<ml-annotation-table />')($scope);
|
||||
}).to.not.throwError();
|
||||
});
|
||||
|
||||
it('Initialization with empty annotations array doesn\'t throw an error', () => {
|
||||
expect(() => {
|
||||
$compile('<ml-annotation-table annotations="[]" />')($scope);
|
||||
}).to.not.throwError();
|
||||
});
|
||||
|
||||
it('Initialization with job config doesn\'t throw an error', () => {
|
||||
const getAnnotationsStub = sinon.stub(ml.annotations, 'getAnnotations').resolves({ annotations: [] });
|
||||
|
||||
expect(() => {
|
||||
$scope.jobs = [jobConfig];
|
||||
$compile('<ml-annotation-table jobs="jobs" />')($scope);
|
||||
}).to.not.throwError();
|
||||
|
||||
getAnnotationsStub.restore();
|
||||
});
|
||||
|
||||
});
|
|
@ -109,7 +109,10 @@ class AnnotationsTable extends Component {
|
|||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.annotations === undefined) {
|
||||
if (
|
||||
this.props.annotations === undefined &&
|
||||
Array.isArray(this.props.jobs) && this.props.jobs.length > 0
|
||||
) {
|
||||
this.getAnnotations();
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +121,7 @@ class AnnotationsTable extends Component {
|
|||
if (
|
||||
this.props.annotations === undefined &&
|
||||
this.state.isLoading === false &&
|
||||
Array.isArray(this.props.jobs) && this.props.jobs.length > 0 &&
|
||||
this.state.jobId !== this.props.jobs[0].job_id
|
||||
) {
|
||||
this.getAnnotations();
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 jobConfig from '../../../common/types/__mocks__/job_config_farequote';
|
||||
import mockAnnotations from './__mocks__/mock_annotations.json';
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { AnnotationsTable } from './annotations_table';
|
||||
|
||||
jest.mock('ui/chrome', () => ({
|
||||
getBasePath: (path) => path,
|
||||
addBasePath: () => {}
|
||||
}));
|
||||
|
||||
jest.mock('../../services/job_service', () => ({
|
||||
mlJobService: {
|
||||
getJob: jest.fn()
|
||||
}
|
||||
}));
|
||||
|
||||
jest.mock('../../services/ml_api_service', () => ({
|
||||
ml: {
|
||||
annotations: {
|
||||
getAnnotations: jest.fn().mockResolvedValue({ annotations: [] })
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
describe('AnnotationsTable', () => {
|
||||
test('Minimal initialization without props.', () => {
|
||||
const wrapper = shallow(<AnnotationsTable />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Initialization with job config prop.', () => {
|
||||
const wrapper = shallow(<AnnotationsTable jobs={[jobConfig]} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Initialization with annotations prop.', () => {
|
||||
const wrapper = shallow(<AnnotationsTable annotations={mockAnnotations} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
});
|
|
@ -19,6 +19,7 @@ describe('ML - Explorer Controller', () => {
|
|||
const scope = $rootScope.$new();
|
||||
$controller('MlExplorerController', { $scope: scope });
|
||||
|
||||
expect(Array.isArray(scope.annotationsData)).to.be(true);
|
||||
expect(Array.isArray(scope.anomalyChartRecords)).to.be(true);
|
||||
expect(scope.loading).to.be(true);
|
||||
});
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AnnotationDescriptionList Initialization with annotation. 1`] = `
|
||||
<EuiDescriptionList
|
||||
align="left"
|
||||
className="ml-annotation-description-list"
|
||||
compressed={false}
|
||||
listItems={
|
||||
Array [
|
||||
Object {
|
||||
"description": "farequote",
|
||||
"title": "Job ID",
|
||||
},
|
||||
Object {
|
||||
"description": "February 9th 2016, 13:56:17",
|
||||
"title": "Start",
|
||||
},
|
||||
Object {
|
||||
"description": "February 9th 2016, 18:19:28",
|
||||
"title": "End",
|
||||
},
|
||||
Object {
|
||||
"description": "January 2nd 2019, 08:18:17",
|
||||
"title": "Created",
|
||||
},
|
||||
Object {
|
||||
"description": "<user unknown>",
|
||||
"title": "Created by",
|
||||
},
|
||||
Object {
|
||||
"description": "January 2nd 2019, 08:18:17",
|
||||
"title": "Last modified",
|
||||
},
|
||||
Object {
|
||||
"description": "<user unknown>",
|
||||
"title": "Modified by",
|
||||
},
|
||||
]
|
||||
}
|
||||
textStyle="normal"
|
||||
type="column"
|
||||
/>
|
||||
`;
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 mockAnnotations from '../../../components/annotations_table/__mocks__/mock_annotations.json';
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import moment from 'moment-timezone';
|
||||
import React from 'react';
|
||||
|
||||
import { AnnotationDescriptionList } from './index';
|
||||
|
||||
describe('AnnotationDescriptionList', () => {
|
||||
beforeEach(() => {
|
||||
moment.tz.setDefault('UTC');
|
||||
});
|
||||
afterEach(() => {
|
||||
moment.tz.setDefault('Browser');
|
||||
});
|
||||
|
||||
test('Initialization with annotation.', () => {
|
||||
const wrapper = shallow(<AnnotationDescriptionList annotation={mockAnnotations[0]} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,120 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`AnnotationFlyout Initialization. 1`] = `
|
||||
<EuiFlyout
|
||||
aria-labelledby="Add annotation"
|
||||
closeButtonAriaLabel="Closes this dialog"
|
||||
hideCloseButton={false}
|
||||
maxWidth={false}
|
||||
onClose={[MockFunction]}
|
||||
ownFocus={false}
|
||||
size="s"
|
||||
>
|
||||
<EuiFlyoutHeader
|
||||
hasBorder={true}
|
||||
>
|
||||
<EuiTitle
|
||||
size="s"
|
||||
textTransform="none"
|
||||
>
|
||||
<h2
|
||||
id="mlAnnotationFlyoutTitle"
|
||||
>
|
||||
Edit
|
||||
annotation
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<Component
|
||||
annotation={
|
||||
Object {
|
||||
"_id": "KCCkDWgB_ZdQ1MFDSYPi",
|
||||
"annotation": "Major spike.",
|
||||
"create_time": 1546417097181,
|
||||
"create_username": "<user unknown>",
|
||||
"end_timestamp": 1455041968976,
|
||||
"job_id": "farequote",
|
||||
"modified_time": 1546417097181,
|
||||
"modified_username": "<user unknown>",
|
||||
"timestamp": 1455026177994,
|
||||
"type": "annotation",
|
||||
}
|
||||
}
|
||||
/>
|
||||
<EuiSpacer
|
||||
size="m"
|
||||
/>
|
||||
<EuiFormRow
|
||||
describedByIds={Array []}
|
||||
fullWidth={true}
|
||||
hasEmptyLabelSpace={false}
|
||||
label="Annotation text"
|
||||
>
|
||||
<EuiTextArea
|
||||
fullWidth={true}
|
||||
isInvalid={false}
|
||||
onChange={[MockFunction]}
|
||||
placeholder="..."
|
||||
resize="vertical"
|
||||
value="Major spike."
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFlyoutBody>
|
||||
<EuiFlyoutFooter>
|
||||
<EuiFlexGroup
|
||||
alignItems="stretch"
|
||||
component="div"
|
||||
direction="row"
|
||||
gutterSize="l"
|
||||
justifyContent="spaceBetween"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
color="primary"
|
||||
flush="left"
|
||||
iconSide="left"
|
||||
iconType="cross"
|
||||
onClick={[MockFunction]}
|
||||
type="button"
|
||||
>
|
||||
Cancel
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButtonEmpty
|
||||
color="danger"
|
||||
iconSide="left"
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Delete
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButton
|
||||
color="primary"
|
||||
fill={true}
|
||||
iconSide="left"
|
||||
isDisabled={false}
|
||||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Update
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiFlyoutFooter>
|
||||
</EuiFlyout>
|
||||
`;
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 mockAnnotations from '../../../components/annotations_table/__mocks__/mock_annotations.json';
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
import { AnnotationFlyout } from './index';
|
||||
|
||||
describe('AnnotationFlyout', () => {
|
||||
test('Initialization.', () => {
|
||||
const props = {
|
||||
annotation: mockAnnotations[0],
|
||||
cancelAction: jest.fn(),
|
||||
controlFunc: jest.fn(),
|
||||
deleteAction: jest.fn(),
|
||||
saveAction: jest.fn(),
|
||||
};
|
||||
|
||||
const wrapper = shallow(<AnnotationFlyout {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,54 @@
|
|||
[
|
||||
{
|
||||
"timestamp": 1454810815950,
|
||||
"end_timestamp": 1455060155890,
|
||||
"annotation": "Still learning the model.",
|
||||
"job_id": "farequote",
|
||||
"type": "annotation",
|
||||
"create_time": 1546530633618,
|
||||
"create_username": "<user unknown>",
|
||||
"modified_time": 1546530633618,
|
||||
"modified_username": "<user unknown>",
|
||||
"_id": "6bpoFGgBrdsAtoAOt0WT",
|
||||
"key": "A"
|
||||
},
|
||||
{
|
||||
"timestamp": 1455020901845,
|
||||
"end_timestamp": 1455075725930,
|
||||
"annotation": "Overlapping annotation.",
|
||||
"job_id": "farequote",
|
||||
"type": "annotation",
|
||||
"create_time": 1546530659999,
|
||||
"create_username": "<user unknown>",
|
||||
"modified_time": 1546530659999,
|
||||
"modified_username": "<user unknown>",
|
||||
"_id": "6rppFGgBrdsAtoAOHkWg",
|
||||
"key": "B"
|
||||
},
|
||||
{
|
||||
"timestamp": 1455027864892,
|
||||
"end_timestamp": 1455042003613,
|
||||
"annotation": "Massive spike.",
|
||||
"job_id": "farequote",
|
||||
"type": "annotation",
|
||||
"create_time": 1546512778313,
|
||||
"create_username": "<user unknown>",
|
||||
"modified_time": 1546512778313,
|
||||
"modified_username": "<user unknown>",
|
||||
"_id": "Gl5YE2gBBwRksc9URChP",
|
||||
"key": "C"
|
||||
},
|
||||
{
|
||||
"timestamp": 1455063006742,
|
||||
"end_timestamp": 1455230768443,
|
||||
"annotation": "Learned the model.",
|
||||
"job_id": "farequote",
|
||||
"type": "annotation",
|
||||
"create_time": 1546530615480,
|
||||
"create_username": "<user unknown>",
|
||||
"modified_time": 1546530615480,
|
||||
"modified_username": "<user unknown>",
|
||||
"_id": "6LpoFGgBrdsAtoAOcEW7",
|
||||
"key": "D"
|
||||
}
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* 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 mockAnnotationsOverlap from './__mocks__/mock_annotations_overlap.json';
|
||||
|
||||
import { getAnnotationLevels } from './timeseries_chart_annotations';
|
||||
|
||||
describe('Timeseries Chart Annotations: getAnnotationLevels()', () => {
|
||||
test('getAnnotationLevels()', () => {
|
||||
const levels = getAnnotationLevels(mockAnnotationsOverlap);
|
||||
expect(levels).toEqual({ A: 0, B: 1, C: 2, D: 2 });
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue