[APM] Correctly format url when linking to other apps (#67446)
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
84ed5096f3
commit
d9ac0489a3
3 changed files with 130 additions and 17 deletions
|
@ -105,10 +105,11 @@ export const TransactionActionMenu: FunctionComponent<Props> = ({
|
|||
|
||||
if (app === 'uptime' || app === 'metrics' || app === 'logs') {
|
||||
event.preventDefault();
|
||||
const search = parsed.search || '';
|
||||
|
||||
const path = `${rest.join('/')}${search}`;
|
||||
core.application.navigateToApp(app, {
|
||||
path: `${rest.join('/')}${
|
||||
parsed.search ? `&${parsed.search}` : ''
|
||||
}`,
|
||||
path,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { render, fireEvent, act } from '@testing-library/react';
|
||||
import { merge, tail } from 'lodash';
|
||||
import { TransactionActionMenu } from '../TransactionActionMenu';
|
||||
import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
|
||||
import * as Transactions from './mockData';
|
||||
|
@ -16,13 +17,43 @@ import {
|
|||
import * as hooks from '../../../../hooks/useFetcher';
|
||||
import { LicenseContext } from '../../../../context/LicenseContext';
|
||||
import { License } from '../../../../../../licensing/common/license';
|
||||
import { MockApmPluginContextWrapper } from '../../../../context/ApmPluginContext/MockApmPluginContext';
|
||||
import {
|
||||
MockApmPluginContextWrapper,
|
||||
mockApmPluginContextValue,
|
||||
} from '../../../../context/ApmPluginContext/MockApmPluginContext';
|
||||
import * as apmApi from '../../../../services/rest/createCallApmApi';
|
||||
import { ApmPluginContextValue } from '../../../../context/ApmPluginContext';
|
||||
|
||||
const renderTransaction = async (transaction: Record<string, any>) => {
|
||||
const getMock = () => {
|
||||
return (merge({}, mockApmPluginContextValue, {
|
||||
core: {
|
||||
application: {
|
||||
navigateToApp: jest.fn(),
|
||||
},
|
||||
http: {
|
||||
basePath: {
|
||||
remove: jest.fn((path: string) => {
|
||||
return tail(path.split('/')).join('/');
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
}) as unknown) as ApmPluginContextValue;
|
||||
};
|
||||
|
||||
const renderTransaction = async (
|
||||
transaction: Record<string, any>,
|
||||
mock: ApmPluginContextValue = getMock()
|
||||
) => {
|
||||
const rendered = render(
|
||||
<TransactionActionMenu transaction={transaction as Transaction} />,
|
||||
{ wrapper: MockApmPluginContextWrapper }
|
||||
{
|
||||
wrapper: ({ children }: { children?: React.ReactNode }) => (
|
||||
<MockApmPluginContextWrapper value={mock}>
|
||||
{children}
|
||||
</MockApmPluginContextWrapper>
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
fireEvent.click(rendered.getByText('Actions'));
|
||||
|
@ -49,11 +80,21 @@ describe('TransactionActionMenu component', () => {
|
|||
});
|
||||
|
||||
it('should always render the trace logs link', async () => {
|
||||
const { queryByText } = await renderTransaction(
|
||||
Transactions.transactionWithMinimalData
|
||||
const mock = getMock();
|
||||
|
||||
const { queryByText, getByText } = await renderTransaction(
|
||||
Transactions.transactionWithMinimalData,
|
||||
mock
|
||||
);
|
||||
|
||||
expect(queryByText('Trace logs')).not.toBeNull();
|
||||
|
||||
fireEvent.click(getByText('Trace logs'));
|
||||
|
||||
expect(mock.core.application.navigateToApp).toHaveBeenCalledWith('logs', {
|
||||
path:
|
||||
'link-to/logs?time=1545092070952&filter=trace.id:%228b60bd32ecc6e1506735a8b6cfcf175c%22%20OR%208b60bd32ecc6e1506735a8b6cfcf175c',
|
||||
});
|
||||
});
|
||||
|
||||
it('should not render the pod links when there is no pod id', async () => {
|
||||
|
@ -66,12 +107,33 @@ describe('TransactionActionMenu component', () => {
|
|||
});
|
||||
|
||||
it('should render the pod links when there is a pod id', async () => {
|
||||
const { queryByText } = await renderTransaction(
|
||||
Transactions.transactionWithKubernetesData
|
||||
const mock = getMock();
|
||||
|
||||
const { queryByText, getByText } = await renderTransaction(
|
||||
Transactions.transactionWithKubernetesData,
|
||||
mock
|
||||
);
|
||||
|
||||
expect(queryByText('Pod logs')).not.toBeNull();
|
||||
expect(queryByText('Pod metrics')).not.toBeNull();
|
||||
|
||||
fireEvent.click(getByText('Pod logs'));
|
||||
|
||||
expect(mock.core.application.navigateToApp).toHaveBeenCalledWith('logs', {
|
||||
path: 'link-to/pod-logs/pod123456abcdef?time=1545092070952',
|
||||
});
|
||||
|
||||
(mock.core.application.navigateToApp as jest.Mock).mockClear();
|
||||
|
||||
fireEvent.click(getByText('Pod metrics'));
|
||||
|
||||
expect(mock.core.application.navigateToApp).toHaveBeenCalledWith(
|
||||
'metrics',
|
||||
{
|
||||
path:
|
||||
'link-to/pod-detail/pod123456abcdef?from=1545091770952&to=1545092370952',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render the container links when there is no container id', async () => {
|
||||
|
@ -84,12 +146,33 @@ describe('TransactionActionMenu component', () => {
|
|||
});
|
||||
|
||||
it('should render the container links when there is a container id', async () => {
|
||||
const { queryByText } = await renderTransaction(
|
||||
Transactions.transactionWithContainerData
|
||||
const mock = getMock();
|
||||
|
||||
const { queryByText, getByText } = await renderTransaction(
|
||||
Transactions.transactionWithContainerData,
|
||||
mock
|
||||
);
|
||||
|
||||
expect(queryByText('Container logs')).not.toBeNull();
|
||||
expect(queryByText('Container metrics')).not.toBeNull();
|
||||
|
||||
fireEvent.click(getByText('Container logs'));
|
||||
|
||||
expect(mock.core.application.navigateToApp).toHaveBeenCalledWith('logs', {
|
||||
path: 'link-to/container-logs/container123456abcdef?time=1545092070952',
|
||||
});
|
||||
|
||||
(mock.core.application.navigateToApp as jest.Mock).mockClear();
|
||||
|
||||
fireEvent.click(getByText('Container metrics'));
|
||||
|
||||
expect(mock.core.application.navigateToApp).toHaveBeenCalledWith(
|
||||
'metrics',
|
||||
{
|
||||
path:
|
||||
'link-to/container-detail/container123456abcdef?from=1545091770952&to=1545092370952',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render the host links when there is no hostname', async () => {
|
||||
|
@ -102,12 +185,32 @@ describe('TransactionActionMenu component', () => {
|
|||
});
|
||||
|
||||
it('should render the host links when there is a hostname', async () => {
|
||||
const { queryByText } = await renderTransaction(
|
||||
Transactions.transactionWithHostData
|
||||
const mock = getMock();
|
||||
const { queryByText, getByText } = await renderTransaction(
|
||||
Transactions.transactionWithHostData,
|
||||
mock
|
||||
);
|
||||
|
||||
expect(queryByText('Host logs')).not.toBeNull();
|
||||
expect(queryByText('Host metrics')).not.toBeNull();
|
||||
|
||||
fireEvent.click(getByText('Host logs'));
|
||||
|
||||
expect(mock.core.application.navigateToApp).toHaveBeenCalledWith('logs', {
|
||||
path: 'link-to/host-logs/227453131a17?time=1545092070952',
|
||||
});
|
||||
|
||||
(mock.core.application.navigateToApp as jest.Mock).mockClear();
|
||||
|
||||
fireEvent.click(getByText('Host metrics'));
|
||||
|
||||
expect(mock.core.application.navigateToApp).toHaveBeenCalledWith(
|
||||
'metrics',
|
||||
{
|
||||
path:
|
||||
'link-to/host-detail/227453131a17?from=1545091770952&to=1545092370952',
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('should not render the uptime link if there is no url available', async () => {
|
||||
|
@ -127,11 +230,20 @@ describe('TransactionActionMenu component', () => {
|
|||
});
|
||||
|
||||
it('should render the uptime link if there is a url with a domain', async () => {
|
||||
const { queryByText } = await renderTransaction(
|
||||
Transactions.transactionWithUrlAndDomain
|
||||
const mock = getMock();
|
||||
|
||||
const { queryByText, getByText } = await renderTransaction(
|
||||
Transactions.transactionWithUrlAndDomain,
|
||||
mock
|
||||
);
|
||||
|
||||
expect(queryByText('Status')).not.toBeNull();
|
||||
|
||||
fireEvent.click(getByText('Status'));
|
||||
|
||||
expect(mock.core.application.navigateToApp).toHaveBeenCalledWith('uptime', {
|
||||
path: '?search=url.domain:%22example.com%22',
|
||||
});
|
||||
});
|
||||
|
||||
it('should match the snapshot', async () => {
|
||||
|
|
|
@ -62,7 +62,7 @@ export const getSections = ({
|
|||
|
||||
const uptimeLink = url.format({
|
||||
pathname: basePath.prepend('/app/uptime'),
|
||||
hash: `/?${fromQuery(
|
||||
search: `?${fromQuery(
|
||||
pick(
|
||||
{
|
||||
dateRangeStart: urlParams.rangeFrom,
|
||||
|
|
Loading…
Reference in a new issue