Skip to content

Commit

Permalink
[APM] Fix broken links (elastic#22592)
Browse files Browse the repository at this point in the history
* [APM] Fix broken links

* Add missing basepaths

* Remove basepath from getMlJobUrl
  • Loading branch information
sorenlouv committed Sep 8, 2018
1 parent 80a4b6c commit 9452877
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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(<DetailView />);
});

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);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`WatcherButton should render initial state 1`] = `
<EuiPopover
anchorPosition="downRight"
button={
<EuiButton
color="primary"
fill={false}
iconSide="right"
iconType="arrowDown"
onClick={[Function]}
size="s"
type="button"
>
Integrations
</EuiButton>
}
closePopover={[Function]}
hasArrow={true}
isOpen={false}
ownFocus={false}
panelPaddingSize="none"
>
<EuiContextMenu
initialPanelId={0}
panels={
Array [
Object {
"id": 0,
"items": Array [
Object {
"icon": <EuiIcon
size="m"
type="plusInCircle"
/>,
"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",
},
]
}
/>
</EuiPopover>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,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{' '}
<a href="/app/ml">Machine Learning jobs management page</a>. It
might take some time for the job to calculate the results. Please
refresh the graph a few minutes after creating the job.
<KibanaLink pathname={'/app/ml'}>
Machine Learning jobs management page
</KibanaLink>
. It might take some time for the job to calculate the results.
Please refresh the graph a few minutes after creating the job.
</p>
<p>
{/* <a href="#">Learn more</a> about the Machine Learning integration. */}
Expand Down
Original file line number Diff line number Diff line change
@@ -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(<DetailView />);
});

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);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`MLButton should render initial state 1`] = `
<EuiPopover
anchorPosition="downRight"
button={
<EuiButton
color="primary"
fill={false}
iconSide="right"
iconType="arrowDown"
onClick={[Function]}
size="s"
type="button"
>
Integrations
</EuiButton>
}
closePopover={[Function]}
hasArrow={true}
isOpen={false}
ownFocus={false}
panelPaddingSize="none"
>
<EuiContextMenu
initialPanelId={0}
panels={
Array [
Object {
"id": 0,
"items": Array [
Object {
"icon": <EuiIcon
size="m"
type="stats"
/>,
"name": "Anomaly detection (BETA)",
"onClick": [Function],
},
Object {
"href": "myBasePath/app/ml",
"icon": "tableOfContents",
"name": "View existing jobs",
"onClick": [Function],
"target": "_blank",
},
],
"title": "Machine Learning",
},
]
}
/>
</EuiPopover>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -75,15 +75,15 @@ class TransactionOverview extends Component {
<EuiIconTip content="The stream around the average response time shows the expected bounds. An annotation is shown for anomaly scores &gt;= 75." />
<MLText>
Machine Learning:{' '}
<a
href={getMlJobUrl(
<KibanaLink
pathname={getMlJobUrl(
serviceName,
transactionType,
this.props.location
)}
>
View Job
</a>
</KibanaLink>
</MLText>
</MLTipContainer>
) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
exports[`KibanaLinkComponent should render correct markup 1`] = `
<a
className="euiLink euiLink--primary"
href="/app/kibana#/discover?_g=&_a=(interval:auto,query:(language:lucene,query:'context.service.name:myServiceName AND error.grouping_key:myGroupId'),sort:('@timestamp':desc))"
href="myBasePath/app/kibana#/discover?_g=&_a=(interval:auto,query:(language:lucene,query:'context.service.name:myServiceName AND error.grouping_key:myGroupId'),sort:('@timestamp':desc))"
>
Go to Discover
</a>
Expand Down
29 changes: 27 additions & 2 deletions x-pack/plugins/apm/public/utils/__test__/url.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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:'*')))`;
Expand Down Expand Up @@ -207,11 +212,31 @@ 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))"
);
});

it('should render correct markup', () => {
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'
);
});
});

0 comments on commit 9452877

Please sign in to comment.