]> source.dussan.org Git - sonarqube.git/blob
fc6a64ba9dff847b9d732dd96492dd600ce3d4cd
[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 {
24   deleteProjectAlmBinding,
25   getAlmSettings,
26   getProjectAlmBinding,
27   setProjectAzureBinding,
28   setProjectBitbucketBinding,
29   setProjectGithubBinding
30 } from '../../../../../api/alm-settings';
31 import { mockComponent } from '../../../../../helpers/testMocks';
32 import { AlmKeys } from '../../../../../types/alm-settings';
33 import PRDecorationBinding from '../PRDecorationBinding';
34
35 jest.mock('../../../../../api/alm-settings', () => ({
36   getAlmSettings: jest.fn().mockResolvedValue([]),
37   getProjectAlmBinding: jest.fn().mockResolvedValue(undefined),
38   setProjectAzureBinding: jest.fn().mockResolvedValue(undefined),
39   setProjectBitbucketBinding: jest.fn().mockResolvedValue(undefined),
40   setProjectGithubBinding: jest.fn().mockResolvedValue(undefined),
41   deleteProjectAlmBinding: jest.fn().mockResolvedValue(undefined)
42 }));
43
44 const PROJECT_KEY = 'project-key';
45
46 beforeEach(() => {
47   jest.clearAllMocks();
48 });
49
50 it('should render correctly', () => {
51   expect(shallowRender()).toMatchSnapshot();
52 });
53
54 it('should fill selects and fill formdata', async () => {
55   const url = 'github.com';
56   const instances = [{ key: 'instance1', url, alm: AlmKeys.GitHub }];
57   const formdata = {
58     key: 'instance1',
59     repository: 'account/repo'
60   };
61   (getAlmSettings as jest.Mock).mockResolvedValueOnce(instances);
62   (getProjectAlmBinding as jest.Mock).mockResolvedValueOnce(formdata);
63
64   const wrapper = shallowRender();
65   await waitAndUpdate(wrapper);
66
67   expect(wrapper.state().loading).toBe(false);
68   expect(wrapper.state().formData).toEqual(formdata);
69   expect(wrapper.state().isChanged).toBe(false);
70 });
71
72 it('should handle reset', async () => {
73   const wrapper = shallowRender();
74   await waitAndUpdate(wrapper);
75   wrapper.setState({
76     formData: {
77       key: 'whatever',
78       repository: 'something/else'
79     }
80   });
81
82   wrapper.instance().handleReset();
83   await waitAndUpdate(wrapper);
84
85   expect(deleteProjectAlmBinding).toBeCalledWith(PROJECT_KEY);
86   expect(wrapper.state().formData).toEqual({ key: '', repository: '', slug: '' });
87   expect(wrapper.state().isChanged).toBe(false);
88 });
89
90 describe('handleSubmit', () => {
91   const instances = [
92     { key: 'github', alm: AlmKeys.GitHub },
93     { key: 'azure', alm: AlmKeys.Azure },
94     { key: 'bitbucket', alm: AlmKeys.Bitbucket }
95   ];
96
97   it('should work for github', async () => {
98     const wrapper = shallowRender();
99     await waitAndUpdate(wrapper);
100     const githubKey = 'github';
101     const repository = 'repo/path';
102     const summaryCommentEnabled = true;
103     wrapper.setState({
104       formData: { key: githubKey, repository, summaryCommentEnabled },
105       instances
106     });
107     wrapper.instance().handleSubmit();
108     await waitAndUpdate(wrapper);
109
110     expect(setProjectGithubBinding).toBeCalledWith({
111       almSetting: githubKey,
112       project: PROJECT_KEY,
113       repository,
114       summaryCommentEnabled
115     });
116     expect(wrapper.state().success).toBe(true);
117   });
118
119   it('should work for azure', async () => {
120     const wrapper = shallowRender();
121     await waitAndUpdate(wrapper);
122     const azureKey = 'azure';
123     wrapper.setState({ formData: { key: azureKey }, instances });
124     wrapper.instance().handleSubmit();
125     await waitAndUpdate(wrapper);
126
127     expect(setProjectAzureBinding).toBeCalledWith({
128       almSetting: azureKey,
129       project: PROJECT_KEY
130     });
131     expect(wrapper.state().success).toBe(true);
132   });
133
134   it('should work for bitbucket', async () => {
135     const wrapper = shallowRender();
136     await waitAndUpdate(wrapper);
137     const bitbucketKey = 'bitbucket';
138     const repository = 'repoKey';
139     const slug = 'repoSlug';
140     wrapper.setState({ formData: { key: bitbucketKey, repository, slug }, instances });
141     wrapper.instance().handleSubmit();
142     await waitAndUpdate(wrapper);
143
144     expect(setProjectBitbucketBinding).toBeCalledWith({
145       almSetting: bitbucketKey,
146       project: PROJECT_KEY,
147       repository,
148       slug
149     });
150     expect(wrapper.state().success).toBe(true);
151   });
152 });
153
154 describe.each([[500], [404]])('For status %i', status => {
155   it('should handle failures gracefully', async () => {
156     const newFormData = {
157       key: 'whatever',
158       repository: 'something/else'
159     };
160
161     (getProjectAlmBinding as jest.Mock).mockRejectedValueOnce({ status });
162     (setProjectGithubBinding as jest.Mock).mockRejectedValueOnce({ status });
163     (deleteProjectAlmBinding as jest.Mock).mockRejectedValueOnce({ status });
164
165     const wrapper = shallowRender();
166     await waitAndUpdate(wrapper);
167     wrapper.setState({
168       formData: newFormData,
169       orignalData: undefined
170     });
171
172     wrapper.instance().handleSubmit();
173     await waitAndUpdate(wrapper);
174     expect(wrapper.instance().state.orignalData).toBeUndefined();
175     wrapper.instance().handleReset();
176     await waitAndUpdate(wrapper);
177     expect(wrapper.instance().state.formData).toEqual(newFormData);
178   });
179 });
180
181 it('should handle field changes', async () => {
182   const url = 'git.enterprise.com';
183   const repository = 'my/repo';
184   const instances = [
185     { key: 'instance1', url, alm: 'github' },
186     { key: 'instance2', url, alm: 'github' },
187     { key: 'instance3', url: 'otherurl', alm: 'github' }
188   ];
189   (getAlmSettings as jest.Mock).mockResolvedValueOnce(instances);
190   const wrapper = shallowRender();
191   await waitAndUpdate(wrapper);
192
193   wrapper.instance().handleFieldChange('key', 'instance2');
194   await waitAndUpdate(wrapper);
195   expect(wrapper.state().formData).toEqual({
196     key: 'instance2'
197   });
198
199   wrapper.instance().handleFieldChange('repository', repository);
200   await waitAndUpdate(wrapper);
201   expect(wrapper.state().formData).toEqual({
202     key: 'instance2',
203     repository
204   });
205
206   wrapper.instance().handleFieldChange('summaryCommentEnabled', true);
207   await waitAndUpdate(wrapper);
208   expect(wrapper.state().formData).toEqual({
209     key: 'instance2',
210     repository,
211     summaryCommentEnabled: true
212   });
213 });
214
215 it('should reject submit github settings', async () => {
216   const wrapper = shallowRender();
217
218   expect.assertions(1);
219   await expect(
220     wrapper.instance().submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', {})
221   ).rejects.toBeUndefined();
222 });
223
224 it('should accept submit github settings', async () => {
225   (setProjectGithubBinding as jest.Mock).mockRestore();
226   const wrapper = shallowRender();
227   await wrapper
228     .instance()
229     .submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', { repository: 'foo' });
230   expect(setProjectGithubBinding).toHaveBeenCalledWith({
231     almSetting: 'github-binding',
232     project: PROJECT_KEY,
233     repository: 'foo',
234     summaryCommentEnabled: true
235   });
236
237   await wrapper.instance().submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', {
238     repository: 'foo',
239     summaryCommentEnabled: true
240   });
241   expect(setProjectGithubBinding).toHaveBeenCalledWith({
242     almSetting: 'github-binding',
243     project: PROJECT_KEY,
244     repository: 'foo',
245     summaryCommentEnabled: true
246   });
247 });
248
249 it('should validate form', async () => {
250   const wrapper = shallowRender();
251   await waitAndUpdate(wrapper);
252
253   expect(wrapper.instance().validateForm({ key: '', repository: '' })).toBe(false);
254   expect(wrapper.instance().validateForm({ key: '', repository: 'c' })).toBe(false);
255
256   wrapper.setState({
257     instances: [
258       { key: 'azure', alm: AlmKeys.Azure },
259       { key: 'bitbucket', alm: AlmKeys.Bitbucket },
260       { key: 'github', alm: AlmKeys.GitHub },
261       { key: 'gitlab', alm: AlmKeys.GitLab }
262     ]
263   });
264
265   expect(wrapper.instance().validateForm({ key: 'azure' })).toBe(true);
266
267   expect(wrapper.instance().validateForm({ key: 'github', repository: '' })).toBe(false);
268   expect(wrapper.instance().validateForm({ key: 'github', repository: 'asdf' })).toBe(true);
269
270   expect(wrapper.instance().validateForm({ key: 'bitbucket', repository: 'key' })).toBe(false);
271   expect(
272     wrapper.instance().validateForm({ key: 'bitbucket', repository: 'key', slug: 'slug' })
273   ).toBe(true);
274
275   expect(wrapper.instance().validateForm({ key: 'gitlab' })).toBe(true);
276   expect(wrapper.instance().validateForm({ key: 'gitlab', repository: 'key' })).toBe(true);
277 });
278
279 function shallowRender(props: Partial<PRDecorationBinding['props']> = {}) {
280   return shallow<PRDecorationBinding>(
281     <PRDecorationBinding component={mockComponent({ key: PROJECT_KEY })} {...props} />
282   );
283 }