1import React, { ComponentProps } from 'react';
2import { render, screen } from '@testing-library/react';
3import { LoadingState, MutableDataFrame, FieldType, LogsSortOrder } from '@grafana/data';
4import { LogsPanel } from './LogsPanel';
5
6type LogsPanelProps = ComponentProps<typeof LogsPanel>;
7
8describe('LogsPanel', () => {
9  describe('when returned series include common labels', () => {
10    const seriesWithCommonLabels = [
11      new MutableDataFrame({
12        fields: [
13          {
14            name: 'time',
15            type: FieldType.time,
16            values: ['2019-04-26T09:28:11.352440161Z', '2019-04-26T14:42:50.991981292Z'],
17          },
18          {
19            name: 'message',
20            type: FieldType.string,
21            values: [
22              't=2019-04-26T11:05:28+0200 lvl=info msg="Initializing DatasourceCacheService" logger=server',
23              't=2019-04-26T16:42:50+0200 lvl=eror msg="new token…t unhashed token=56d9fdc5c8b7400bd51b060eea8ca9d7',
24            ],
25            labels: {
26              app: 'common_app',
27              job: 'common_job',
28            },
29          },
30        ],
31      }),
32    ];
33
34    it('shows common labels when showCommonLabels is set to true', () => {
35      setup({ data: { series: seriesWithCommonLabels }, options: { showCommonLabels: true } });
36
37      expect(screen.getByText(/common labels:/i)).toBeInTheDocument();
38      expect(screen.getByText(/common_app/i)).toBeInTheDocument();
39      expect(screen.getByText(/common_job/i)).toBeInTheDocument();
40    });
41    it('shows common labels on top when descending sort order', () => {
42      const { container } = setup({
43        data: { series: seriesWithCommonLabels },
44        options: { showCommonLabels: true, sortOrder: LogsSortOrder.Descending },
45      });
46
47      expect(container.firstChild?.childNodes[0].textContent).toMatch(/^Common labels:common_appcommon_job/);
48    });
49    it('shows common labels on bottom when ascending sort order', () => {
50      const { container } = setup({
51        data: { series: seriesWithCommonLabels },
52        options: { showCommonLabels: true, sortOrder: LogsSortOrder.Ascending },
53      });
54
55      expect(container.firstChild?.childNodes[0].textContent).toMatch(/Common labels:common_appcommon_job$/);
56    });
57    it('does not show common labels when showCommonLabels is set to false', () => {
58      setup({ data: { series: seriesWithCommonLabels }, options: { showCommonLabels: false } });
59
60      expect(screen.queryByText(/common labels:/i)).not.toBeInTheDocument();
61      expect(screen.queryByText(/common_app/i)).not.toBeInTheDocument();
62      expect(screen.queryByText(/common_job/i)).not.toBeInTheDocument();
63    });
64  });
65  describe('when returned series does not include common labels', () => {
66    const seriesWithoutCommonLabels = [
67      new MutableDataFrame({
68        fields: [
69          {
70            name: 'time',
71            type: FieldType.time,
72            values: ['2019-04-26T09:28:11.352440161Z', '2019-04-26T14:42:50.991981292Z'],
73          },
74          {
75            name: 'message',
76            type: FieldType.string,
77            values: [
78              't=2019-04-26T11:05:28+0200 lvl=info msg="Initializing DatasourceCacheService" logger=server',
79              't=2019-04-26T16:42:50+0200 lvl=eror msg="new token…t unhashed token=56d9fdc5c8b7400bd51b060eea8ca9d7',
80            ],
81          },
82        ],
83      }),
84    ];
85    it('shows (no common labels) when showCommonLabels is set to true', () => {
86      setup({ data: { series: seriesWithoutCommonLabels }, options: { showCommonLabels: true } });
87      expect(screen.getByText(/common labels:/i)).toBeInTheDocument();
88      expect(screen.getByText(/(no common labels)/i)).toBeInTheDocument();
89    });
90    it('does not show common labels when showCommonLabels is set to false', () => {
91      setup({ data: { series: seriesWithoutCommonLabels }, options: { showCommonLabels: false } });
92      expect(screen.queryByText(/common labels:/i)).not.toBeInTheDocument();
93      expect(screen.queryByText(/(no common labels)/i)).not.toBeInTheDocument();
94    });
95  });
96});
97
98const setup = (propsOverrides?: {}) => {
99  const props = ({
100    data: {
101      error: undefined,
102      request: {
103        panelId: 4,
104        dashboardId: 123,
105        app: 'dashboard',
106        requestId: 'A',
107        timezone: 'browser',
108        interval: '30s',
109        intervalMs: 30000,
110        maxDataPoints: 823,
111        targets: [],
112        range: {},
113      },
114      series: [],
115      state: LoadingState.Done,
116    },
117    timeZone: 'utc',
118    options: {},
119    title: 'Logs panel',
120    id: 1,
121    ...propsOverrides,
122  } as unknown) as LogsPanelProps;
123
124  return render(<LogsPanel {...props} />);
125};
126