1import React from 'react';
2import { LogLevel, LogRowModel, MutableDataFrame } from '@grafana/data';
3import { mount } from 'enzyme';
4import { LiveLogsWithTheme } from './LiveLogs';
5
6describe('LiveLogs', () => {
7  it('renders logs', () => {
8    const rows: LogRowModel[] = [makeLog({ uid: '1' }), makeLog({ uid: '2' }), makeLog({ uid: '3' })];
9    const wrapper = mount(
10      <LiveLogsWithTheme
11        logRows={rows}
12        timeZone={'utc'}
13        stopLive={() => {}}
14        onPause={() => {}}
15        onResume={() => {}}
16        isPaused={true}
17      />
18    );
19
20    expect(wrapper.contains('log message 1')).toBeTruthy();
21    expect(wrapper.contains('log message 2')).toBeTruthy();
22    expect(wrapper.contains('log message 3')).toBeTruthy();
23  });
24
25  it('renders new logs only when not paused', () => {
26    const rows: LogRowModel[] = [makeLog({ uid: '1' }), makeLog({ uid: '2' }), makeLog({ uid: '3' })];
27    const wrapper = mount(
28      <LiveLogsWithTheme
29        logRows={rows}
30        timeZone={'utc'}
31        stopLive={() => {}}
32        onPause={() => {}}
33        onResume={() => {}}
34        isPaused={true}
35      />
36    );
37
38    wrapper.setProps({
39      ...wrapper.props(),
40      logRows: [makeLog({ uid: '4' }), makeLog({ uid: '5' }), makeLog({ uid: '6' })],
41    });
42
43    expect(wrapper.contains('log message 1')).toBeTruthy();
44    expect(wrapper.contains('log message 2')).toBeTruthy();
45    expect(wrapper.contains('log message 3')).toBeTruthy();
46
47    (wrapper.find('LiveLogs').instance() as any).scrollContainerRef.current.scrollTo = () => {};
48
49    wrapper.setProps({
50      ...wrapper.props(),
51      isPaused: false,
52    });
53
54    expect(wrapper.contains('log message 4')).toBeTruthy();
55    expect(wrapper.contains('log message 5')).toBeTruthy();
56    expect(wrapper.contains('log message 6')).toBeTruthy();
57  });
58
59  it('renders ansi logs', () => {
60    const rows: LogRowModel[] = [
61      makeLog({ uid: '1' }),
62      makeLog({ hasAnsi: true, raw: 'log message \u001B[31m2\u001B[0m', uid: '2' }),
63      makeLog({ hasAnsi: true, raw: 'log message \u001B[31m3\u001B[0m', uid: '3' }),
64    ];
65    const wrapper = mount(
66      <LiveLogsWithTheme
67        logRows={rows}
68        timeZone={'utc'}
69        stopLive={() => {}}
70        onPause={() => {}}
71        onResume={() => {}}
72        isPaused={true}
73      />
74    );
75
76    expect(wrapper.contains('log message 1')).toBeTruthy();
77    expect(wrapper.contains('log message 2')).not.toBeTruthy();
78    expect(wrapper.contains('log message 3')).not.toBeTruthy();
79    expect(wrapper.find('LogMessageAnsi')).toHaveLength(2);
80    expect(wrapper.find('LogMessageAnsi').first().prop('value')).toBe('log message \u001B[31m2\u001B[0m');
81    expect(wrapper.find('LogMessageAnsi').last().prop('value')).toBe('log message \u001B[31m3\u001B[0m');
82  });
83});
84
85const makeLog = (overrides: Partial<LogRowModel>): LogRowModel => {
86  const uid = overrides.uid || '1';
87  const entry = `log message ${uid}`;
88  return {
89    uid,
90    entryFieldIndex: 0,
91    rowIndex: 0,
92    dataFrame: new MutableDataFrame(),
93    logLevel: LogLevel.debug,
94    entry,
95    hasAnsi: false,
96    hasUnescapedContent: false,
97    labels: {},
98    raw: entry,
99    timeFromNow: '',
100    timeEpochMs: 1,
101    timeEpochNs: '1000000',
102    timeLocal: '',
103    timeUtc: '',
104    ...overrides,
105  };
106};
107