]> source.dussan.org Git - sonarqube.git/blob
6b194e14452cee37970602c0075a3001fabb02be
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2019 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 * as React from 'react';
21 import { shallow } from 'enzyme';
22 import { times } from 'lodash';
23 import ComponentSourceSnippetViewer from '../ComponentSourceSnippetViewer';
24 import {
25   mockMainBranch,
26   mockIssue,
27   mockSourceViewerFile,
28   mockFlowLocation,
29   mockSnippetsByComponent,
30   mockSourceLine
31 } from '../../../../helpers/testMocks';
32 import { waitAndUpdate } from '../../../../helpers/testUtils';
33 import { getSources } from '../../../../api/components';
34
35 jest.mock('../../../../api/components', () => ({
36   getSources: jest.fn().mockResolvedValue([])
37 }));
38
39 beforeEach(() => {
40   jest.clearAllMocks();
41 });
42
43 it('should render correctly', () => {
44   expect(shallowRender()).toMatchSnapshot();
45 });
46
47 it('should expand block', async () => {
48   (getSources as jest.Mock).mockResolvedValueOnce(
49     Object.values(mockSnippetsByComponent('a', [22, 23, 24, 25, 26, 27, 28, 29, 30, 31]).sources)
50   );
51   const snippetGroup: T.SnippetGroup = {
52     locations: [
53       mockFlowLocation({
54         component: 'a',
55         textRange: { startLine: 34, endLine: 34, startOffset: 0, endOffset: 0 }
56       }),
57       mockFlowLocation({
58         component: 'a',
59         textRange: { startLine: 54, endLine: 54, startOffset: 0, endOffset: 0 }
60       })
61     ],
62     ...mockSnippetsByComponent('a', [32, 33, 34, 35, 36, 52, 53, 54, 55, 56])
63   };
64
65   const wrapper = shallowRender({ snippetGroup });
66
67   wrapper.instance().expandBlock(0, 'up');
68   await waitAndUpdate(wrapper);
69
70   expect(getSources).toHaveBeenCalledWith({ from: 19, key: 'a', to: 31 });
71   expect(wrapper.state('snippets')).toHaveLength(2);
72   expect(wrapper.state('snippets')[0]).toHaveLength(15);
73   expect(Object.keys(wrapper.state('additionalLines'))).toHaveLength(10);
74 });
75
76 it('should expand full component', async () => {
77   (getSources as jest.Mock).mockResolvedValueOnce(
78     Object.values(mockSnippetsByComponent('a', times(14)).sources)
79   );
80   const snippetGroup: T.SnippetGroup = {
81     locations: [
82       mockFlowLocation({
83         component: 'a',
84         textRange: { startLine: 3, endLine: 3, startOffset: 0, endOffset: 0 }
85       }),
86       mockFlowLocation({
87         component: 'a',
88         textRange: { startLine: 12, endLine: 12, startOffset: 0, endOffset: 0 }
89       })
90     ],
91     ...mockSnippetsByComponent('a', [1, 2, 3, 4, 5, 10, 11, 12, 13, 14])
92   };
93
94   const wrapper = shallowRender({ snippetGroup });
95
96   wrapper.instance().expandComponent();
97   await waitAndUpdate(wrapper);
98
99   expect(getSources).toHaveBeenCalledWith({ key: 'a' });
100   expect(wrapper.state('snippets')).toHaveLength(1);
101   expect(wrapper.state('snippets')[0]).toHaveLength(14);
102 });
103
104 it('should handle correctly open/close issue', () => {
105   const wrapper = shallowRender();
106   const sourceLine = mockSourceLine();
107   expect(wrapper.state('openIssuesByLine')).toEqual({});
108   wrapper.instance().handleOpenIssues(sourceLine);
109   expect(wrapper.state('openIssuesByLine')).toEqual({ [sourceLine.line]: true });
110   wrapper.instance().handleCloseIssues(sourceLine);
111   expect(wrapper.state('openIssuesByLine')).toEqual({ [sourceLine.line]: false });
112 });
113
114 it('should handle symbol highlighting', () => {
115   const wrapper = shallowRender();
116   expect(wrapper.state('highlightedSymbols')).toEqual([]);
117   wrapper.instance().handleSymbolClick(['foo']);
118   expect(wrapper.state('highlightedSymbols')).toEqual(['foo']);
119 });
120
121 it('should correctly handle lines actions', () => {
122   const snippetGroup: T.SnippetGroup = {
123     locations: [
124       mockFlowLocation({
125         component: 'a',
126         textRange: { startLine: 34, endLine: 34, startOffset: 0, endOffset: 0 }
127       }),
128       mockFlowLocation({
129         component: 'a',
130         textRange: { startLine: 54, endLine: 54, startOffset: 0, endOffset: 0 }
131       })
132     ],
133     ...mockSnippetsByComponent('a', [32, 33, 34, 35, 36, 52, 53, 54, 55, 56])
134   };
135   const loadDuplications = jest.fn();
136   const onLinePopupToggle = jest.fn();
137   const renderDuplicationPopup = jest.fn();
138
139   const wrapper = shallowRender({
140     loadDuplications,
141     onLinePopupToggle,
142     renderDuplicationPopup,
143     snippetGroup
144   });
145
146   const line = mockSourceLine();
147   wrapper
148     .find('Line')
149     .first()
150     .prop<Function>('loadDuplications')(line);
151   expect(loadDuplications).toHaveBeenCalledWith('a', line);
152
153   wrapper
154     .find('Line')
155     .first()
156     .prop<Function>('onLinePopupToggle')({ line: 13, name: 'foo' });
157   expect(onLinePopupToggle).toHaveBeenCalledWith({ component: 'a', line: 13, name: 'foo' });
158
159   wrapper
160     .find('Line')
161     .first()
162     .prop<Function>('renderDuplicationPopup')(1, 13);
163   expect(renderDuplicationPopup).toHaveBeenCalledWith(
164     mockSourceViewerFile({ key: 'a', path: 'a' }),
165     1,
166     13
167   );
168 });
169
170 function shallowRender(props: Partial<ComponentSourceSnippetViewer['props']> = {}) {
171   const snippetGroup: T.SnippetGroup = {
172     component: mockSourceViewerFile(),
173     locations: [],
174     sources: []
175   };
176   return shallow<ComponentSourceSnippetViewer>(
177     <ComponentSourceSnippetViewer
178       branchLike={mockMainBranch()}
179       duplications={undefined}
180       duplicationsByLine={undefined}
181       highlightedLocationMessage={{ index: 0, text: '' }}
182       issue={mockIssue()}
183       issuesByLine={{}}
184       last={false}
185       linePopup={undefined}
186       loadDuplications={jest.fn()}
187       locations={[]}
188       onIssueChange={jest.fn()}
189       onIssuePopupToggle={jest.fn()}
190       onLinePopupToggle={jest.fn()}
191       onLocationSelect={jest.fn()}
192       renderDuplicationPopup={jest.fn()}
193       scroll={jest.fn()}
194       snippetGroup={snippetGroup}
195       {...props}
196     />
197   );
198 }