|
|
|
@ -1,11 +1,42 @@ |
|
|
|
|
import { render, screen } from '@testing-library/react'; |
|
|
|
|
import { render, screen, waitFor } from '@testing-library/react'; |
|
|
|
|
import userEvent from '@testing-library/user-event'; |
|
|
|
|
import React, { ComponentProps } from 'react'; |
|
|
|
|
import { DatasourceSrvMock, MockDataSourceApi } from 'test/mocks/datasource_srv'; |
|
|
|
|
|
|
|
|
|
import { LoadingState, createDataFrame, FieldType, LogsSortOrder } from '@grafana/data'; |
|
|
|
|
import { LoadingState, createDataFrame, FieldType, LogsSortOrder, CoreApp } from '@grafana/data'; |
|
|
|
|
import { LogRowContextModal } from 'app/features/logs/components/log-context/LogRowContextModal'; |
|
|
|
|
|
|
|
|
|
import { LogsPanel } from './LogsPanel'; |
|
|
|
|
|
|
|
|
|
type LogsPanelProps = ComponentProps<typeof LogsPanel>; |
|
|
|
|
type LogRowContextModalProps = ComponentProps<typeof LogRowContextModal>; |
|
|
|
|
|
|
|
|
|
const logRowContextModalMock = jest.fn().mockReturnValue(<div>LogRowContextModal</div>); |
|
|
|
|
jest.mock('app/features/logs/components/log-context/LogRowContextModal', () => ({ |
|
|
|
|
LogRowContextModal: (props: LogRowContextModalProps) => logRowContextModalMock(props), |
|
|
|
|
})); |
|
|
|
|
|
|
|
|
|
const defaultDs = new MockDataSourceApi('default datasource', { data: ['default data'] }); |
|
|
|
|
const noShowContextDs = new MockDataSourceApi('no-show-context'); |
|
|
|
|
const showContextDs = new MockDataSourceApi('show-context') as MockDataSourceApi & { getLogRowContext: jest.Mock }; |
|
|
|
|
|
|
|
|
|
const datasourceSrv = new DatasourceSrvMock(defaultDs, { |
|
|
|
|
'no-show-context': noShowContextDs, |
|
|
|
|
'show-context': showContextDs, |
|
|
|
|
}); |
|
|
|
|
const getDataSourceSrvMock = jest.fn().mockReturnValue(datasourceSrv); |
|
|
|
|
jest.mock('@grafana/runtime', () => ({ |
|
|
|
|
...jest.requireActual('@grafana/runtime'), |
|
|
|
|
getDataSourceSrv: () => getDataSourceSrvMock(), |
|
|
|
|
})); |
|
|
|
|
|
|
|
|
|
const hasLogsContextSupport = jest.fn().mockImplementation((ds) => { |
|
|
|
|
return ds.name === 'show-context'; |
|
|
|
|
}); |
|
|
|
|
jest.mock('@grafana/data', () => ({ |
|
|
|
|
...jest.requireActual('@grafana/data'), |
|
|
|
|
hasLogsContextSupport: (ds: MockDataSourceApi) => hasLogsContextSupport(ds), |
|
|
|
|
})); |
|
|
|
|
|
|
|
|
|
describe('LogsPanel', () => { |
|
|
|
|
describe('when returned series include common labels', () => { |
|
|
|
@ -33,35 +64,37 @@ describe('LogsPanel', () => { |
|
|
|
|
}), |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
it('shows common labels when showCommonLabels is set to true', () => { |
|
|
|
|
it('shows common labels when showCommonLabels is set to true', async () => { |
|
|
|
|
setup({ data: { series: seriesWithCommonLabels }, options: { showCommonLabels: true } }); |
|
|
|
|
|
|
|
|
|
expect(screen.getByText(/common labels:/i)).toBeInTheDocument(); |
|
|
|
|
expect(screen.getByText(/common_app/i)).toBeInTheDocument(); |
|
|
|
|
expect(screen.getByText(/common_job/i)).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByText(/common labels:/i)).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByText(/common_app/i)).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByText(/common_job/i)).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
it('shows common labels on top when descending sort order', () => { |
|
|
|
|
it('shows common labels on top when descending sort order', async () => { |
|
|
|
|
const { container } = setup({ |
|
|
|
|
data: { series: seriesWithCommonLabels }, |
|
|
|
|
options: { showCommonLabels: true, sortOrder: LogsSortOrder.Descending }, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
expect(await screen.findByText(/common labels:/i)).toBeInTheDocument(); |
|
|
|
|
expect(container.firstChild?.childNodes[0].textContent).toMatch(/^Common labels:common_appcommon_job/); |
|
|
|
|
}); |
|
|
|
|
it('shows common labels on bottom when ascending sort order', () => { |
|
|
|
|
it('shows common labels on bottom when ascending sort order', async () => { |
|
|
|
|
const { container } = setup({ |
|
|
|
|
data: { series: seriesWithCommonLabels }, |
|
|
|
|
options: { showCommonLabels: true, sortOrder: LogsSortOrder.Ascending }, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
expect(await screen.findByText(/common labels:/i)).toBeInTheDocument(); |
|
|
|
|
expect(container.firstChild?.childNodes[0].textContent).toMatch(/Common labels:common_appcommon_job$/); |
|
|
|
|
}); |
|
|
|
|
it('does not show common labels when showCommonLabels is set to false', () => { |
|
|
|
|
it('does not show common labels when showCommonLabels is set to false', async () => { |
|
|
|
|
setup({ data: { series: seriesWithCommonLabels }, options: { showCommonLabels: false } }); |
|
|
|
|
|
|
|
|
|
expect(screen.queryByText(/common labels:/i)).not.toBeInTheDocument(); |
|
|
|
|
expect(screen.queryByText(/common_app/i)).not.toBeInTheDocument(); |
|
|
|
|
expect(screen.queryByText(/common_job/i)).not.toBeInTheDocument(); |
|
|
|
|
await waitFor(async () => { |
|
|
|
|
expect(screen.queryByText(/common labels:/i)).toBeNull(); |
|
|
|
|
expect(screen.queryByText(/common_app/i)).toBeNull(); |
|
|
|
|
expect(screen.queryByText(/common_job/i)).toBeNull(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
describe('when returned series does not include common labels', () => { |
|
|
|
@ -84,15 +117,139 @@ describe('LogsPanel', () => { |
|
|
|
|
], |
|
|
|
|
}), |
|
|
|
|
]; |
|
|
|
|
it('shows (no common labels) when showCommonLabels is set to true', () => { |
|
|
|
|
it('shows (no common labels) when showCommonLabels is set to true', async () => { |
|
|
|
|
setup({ data: { series: seriesWithoutCommonLabels }, options: { showCommonLabels: true } }); |
|
|
|
|
expect(screen.getByText(/common labels:/i)).toBeInTheDocument(); |
|
|
|
|
expect(screen.getByText(/(no common labels)/i)).toBeInTheDocument(); |
|
|
|
|
|
|
|
|
|
expect(await screen.findByText(/common labels:/i)).toBeInTheDocument(); |
|
|
|
|
expect(await screen.findByText(/(no common labels)/i)).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
it('does not show common labels when showCommonLabels is set to false', () => { |
|
|
|
|
it('does not show common labels when showCommonLabels is set to false', async () => { |
|
|
|
|
setup({ data: { series: seriesWithoutCommonLabels }, options: { showCommonLabels: false } }); |
|
|
|
|
expect(screen.queryByText(/common labels:/i)).not.toBeInTheDocument(); |
|
|
|
|
expect(screen.queryByText(/(no common labels)/i)).not.toBeInTheDocument(); |
|
|
|
|
await waitFor(async () => { |
|
|
|
|
expect(screen.queryByText(/common labels:/i)).toBeNull(); |
|
|
|
|
expect(screen.queryByText(/(no common labels)/i)).toBeNull(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
describe('log context', () => { |
|
|
|
|
const series = [ |
|
|
|
|
createDataFrame({ |
|
|
|
|
refId: 'A', |
|
|
|
|
fields: [ |
|
|
|
|
{ |
|
|
|
|
name: 'time', |
|
|
|
|
type: FieldType.time, |
|
|
|
|
values: ['2019-04-26T09:28:11.352440161Z', '2019-04-26T14:42:50.991981292Z'], |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
name: 'message', |
|
|
|
|
type: FieldType.string, |
|
|
|
|
values: ['logline text'], |
|
|
|
|
labels: { |
|
|
|
|
app: 'common_app', |
|
|
|
|
job: 'common_job', |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
}), |
|
|
|
|
]; |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
showContextDs.getLogRowContext = jest.fn().mockImplementation(() => {}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should not show the toggle if the datasource does not support show context', async () => { |
|
|
|
|
setup({ |
|
|
|
|
data: { |
|
|
|
|
series, |
|
|
|
|
options: { showCommonLabels: false }, |
|
|
|
|
request: { |
|
|
|
|
app: CoreApp.Dashboard, |
|
|
|
|
targets: [{ refId: 'A', datasource: { uid: 'no-show-context' } }], |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
await waitFor(async () => { |
|
|
|
|
await userEvent.hover(screen.getByText(/logline text/i)); |
|
|
|
|
expect(screen.queryByLabelText(/show context/i)).toBeNull(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should show the toggle if the datasource does support show context', async () => { |
|
|
|
|
setup({ |
|
|
|
|
data: { |
|
|
|
|
series, |
|
|
|
|
options: { showCommonLabels: false }, |
|
|
|
|
request: { |
|
|
|
|
app: CoreApp.Dashboard, |
|
|
|
|
targets: [{ refId: 'A', datasource: { uid: 'show-context' } }], |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
await waitFor(async () => { |
|
|
|
|
await userEvent.hover(screen.getByText(/logline text/i)); |
|
|
|
|
expect(screen.getByLabelText(/show context/i)).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should not show the toggle if the datasource does support show context but the app is not Dashboard', async () => { |
|
|
|
|
setup({ |
|
|
|
|
data: { |
|
|
|
|
series, |
|
|
|
|
options: { showCommonLabels: false }, |
|
|
|
|
request: { |
|
|
|
|
app: CoreApp.CloudAlerting, |
|
|
|
|
targets: [{ refId: 'A', datasource: { uid: 'show-context' } }], |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
await waitFor(async () => { |
|
|
|
|
await userEvent.hover(screen.getByText(/logline text/i)); |
|
|
|
|
expect(screen.queryByLabelText(/show context/i)).toBeNull(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should render the mocked `LogRowContextModal` after click', async () => { |
|
|
|
|
setup({ |
|
|
|
|
data: { |
|
|
|
|
series, |
|
|
|
|
options: { showCommonLabels: false }, |
|
|
|
|
request: { |
|
|
|
|
app: CoreApp.Dashboard, |
|
|
|
|
targets: [{ refId: 'A', datasource: { uid: 'show-context' } }], |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
await waitFor(async () => { |
|
|
|
|
await userEvent.hover(screen.getByText(/logline text/i)); |
|
|
|
|
await userEvent.click(screen.getByLabelText(/show context/i)); |
|
|
|
|
expect(screen.getByText(/LogRowContextModal/i)).toBeInTheDocument(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
it('should call `getLogRowContext` if the user clicks the show context toggle', async () => { |
|
|
|
|
setup({ |
|
|
|
|
data: { |
|
|
|
|
series, |
|
|
|
|
options: { showCommonLabels: false }, |
|
|
|
|
request: { |
|
|
|
|
app: CoreApp.Dashboard, |
|
|
|
|
targets: [{ refId: 'A', datasource: { uid: 'show-context' } }], |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}); |
|
|
|
|
await waitFor(async () => { |
|
|
|
|
await userEvent.hover(screen.getByText(/logline text/i)); |
|
|
|
|
await userEvent.click(screen.getByLabelText(/show context/i)); |
|
|
|
|
|
|
|
|
|
const getRowContextCb = logRowContextModalMock.mock.calls[0][0].getRowContext; |
|
|
|
|
getRowContextCb(); |
|
|
|
|
expect(showContextDs.getLogRowContext).toBeCalled(); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|