From 5f02f3e4ea42044debbf87932d278e81814e0a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Thu, 6 Sep 2018 15:50:45 +0200 Subject: [PATCH] [APM] Fix broken links (#22592) * [APM] Fix broken links * Add missing basepaths * Remove basepath from getMlJobUrl --- .../Watcher/WatcherButton.js | 5 +- .../Watcher/__test__/WatcherButton.test.js | 41 ++++++++++++++ .../__snapshots__/WatcherButton.test.js.snap | 54 +++++++++++++++++++ .../DynamicBaseline/Button.js | 3 +- .../DynamicBaseline/Flyout.js | 8 +-- .../DynamicBaseline/__jest__/Button.test.js | 39 ++++++++++++++ .../__snapshots__/Button.test.js.snap | 54 +++++++++++++++++++ .../app/TransactionOverview/view.js | 8 +-- .../__test__/__snapshots__/url.test.js.snap | 2 +- .../apm/public/utils/__test__/url.test.js | 29 +++++++++- 10 files changed, 231 insertions(+), 12 deletions(-) create mode 100644 x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/__test__/WatcherButton.test.js create mode 100644 x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/__test__/__snapshots__/WatcherButton.test.js.snap create mode 100644 x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/__jest__/Button.test.js create mode 100644 x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/__jest__/__snapshots__/Button.test.js.snap diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/WatcherButton.js b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/WatcherButton.js index 4f682ed3a531..a3c034ca3bc0 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/WatcherButton.js +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/WatcherButton.js @@ -5,6 +5,7 @@ */ import React, { Component } from 'react'; +import chrome from 'ui/chrome'; import { EuiButton, EuiContextMenu, EuiIcon, EuiPopover } from '@elastic/eui'; export default class WatcherButton extends Component { @@ -31,7 +32,9 @@ export default class WatcherButton extends Component { { name: 'View existing watches', icon: 'tableOfContents', - href: '/app/kibana#/management/elasticsearch/watcher/', + href: chrome.addBasePath( + '/app/kibana#/management/elasticsearch/watcher/' + ), target: '_blank', onClick: () => this.closePopover() } diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/__test__/WatcherButton.test.js b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/__test__/WatcherButton.test.js new file mode 100644 index 000000000000..23590be5f0d3 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/__test__/WatcherButton.test.js @@ -0,0 +1,41 @@ +/* + * 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 React from 'react'; +import { shallow } from 'enzyme'; +import DetailView from '../WatcherButton'; + +jest.mock('ui/chrome', () => ({ + addBasePath: path => `myBasePath${path}` +})); + +describe('WatcherButton', () => { + let wrapper; + beforeEach(() => { + wrapper = shallow(); + }); + + it('should render initial state', () => { + expect(wrapper).toMatchSnapshot(); + }); + + it('should have correct url', () => { + const panels = wrapper.find('EuiContextMenu').prop('panels'); + expect(panels[0].items[1].href).toBe( + 'myBasePath/app/kibana#/management/elasticsearch/watcher/' + ); + }); + + it('popover should be closed', () => { + expect(wrapper.find('EuiPopover').prop('isOpen')).toBe(false); + }); + + it('should open popover', async () => { + await wrapper.instance().onButtonClick(); + wrapper.update(); + expect(wrapper.find('EuiPopover').prop('isOpen')).toBe(true); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/__test__/__snapshots__/WatcherButton.test.js.snap b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/__test__/__snapshots__/WatcherButton.test.js.snap new file mode 100644 index 000000000000..8918566a7cea --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupOverview/Watcher/__test__/__snapshots__/WatcherButton.test.js.snap @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`WatcherButton should render initial state 1`] = ` + + Integrations + + } + closePopover={[Function]} + hasArrow={true} + isOpen={false} + ownFocus={false} + panelPaddingSize="none" +> + , + "name": "Enable error reports", + "onClick": [Function], + }, + Object { + "href": "myBasePath/app/kibana#/management/elasticsearch/watcher/", + "icon": "tableOfContents", + "name": "View existing watches", + "onClick": [Function], + "target": "_blank", + }, + ], + "title": "Watcher", + }, + ] + } + /> + +`; diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/Button.js b/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/Button.js index bbba48082d3b..b7f8589dbd58 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/Button.js +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/Button.js @@ -5,6 +5,7 @@ */ import React, { Component } from 'react'; +import chrome from 'ui/chrome'; import { EuiButton, EuiPopover, EuiIcon, EuiContextMenu } from '@elastic/eui'; export default class DynamicBaselineButton extends Component { @@ -31,7 +32,7 @@ export default class DynamicBaselineButton extends Component { { name: 'View existing jobs', icon: 'tableOfContents', - href: '/app/ml', + href: chrome.addBasePath('/app/ml'), target: '_blank', onClick: () => this.closePopover() } diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/Flyout.js b/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/Flyout.js index a48db866b41d..1231e60e5bd8 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/Flyout.js +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/Flyout.js @@ -172,9 +172,11 @@ export default class DynamicBaselineFlyout extends Component { Jobs can be created per transaction type and based on the average response time. Once a job is created, you can manage it and see more details in the{' '} - Machine Learning jobs management page. It - might take some time for the job to calculate the results. Please - refresh the graph a few minutes after creating the job. + + Machine Learning jobs management page + + . It might take some time for the job to calculate the results. + Please refresh the graph a few minutes after creating the job.

{/* Learn more about the Machine Learning integration. */} diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/__jest__/Button.test.js b/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/__jest__/Button.test.js new file mode 100644 index 000000000000..c7396cf8c484 --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/__jest__/Button.test.js @@ -0,0 +1,39 @@ +/* + * 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 React from 'react'; +import { shallow } from 'enzyme'; +import DetailView from '../Button'; + +jest.mock('ui/chrome', () => ({ + addBasePath: path => `myBasePath${path}` +})); + +describe('MLButton', () => { + let wrapper; + beforeEach(() => { + wrapper = shallow(); + }); + + it('should render initial state', () => { + expect(wrapper).toMatchSnapshot(); + }); + + it('should have correct url', () => { + const panels = wrapper.find('EuiContextMenu').prop('panels'); + expect(panels[0].items[1].href).toBe('myBasePath/app/ml'); + }); + + it('popover should be closed', () => { + expect(wrapper.find('EuiPopover').prop('isOpen')).toBe(false); + }); + + it('should open popover', async () => { + await wrapper.instance().onButtonClick(); + wrapper.update(); + expect(wrapper.find('EuiPopover').prop('isOpen')).toBe(true); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/__jest__/__snapshots__/Button.test.js.snap b/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/__jest__/__snapshots__/Button.test.js.snap new file mode 100644 index 000000000000..6e57f557d1bd --- /dev/null +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/DynamicBaseline/__jest__/__snapshots__/Button.test.js.snap @@ -0,0 +1,54 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`MLButton should render initial state 1`] = ` + + Integrations + + } + closePopover={[Function]} + hasArrow={true} + isOpen={false} + ownFocus={false} + panelPaddingSize="none" +> + , + "name": "Anomaly detection (BETA)", + "onClick": [Function], + }, + Object { + "href": "myBasePath/app/ml", + "icon": "tableOfContents", + "name": "View existing jobs", + "onClick": [Function], + "target": "_blank", + }, + ], + "title": "Machine Learning", + }, + ] + } + /> + +`; diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/view.js b/x-pack/plugins/apm/public/components/app/TransactionOverview/view.js index ec1424223269..b250afe83796 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/view.js +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/view.js @@ -13,7 +13,7 @@ import { get } from 'lodash'; import { HeaderContainer, HeaderMedium } from '../../shared/UIComponents'; import TabNavigation from '../../shared/TabNavigation'; import Charts from '../../shared/charts/TransactionCharts'; -import { getMlJobUrl } from '../../../utils/url'; +import { getMlJobUrl, KibanaLink } from '../../../utils/url'; import List from './List'; import { units, px, fontSizes } from '../../../style/variables'; import { OverviewChartsRequest } from '../../../store/reactReduxRequest/overviewCharts'; @@ -75,15 +75,15 @@ class TransactionOverview extends Component { Machine Learning:{' '} - View Job - + ) : null; diff --git a/x-pack/plugins/apm/public/utils/__test__/__snapshots__/url.test.js.snap b/x-pack/plugins/apm/public/utils/__test__/__snapshots__/url.test.js.snap index 4e5e7a8c6404..2252f7f40ce6 100644 --- a/x-pack/plugins/apm/public/utils/__test__/__snapshots__/url.test.js.snap +++ b/x-pack/plugins/apm/public/utils/__test__/__snapshots__/url.test.js.snap @@ -3,7 +3,7 @@ exports[`KibanaLinkComponent should render correct markup 1`] = ` Go to Discover diff --git a/x-pack/plugins/apm/public/utils/__test__/url.test.js b/x-pack/plugins/apm/public/utils/__test__/url.test.js index 87ed6764a1fb..28a8a6bbd469 100644 --- a/x-pack/plugins/apm/public/utils/__test__/url.test.js +++ b/x-pack/plugins/apm/public/utils/__test__/url.test.js @@ -15,10 +15,15 @@ import { KibanaLinkComponent, RelativeLinkComponent, encodeKibanaSearchParams, - decodeKibanaSearchParams + decodeKibanaSearchParams, + getMlJobUrl } from '../url'; import { toJson } from '../testHelpers'; +jest.mock('ui/chrome', () => ({ + addBasePath: path => `myBasePath${path}` +})); + describe('encodeKibanaSearchParams and decodeKibanaSearchParams should return the original string', () => { it('should convert string to object', () => { const search = `?_g=(ml:(jobIds:!(opbeans-node-request-high_mean_response_time)),refreshInterval:(display:Off,pause:!f,value:0),time:(from:'2018-06-06T08:20:45.437Z',mode:absolute,to:'2018-06-14T21:56:58.505Z'))&_a=(filters:!(),mlSelectInterval:(interval:(display:Auto,val:auto)),mlSelectSeverity:(threshold:(display:warning,val:0)),mlTimeSeriesExplorer:(),query:(query_string:(analyze_wildcard:!t,query:'*')))`; @@ -207,7 +212,7 @@ describe('KibanaLinkComponent', () => { it('should have correct url', () => { expect(wrapper.find('a').prop('href')).toBe( - "/app/kibana#/discover?_g=&_a=(interval:auto,query:(language:lucene,query:'context.service.name:myServiceName AND error.grouping_key:myGroupId'),sort:('@timestamp':desc))" + "myBasePath/app/kibana#/discover?_g=&_a=(interval:auto,query:(language:lucene,query:'context.service.name:myServiceName AND error.grouping_key:myGroupId'),sort:('@timestamp':desc))" ); }); @@ -215,3 +220,23 @@ describe('KibanaLinkComponent', () => { expect(toJson(wrapper)).toMatchSnapshot(); }); }); + +describe('getMlJobUrl', () => { + it('should have correct url', () => { + const serviceName = 'myServiceName'; + const transactionType = 'myTransactionType'; + const location = { search: '' }; + expect(getMlJobUrl(serviceName, transactionType, location)).toBe( + '/app/ml#/timeseriesexplorer/?_g=(ml:(jobIds:!(myServiceName-myTransactionType-high_mean_response_time)))&_a=!n' + ); + }); + + it('should not contain basePath', () => { + const serviceName = 'myServiceName'; + const transactionType = 'myTransactionType'; + const location = { search: '' }; + expect(getMlJobUrl(serviceName, transactionType, location)).toBe( + '/app/ml#/timeseriesexplorer/?_g=(ml:(jobIds:!(myServiceName-myTransactionType-high_mean_response_time)))&_a=!n' + ); + }); +});