]> source.dussan.org Git - sonarqube.git/blob
3ac432bb989fce7ee9ca21a1e8760a393ffbb6f4
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2023 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 java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
26 import java.util.Optional;
27 import org.junit.Before;
28 import org.junit.BeforeClass;
29 import org.junit.Rule;
30 import org.junit.Test;
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.api.server.ws.WebService;
37 import org.sonar.api.utils.System2;
38 import org.sonar.core.platform.EditionProvider;
39 import org.sonar.core.platform.PlatformEditionProvider;
40 import org.sonar.core.util.SequenceUuidFactory;
41 import org.sonar.db.DbTester;
42 import org.sonar.db.alm.pat.AlmPatDto;
43 import org.sonar.db.alm.setting.AlmSettingDto;
44 import org.sonar.db.component.BranchDto;
45 import org.sonar.db.newcodeperiod.NewCodePeriodDto;
46 import org.sonar.db.project.ProjectDto;
47 import org.sonar.db.user.UserDto;
48 import org.sonar.server.almintegration.ws.ImportHelper;
49 import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
50 import org.sonar.server.component.ComponentUpdater;
51 import org.sonar.server.es.TestProjectIndexers;
52 import org.sonar.server.exceptions.BadRequestException;
53 import org.sonar.server.exceptions.ForbiddenException;
54 import org.sonar.server.exceptions.NotFoundException;
55 import org.sonar.server.exceptions.UnauthorizedException;
56 import org.sonar.server.favorite.FavoriteUpdater;
57 import org.sonar.server.l18n.I18nRule;
58 import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
59 import org.sonar.server.permission.PermissionTemplateService;
60 import org.sonar.server.project.DefaultBranchNameResolver;
61 import org.sonar.server.project.ProjectDefaultVisibility;
62 import org.sonar.server.project.Visibility;
63 import org.sonar.server.tester.UserSessionRule;
64 import org.sonar.server.ws.WsActionTester;
65 import org.sonarqube.ws.Projects;
66
67 import static java.util.Objects.requireNonNull;
68 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
69 import static org.apache.commons.lang.math.JVMRandom.nextLong;
70 import static org.assertj.core.api.Assertions.assertThat;
71 import static org.assertj.core.api.Assertions.assertThatThrownBy;
72 import static org.assertj.core.api.Assertions.tuple;
73 import static org.mockito.ArgumentMatchers.any;
74 import static org.mockito.Mockito.mock;
75 import static org.mockito.Mockito.verify;
76 import static org.mockito.Mockito.when;
77 import static org.sonar.db.alm.integration.pat.AlmPatsTesting.newAlmPatDto;
78 import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME;
79 import static org.sonar.db.newcodeperiod.NewCodePeriodType.NUMBER_OF_DAYS;
80 import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH;
81 import static org.sonar.db.permission.GlobalPermission.PROVISION_PROJECTS;
82 import static org.sonar.db.permission.GlobalPermission.SCAN;
83 import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NEW_CODE_DEFINITION_TYPE;
84 import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NEW_CODE_DEFINITION_VALUE;
85
86 public class ImportBitbucketServerProjectActionIT {
87   private static final String GENERATED_PROJECT_KEY = "TEST_PROJECT_KEY";
88
89   @Rule
90   public UserSessionRule userSession = UserSessionRule.standalone();
91   @Rule
92   public DbTester db = DbTester.create(true);
93   @Rule
94   public final I18nRule i18n = new I18nRule();
95
96   private final ProjectDefaultVisibility projectDefaultVisibility = mock(ProjectDefaultVisibility.class);
97   private final BitbucketServerRestClient bitbucketServerRestClient = mock(BitbucketServerRestClient.class);
98   private final DefaultBranchNameResolver defaultBranchNameResolver = mock(DefaultBranchNameResolver.class);
99   private PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class);
100   private NewCodeDefinitionResolver newCodeDefinitionResolver = new NewCodeDefinitionResolver(db.getDbClient(), editionProvider);
101
102   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), i18n, System2.INSTANCE,
103     mock(PermissionTemplateService.class), new FavoriteUpdater(db.getDbClient()), new TestProjectIndexers(), new SequenceUuidFactory(),
104     defaultBranchNameResolver, true);
105
106   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
107   private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class);
108   private final WsActionTester ws = new WsActionTester(new ImportBitbucketServerProjectAction(db.getDbClient(), userSession,
109     bitbucketServerRestClient, projectDefaultVisibility, componentUpdater, importHelper, projectKeyGenerator, newCodeDefinitionResolver, defaultBranchNameResolver));
110
111   private static BranchesList defaultBranchesList;
112
113   @BeforeClass
114   public static void beforeAll() {
115     Branch defaultBranch = new Branch("default", true);
116     defaultBranchesList = new BranchesList(Collections.singletonList(defaultBranch));
117   }
118
119   @Before
120   public void before() {
121     when(projectDefaultVisibility.get(any())).thenReturn(Visibility.PRIVATE);
122     when(projectKeyGenerator.generateUniqueProjectKey(any(), any())).thenReturn(GENERATED_PROJECT_KEY);
123     when(defaultBranchNameResolver.getEffectiveMainBranchName()).thenReturn(DEFAULT_MAIN_BRANCH_NAME);
124   }
125
126   @Test
127   public void import_project() {
128     UserDto user = db.users().insertUser();
129     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
130     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
131     db.almPats().insert(dto -> {
132       dto.setAlmSettingUuid(almSetting.getUuid());
133       dto.setUserUuid(user.getUuid());
134     });
135     Project project = getGsonBBSProject();
136     Repository repo = getGsonBBSRepo(project);
137     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
138     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(defaultBranchesList);
139
140     Projects.CreateWsResponse response = ws.newRequest()
141       .setParam("almSetting", almSetting.getKey())
142       .setParam("projectKey", "projectKey")
143       .setParam("repositorySlug", "repo-slug")
144       .executeProtobuf(Projects.CreateWsResponse.class);
145
146     Projects.CreateWsResponse.Project result = response.getProject();
147     assertThat(result.getKey()).isEqualTo(GENERATED_PROJECT_KEY);
148     assertThat(result.getName()).isEqualTo(repo.getName());
149
150     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
151     assertThat(projectDto).isPresent();
152     assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get())).isPresent();
153     verify(projectKeyGenerator).generateUniqueProjectKey(requireNonNull(project.getKey()), repo.getSlug());
154   }
155
156   @Test
157   public void import_project_with_NCD_developer_edition_sets_project_NCD() {
158     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.DEVELOPER));
159
160     UserDto user = db.users().insertUser();
161     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
162     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
163     db.almPats().insert(dto -> {
164       dto.setAlmSettingUuid(almSetting.getUuid());
165       dto.setUserUuid(user.getUuid());
166     });
167     Project project = getGsonBBSProject();
168     Repository repo = getGsonBBSRepo(project);
169     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
170     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(defaultBranchesList);
171
172     Projects.CreateWsResponse response = ws.newRequest()
173       .setParam("almSetting", almSetting.getKey())
174       .setParam("projectKey", "projectKey")
175       .setParam("repositorySlug", "repo-slug")
176       .setParam(PARAM_NEW_CODE_DEFINITION_TYPE, "NUMBER_OF_DAYS")
177       .setParam(PARAM_NEW_CODE_DEFINITION_VALUE, "30")
178       .executeProtobuf(Projects.CreateWsResponse.class);
179
180     Projects.CreateWsResponse.Project result = response.getProject();
181     assertThat(result.getKey()).isEqualTo(GENERATED_PROJECT_KEY);
182     assertThat(result.getName()).isEqualTo(repo.getName());
183
184     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
185     assertThat(projectDto).isPresent();
186     assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get())).isPresent();
187     verify(projectKeyGenerator).generateUniqueProjectKey(requireNonNull(project.getKey()), repo.getSlug());
188
189     assertThat(db.getDbClient().newCodePeriodDao().selectByProject(db.getSession(),  projectDto.get().getUuid()))
190       .isPresent()
191       .get()
192       .extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue, NewCodePeriodDto::getBranchUuid)
193       .containsExactly(NUMBER_OF_DAYS, "30", null);
194   }
195
196   @Test
197   public void import_project_with_NCD_community_edition_sets_branch_NCD() {
198     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY));
199
200     UserDto user = db.users().insertUser();
201     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
202     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
203     db.almPats().insert(dto -> {
204       dto.setAlmSettingUuid(almSetting.getUuid());
205       dto.setUserUuid(user.getUuid());
206     });
207     Project project = getGsonBBSProject();
208     Repository repo = getGsonBBSRepo(project);
209     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
210     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(defaultBranchesList);
211
212     Projects.CreateWsResponse response = ws.newRequest()
213       .setParam("almSetting", almSetting.getKey())
214       .setParam("projectKey", "projectKey")
215       .setParam("repositorySlug", "repo-slug")
216       .setParam(PARAM_NEW_CODE_DEFINITION_TYPE, "NUMBER_OF_DAYS")
217       .setParam(PARAM_NEW_CODE_DEFINITION_VALUE, "30")
218       .executeProtobuf(Projects.CreateWsResponse.class);
219
220     Projects.CreateWsResponse.Project result = response.getProject();
221
222     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
223     assertThat(projectDto).isPresent();
224
225
226     String projectUuid = projectDto.get().getUuid();
227     assertThat(db.getDbClient().newCodePeriodDao().selectByBranch(db.getSession(), projectUuid, projectUuid))
228       .isPresent()
229       .get()
230       .extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue, NewCodePeriodDto::getBranchUuid)
231       .containsExactly(NUMBER_OF_DAYS, "30", projectUuid);
232   }
233
234   @Test
235   public void import_project_reference_branch_ncd_no_default_branch() {
236     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.DEVELOPER));
237     when(defaultBranchNameResolver.getEffectiveMainBranchName()).thenReturn("default-branch");
238
239     UserDto user = db.users().insertUser();
240     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
241     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
242     db.almPats().insert(dto -> {
243       dto.setAlmSettingUuid(almSetting.getUuid());
244       dto.setUserUuid(user.getUuid());
245     });
246     Project project = getGsonBBSProject();
247     Repository repo = getGsonBBSRepo(project);
248     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
249     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(new BranchesList());
250
251     Projects.CreateWsResponse response = ws.newRequest()
252       .setParam("almSetting", almSetting.getKey())
253       .setParam("projectKey", "projectKey")
254       .setParam("repositorySlug", "repo-slug")
255       .setParam(PARAM_NEW_CODE_DEFINITION_TYPE, "REFERENCE_BRANCH")
256       .executeProtobuf(Projects.CreateWsResponse.class);
257
258     Projects.CreateWsResponse.Project result = response.getProject();
259
260     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
261     assertThat(projectDto).isPresent();
262
263
264     String projectUuid = projectDto.get().getUuid();
265     assertThat(db.getDbClient().newCodePeriodDao().selectByProject(db.getSession(), projectUuid))
266       .isPresent()
267       .get()
268       .extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue)
269       .containsExactly(REFERENCE_BRANCH, "default-branch");
270   }
271
272   @Test
273   public void import_project_reference_branch_ncd() {
274     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.DEVELOPER));
275
276     UserDto user = db.users().insertUser();
277     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
278     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
279     db.almPats().insert(dto -> {
280       dto.setAlmSettingUuid(almSetting.getUuid());
281       dto.setUserUuid(user.getUuid());
282     });
283     Project project = getGsonBBSProject();
284     Repository repo = getGsonBBSRepo(project);
285     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
286     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(defaultBranchesList);
287
288     Projects.CreateWsResponse response = ws.newRequest()
289       .setParam("almSetting", almSetting.getKey())
290       .setParam("projectKey", "projectKey")
291       .setParam("repositorySlug", "repo-slug")
292       .setParam(PARAM_NEW_CODE_DEFINITION_TYPE, "REFERENCE_BRANCH")
293       .executeProtobuf(Projects.CreateWsResponse.class);
294
295     Projects.CreateWsResponse.Project result = response.getProject();
296
297     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
298     assertThat(projectDto).isPresent();
299
300
301     String projectUuid = projectDto.get().getUuid();
302     assertThat(db.getDbClient().newCodePeriodDao().selectByProject(db.getSession(), projectUuid))
303       .isPresent()
304       .get()
305       .extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue)
306       .containsExactly(REFERENCE_BRANCH, "default");
307   }
308
309   @Test
310   public void fail_project_already_exist() {
311     UserDto user = db.users().insertUser();
312     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
313     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
314     db.almPats().insert(dto -> {
315       dto.setAlmSettingUuid(almSetting.getUuid());
316       dto.setUserUuid(user.getUuid());
317     });
318     Project project = getGsonBBSProject();
319     Repository repo = getGsonBBSRepo(project);
320     db.components().insertPublicProject(p -> p.setKey(GENERATED_PROJECT_KEY)).getMainBranchComponent();
321
322     assertThatThrownBy(() -> {
323       when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
324       when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(defaultBranchesList);
325
326       ws.newRequest()
327         .setParam("almSetting", almSetting.getKey())
328         .setParam("projectKey", "projectKey")
329         .setParam("repositorySlug", "repo-slug")
330         .execute();
331     })
332       .isInstanceOf(BadRequestException.class)
333       .hasMessage("Could not create Project with key: \"%s\". A similar key already exists: \"%s\"", GENERATED_PROJECT_KEY, GENERATED_PROJECT_KEY);
334   }
335
336   @Test
337   public void fail_when_not_logged_in() {
338     assertThatThrownBy(() -> {
339       ws.newRequest()
340         .setParam("almSetting", "sdgfdshfjztutz")
341         .setParam("projectKey", "projectKey")
342         .setParam("repositorySlug", "repo-slug")
343         .execute();
344     })
345       .isInstanceOf(UnauthorizedException.class);
346   }
347
348   @Test
349   public void fail_when_missing_project_creator_permission() {
350     UserDto user = db.users().insertUser();
351     userSession.logIn(user).addPermission(SCAN);
352
353     assertThatThrownBy(() -> {
354       ws.newRequest()
355         .setParam("almSetting", "sdgfdshfjztutz")
356         .setParam("projectKey", "projectKey")
357         .setParam("repositorySlug", "repo-slug")
358         .execute();
359     })
360       .isInstanceOf(ForbiddenException.class)
361       .hasMessage("Insufficient privileges");
362   }
363
364   @Test
365   public void check_pat_is_missing() {
366     UserDto user = db.users().insertUser();
367     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
368     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
369
370     assertThatThrownBy(() -> {
371       ws.newRequest()
372         .setParam("almSetting", almSetting.getKey())
373         .execute();
374     })
375       .isInstanceOf(IllegalArgumentException.class)
376       .hasMessage("personal access token for '" + almSetting.getKey() + "' is missing");
377   }
378
379   @Test
380   public void fail_check_alm_setting_not_found() {
381     UserDto user = db.users().insertUser();
382     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
383     AlmPatDto almPatDto = newAlmPatDto();
384     db.getDbClient().almPatDao().insert(db.getSession(), almPatDto, user.getLogin(), null);
385
386     assertThatThrownBy(() -> {
387       ws.newRequest()
388         .setParam("almSetting", "testKey")
389         .execute();
390     })
391       .isInstanceOf(NotFoundException.class)
392       .hasMessage("DevOps Platform Setting 'testKey' not found");
393   }
394
395   @Test
396   public void fail_when_no_creation_project_permission() {
397     UserDto user = db.users().insertUser();
398     userSession.logIn(user);
399
400     assertThatThrownBy(() -> {
401       ws.newRequest()
402         .setParam("almSetting", "anyvalue")
403         .execute();
404     })
405       .isInstanceOf(ForbiddenException.class)
406       .hasMessage("Insufficient privileges");
407   }
408
409   @Test
410   public void handle_givenNoDefaultBranchFound_doNotUpdateDefaultBranchName() {
411     BranchesList branchesList = new BranchesList();
412     Branch branch = new Branch("not_a_master", false);
413     branchesList.addBranch(branch);
414
415     UserDto user = db.users().insertUser();
416     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
417     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
418     db.almPats().insert(dto -> {
419       dto.setAlmSettingUuid(almSetting.getUuid());
420       dto.setUserUuid(user.getUuid());
421     });
422     Project project = getGsonBBSProject();
423     Repository repo = getGsonBBSRepo(project);
424     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
425     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(branchesList);
426
427     Projects.CreateWsResponse response = ws.newRequest()
428       .setParam("almSetting", almSetting.getKey())
429       .setParam("projectKey", "projectKey")
430       .setParam("repositorySlug", "repo-slug")
431       .executeProtobuf(Projects.CreateWsResponse.class);
432
433     Projects.CreateWsResponse.Project result = response.getProject();
434
435     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
436
437     Collection<BranchDto> branchDtos = db.getDbClient().branchDao().selectByProject(db.getSession(), projectDto.get());
438     List<BranchDto> collect = branchDtos.stream().filter(BranchDto::isMain).toList();
439     String mainBranchName = collect.iterator().next().getKey();
440     assertThat(mainBranchName).isEqualTo(DEFAULT_MAIN_BRANCH_NAME);
441   }
442
443   @Test
444   public void handle_givenDefaultBranchNamedDefault_updateDefaultBranchNameToDefault() {
445     BranchesList branchesList = new BranchesList();
446     Branch branch = new Branch("default", true);
447     branchesList.addBranch(branch);
448
449     UserDto user = db.users().insertUser();
450     userSession.logIn(user).addPermission(PROVISION_PROJECTS);
451     AlmSettingDto almSetting = db.almSettings().insertGitHubAlmSetting();
452     db.almPats().insert(dto -> {
453       dto.setAlmSettingUuid(almSetting.getUuid());
454       dto.setUserUuid(user.getUuid());
455     });
456     Project project = getGsonBBSProject();
457     Repository repo = getGsonBBSRepo(project);
458     when(bitbucketServerRestClient.getRepo(any(), any(), any(), any())).thenReturn(repo);
459     when(bitbucketServerRestClient.getBranches(any(), any(), any(), any())).thenReturn(branchesList);
460
461     Projects.CreateWsResponse response = ws.newRequest()
462       .setParam("almSetting", almSetting.getKey())
463       .setParam("projectKey", "projectKey")
464       .setParam("repositorySlug", "repo-slug")
465       .executeProtobuf(Projects.CreateWsResponse.class);
466
467     Projects.CreateWsResponse.Project result = response.getProject();
468
469     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
470
471     Collection<BranchDto> branchDtos = db.getDbClient().branchDao().selectByProject(db.getSession(), projectDto.get());
472     List<BranchDto> collect = branchDtos.stream().filter(BranchDto::isMain).toList();
473     String mainBranchName = collect.iterator().next().getKey();
474     assertThat(mainBranchName).isEqualTo("default");
475   }
476
477   @Test
478   public void definition() {
479     WebService.Action def = ws.getDef();
480
481     assertThat(def.since()).isEqualTo("8.2");
482     assertThat(def.isPost()).isTrue();
483     assertThat(def.params())
484       .extracting(WebService.Param::key, WebService.Param::isRequired)
485       .containsExactlyInAnyOrder(
486         tuple("almSetting", true),
487         tuple("repositorySlug", true),
488         tuple("projectKey", true),
489         tuple(PARAM_NEW_CODE_DEFINITION_TYPE, false),
490         tuple(PARAM_NEW_CODE_DEFINITION_VALUE, false));
491   }
492
493   private Repository getGsonBBSRepo(Project project) {
494     Repository bbsResult = new Repository();
495     bbsResult.setProject(project);
496     bbsResult.setSlug(randomAlphanumeric(5));
497     bbsResult.setName(randomAlphanumeric(5));
498     bbsResult.setId(nextLong(100));
499     return bbsResult;
500   }
501
502   private Project getGsonBBSProject() {
503     return new Project()
504       .setKey(randomAlphanumeric(5))
505       .setId(nextLong(100))
506       .setName(randomAlphanumeric(5));
507   }
508
509 }