grafana/public/app/features/explore/Logs/LogsTableWrap.test.tsx
Galen Kistler faa29db241
Logs Panel: Table UI - Pull logs table into dashboard panel (#77757)
* Allows users to add a logs table in explore to a dashboard panel via the includeByName transformation
2023-11-29 10:01:28 -06:00

195 lines
5.7 KiB
TypeScript

import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import React, { ComponentProps } from 'react';
import { act } from 'react-test-renderer';
import {
createTheme,
ExploreLogsPanelState,
LogsSortOrder,
standardTransformersRegistry,
toUtc,
} from '@grafana/data/src';
import { organizeFieldsTransformer } from '@grafana/data/src/transformations/transformers/organize';
import { config } from '@grafana/runtime';
import { extractFieldsTransformer } from '../../transformers/extractFields/extractFields';
import { LogsTableWrap } from './LogsTableWrap';
import { getMockLokiFrame, getMockLokiFrameDataPlane } from './utils/testMocks.test';
const getComponent = (partialProps?: Partial<ComponentProps<typeof LogsTableWrap>>) => {
return (
<LogsTableWrap
range={{
from: toUtc('2019-01-01 10:00:00'),
to: toUtc('2019-01-01 16:00:00'),
raw: { from: 'now-1h', to: 'now' },
}}
onClickFilterOutLabel={() => undefined}
onClickFilterLabel={() => undefined}
updatePanelState={() => undefined}
panelState={undefined}
logsSortOrder={LogsSortOrder.Descending}
splitOpen={() => undefined}
timeZone={'utc'}
width={50}
logsFrames={[getMockLokiFrame()]}
theme={createTheme()}
{...partialProps}
/>
);
};
const setup = (partialProps?: Partial<ComponentProps<typeof LogsTableWrap>>) => {
return render(getComponent(partialProps));
};
describe('LogsTableWrap', () => {
beforeAll(() => {
const transformers = [extractFieldsTransformer, organizeFieldsTransformer];
standardTransformersRegistry.setInit(() => {
return transformers.map((t) => {
return {
id: t.id,
aliasIds: t.aliasIds,
name: t.name,
transformation: t,
description: t.description,
editor: () => null,
};
});
});
});
it('should render 4 table rows', async () => {
setup();
await waitFor(() => {
const rows = screen.getAllByRole('row');
// tableFrame has 3 rows + 1 header row
expect(rows.length).toBe(4);
});
});
it('should render 4 table rows (dataplane)', async () => {
config.featureToggles.lokiLogsDataplane = true;
setup({ logsFrames: [getMockLokiFrameDataPlane()] });
await waitFor(() => {
const rows = screen.getAllByRole('row');
// tableFrame has 3 rows + 1 header row
expect(rows.length).toBe(4);
});
});
it('updatePanelState should be called when a column is selected', async () => {
const updatePanelState = jest.fn() as (panelState: Partial<ExploreLogsPanelState>) => void;
setup({
panelState: {
visualisationType: 'table',
columns: undefined,
},
updatePanelState: updatePanelState,
});
expect.assertions(3);
expect(screen.getByLabelText('app')).toBeInTheDocument();
// Add a new column
act(() => {
screen.getByLabelText('app').click();
});
await waitFor(() => {
expect(updatePanelState).toBeCalledWith({
visualisationType: 'table',
columns: { 0: 'app', 1: 'Line', 2: 'Time' },
labelFieldName: 'labels',
});
});
// Remove the same column
act(() => {
screen.getByLabelText('app').click();
});
await waitFor(() => {
expect(updatePanelState).toBeCalledWith({
visualisationType: 'table',
columns: { 0: 'Line', 1: 'Time' },
labelFieldName: 'labels',
});
});
});
it('search input should search matching columns', async () => {
config.featureToggles.lokiLogsDataplane = false;
const updatePanelState = jest.fn() as (panelState: Partial<ExploreLogsPanelState>) => void;
setup({
panelState: {
visualisationType: 'table',
columns: undefined,
},
updatePanelState: updatePanelState,
});
await waitFor(() => {
expect(screen.getByLabelText('app')).toBeInTheDocument();
expect(screen.getByLabelText('cluster')).toBeInTheDocument();
});
const searchInput = screen.getByPlaceholderText('Search fields by name');
fireEvent.change(searchInput, { target: { value: 'app' } });
expect(screen.getByLabelText('app')).toBeInTheDocument();
await waitFor(() => {
expect(screen.queryByLabelText('cluster')).not.toBeInTheDocument();
});
});
it('should update selected dataframe when dataFrames update', async () => {
const initialProps = { logsFrames: [getMockLokiFrameDataPlane(undefined, 3)] };
const render = setup(initialProps);
await waitFor(() => {
const rows = render.getAllByRole('row');
expect(rows.length).toBe(4);
});
render.rerender(
getComponent({
...initialProps,
logsFrames: [getMockLokiFrameDataPlane(undefined, 4)],
})
);
await waitFor(() => {
const rows = render.getAllByRole('row');
expect(rows.length).toBe(5);
});
});
it('search input should search matching columns (dataplane)', async () => {
config.featureToggles.lokiLogsDataplane = true;
const updatePanelState = jest.fn() as (panelState: Partial<ExploreLogsPanelState>) => void;
setup({
panelState: {},
updatePanelState: updatePanelState,
logsFrames: [getMockLokiFrameDataPlane()],
});
await waitFor(() => {
expect(screen.getByLabelText('app')).toBeInTheDocument();
expect(screen.getByLabelText('cluster')).toBeInTheDocument();
});
const searchInput = screen.getByPlaceholderText('Search fields by name');
fireEvent.change(searchInput, { target: { value: 'app' } });
expect(screen.getByLabelText('app')).toBeInTheDocument();
await waitFor(() => {
expect(screen.queryByLabelText('cluster')).not.toBeInTheDocument();
});
});
});