From 090831922d40bf2f74dd0677d33c7a09a8e64c52 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Mon, 21 Nov 2022 13:19:07 -0700 Subject: [PATCH] [ML] Api Integration tests: adds tests for 'api/ml/results/datafeed_results_chart' (#145619) ## Summary Related meta issue https://github.com/elastic/kibana/issues/142456 This PR adds api integration tests for the `api/ml/results/datafeed_results_chart` endpoint ### 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 Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> (cherry picked from commit a74bfee93f174e9cde586c27746053f71d899b55) --- .../ml/results/get_datafeed_results_chart.ts | 126 ++++++++++++++++++ .../api_integration/apis/ml/results/index.ts | 1 + 2 files changed, 127 insertions(+) create mode 100644 x-pack/test/api_integration/apis/ml/results/get_datafeed_results_chart.ts diff --git a/x-pack/test/api_integration/apis/ml/results/get_datafeed_results_chart.ts b/x-pack/test/api_integration/apis/ml/results/get_datafeed_results_chart.ts new file mode 100644 index 0000000000000..b50676b8591ef --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/results/get_datafeed_results_chart.ts @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { Datafeed, Job } from '@kbn/ml-plugin/common/types/anomaly_detection_jobs'; +import { ANNOTATION_TYPE } from '@kbn/ml-plugin/common/constants/annotations'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { USER } from '../../../../functional/services/ml/security_common'; +import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; + +export default ({ getService }: FtrProviderContext) => { + const esArchiver = getService('esArchiver'); + const supertest = getService('supertestWithoutAuth'); + const ml = getService('ml'); + + // @ts-expect-error not full interface + const JOB_CONFIG: Job = { + job_id: `fq_multi_1_ae`, + description: + 'mean/min/max(responsetime) partition=airline on farequote dataset with 1h bucket span', + groups: ['farequote', 'automated', 'multi-metric'], + analysis_config: { + bucket_span: '1h', + influencers: ['airline'], + detectors: [ + { function: 'mean', field_name: 'responsetime', partition_field_name: 'airline' }, + { function: 'min', field_name: 'responsetime', partition_field_name: 'airline' }, + { function: 'max', field_name: 'responsetime', partition_field_name: 'airline' }, + ], + }, + data_description: { time_field: '@timestamp' }, + analysis_limits: { model_memory_limit: '20mb' }, + model_plot_config: { enabled: true }, + }; + + // @ts-expect-error not full interface + const DATAFEED_CONFIG: Datafeed = { + datafeed_id: 'datafeed-fq_multi_1_ae', + indices: ['ft_farequote'], + job_id: 'fq_multi_1_ae', + query: { bool: { must: [{ match_all: {} }] } }, + }; + + async function createMockJobs() { + await ml.api.createAndRunAnomalyDetectionLookbackJob(JOB_CONFIG, DATAFEED_CONFIG); + await ml.api.indexAnnotation({ + timestamp: 1454950800000, + end_timestamp: 1454950860000, + annotation: 'Test annotation', + job_id: JOB_CONFIG.job_id, + type: ANNOTATION_TYPE.ANNOTATION, + event: 'user', + detector_index: 1, + partition_field_name: 'airline', + partition_field_value: 'AAL', + }); + } + + const requestBody = { + jobId: JOB_CONFIG.job_id, + start: 1454889600000, // February 8, 2016 12:00:00 AM GMT + end: 1454976000000, // February 9, 2016 12:00:00 AM GMT + }; + + describe('GetDatafeedResultsChart', () => { + before(async () => { + await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); + await ml.testResources.setKibanaTimeZoneToUTC(); + await createMockJobs(); + }); + + after(async () => { + await ml.api.cleanMlIndices(); + }); + + it('it should fetch datafeed chart data', async () => { + const { body, status } = await supertest + .post(`/api/ml/results/datafeed_results_chart`) + .auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) + .set(COMMON_REQUEST_HEADERS) + .send(requestBody); + ml.api.assertResponseStatusCode(200, status, body); + + expect(body.bucketResults.length).to.eql(24); + expect(body.datafeedResults.length).to.eql(24); + expect(body.annotationResultsRect.length).to.eql(1); + expect(body.annotationResultsLine.length).to.eql(0); + }); + + it('should validate request body', async () => { + const incompleteRequestBody = { + // MISSING JOB ID + start: 1454889600000, // February 8, 2016 12:00:00 AM GMT + end: 1454976000000, // February 9, 2016 12:00:00 AM GMT + }; + + const { body, status } = await supertest + .post(`/api/ml/results/datafeed_results_chart`) + .auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) + .set(COMMON_REQUEST_HEADERS) + .send(incompleteRequestBody); + ml.api.assertResponseStatusCode(400, status, body); + + expect(body.error).to.eql('Bad Request'); + expect(body.message).to.eql( + '[request body.jobId]: expected value of type [string] but got [undefined]' + ); + }); + + it('it should not allow fetching of datafeed chart data without required permissions', async () => { + const { body, status } = await supertest + .post(`/api/ml/results/datafeed_results_chart`) + .auth(USER.ML_UNAUTHORIZED, ml.securityCommon.getPasswordForUser(USER.ML_UNAUTHORIZED)) + .set(COMMON_REQUEST_HEADERS) + .send(requestBody); + ml.api.assertResponseStatusCode(403, status, body); + + expect(body.error).to.eql('Forbidden'); + expect(body.message).to.eql('Forbidden'); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/results/index.ts b/x-pack/test/api_integration/apis/ml/results/index.ts index e9accf88eadab..81687e155eb5c 100644 --- a/x-pack/test/api_integration/apis/ml/results/index.ts +++ b/x-pack/test/api_integration/apis/ml/results/index.ts @@ -17,5 +17,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./max_anomaly_score')); loadTestFile(require.resolve('./get_partition_fields_values')); loadTestFile(require.resolve('./get_anomaly_search')); + loadTestFile(require.resolve('./get_datafeed_results_chart')); }); }