]> source.dussan.org Git - sonarqube.git/blob
d3cdd223bb68a5778142715ad9394d5e0d68a10d
[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 package org.sonar.server.almintegration.ws.bitbucketserver;
21
22 import org.junit.Before;
23 import org.junit.BeforeClass;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.junit.rules.ExpectedException;
27 import org.sonar.alm.client.bitbucketserver.BitbucketServerRestClient;
28 import org.sonar.alm.client.bitbucketserver.Branch;
29 import org.sonar.alm.client.bitbucketserver.BranchesList;
30 import org.sonar.alm.client.bitbucketserver.Project;
31 import org.sonar.alm.client.bitbucketserver.Repository;
32 import org.sonar.api.server.ws.WebService;
33 import org.sonar.api.utils.System2;
34 import org.sonar.core.i18n.I18n;
35 import org.sonar.core.util.SequenceUuidFactory;
36 import org.sonar.db.DbTester;
37 import org.sonar.db.alm.pat.AlmPatDto;
38 import org.sonar.db.alm.setting.AlmSettingDto;
39 import org.sonar.db.component.BranchDto;
40 import org.sonar.db.project.ProjectDto;
41 import org.sonar.db.user.UserDto;
42 import org.sonar.server.almintegration.ws.ImportHelper;
43 import org.sonar.server.component.ComponentUpdater;
44 import org.sonar.server.es.TestProjectIndexers;
45 import org.sonar.server.exceptions.BadRequestException;
46 import org.sonar.server.exceptions.ForbiddenException;
47 import org.sonar.server.exceptions.NotFoundException;
48 import org.sonar.server.exceptions.UnauthorizedException;
49 import org.sonar.server.favorite.FavoriteUpdater;
50 import org.sonar.server.permission.PermissionTemplateService;
51 import org.sonar.server.project.ProjectDefaultVisibility;
52 import org.sonar.server.project.Visibility;
53 import org.sonar.server.tester.UserSessionRule;
54 import org.sonar.server.ws.WsActionTester;
55 import org.sonarqube.ws.Projects;
56
57 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
58 import static org.apache.commons.lang.math.JVMRandom.nextLong;
59 import static org.assertj.core.api.Assertions.assertThat;
60 import static org.assertj.core.api.Assertions.tuple;
61 import static org.mockito.ArgumentMatchers.any;
62 import static org.mockito.Mockito.mock;
63 import static org.mockito.Mockito.when;
64 import static org.sonar.db.alm.integration.pat.AlmPatsTesting.newAlmPatDto;
65 import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS;
66 import static org.sonar.db.permission.GlobalPermission.SCAN;
67 import java.util.Collection;
68 import java.util.Collections;
69 import java.util.List;
70 import java.util.Optional;
71 import java.util.stream.Collectors;
72
73 public class ImportBitbucketServerProjectActionTest {
74
75   @Rule
76   public ExpectedException expectedException = ExpectedException.none();
77   @Rule
78   public UserSessionRule userSession = UserSessionRule.standalone();
79   @Rule
80   public DbTester db = DbTester.create();
81
82   private final ProjectDefaultVisibility projectDefaultVisibility = mock(ProjectDefaultVisibility.class);
83   private final BitbucketServerRestClient bitbucketServerRestClient = mock(BitbucketServerRestClient.class);
84
85   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), System2.INSTANCE,
86     mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestProjectIndexers(), new SequenceUuidFactory());
87
88   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
89   private final WsActionTester ws = new WsActionTester(new ImportBitbucketServerProjectAction(db.getDbClient(), userSession,
90     bitbucketServerRestClient, projectDefaultVisibility, componentUpdater, importHelper));
91
92   private static BranchesList defaultBranchesList;
93
94   @BeforeClass
95   public static void beforeAll() {
96     Branch defaultBranch = new Branch("default", true);
97     defaultBranchesList = new BranchesList(Collections.singletonList(defaultBranch));
98   }
99
100   @Before
101   public void before() {
102     when(projectDefaultVisibility.get(any())).thenReturn(Visibility.PRIVATE);
103   }
104
105   @Test
106   public void import_project() {
107     UserDto user = db.users().insertUser();
108     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
109     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
110     db.almPats().insert(dto -> {
111       dto.setAlmSettingUuid(almSetting.getUuid());
112       dto.setUserUuid(user.getUuid());
113     });
114     Project project = getGsonBBSProject();
115     Repository repo = getGsonBBSRepo(project);
116     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
117     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(defaultBranchesList);
118
119     Projects.CreateWsResponse response = ws.newRequest()
120       .setParam("almSetting", almSetting.getKey())
121       .setParam("projectKey", "projectKey")
122       .setParam("repositorySlug", "repo-slug")
123       .executeProtobuf(Projects.CreateWsResponse.class);
124
125     Projects.CreateWsResponse.Project result = response.getProject();
126     assertThat(result.getKey()).isEqualTo(project.getKey() + "_" + repo.getSlug());
127     assertThat(result.getName()).isEqualTo(repo.getName());
128
129     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
130     assertThat(projectDto).isPresent();
131     assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get())).isPresent();
132   }
133
134   @Test
135   public void fail_project_already_exist() {
136     UserDto user = db.users().insertUser();
137     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
138     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
139     db.almPats().insert(dto -> {
140       dto.setAlmSettingUuid(almSetting.getUuid());
141       dto.setUserUuid(user.getUuid());
142     });
143     Project project = getGsonBBSProject();
144     Repository repo = getGsonBBSRepo(project);
145     String projectKey = project.getKey() + "_" + repo.getSlug();
146     db.components().insertPublicProject(p -> p.setDbKey(projectKey));
147
148     expectedException.expect(BadRequestException.class);
149     expectedException.expectMessage("Could not create null, key already exists: " + projectKey);
150
151     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
152     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(defaultBranchesList);
153     
154     ws.newRequest()
155       .setParam("almSetting", almSetting.getKey())
156       .setParam("projectKey", "projectKey")
157       .setParam("repositorySlug", "repo-slug")
158       .execute();
159   }
160
161   @Test
162   public void fail_when_not_logged_in() {
163     expectedException.expect(UnauthorizedException.class);
164
165     ws.newRequest()
166       .setParam("almSetting", "sdgfdshfjztutz")
167       .setParam("projectKey", "projectKey")
168       .setParam("repositorySlug", "repo-slug")
169       .execute();
170   }
171
172   @Test
173   public void fail_when_missing_project_creator_permission() {
174     UserDto user = db.users().insertUser();
175     userSession.logIn(user).addPermission(SCAN);
176
177     expectedException.expect(ForbiddenException.class);
178     expectedException.expectMessage("Insufficient privileges");
179
180     ws.newRequest()
181       .setParam("almSetting", "sdgfdshfjztutz")
182       .setParam("projectKey", "projectKey")
183       .setParam("repositorySlug", "repo-slug")
184       .execute();
185   }
186
187   @Test
188   public void check_pat_is_missing() {
189     UserDto user = db.users().insertUser();
190     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
191     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
192
193     expectedException.expect(IllegalArgumentException.class);
194     expectedException.expectMessage("personal access token for '" + almSetting.getKey() + "' is missing");
195
196     ws.newRequest()
197       .setParam("almSetting", almSetting.getKey())
198       .execute();
199   }
200
201   @Test
202   public void fail_check_alm_setting_not_found() {
203     UserDto user = db.users().insertUser();
204     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
205     AlmPatDto almPatDto = newAlmPatDto();
206     db.getDbClient().almPatDao().insert(db.getSession(), almPatDto, user.getLogin(), null);
207
208     expectedException.expect(NotFoundException.class);
209     expectedException.expectMessage("ALM Setting 'testKey' not found");
210
211     ws.newRequest()
212       .setParam("almSetting", "testKey")
213       .execute();
214   }
215
216   @Test
217   public void fail_when_no_creation_project_permission() {
218     UserDto user = db.users().insertUser();
219     userSession.logIn(user);
220
221     expectedException.expect(ForbiddenException.class);
222     expectedException.expectMessage("Insufficient privileges");
223
224     ws.newRequest()
225       .setParam("almSetting", "anyvalue")
226       .execute();
227   }
228
229   @Test
230   public void handle_givenNoDefaultBranchFound_doNotUpdateDefaultBranchName() {
231     BranchesList branchesList = new BranchesList();
232     Branch branch = new Branch("not_a_master", false);
233     branchesList.addBranch(branch);
234
235     UserDto user = db.users().insertUser();
236     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
237     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
238     db.almPats().insert(dto -> {
239       dto.setAlmSettingUuid(almSetting.getUuid());
240       dto.setUserUuid(user.getUuid());
241     });
242     Project project = getGsonBBSProject();
243     Repository repo = getGsonBBSRepo(project);
244     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
245     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(branchesList);
246
247     Projects.CreateWsResponse response = ws.newRequest()
248       .setParam("almSetting", almSetting.getKey())
249       .setParam("projectKey", "projectKey")
250       .setParam("repositorySlug", "repo-slug")
251       .executeProtobuf(Projects.CreateWsResponse.class);
252
253     Projects.CreateWsResponse.Project result = response.getProject();
254
255     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
256
257     Collection<BranchDto> branchDtos = db.getDbClient().branchDao().selectByProject(db.getSession(), projectDto.get());
258     List<BranchDto> collect = branchDtos.stream().filter(BranchDto::isMain).collect(Collectors.toList());
259     String mainBranchName = collect.iterator().next().getKey();
260     assertThat(mainBranchName).isEqualTo("master");
261   }
262
263   @Test
264   public void handle_givenDefaultBranchNamedDefault_updateDefaultBranchNameToDefault() {
265     BranchesList branchesList = new BranchesList();
266     Branch branch = new Branch("default", true);
267     branchesList.addBranch(branch);
268
269     UserDto user = db.users().insertUser();
270     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
271     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
272     db.almPats().insert(dto -> {
273       dto.setAlmSettingUuid(almSetting.getUuid());
274       dto.setUserUuid(user.getUuid());
275     });
276     Project project = getGsonBBSProject();
277     Repository repo = getGsonBBSRepo(project);
278     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
279     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(branchesList);
280
281     Projects.CreateWsResponse response = ws.newRequest()
282       .setParam("almSetting", almSetting.getKey())
283       .setParam("projectKey", "projectKey")
284       .setParam("repositorySlug", "repo-slug")
285       .executeProtobuf(Projects.CreateWsResponse.class);
286
287     Projects.CreateWsResponse.Project result = response.getProject();
288
289     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
290
291     Collection<BranchDto> branchDtos = db.getDbClient().branchDao().selectByProject(db.getSession(), projectDto.get());
292     List<BranchDto> collect = branchDtos.stream().filter(BranchDto::isMain).collect(Collectors.toList());
293     String mainBranchName = collect.iterator().next().getKey();
294     assertThat(mainBranchName).isEqualTo("default");
295   }
296
297   @Test
298   public void definition() {
299     WebService.Action def = ws.getDef();
300
301     assertThat(def.since()).isEqualTo("8.2");
302     assertThat(def.isPost()).isTrue();
303     assertThat(def.params())
304       .extracting(WebService.Param::key, WebService.Param::isRequired)
305       .containsExactlyInAnyOrder(
306         tuple("almSetting", true),
307         tuple("repositorySlug", true),
308         tuple("projectKey", true));
309   }
310
311   private Repository getGsonBBSRepo(Project project) {
312     Repository bbsResult = new Repository();
313     bbsResult.setProject(project);
314     bbsResult.setSlug(randomAlphanumeric(5));
315     bbsResult.setName(randomAlphanumeric(5));
316     bbsResult.setId(nextLong(100));
317     return bbsResult;
318   }
319
320   private Project getGsonBBSProject() {
321     return new Project()
322       .setKey(randomAlphanumeric(5))
323       .setId(nextLong(100))
324       .setName(randomAlphanumeric(5));
325   }
326
327 }