]> source.dussan.org Git - sonarqube.git/blob
53e7289bf8cb2c08ba8abb51b8dfbef692d8a0e5
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2021 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, AlmSettingsInstance } 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: AlmSettingsInstance[] = [
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     const monorepo = true;
104     wrapper.setState({
105       formData: { key: githubKey, repository, summaryCommentEnabled, monorepo },
106       instances
107     });
108     wrapper.instance().handleSubmit();
109     await waitAndUpdate(wrapper);
110
111     expect(setProjectGithubBinding).toBeCalledWith({
112       almSetting: githubKey,
113       project: PROJECT_KEY,
114       repository,
115       summaryCommentEnabled,
116       monorepo
117     });
118     expect(wrapper.state().success).toBe(true);
119   });
120
121   it('should work for azure', async () => {
122     const wrapper = shallowRender();
123     await waitAndUpdate(wrapper);
124     const azureKey = 'azure';
125     const repository = 'az-rep';
126     const slug = 'az-project';
127     const monorepo = true;
128     wrapper.setState({
129       formData: { key: azureKey, repository, slug, monorepo },
130       instances
131     });
132     wrapper.instance().handleSubmit();
133     await waitAndUpdate(wrapper);
134
135     expect(setProjectAzureBinding).toBeCalledWith({
136       almSetting: azureKey,
137       project: PROJECT_KEY,
138       projectName: slug,
139       repositoryName: repository,
140       monorepo
141     });
142     expect(wrapper.state().success).toBe(true);
143   });
144
145   it('should work for bitbucket', async () => {
146     const wrapper = shallowRender();
147     await waitAndUpdate(wrapper);
148     const bitbucketKey = 'bitbucket';
149     const repository = 'repoKey';
150     const slug = 'repoSlug';
151     const monorepo = true;
152     wrapper.setState({ formData: { key: bitbucketKey, repository, slug, monorepo }, instances });
153     wrapper.instance().handleSubmit();
154     await waitAndUpdate(wrapper);
155
156     expect(setProjectBitbucketBinding).toBeCalledWith({
157       almSetting: bitbucketKey,
158       project: PROJECT_KEY,
159       repository,
160       slug,
161       monorepo
162     });
163     expect(wrapper.state().success).toBe(true);
164   });
165 });
166
167 describe.each([[500], [404]])('For status %i', status => {
168   it('should handle failures gracefully', async () => {
169     const newFormData = {
170       key: 'whatever',
171       repository: 'something/else'
172     };
173
174     (getProjectAlmBinding as jest.Mock).mockRejectedValueOnce({ status });
175     (setProjectGithubBinding as jest.Mock).mockRejectedValueOnce({ status });
176     (deleteProjectAlmBinding as jest.Mock).mockRejectedValueOnce({ status });
177
178     const wrapper = shallowRender();
179     await waitAndUpdate(wrapper);
180     wrapper.setState({
181       formData: newFormData,
182       orignalData: undefined
183     });
184
185     wrapper.instance().handleSubmit();
186     await waitAndUpdate(wrapper);
187     expect(wrapper.instance().state.orignalData).toBeUndefined();
188     wrapper.instance().handleReset();
189     await waitAndUpdate(wrapper);
190     expect(wrapper.instance().state.formData).toEqual(newFormData);
191   });
192 });
193
194 it('should handle field changes', async () => {
195   const url = 'git.enterprise.com';
196   const repository = 'my/repo';
197   const instances: AlmSettingsInstance[] = [
198     { key: 'instance1', url, alm: AlmKeys.GitHub },
199     { key: 'instance2', url, alm: AlmKeys.GitHub },
200     { key: 'instance3', url: 'otherurl', alm: AlmKeys.GitHub }
201   ];
202   (getAlmSettings as jest.Mock).mockResolvedValueOnce(instances);
203   const wrapper = shallowRender();
204   await waitAndUpdate(wrapper);
205
206   wrapper.instance().handleFieldChange('key', 'instance2');
207   await waitAndUpdate(wrapper);
208   expect(wrapper.state().formData).toEqual({
209     key: 'instance2'
210   });
211
212   wrapper.instance().handleFieldChange('repository', repository);
213   await waitAndUpdate(wrapper);
214   expect(wrapper.state().formData).toEqual({
215     key: 'instance2',
216     repository
217   });
218
219   wrapper.instance().handleFieldChange('summaryCommentEnabled', true);
220   await waitAndUpdate(wrapper);
221   expect(wrapper.state().formData).toEqual({
222     key: 'instance2',
223     repository,
224     summaryCommentEnabled: true
225   });
226
227   wrapper.instance().handleFieldChange('monorepo', true);
228   await waitAndUpdate(wrapper);
229   expect(wrapper.state().formData).toEqual({
230     key: 'instance2',
231     repository,
232     summaryCommentEnabled: true,
233     monorepo: true
234   });
235 });
236
237 it('should reject submitted azure settings', async () => {
238   const wrapper = shallowRender();
239
240   expect.assertions(2);
241   await expect(
242     wrapper.instance().submitProjectAlmBinding(AlmKeys.Azure, 'azure-binding', { slug: 'project' })
243   ).rejects.toBeUndefined();
244   await expect(
245     wrapper
246       .instance()
247       .submitProjectAlmBinding(AlmKeys.Azure, 'azure-binding', { repository: 'repo' })
248   ).rejects.toBeUndefined();
249 });
250
251 it('should accept submit azure settings', async () => {
252   const wrapper = shallowRender();
253   await wrapper
254     .instance()
255     .submitProjectAlmBinding(AlmKeys.Azure, 'azure', { repository: 'az-repo', slug: 'az-project' });
256   expect(setProjectAzureBinding).toHaveBeenCalledWith({
257     almSetting: 'azure',
258     project: PROJECT_KEY,
259     repositoryName: 'az-repo',
260     projectName: 'az-project',
261     monorepo: false
262   });
263 });
264
265 it('should reject submitted bbs settings', async () => {
266   const wrapper = shallowRender();
267
268   expect.assertions(2);
269   await expect(
270     wrapper
271       .instance()
272       .submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs-binding', { slug: 'project' })
273   ).rejects.toBeUndefined();
274   await expect(
275     wrapper
276       .instance()
277       .submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs-binding', { repository: 'repo' })
278   ).rejects.toBeUndefined();
279 });
280
281 it('should accept submit bbs settings', async () => {
282   const wrapper = shallowRender();
283   await wrapper.instance().submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs', {
284     repository: 'bbs-repo',
285     slug: 'bbs-project'
286   });
287   expect(setProjectBitbucketBinding).toHaveBeenCalledWith({
288     almSetting: 'bbs',
289     project: PROJECT_KEY,
290     repository: 'bbs-repo',
291     slug: 'bbs-project',
292     monorepo: false
293   });
294 });
295
296 it('should reject submit github settings', async () => {
297   const wrapper = shallowRender();
298
299   expect.assertions(1);
300   await expect(
301     wrapper.instance().submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', {})
302   ).rejects.toBeUndefined();
303 });
304
305 it('should accept submit github settings', async () => {
306   (setProjectGithubBinding as jest.Mock).mockRestore();
307   const wrapper = shallowRender();
308   await wrapper
309     .instance()
310     .submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', { repository: 'foo' });
311   expect(setProjectGithubBinding).toHaveBeenCalledWith({
312     almSetting: 'github-binding',
313     project: PROJECT_KEY,
314     repository: 'foo',
315     summaryCommentEnabled: true,
316     monorepo: false
317   });
318
319   await wrapper.instance().submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', {
320     repository: 'foo',
321     summaryCommentEnabled: true
322   });
323   expect(setProjectGithubBinding).toHaveBeenCalledWith({
324     almSetting: 'github-binding',
325     project: PROJECT_KEY,
326     repository: 'foo',
327     summaryCommentEnabled: true,
328     monorepo: false
329   });
330 });
331
332 it('should validate form', async () => {
333   const wrapper = shallowRender();
334   await waitAndUpdate(wrapper);
335
336   expect(wrapper.instance().validateForm({ key: '', repository: '' })).toBe(false);
337   expect(wrapper.instance().validateForm({ key: '', repository: 'c' })).toBe(false);
338
339   wrapper.setState({
340     instances: [
341       { key: 'azure', alm: AlmKeys.Azure },
342       { key: 'bitbucket', alm: AlmKeys.Bitbucket },
343       { key: 'github', alm: AlmKeys.GitHub },
344       { key: 'gitlab', alm: AlmKeys.GitLab }
345     ]
346   });
347
348   expect(wrapper.instance().validateForm({ key: 'azure', repository: 'rep' })).toBe(false);
349   expect(wrapper.instance().validateForm({ key: 'azure', slug: 'project' })).toBe(false);
350   expect(
351     wrapper
352       .instance()
353       .validateForm({ key: 'azure', repository: 'repo', slug: 'project', monorepo: true })
354   ).toBe(true);
355
356   expect(wrapper.instance().validateForm({ key: 'github', repository: '' })).toBe(false);
357   expect(wrapper.instance().validateForm({ key: 'github', repository: 'asdf' })).toBe(true);
358
359   expect(wrapper.instance().validateForm({ key: 'bitbucket', repository: 'key' })).toBe(false);
360   expect(
361     wrapper.instance().validateForm({ key: 'bitbucket', repository: 'key', slug: 'slug' })
362   ).toBe(true);
363
364   expect(wrapper.instance().validateForm({ key: 'gitlab' })).toBe(false);
365   expect(wrapper.instance().validateForm({ key: 'gitlab', repository: 'key' })).toBe(true);
366 });
367
368 function shallowRender(props: Partial<PRDecorationBinding['props']> = {}) {
369   return shallow<PRDecorationBinding>(
370     <PRDecorationBinding
371       component={mockComponent({ key: PROJECT_KEY })}
372       monorepoEnabled={false}
373       {...props}
374     />
375   );
376 }