3 * Copyright (C) 2009-2021 SonarSource SA
4 * mailto:info AT sonarsource DOT com
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.
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.
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.
20 import { shallow } from 'enzyme';
21 import * as React from 'react';
22 import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
24 deleteProjectAlmBinding,
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';
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)
44 const PROJECT_KEY = 'project-key';
50 it('should render correctly', () => {
51 expect(shallowRender()).toMatchSnapshot();
54 it('should fill selects and fill formdata', async () => {
55 const url = 'github.com';
56 const instances = [{ key: 'instance1', url, alm: AlmKeys.GitHub }];
59 repository: 'account/repo'
61 (getAlmSettings as jest.Mock).mockResolvedValueOnce(instances);
62 (getProjectAlmBinding as jest.Mock).mockResolvedValueOnce(formdata);
64 const wrapper = shallowRender();
65 await waitAndUpdate(wrapper);
67 expect(wrapper.state().loading).toBe(false);
68 expect(wrapper.state().formData).toEqual(formdata);
69 expect(wrapper.state().isChanged).toBe(false);
72 it('should handle reset', async () => {
73 const wrapper = shallowRender();
74 await waitAndUpdate(wrapper);
78 repository: 'something/else'
82 wrapper.instance().handleReset();
83 await waitAndUpdate(wrapper);
85 expect(deleteProjectAlmBinding).toBeCalledWith(PROJECT_KEY);
86 expect(wrapper.state().formData).toEqual({ key: '', repository: '', slug: '' });
87 expect(wrapper.state().isChanged).toBe(false);
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 }
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;
105 formData: { key: githubKey, repository, summaryCommentEnabled, monorepo },
108 wrapper.instance().handleSubmit();
109 await waitAndUpdate(wrapper);
111 expect(setProjectGithubBinding).toBeCalledWith({
112 almSetting: githubKey,
113 project: PROJECT_KEY,
115 summaryCommentEnabled,
118 expect(wrapper.state().success).toBe(true);
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;
129 formData: { key: azureKey, repository, slug, monorepo },
132 wrapper.instance().handleSubmit();
133 await waitAndUpdate(wrapper);
135 expect(setProjectAzureBinding).toBeCalledWith({
136 almSetting: azureKey,
137 project: PROJECT_KEY,
139 repositoryName: repository,
142 expect(wrapper.state().success).toBe(true);
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);
156 expect(setProjectBitbucketBinding).toBeCalledWith({
157 almSetting: bitbucketKey,
158 project: PROJECT_KEY,
163 expect(wrapper.state().success).toBe(true);
167 describe.each([[500], [404]])('For status %i', status => {
168 it('should handle failures gracefully', async () => {
169 const newFormData = {
171 repository: 'something/else'
174 (getProjectAlmBinding as jest.Mock).mockRejectedValueOnce({ status });
175 (setProjectGithubBinding as jest.Mock).mockRejectedValueOnce({ status });
176 (deleteProjectAlmBinding as jest.Mock).mockRejectedValueOnce({ status });
178 const wrapper = shallowRender();
179 await waitAndUpdate(wrapper);
181 formData: newFormData,
182 orignalData: undefined
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);
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 }
202 (getAlmSettings as jest.Mock).mockResolvedValueOnce(instances);
203 const wrapper = shallowRender();
204 await waitAndUpdate(wrapper);
206 wrapper.instance().handleFieldChange('key', 'instance2');
207 await waitAndUpdate(wrapper);
208 expect(wrapper.state().formData).toEqual({
212 wrapper.instance().handleFieldChange('repository', repository);
213 await waitAndUpdate(wrapper);
214 expect(wrapper.state().formData).toEqual({
219 wrapper.instance().handleFieldChange('summaryCommentEnabled', true);
220 await waitAndUpdate(wrapper);
221 expect(wrapper.state().formData).toEqual({
224 summaryCommentEnabled: true
227 wrapper.instance().handleFieldChange('monorepo', true);
228 await waitAndUpdate(wrapper);
229 expect(wrapper.state().formData).toEqual({
232 summaryCommentEnabled: true,
237 it('should reject submitted azure settings', async () => {
238 const wrapper = shallowRender();
240 expect.assertions(2);
242 wrapper.instance().submitProjectAlmBinding(AlmKeys.Azure, 'azure-binding', { slug: 'project' })
243 ).rejects.toBeUndefined();
247 .submitProjectAlmBinding(AlmKeys.Azure, 'azure-binding', { repository: 'repo' })
248 ).rejects.toBeUndefined();
251 it('should accept submit azure settings', async () => {
252 const wrapper = shallowRender();
255 .submitProjectAlmBinding(AlmKeys.Azure, 'azure', { repository: 'az-repo', slug: 'az-project' });
256 expect(setProjectAzureBinding).toHaveBeenCalledWith({
258 project: PROJECT_KEY,
259 repositoryName: 'az-repo',
260 projectName: 'az-project',
265 it('should reject submitted bbs settings', async () => {
266 const wrapper = shallowRender();
268 expect.assertions(2);
272 .submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs-binding', { slug: 'project' })
273 ).rejects.toBeUndefined();
277 .submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs-binding', { repository: 'repo' })
278 ).rejects.toBeUndefined();
281 it('should accept submit bbs settings', async () => {
282 const wrapper = shallowRender();
283 await wrapper.instance().submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs', {
284 repository: 'bbs-repo',
287 expect(setProjectBitbucketBinding).toHaveBeenCalledWith({
289 project: PROJECT_KEY,
290 repository: 'bbs-repo',
296 it('should reject submit github settings', async () => {
297 const wrapper = shallowRender();
299 expect.assertions(1);
301 wrapper.instance().submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', {})
302 ).rejects.toBeUndefined();
305 it('should accept submit github settings', async () => {
306 (setProjectGithubBinding as jest.Mock).mockRestore();
307 const wrapper = shallowRender();
310 .submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', { repository: 'foo' });
311 expect(setProjectGithubBinding).toHaveBeenCalledWith({
312 almSetting: 'github-binding',
313 project: PROJECT_KEY,
315 summaryCommentEnabled: true,
319 await wrapper.instance().submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', {
321 summaryCommentEnabled: true
323 expect(setProjectGithubBinding).toHaveBeenCalledWith({
324 almSetting: 'github-binding',
325 project: PROJECT_KEY,
327 summaryCommentEnabled: true,
332 it('should validate form', async () => {
333 const wrapper = shallowRender();
334 await waitAndUpdate(wrapper);
336 expect(wrapper.instance().validateForm({ key: '', repository: '' })).toBe(false);
337 expect(wrapper.instance().validateForm({ key: '', repository: 'c' })).toBe(false);
341 { key: 'azure', alm: AlmKeys.Azure },
342 { key: 'bitbucket', alm: AlmKeys.Bitbucket },
343 { key: 'github', alm: AlmKeys.GitHub },
344 { key: 'gitlab', alm: AlmKeys.GitLab }
348 expect(wrapper.instance().validateForm({ key: 'azure', repository: 'rep' })).toBe(false);
349 expect(wrapper.instance().validateForm({ key: 'azure', slug: 'project' })).toBe(false);
353 .validateForm({ key: 'azure', repository: 'repo', slug: 'project', monorepo: true })
356 expect(wrapper.instance().validateForm({ key: 'github', repository: '' })).toBe(false);
357 expect(wrapper.instance().validateForm({ key: 'github', repository: 'asdf' })).toBe(true);
359 expect(wrapper.instance().validateForm({ key: 'bitbucket', repository: 'key' })).toBe(false);
361 wrapper.instance().validateForm({ key: 'bitbucket', repository: 'key', slug: 'slug' })
364 expect(wrapper.instance().validateForm({ key: 'gitlab' })).toBe(false);
365 expect(wrapper.instance().validateForm({ key: 'gitlab', repository: 'key' })).toBe(true);
368 function shallowRender(props: Partial<PRDecorationBinding['props']> = {}) {
369 return shallow<PRDecorationBinding>(
371 component={mockComponent({ key: PROJECT_KEY })}
372 monorepoEnabled={false}