]> source.dussan.org Git - sonarqube.git/blob
b5888283c02f499617cbbd1d5ff7190d623fd970
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 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 package org.sonar.server.common.almsettings.bitbucketserver;
21
22 import java.util.List;
23 import java.util.Optional;
24 import org.junit.jupiter.api.Test;
25 import org.junit.jupiter.api.extension.ExtendWith;
26 import org.mockito.Answers;
27 import org.mockito.ArgumentCaptor;
28 import org.mockito.InjectMocks;
29 import org.mockito.Mock;
30 import org.mockito.junit.jupiter.MockitoExtension;
31 import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient;
32 import org.sonar.alm.client.bitbucketserver.Branch;
33 import org.sonar.alm.client.bitbucketserver.BranchesList;
34 import org.sonar.alm.client.bitbucketserver.Project;
35 import org.sonar.alm.client.bitbucketserver.Repository;
36 import org.sonar.db.DbClient;
37 import org.sonar.db.DbSession;
38 import org.sonar.db.alm.pat.AlmPatDto;
39 import org.sonar.db.alm.setting.ALM;
40 import org.sonar.db.alm.setting.AlmSettingDto;
41 import org.sonar.db.alm.setting.ProjectAlmSettingDto;
42 import org.sonar.db.project.CreationMethod;
43 import org.sonar.db.project.ProjectDto;
44 import org.sonar.server.common.almintegration.ProjectKeyGenerator;
45 import org.sonar.server.common.almsettings.DevOpsProjectDescriptor;
46 import org.sonar.server.common.project.ProjectCreator;
47 import org.sonar.server.component.ComponentCreationData;
48 import org.sonar.server.user.UserSession;
49
50 import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
51 import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
52 import static org.mockito.ArgumentMatchers.any;
53 import static org.mockito.ArgumentMatchers.eq;
54 import static org.mockito.Mockito.lenient;
55 import static org.mockito.Mockito.mock;
56 import static org.mockito.Mockito.verify;
57 import static org.mockito.Mockito.when;
58
59 @ExtendWith(MockitoExtension.class)
60 class BitbucketServerProjectCreatorTest {
61
62   private static final String USER_LOGIN = "userLogin";
63   private static final String USER_UUID = "userUuid";
64   private static final String DOP_REPOSITORY_ID = "repository";
65   private static final String DOP_PROJECT_ID = "project";
66   private static final String URL = "http://rest/api/1.0/projects/projectKey/repos/repoName";
67   private static final String ALM_SETTING_KEY = "bitbucketserver_config_1";
68   private static final String ALM_SETTING_UUID = "almSettingUuid";
69   private static final String USER_PAT = "1234";
70   private static final String PROJECT_UUID = "projectUuid";
71   private static final String MAIN_BRANCH_NAME = "main";
72
73   @Mock(answer = Answers.RETURNS_DEEP_STUBS)
74   private DbClient dbClient;
75   @Mock
76   private AlmSettingDto almSettingDto;
77   @Mock
78   private DevOpsProjectDescriptor devOpsProjectDescriptor;
79   @Mock
80   private UserSession userSession;
81   @Mock
82   private BitbucketServerRestClient bitbucketServerRestClient;
83   @Mock
84   private ProjectCreator projectCreator;
85   @Mock
86   private ProjectKeyGenerator projectKeyGenerator;
87
88   @InjectMocks
89   private BitbucketServerProjectCreator underTest;
90
91   @Test
92   void isScanAllowedUsingPermissionsFromDevopsPlatform_shouldThrowUnsupportedOperationException() {
93     assertThatThrownBy(() -> underTest.isScanAllowedUsingPermissionsFromDevopsPlatform())
94       .isInstanceOf(UnsupportedOperationException.class)
95       .hasMessage("Not Implemented");
96   }
97
98   @Test
99   void createProjectAndBindToDevOpsPlatform_whenPatIsMissing_shouldThrow() {
100     mockValidUserSession();
101     mockValidAlmSettingsDto();
102     assertThatThrownBy(() -> underTest.createProjectAndBindToDevOpsPlatform(mock(DbSession.class), CreationMethod.ALM_IMPORT_API, false, null, null))
103       .isInstanceOf(IllegalArgumentException.class)
104       .hasMessage("personal access token for 'bitbucketserver_config_1' is missing");
105   }
106
107   @Test
108   void createProjectAndBindToDevOpsPlatform_whenBitBucketProjectNotProvided_shouldThrow() {
109     mockValidUserSession();
110     mockValidAlmSettingsDto();
111     mockValidPatForUser();
112
113     assertThatThrownBy(() -> underTest.createProjectAndBindToDevOpsPlatform(mock(DbSession.class), CreationMethod.ALM_IMPORT_API, false, "projectKey", null))
114       .isInstanceOf(IllegalArgumentException.class)
115       .hasMessage("The BitBucket project, in which the repository null is located, is mandatory");
116   }
117
118   @Test
119   void createProjectAndBindToDevOpsPlatform_whenRepositoryNotFound_shouldThrow() {
120     mockValidUserSession();
121     mockValidAlmSettingsDto();
122     mockValidPatForUser();
123     mockValidProjectDescriptor();
124     when(bitbucketServerRestClient.getRepo(URL, USER_PAT, DOP_PROJECT_ID, DOP_REPOSITORY_ID)).thenThrow(new IllegalArgumentException("Problem"));
125
126     assertThatThrownBy(() -> underTest.createProjectAndBindToDevOpsPlatform(mock(DbSession.class), CreationMethod.ALM_IMPORT_API, false, "projectKey", null))
127       .isInstanceOf(IllegalArgumentException.class)
128       .hasMessage("Problem");
129   }
130
131   @Test
132   void createProjectAndBindToDevOpsPlatform_whenRepoFoundOnBitbucket_successfullyCreatesProject() {
133     mockValidUserSession();
134     mockValidAlmSettingsDto();
135     mockValidPatForUser();
136     mockValidProjectDescriptor();
137     mockValidBitBucketRepository();
138     mockProjectCreation("projectKey", "projectName");
139
140     underTest.createProjectAndBindToDevOpsPlatform(mock(DbSession.class), CreationMethod.ALM_IMPORT_API, true, "projectKey", "projectName");
141
142     ArgumentCaptor<ProjectAlmSettingDto> projectAlmSettingCaptor = ArgumentCaptor.forClass(ProjectAlmSettingDto.class);
143     verify(dbClient.projectAlmSettingDao()).insertOrUpdate(any(), projectAlmSettingCaptor.capture(), eq(ALM_SETTING_KEY), eq("projectName"), eq("projectKey"));
144     ProjectAlmSettingDto createdProjectAlmSettingDto = projectAlmSettingCaptor.getValue();
145
146     assertThat(createdProjectAlmSettingDto.getAlmSettingUuid()).isEqualTo(ALM_SETTING_UUID);
147     assertThat(createdProjectAlmSettingDto.getAlmRepo()).isEqualTo(DOP_REPOSITORY_ID);
148     assertThat(createdProjectAlmSettingDto.getProjectUuid()).isEqualTo(PROJECT_UUID);
149     assertThat(createdProjectAlmSettingDto.getMonorepo()).isTrue();
150   }
151
152   @Test
153   void createProjectAndBindToDevOpsPlatform_whenNoKeyAndNameSpecified_generatesKeyAndUsersBitbucketRepositoryName() {
154     mockValidUserSession();
155     mockValidAlmSettingsDto();
156     mockValidPatForUser();
157     mockValidProjectDescriptor();
158     Repository repository = mockValidBitBucketRepository();
159     String generatedProjectKey = "generatedProjectKey";
160     when(projectKeyGenerator.generateUniqueProjectKey(repository.getProject().getKey(), repository.getSlug())).thenReturn(generatedProjectKey);
161     mockProjectCreation(generatedProjectKey, repository.getName());
162
163     underTest.createProjectAndBindToDevOpsPlatform(mock(DbSession.class), CreationMethod.ALM_IMPORT_API, true, null, null);
164
165     ArgumentCaptor<ProjectAlmSettingDto> projectAlmSettingCaptor = ArgumentCaptor.forClass(ProjectAlmSettingDto.class);
166     verify(dbClient.projectAlmSettingDao()).insertOrUpdate(any(), projectAlmSettingCaptor.capture(), eq(ALM_SETTING_KEY), eq(repository.getName()), eq(generatedProjectKey));
167     ProjectAlmSettingDto createdProjectAlmSettingDto = projectAlmSettingCaptor.getValue();
168
169     assertThat(createdProjectAlmSettingDto.getAlmSettingUuid()).isEqualTo(ALM_SETTING_UUID);
170     assertThat(createdProjectAlmSettingDto.getAlmRepo()).isEqualTo(DOP_REPOSITORY_ID);
171     assertThat(createdProjectAlmSettingDto.getProjectUuid()).isEqualTo(PROJECT_UUID);
172     assertThat(createdProjectAlmSettingDto.getMonorepo()).isTrue();
173   }
174
175   private void mockValidUserSession() {
176     lenient().when(userSession.getLogin()).thenReturn(USER_LOGIN);
177     lenient().when(userSession.getUuid()).thenReturn(USER_UUID);
178   }
179
180   private void mockValidPatForUser() {
181     AlmPatDto almPatDto = mock();
182     when(almPatDto.getPersonalAccessToken()).thenReturn(USER_PAT);
183     when(dbClient.almPatDao().selectByUserAndAlmSetting(any(), eq(USER_UUID), eq(almSettingDto))).thenReturn(Optional.of(almPatDto));
184   }
185
186   private void mockValidAlmSettingsDto() {
187     lenient().when(almSettingDto.getUrl()).thenReturn(URL);
188     lenient().when(almSettingDto.getKey()).thenReturn(ALM_SETTING_KEY);
189     lenient().when(almSettingDto.getUuid()).thenReturn(ALM_SETTING_UUID);
190   }
191
192   private void mockValidProjectDescriptor() {
193     lenient().when(devOpsProjectDescriptor.alm()).thenReturn(ALM.BITBUCKET);
194     lenient().when(devOpsProjectDescriptor.url()).thenReturn(URL);
195     lenient().when(devOpsProjectDescriptor.repositoryIdentifier()).thenReturn(DOP_REPOSITORY_ID);
196     lenient().when(devOpsProjectDescriptor.projectIdentifier()).thenReturn(DOP_PROJECT_ID);
197   }
198
199   private Repository mockValidBitBucketRepository() {
200     Repository repository = new Repository(DOP_REPOSITORY_ID, "Repository name", 12L, new Project(DOP_PROJECT_ID, "Project name", 42L));
201     when(bitbucketServerRestClient.getRepo(URL, USER_PAT, DOP_PROJECT_ID, DOP_REPOSITORY_ID)).thenReturn(repository);
202
203     BranchesList branches = new BranchesList(List.of(
204       new Branch(MAIN_BRANCH_NAME, true),
205       new Branch("feature", false)));
206     when(bitbucketServerRestClient.getBranches(URL, USER_PAT, DOP_PROJECT_ID, DOP_REPOSITORY_ID)).thenReturn(branches);
207
208     return repository;
209   }
210
211   private void mockProjectCreation(String projectKey, String projectName) {
212     ComponentCreationData componentCreationData = mock();
213     ProjectDto projectDto = mock();
214     when(componentCreationData.projectDto()).thenReturn(projectDto);
215     when(projectDto.getUuid()).thenReturn(PROJECT_UUID);
216     when(projectDto.getKey()).thenReturn(projectKey);
217     when(projectDto.getName()).thenReturn(projectName);
218     when(projectCreator.createProject(any(), eq(projectKey), eq(projectName), eq(MAIN_BRANCH_NAME), eq(CreationMethod.ALM_IMPORT_API)))
219       .thenReturn(componentCreationData);
220   }
221 }