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