]> source.dussan.org Git - sonarqube.git/blob
c5735a79fb3ae05e0aee52127f0237bf7df346f4
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2022 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 import { shallow } from 'enzyme';
21 import * as React from 'react';
22 import { getDuplications } from '../../../../api/components';
23 import { getIssueFlowSnippets } from '../../../../api/issues';
24 import {
25   mockSnippetsByComponent,
26   mockSourceLine,
27   mockSourceViewerFile,
28 } from '../../../../helpers/mocks/sources';
29 import { mockFlowLocation, mockIssue } from '../../../../helpers/testMocks';
30 import { waitAndUpdate } from '../../../../helpers/testUtils';
31 import { IssueStatus } from '../../../../types/issues';
32 import ComponentSourceSnippetGroupViewer from '../ComponentSourceSnippetGroupViewer';
33 import CrossComponentSourceViewer from '../CrossComponentSourceViewer';
34
35 jest.mock('../../../../api/issues', () => {
36   const { mockSnippetsByComponent } = jest.requireActual('../../../../helpers/mocks/sources');
37   return {
38     getIssueFlowSnippets: jest.fn().mockResolvedValue({ 'main.js': mockSnippetsByComponent() }),
39   };
40 });
41
42 jest.mock('../../../../api/components', () => ({
43   getDuplications: jest.fn().mockResolvedValue({}),
44   getComponentForSourceViewer: jest.fn().mockResolvedValue({}),
45 }));
46
47 beforeEach(() => {
48   jest.clearAllMocks();
49 });
50
51 it('should render correctly', async () => {
52   let wrapper = shallowRender();
53   expect(wrapper).toMatchSnapshot();
54
55   await waitAndUpdate(wrapper);
56   expect(wrapper).toMatchSnapshot();
57
58   wrapper = shallowRender({ issue: mockIssue(true, { component: 'test.js', key: 'unknown' }) });
59   await waitAndUpdate(wrapper);
60
61   expect(wrapper).toMatchSnapshot('no component found');
62 });
63
64 it('Should fetch data', async () => {
65   const wrapper = shallowRender();
66   wrapper.instance().fetchIssueFlowSnippets();
67   await waitAndUpdate(wrapper);
68   expect(getIssueFlowSnippets).toHaveBeenCalledWith('1');
69   expect(wrapper.state('components')).toEqual(
70     expect.objectContaining({ 'main.js': mockSnippetsByComponent() })
71   );
72
73   (getIssueFlowSnippets as jest.Mock).mockClear();
74   wrapper.setProps({ issue: mockIssue(true, { key: 'foo' }) });
75   expect(getIssueFlowSnippets).toHaveBeenCalledWith('foo');
76 });
77
78 it('Should handle a closed issue', async () => {
79   const wrapper = shallowRender({ issue: mockIssue(true, { status: IssueStatus.Closed }) });
80   wrapper.instance().fetchIssueFlowSnippets();
81   await waitAndUpdate(wrapper);
82   expect(getIssueFlowSnippets).not.toHaveBeenCalled();
83 });
84
85 it('Should handle no access rights', async () => {
86   (getIssueFlowSnippets as jest.Mock).mockRejectedValueOnce({ status: 403 });
87
88   const wrapper = shallowRender();
89   await waitAndUpdate(wrapper);
90
91   expect(wrapper.state().notAccessible).toBe(true);
92   expect(wrapper).toMatchSnapshot();
93 });
94
95 it('should handle duplication popup', async () => {
96   const files = { b: { key: 'b', name: 'B.tsx', project: 'foo', projectName: 'Foo' } };
97   const duplications = [{ blocks: [{ _ref: '1', from: 1, size: 2 }] }];
98   (getDuplications as jest.Mock).mockResolvedValueOnce({ duplications, files });
99
100   const wrapper = shallowRender();
101   await waitAndUpdate(wrapper);
102
103   wrapper.find(ComponentSourceSnippetGroupViewer).props().loadDuplications('foo', mockSourceLine());
104
105   await waitAndUpdate(wrapper);
106   expect(getDuplications).toHaveBeenCalledWith({ key: 'foo' });
107   expect(wrapper.state('duplicatedFiles')).toEqual(files);
108   expect(wrapper.state('duplications')).toEqual(duplications);
109   expect(wrapper.state('duplicationsByLine')).toEqual({ '1': [0], '2': [0] });
110
111   expect(
112     wrapper
113       .find(ComponentSourceSnippetGroupViewer)
114       .props()
115       .renderDuplicationPopup(mockSourceViewerFile(), 0, 16)
116   ).toMatchSnapshot();
117 });
118
119 function shallowRender(props: Partial<CrossComponentSourceViewer['props']> = {}) {
120   return shallow<CrossComponentSourceViewer>(
121     <CrossComponentSourceViewer
122       branchLike={undefined}
123       highlightedLocationMessage={undefined}
124       issue={mockIssue(true, {
125         key: '1',
126         component: 'project:main.js',
127         textRange: { startLine: 1, endLine: 2, startOffset: 0, endOffset: 15 },
128       })}
129       issues={[]}
130       locations={[mockFlowLocation({ component: 'project:main.js' })]}
131       onIssueSelect={jest.fn()}
132       onLocationSelect={jest.fn()}
133       selectedFlowIndex={0}
134       {...props}
135     />
136   );
137 }