]> source.dussan.org Git - sonarqube.git/blob
6f6c489f5756a9000d6aeaa7f680001d0210d4fb
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2020 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 { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
23 import { getDuplications } from '../../../../api/components';
24 import { getIssueFlowSnippets } from '../../../../api/issues';
25 import {
26   mockFlowLocation,
27   mockIssue,
28   mockSnippetsByComponent,
29   mockSourceLine,
30   mockSourceViewerFile
31 } from '../../../../helpers/testMocks';
32 import CrossComponentSourceViewerWrapper from '../CrossComponentSourceViewerWrapper';
33
34 jest.mock('../../../../api/issues', () => {
35   const { mockSnippetsByComponent } = require.requireActual('../../../../helpers/testMocks');
36   return {
37     getIssueFlowSnippets: jest.fn().mockResolvedValue({ 'main.js': mockSnippetsByComponent() })
38   };
39 });
40
41 jest.mock('../../../../api/components', () => ({
42   getDuplications: jest.fn().mockResolvedValue({})
43 }));
44
45 beforeEach(() => {
46   jest.clearAllMocks();
47 });
48
49 it('should render correctly', async () => {
50   const wrapper = shallowRender();
51   expect(wrapper).toMatchSnapshot();
52
53   await waitAndUpdate(wrapper);
54   expect(wrapper).toMatchSnapshot();
55 });
56
57 it('Should fetch data', async () => {
58   const wrapper = shallowRender();
59   wrapper.instance().fetchIssueFlowSnippets('124');
60   await waitAndUpdate(wrapper);
61   expect(getIssueFlowSnippets).toHaveBeenCalledWith('1');
62   expect(wrapper.state('components')).toEqual({ 'main.js': mockSnippetsByComponent() });
63
64   (getIssueFlowSnippets as jest.Mock).mockClear();
65   wrapper.setProps({ issue: mockIssue(true, { key: 'foo' }) });
66   expect(getIssueFlowSnippets).toBeCalledWith('foo');
67 });
68
69 it('Should handle no access rights', async () => {
70   (getIssueFlowSnippets as jest.Mock).mockRejectedValueOnce({ status: 403 });
71
72   const wrapper = shallowRender();
73   await waitAndUpdate(wrapper);
74
75   expect(wrapper.state().notAccessible).toBe(true);
76   expect(wrapper).toMatchSnapshot();
77 });
78
79 it('should handle issue popup', () => {
80   const wrapper = shallowRender();
81   // open
82   wrapper.instance().handleIssuePopupToggle('1', 'popup1');
83   expect(wrapper.state('issuePopup')).toEqual({ issue: '1', name: 'popup1' });
84
85   // close
86   wrapper.instance().handleIssuePopupToggle('1', 'popup1');
87   expect(wrapper.state('issuePopup')).toBeUndefined();
88 });
89
90 it('should handle line popup', async () => {
91   const wrapper = shallowRender();
92   await waitAndUpdate(wrapper);
93
94   const linePopup = { component: 'foo', index: 0, line: 16, name: 'b.tsx' };
95   wrapper.find('ComponentSourceSnippetGroupViewer').prop<Function>('onLinePopupToggle')(linePopup);
96   expect(wrapper.state('linePopup')).toEqual(linePopup);
97
98   wrapper.find('ComponentSourceSnippetGroupViewer').prop<Function>('onLinePopupToggle')(linePopup);
99   expect(wrapper.state('linePopup')).toBeUndefined();
100
101   const openLinePopup = { ...linePopup, open: true };
102   wrapper.find('ComponentSourceSnippetGroupViewer').prop<Function>('onLinePopupToggle')(
103     openLinePopup
104   );
105   wrapper.find('ComponentSourceSnippetGroupViewer').prop<Function>('onLinePopupToggle')(
106     openLinePopup
107   );
108   expect(wrapper.state('linePopup')).toEqual(linePopup);
109 });
110
111 it('should handle duplication popup', async () => {
112   const files = { b: { key: 'b', name: 'B.tsx', project: 'foo', projectName: 'Foo' } };
113   const duplications = [{ blocks: [{ _ref: '1', from: 1, size: 2 }] }];
114   (getDuplications as jest.Mock).mockResolvedValueOnce({ duplications, files });
115
116   const wrapper = shallowRender();
117   await waitAndUpdate(wrapper);
118
119   wrapper.find('ComponentSourceSnippetGroupViewer').prop<Function>('loadDuplications')(
120     'foo',
121     mockSourceLine()
122   );
123
124   await waitAndUpdate(wrapper);
125   expect(getDuplications).toHaveBeenCalledWith({ key: 'foo' });
126   expect(wrapper.state('duplicatedFiles')).toEqual(files);
127   expect(wrapper.state('duplications')).toEqual(duplications);
128   expect(wrapper.state('duplicationsByLine')).toEqual({ '1': [0], '2': [0] });
129   expect(wrapper.state('linePopup')).toEqual({
130     component: 'foo',
131     index: 0,
132     line: 16,
133     name: 'duplications'
134   });
135
136   expect(
137     wrapper.find('ComponentSourceSnippetGroupViewer').prop<Function>('renderDuplicationPopup')(
138       mockSourceViewerFile(),
139       0,
140       16
141     )
142   ).toMatchSnapshot();
143 });
144
145 function shallowRender(props: Partial<CrossComponentSourceViewerWrapper['props']> = {}) {
146   return shallow<CrossComponentSourceViewerWrapper>(
147     <CrossComponentSourceViewerWrapper
148       branchLike={undefined}
149       highlightedLocationMessage={undefined}
150       issue={mockIssue(true, { key: '1' })}
151       issues={[]}
152       locations={[mockFlowLocation()]}
153       onIssueChange={jest.fn()}
154       onLoaded={jest.fn()}
155       onLocationSelect={jest.fn()}
156       scroll={jest.fn()}
157       selectedFlowIndex={0}
158       {...props}
159     />
160   );
161 }