]> source.dussan.org Git - sonarqube.git/blob
df056b47dd6f41aa92cbe6255763c93120a5b6f3
[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.github;
21
22 import java.util.Optional;
23 import org.junit.Before;
24 import org.junit.Rule;
25 import org.junit.Test;
26 import org.mockito.ArgumentCaptor;
27 import org.sonar.alm.client.github.GithubApplicationClient;
28 import org.sonar.alm.client.github.GithubApplicationClientImpl;
29 import org.sonar.api.server.ws.WebService;
30 import org.sonar.api.utils.System2;
31 import org.sonar.auth.github.GitHubSettings;
32 import org.sonar.core.i18n.I18n;
33 import org.sonar.core.platform.EditionProvider;
34 import org.sonar.core.platform.PlatformEditionProvider;
35 import org.sonar.core.util.SequenceUuidFactory;
36 import org.sonar.db.DbSession;
37 import org.sonar.db.DbTester;
38 import org.sonar.db.alm.setting.AlmSettingDto;
39 import org.sonar.db.component.BranchDto;
40 import org.sonar.db.entity.EntityDto;
41 import org.sonar.db.newcodeperiod.NewCodePeriodDto;
42 import org.sonar.db.permission.GlobalPermission;
43 import org.sonar.db.project.ProjectDto;
44 import org.sonar.db.user.UserDto;
45 import org.sonar.server.almintegration.ws.ImportHelper;
46 import org.sonar.server.almintegration.ws.ProjectKeyGenerator;
47 import org.sonar.server.component.ComponentUpdater;
48 import org.sonar.server.es.TestIndexers;
49 import org.sonar.server.exceptions.NotFoundException;
50 import org.sonar.server.exceptions.UnauthorizedException;
51 import org.sonar.server.favorite.FavoriteUpdater;
52 import org.sonar.server.newcodeperiod.NewCodeDefinitionResolver;
53 import org.sonar.server.permission.PermissionTemplateService;
54 import org.sonar.server.project.DefaultBranchNameResolver;
55 import org.sonar.server.project.ProjectDefaultVisibility;
56 import org.sonar.server.project.Visibility;
57 import org.sonar.server.tester.UserSessionRule;
58 import org.sonar.server.ws.TestRequest;
59 import org.sonar.server.ws.WsActionTester;
60 import org.sonarqube.ws.Projects;
61
62 import static org.assertj.core.api.Assertions.assertThat;
63 import static org.assertj.core.api.Assertions.assertThatThrownBy;
64 import static org.assertj.core.api.Assertions.tuple;
65 import static org.mockito.ArgumentMatchers.any;
66 import static org.mockito.ArgumentMatchers.eq;
67 import static org.mockito.Mockito.mock;
68 import static org.mockito.Mockito.never;
69 import static org.mockito.Mockito.verify;
70 import static org.mockito.Mockito.when;
71 import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME;
72 import static org.sonar.db.newcodeperiod.NewCodePeriodType.NUMBER_OF_DAYS;
73 import static org.sonar.db.newcodeperiod.NewCodePeriodType.REFERENCE_BRANCH;
74 import static org.sonar.server.almintegration.ws.ImportHelper.PARAM_ALM_SETTING;
75 import static org.sonar.server.almintegration.ws.github.ImportGithubProjectAction.PARAM_ORGANIZATION;
76 import static org.sonar.server.almintegration.ws.github.ImportGithubProjectAction.PARAM_REPOSITORY_KEY;
77 import static org.sonar.server.tester.UserSessionRule.standalone;
78 import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NEW_CODE_DEFINITION_TYPE;
79 import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_NEW_CODE_DEFINITION_VALUE;
80
81 public class ImportGithubProjectActionIT {
82
83   private static final String PROJECT_KEY_NAME = "PROJECT_NAME";
84
85   @Rule
86   public UserSessionRule userSession = standalone();
87
88   private final System2 system2 = mock(System2.class);
89   private final GithubApplicationClientImpl appClient = mock(GithubApplicationClientImpl.class);
90   private final DefaultBranchNameResolver defaultBranchNameResolver = mock(DefaultBranchNameResolver.class);
91
92   @Rule
93   public DbTester db = DbTester.create(system2);
94   private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
95   private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), System2.INSTANCE,
96     permissionTemplateService, new FavoriteUpdater(db.getDbClient()), new TestIndexers(), new SequenceUuidFactory(),
97     defaultBranchNameResolver, true);
98
99   private final ImportHelper importHelper = new ImportHelper(db.getDbClient(), userSession);
100   private final ProjectKeyGenerator projectKeyGenerator = mock(ProjectKeyGenerator.class);
101   private final ProjectDefaultVisibility projectDefaultVisibility = mock(ProjectDefaultVisibility.class);
102   private PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class);
103
104   private final GitHubSettings gitHubSettings = mock(GitHubSettings.class);
105   private NewCodeDefinitionResolver newCodeDefinitionResolver = new NewCodeDefinitionResolver(db.getDbClient(), editionProvider);
106
107   private final WsActionTester ws = new WsActionTester(new ImportGithubProjectAction(db.getDbClient(), userSession,
108     projectDefaultVisibility, appClient, componentUpdater, importHelper, projectKeyGenerator, newCodeDefinitionResolver,
109     defaultBranchNameResolver, gitHubSettings));
110
111   @Before
112   public void before() {
113     when(projectDefaultVisibility.get(any())).thenReturn(Visibility.PRIVATE);
114     when(defaultBranchNameResolver.getEffectiveMainBranchName()).thenReturn(DEFAULT_MAIN_BRANCH_NAME);
115   }
116
117   @Test
118   public void importProject_ifProjectWithSameNameDoesNotExist_importSucceed() {
119     AlmSettingDto githubAlmSetting = setupAlm();
120     db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));
121
122     GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false,
123       "octocat/" + PROJECT_KEY_NAME,
124       "https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "default-branch");
125     when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
126     when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
127
128     Projects.CreateWsResponse response = ws.newRequest()
129       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
130       .setParam(PARAM_ORGANIZATION, "octocat")
131       .setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME)
132       .executeProtobuf(Projects.CreateWsResponse.class);
133
134     Projects.CreateWsResponse.Project result = response.getProject();
135     assertThat(result.getKey()).isEqualTo(PROJECT_KEY_NAME);
136     assertThat(result.getName()).isEqualTo(repository.getName());
137
138     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
139     assertThat(projectDto).isPresent();
140     assertThat(db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get())).isPresent();
141     Optional<BranchDto> mainBranch = db.getDbClient().branchDao().selectByProject(db.getSession(), projectDto.get()).stream().filter(BranchDto::isMain).findAny();
142     assertThat(mainBranch).isPresent();
143     assertThat(mainBranch.get().getKey()).isEqualTo("default-branch");
144
145   }
146
147   @Test
148   public void importProject_withNCD_developer_edition() {
149     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.DEVELOPER));
150
151     AlmSettingDto githubAlmSetting = setupAlm();
152     db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));
153
154     GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false,
155       "octocat/" + PROJECT_KEY_NAME,
156       "https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "default-branch");
157     when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
158     when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
159
160     Projects.CreateWsResponse response = ws.newRequest()
161       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
162       .setParam(PARAM_ORGANIZATION, "octocat")
163       .setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME)
164       .setParam(PARAM_NEW_CODE_DEFINITION_TYPE, "NUMBER_OF_DAYS")
165       .setParam(PARAM_NEW_CODE_DEFINITION_VALUE, "30")
166       .executeProtobuf(Projects.CreateWsResponse.class);
167
168     Projects.CreateWsResponse.Project result = response.getProject();
169
170     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
171     assertThat(projectDto).isPresent();
172
173     assertThat(db.getDbClient().newCodePeriodDao().selectByProject(db.getSession(),  projectDto.get().getUuid()))
174       .isPresent()
175       .get()
176       .extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue, NewCodePeriodDto::getBranchUuid)
177       .containsExactly(NUMBER_OF_DAYS, "30", null);
178   }
179
180   @Test
181   public void importProject_withNCD_community_edition() {
182     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.COMMUNITY));
183
184     AlmSettingDto githubAlmSetting = setupAlm();
185     db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));
186
187     GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false,
188       "octocat/" + PROJECT_KEY_NAME,
189       "https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "default-branch");
190     when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
191     when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
192
193     Projects.CreateWsResponse response = ws.newRequest()
194       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
195       .setParam(PARAM_ORGANIZATION, "octocat")
196       .setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME)
197       .setParam(PARAM_NEW_CODE_DEFINITION_TYPE, "NUMBER_OF_DAYS")
198       .setParam(PARAM_NEW_CODE_DEFINITION_VALUE, "30")
199       .executeProtobuf(Projects.CreateWsResponse.class);
200
201     Projects.CreateWsResponse.Project result = response.getProject();
202
203     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
204     assertThat(projectDto).isPresent();
205     BranchDto branchDto = db.getDbClient().branchDao().selectMainBranchByProjectUuid(db.getSession(), projectDto.get().getUuid()).orElseThrow();
206
207     String projectUuid = projectDto.get().getUuid();
208     assertThat(db.getDbClient().newCodePeriodDao().selectByBranch(db.getSession(), projectUuid, branchDto.getUuid()))
209       .isPresent()
210       .get()
211       .extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue, NewCodePeriodDto::getBranchUuid)
212       .containsExactly(NUMBER_OF_DAYS, "30", branchDto.getUuid());
213   }
214
215   @Test
216   public void importProject_reference_branch_ncd_no_default_branch() {
217     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.DEVELOPER));
218     when(defaultBranchNameResolver.getEffectiveMainBranchName()).thenReturn("default-branch");
219
220     AlmSettingDto githubAlmSetting = setupAlm();
221     db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));
222
223     GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false,
224       "octocat/" + PROJECT_KEY_NAME,
225       "https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, null);
226     when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
227     when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
228
229     Projects.CreateWsResponse response = ws.newRequest()
230       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
231       .setParam(PARAM_ORGANIZATION, "octocat")
232       .setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME)
233       .setParam(PARAM_NEW_CODE_DEFINITION_TYPE, "reference_branch")
234       .executeProtobuf(Projects.CreateWsResponse.class);
235
236     Projects.CreateWsResponse.Project result = response.getProject();
237
238     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
239     assertThat(projectDto).isPresent();
240
241     assertThat(db.getDbClient().newCodePeriodDao().selectByProject(db.getSession(), projectDto.get().getUuid()))
242       .isPresent()
243       .get()
244       .extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue)
245       .containsExactly(REFERENCE_BRANCH, "default-branch");
246   }
247
248   @Test
249   public void importProject_reference_branch_ncd() {
250     when(editionProvider.get()).thenReturn(Optional.of(EditionProvider.Edition.DEVELOPER));
251
252     AlmSettingDto githubAlmSetting = setupAlm();
253     db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));
254
255     GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false,
256       "octocat/" + PROJECT_KEY_NAME,
257       "https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "mainBranch");
258     when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
259     when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
260
261     Projects.CreateWsResponse response = ws.newRequest()
262       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
263       .setParam(PARAM_ORGANIZATION, "octocat")
264       .setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME)
265       .setParam(PARAM_NEW_CODE_DEFINITION_TYPE, "reference_branch")
266       .executeProtobuf(Projects.CreateWsResponse.class);
267
268     Projects.CreateWsResponse.Project result = response.getProject();
269
270     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
271     assertThat(projectDto).isPresent();
272
273     assertThat(db.getDbClient().newCodePeriodDao().selectByProject(db.getSession(), projectDto.get().getUuid()))
274       .isPresent()
275       .get()
276       .extracting(NewCodePeriodDto::getType, NewCodePeriodDto::getValue)
277       .containsExactly(REFERENCE_BRANCH, "mainBranch");
278   }
279
280   @Test
281   public void importProject_ifProjectWithSameNameAlreadyExists_importSucceed() {
282     AlmSettingDto githubAlmSetting = setupAlm();
283     db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));
284     db.components().insertPublicProject(p -> p.setKey("Hello-World")).getMainBranchComponent();
285
286     GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, "Hello-World", false, "Hello-World",
287       "https://github.sonarsource.com/api/v3/repos/octocat/Hello-World", "main");
288     when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
289     when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
290
291     Projects.CreateWsResponse response = ws.newRequest()
292       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
293       .setParam(PARAM_ORGANIZATION, "octocat")
294       .setParam(PARAM_REPOSITORY_KEY, "Hello-World")
295       .executeProtobuf(Projects.CreateWsResponse.class);
296
297     Projects.CreateWsResponse.Project result = response.getProject();
298     assertThat(result.getKey()).isEqualTo(PROJECT_KEY_NAME);
299     assertThat(result.getName()).isEqualTo(repository.getName());
300   }
301
302   @Test
303   public void importProject_whenGithubProvisioningIsDisabled_shouldApplyPermissionTemplate() {
304     AlmSettingDto githubAlmSetting = setupAlm();
305     db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));
306
307     GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false,
308       "octocat/" + PROJECT_KEY_NAME,
309       "https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "default-branch");
310     when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
311     when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
312     when(gitHubSettings.isProvisioningEnabled()).thenReturn(false);
313
314     ws.newRequest()
315       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
316       .setParam(PARAM_ORGANIZATION, "octocat")
317       .setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME)
318       .executeProtobuf(Projects.CreateWsResponse.class);
319
320     ArgumentCaptor<EntityDto> projectDtoArgumentCaptor = ArgumentCaptor.forClass(EntityDto.class);
321     verify(permissionTemplateService).applyDefaultToNewComponent(any(DbSession.class), projectDtoArgumentCaptor.capture(), eq(userSession.getUuid()));
322     String projectKey = projectDtoArgumentCaptor.getValue().getKey();
323     assertThat(projectKey).isEqualTo(PROJECT_KEY_NAME);
324
325   }
326
327   @Test
328   public void importProject_whenGithubProvisioningIsEnabled_shouldNotApplyPermissionTemplate() {
329     AlmSettingDto githubAlmSetting = setupAlm();
330     db.almPats().insert(p -> p.setAlmSettingUuid(githubAlmSetting.getUuid()).setUserUuid(userSession.getUuid()));
331
332     GithubApplicationClient.Repository repository = new GithubApplicationClient.Repository(1L, PROJECT_KEY_NAME, false,
333       "octocat/" + PROJECT_KEY_NAME,
334       "https://github.sonarsource.com/api/v3/repos/octocat/" + PROJECT_KEY_NAME, "default-branch");
335     when(appClient.getRepository(any(), any(), any(), any())).thenReturn(Optional.of(repository));
336     when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn(PROJECT_KEY_NAME);
337     when(gitHubSettings.isProvisioningEnabled()).thenReturn(true);
338
339     ws.newRequest()
340       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
341       .setParam(PARAM_ORGANIZATION, "octocat")
342       .setParam(PARAM_REPOSITORY_KEY, "octocat/" + PROJECT_KEY_NAME)
343       .executeProtobuf(Projects.CreateWsResponse.class);
344
345     verify(permissionTemplateService, never()).applyDefaultToNewComponent(any(), any(), any());
346
347   }
348
349   @Test
350   public void fail_when_not_logged_in() {
351     TestRequest request = ws.newRequest()
352       .setParam(PARAM_ALM_SETTING, "asdfghjkl")
353       .setParam(PARAM_ORGANIZATION, "test")
354       .setParam(PARAM_REPOSITORY_KEY, "test/repo");
355     assertThatThrownBy(request::execute)
356       .isInstanceOf(UnauthorizedException.class);
357   }
358
359   @Test
360   public void fail_when_missing_create_project_permission() {
361     TestRequest request = ws.newRequest();
362     assertThatThrownBy(request::execute)
363       .isInstanceOf(UnauthorizedException.class);
364   }
365
366   @Test
367   public void fail_when_almSetting_does_not_exist() {
368     UserDto user = db.users().insertUser();
369     userSession.logIn(user).addPermission(GlobalPermission.PROVISION_PROJECTS);
370
371     TestRequest request = ws.newRequest()
372       .setParam(PARAM_ALM_SETTING, "unknown")
373       .setParam(PARAM_ORGANIZATION, "test")
374       .setParam(PARAM_REPOSITORY_KEY, "test/repo");
375     assertThatThrownBy(request::execute)
376       .isInstanceOf(NotFoundException.class)
377       .hasMessage("DevOps Platform Setting 'unknown' not found");
378   }
379
380   @Test
381   public void fail_when_personal_access_token_doesnt_exist() {
382     AlmSettingDto githubAlmSetting = setupAlm();
383
384     TestRequest request = ws.newRequest()
385       .setParam(PARAM_ALM_SETTING, githubAlmSetting.getKey())
386       .setParam(PARAM_ORGANIZATION, "test")
387       .setParam(PARAM_REPOSITORY_KEY, "test/repo");
388     assertThatThrownBy(request::execute)
389       .isInstanceOf(IllegalArgumentException.class)
390       .hasMessage("No personal access token found");
391   }
392
393   @Test
394   public void definition() {
395     WebService.Action def = ws.getDef();
396
397     assertThat(def.since()).isEqualTo("8.4");
398     assertThat(def.isPost()).isTrue();
399     assertThat(def.params())
400       .extracting(WebService.Param::key, WebService.Param::isRequired)
401       .containsExactlyInAnyOrder(
402         tuple(PARAM_ALM_SETTING, true),
403         tuple(PARAM_ORGANIZATION, true),
404         tuple(PARAM_REPOSITORY_KEY, true),
405         tuple(PARAM_NEW_CODE_DEFINITION_TYPE, false),
406         tuple(PARAM_NEW_CODE_DEFINITION_VALUE, false));
407   }
408
409   private AlmSettingDto setupAlm() {
410     UserDto user = db.users().insertUser();
411     userSession.logIn(user).addPermission(GlobalPermission.PROVISION_PROJECTS);
412
413     return db.almSettings().insertGitHubAlmSetting(alm -> alm.setClientId("client_123").setClientSecret("client_secret_123"));
414   }
415 }