summaryrefslogtreecommitdiff
path: root/spec/frontend/error_tracking/components/stacktrace_entry_spec.js
blob: de746b8ac8435ff2286aa23b55281e7e04ed7ae1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { shallowMount } from '@vue/test-utils';
import { GlSprintf } from '@gitlab/ui';
import StackTraceEntry from '~/error_tracking/components/stacktrace_entry.vue';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import Icon from '~/vue_shared/components/icon.vue';
import { trimText } from 'helpers/text_helper';

describe('Stacktrace Entry', () => {
  let wrapper;

  const lines = [
    [22, '    def safe_thread(name, \u0026block)\n'],
    [23, '      Thread.new do\n'],
    [24, "        Thread.current['sidekiq_label'] = name\n"],
    [25, '        watchdog(name, \u0026block)\n'],
  ];

  function mountComponent(props) {
    wrapper = shallowMount(StackTraceEntry, {
      propsData: {
        filePath: 'sidekiq/util.rb',
        errorLine: 24,
        ...props,
      },
      stubs: {
        GlSprintf,
      },
    });
  }

  afterEach(() => {
    if (wrapper) {
      wrapper.destroy();
    }
  });

  it('should render stacktrace entry collapsed', () => {
    mountComponent({ lines });
    expect(wrapper.find(StackTraceEntry).exists()).toBe(true);
    expect(wrapper.find(ClipboardButton).exists()).toBe(true);
    expect(wrapper.find(Icon).exists()).toBe(true);
    expect(wrapper.find(FileIcon).exists()).toBe(true);
    expect(wrapper.find('table').exists()).toBe(false);
  });

  it('should render stacktrace entry table expanded', () => {
    mountComponent({ expanded: true, lines });
    expect(wrapper.find('table').exists()).toBe(true);
    expect(wrapper.findAll('tr.line_holder').length).toBe(4);
    expect(wrapper.findAll('.line_content.old').length).toBe(1);
  });

  describe('entry caption', () => {
    const findFileHeaderContent = () => wrapper.find('.file-header-content').text();

    it('should hide collapse icon and render error fn name and error line when there is no code block', () => {
      const extraInfo = { errorLine: 34, errorFn: 'errorFn', errorColumn: 77 };
      mountComponent({ expanded: false, lines: [], ...extraInfo });
      expect(wrapper.find(Icon).exists()).toBe(false);
      expect(trimText(findFileHeaderContent())).toContain(
        `in ${extraInfo.errorFn} at line ${extraInfo.errorLine}:${extraInfo.errorColumn}`,
      );
    });

    it('should render only lineNo:columnNO when there is no errorFn ', () => {
      const extraInfo = { errorLine: 34, errorFn: null, errorColumn: 77 };
      mountComponent({ expanded: false, lines: [], ...extraInfo });
      const fileHeaderContent = trimText(findFileHeaderContent());
      expect(fileHeaderContent).not.toContain(`in ${extraInfo.errorFn}`);
      expect(fileHeaderContent).toContain(`${extraInfo.errorLine}:${extraInfo.errorColumn}`);
    });

    it('should render only lineNo when there is no errorColumn ', () => {
      const extraInfo = { errorLine: 34, errorFn: 'errorFn', errorColumn: null };
      mountComponent({ expanded: false, lines: [], ...extraInfo });
      const fileHeaderContent = trimText(findFileHeaderContent());
      expect(fileHeaderContent).toContain(`in ${extraInfo.errorFn} at line ${extraInfo.errorLine}`);
      expect(fileHeaderContent).not.toContain(`:${extraInfo.errorColumn}`);
    });
  });
});