You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GithubProjectCreatorTest.java 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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.github;
  21. import java.util.Arrays;
  22. import java.util.Collection;
  23. import java.util.Optional;
  24. import java.util.Set;
  25. import org.junit.jupiter.api.BeforeEach;
  26. import org.junit.jupiter.api.Test;
  27. import org.junit.jupiter.api.extension.ExtendWith;
  28. import org.mockito.Answers;
  29. import org.mockito.ArgumentCaptor;
  30. import org.mockito.Captor;
  31. import org.mockito.Mock;
  32. import org.mockito.junit.jupiter.MockitoExtension;
  33. import org.sonar.alm.client.github.GithubPermissionConverter;
  34. import org.sonar.api.resources.Qualifiers;
  35. import org.sonar.api.web.UserRole;
  36. import org.sonar.auth.github.AppInstallationToken;
  37. import org.sonar.auth.github.GitHubSettings;
  38. import org.sonar.auth.github.GsonRepositoryCollaborator;
  39. import org.sonar.auth.github.GsonRepositoryPermissions;
  40. import org.sonar.auth.github.GsonRepositoryTeam;
  41. import org.sonar.auth.github.client.GithubApplicationClient;
  42. import org.sonar.auth.github.security.AccessToken;
  43. import org.sonar.db.DbClient;
  44. import org.sonar.db.alm.setting.ALM;
  45. import org.sonar.db.alm.setting.AlmSettingDto;
  46. import org.sonar.db.alm.setting.ProjectAlmSettingDao;
  47. import org.sonar.db.alm.setting.ProjectAlmSettingDto;
  48. import org.sonar.db.component.BranchDto;
  49. import org.sonar.db.project.CreationMethod;
  50. import org.sonar.db.project.ProjectDto;
  51. import org.sonar.db.provisioning.GithubPermissionsMappingDto;
  52. import org.sonar.db.user.GroupDto;
  53. import org.sonar.server.common.almintegration.ProjectKeyGenerator;
  54. import org.sonar.server.common.almsettings.DevOpsProjectDescriptor;
  55. import org.sonar.server.common.component.ComponentCreationParameters;
  56. import org.sonar.server.common.component.ComponentUpdater;
  57. import org.sonar.server.common.component.NewComponent;
  58. import org.sonar.server.common.permission.PermissionUpdater;
  59. import org.sonar.server.common.permission.UserPermissionChange;
  60. import org.sonar.server.common.project.ProjectCreator;
  61. import org.sonar.server.component.ComponentCreationData;
  62. import org.sonar.server.management.ManagedProjectService;
  63. import org.sonar.server.permission.PermissionService;
  64. import org.sonar.server.permission.PermissionServiceImpl;
  65. import org.sonar.server.project.ProjectDefaultVisibility;
  66. import org.sonar.server.project.Visibility;
  67. import org.sonar.server.user.UserSession;
  68. import static java.util.Objects.requireNonNull;
  69. import static java.util.stream.Collectors.toSet;
  70. import static org.assertj.core.api.Assertions.assertThat;
  71. import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
  72. import static org.mockito.ArgumentMatchers.any;
  73. import static org.mockito.ArgumentMatchers.eq;
  74. import static org.mockito.Mockito.lenient;
  75. import static org.mockito.Mockito.mock;
  76. import static org.mockito.Mockito.verify;
  77. import static org.mockito.Mockito.when;
  78. import static org.sonar.db.project.CreationMethod.ALM_IMPORT_API;
  79. import static org.sonar.db.project.CreationMethod.SCANNER_API_DEVOPS_AUTO_CONFIG;
  80. @ExtendWith(MockitoExtension.class)
  81. class GithubProjectCreatorTest {
  82. private static final String ORGANIZATION_NAME = "orga2";
  83. private static final String REPOSITORY_NAME = "repo1";
  84. private static final String MAIN_BRANCH_NAME = "defaultBranch";
  85. private static final DevOpsProjectDescriptor DEVOPS_PROJECT_DESCRIPTOR = new DevOpsProjectDescriptor(ALM.GITHUB, "http://api.com", ORGANIZATION_NAME + "/" + REPOSITORY_NAME, null);
  86. private static final String ALM_SETTING_KEY = "github_config_1";
  87. private static final String USER_LOGIN = "userLogin";
  88. private static final String USER_UUID = "userUuid";
  89. @Mock(answer = Answers.RETURNS_DEEP_STUBS)
  90. private DbClient dbClient;
  91. @Mock
  92. private GithubApplicationClient githubApplicationClient;
  93. @Mock
  94. private GithubPermissionConverter githubPermissionConverter;
  95. @Mock
  96. private ProjectKeyGenerator projectKeyGenerator;
  97. @Mock
  98. private ComponentUpdater componentUpdater;
  99. @Mock
  100. private GithubProjectCreationParameters githubProjectCreationParameters;
  101. @Mock
  102. private AccessToken devOpsAppInstallationToken;
  103. @Mock
  104. private AppInstallationToken authAppInstallationToken;
  105. @Mock
  106. private UserSession userSession;
  107. @Mock
  108. private AlmSettingDto almSettingDto;
  109. private final PermissionService permissionService = new PermissionServiceImpl(mock());
  110. @Mock
  111. private PermissionUpdater<UserPermissionChange> permissionUpdater;
  112. @Mock
  113. private ManagedProjectService managedProjectService;
  114. @Mock(answer = Answers.RETURNS_DEEP_STUBS)
  115. private ProjectDefaultVisibility projectDefaultVisibility;
  116. private final GitHubSettings gitHubSettings = mock();
  117. private GithubProjectCreator githubProjectCreator;
  118. @Captor
  119. ArgumentCaptor<ComponentCreationParameters> componentCreationParametersCaptor;
  120. @Captor
  121. ArgumentCaptor<ProjectAlmSettingDto> projectAlmSettingDtoCaptor;
  122. @BeforeEach
  123. void setup() {
  124. lenient().when(userSession.getLogin()).thenReturn(USER_LOGIN);
  125. lenient().when(userSession.getUuid()).thenReturn(USER_UUID);
  126. lenient().when(almSettingDto.getUrl()).thenReturn(DEVOPS_PROJECT_DESCRIPTOR.url());
  127. lenient().when(almSettingDto.getKey()).thenReturn(ALM_SETTING_KEY);
  128. when(githubProjectCreationParameters.devOpsProjectDescriptor()).thenReturn(DEVOPS_PROJECT_DESCRIPTOR);
  129. when(githubProjectCreationParameters.userSession()).thenReturn(userSession);
  130. when(githubProjectCreationParameters.devOpsAppInstallationToken()).thenReturn(devOpsAppInstallationToken);
  131. when(githubProjectCreationParameters.authAppInstallationToken()).thenReturn(authAppInstallationToken);
  132. when(githubProjectCreationParameters.almSettingDto()).thenReturn(almSettingDto);
  133. ProjectCreator projectCreator = new ProjectCreator(userSession, projectDefaultVisibility, componentUpdater);
  134. githubProjectCreator = new GithubProjectCreator(dbClient, githubApplicationClient, githubPermissionConverter, projectKeyGenerator,
  135. permissionUpdater, permissionService, managedProjectService, projectCreator, githubProjectCreationParameters, gitHubSettings);
  136. }
  137. @Test
  138. void isScanAllowedUsingPermissionsFromDevopsPlatform_whenNoAuthToken_throws() {
  139. when(githubProjectCreationParameters.authAppInstallationToken()).thenReturn(null);
  140. assertThatIllegalStateException().isThrownBy(() -> githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform())
  141. .withMessage("An auth app token is required in case repository permissions checking is necessary.");
  142. }
  143. @Test
  144. void isScanAllowedUsingPermissionsFromDevopsPlatform_whenUserIsNotAGitHubUser_returnsFalse() {
  145. assertThat(githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform()).isFalse();
  146. }
  147. @Test
  148. void isScanAllowedUsingPermissionsFromDevopsPlatform_whenCollaboratorHasDirectAccessButNoScanPermissions_returnsFalse() {
  149. GsonRepositoryCollaborator collaborator1 = mockCollaborator("collaborator1", 1, "role1", "read", "admin");
  150. mockGithubCollaboratorsFromApi(collaborator1);
  151. bindSessionToCollaborator(collaborator1);
  152. assertThat(githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform()).isFalse();
  153. }
  154. @Test
  155. void isScanAllowedUsingPermissionsFromDevopsPlatform_whenCollaboratorHasDirectAccess_returnsTrue() {
  156. GsonRepositoryCollaborator collaborator1 = mockCollaborator("collaborator1", 1, "role1", "read", "admin");
  157. GsonRepositoryCollaborator collaborator2 = mockCollaborator("collaborator2", 2, "role2", "read", "scan");
  158. mockGithubCollaboratorsFromApi(collaborator1, collaborator2);
  159. bindSessionToCollaborator(collaborator2);
  160. assertThat(githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform()).isTrue();
  161. }
  162. @Test
  163. void isScanAllowedUsingPermissionsFromDevopsPlatform_whenAccessViaTeamButNoScanPermissions_returnsFalse() {
  164. GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", "another_perm", UserRole.ADMIN);
  165. mockTeamsFromApi(team2);
  166. bindGroupsToUser(team2.name());
  167. assertThat(githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform()).isFalse();
  168. }
  169. @Test
  170. void isScanAllowedUsingPermissionsFromDevopsPlatform_whenAccessViaTeam_returnsTrue() {
  171. GsonRepositoryTeam team1 = mockGithubTeam("team1", 1, "role1", "read", "another_perm");
  172. GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", "another_perm", UserRole.SCAN);
  173. mockTeamsFromApi(team1, team2);
  174. bindGroupsToUser(team1.name(), team2.name());
  175. assertThat(githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform()).isTrue();
  176. }
  177. @Test
  178. void isScanAllowedUsingPermissionsFromDevopsPlatform_whenAccessViaTeamButUserNotInTeam_returnsFalse() {
  179. GsonRepositoryTeam team1 = mockGithubTeam("team1", 1, "role1", "read", "another_perm");
  180. GsonRepositoryTeam team2 = mockGithubTeam("team2", 2, "role2", "another_perm", UserRole.SCAN);
  181. mockTeamsFromApi(team1, team2);
  182. bindGroupsToUser(team1.name());
  183. assertThat(githubProjectCreator.isScanAllowedUsingPermissionsFromDevopsPlatform()).isFalse();
  184. }
  185. private void bindSessionToCollaborator(GsonRepositoryCollaborator collaborator1) {
  186. UserSession.ExternalIdentity externalIdentity = new UserSession.ExternalIdentity(String.valueOf(collaborator1.id()), collaborator1.name());
  187. when(userSession.getExternalIdentity()).thenReturn(Optional.of(externalIdentity));
  188. }
  189. private GsonRepositoryCollaborator mockCollaborator(String collaboratorLogin, int id, String role1, String... sqPermissions) {
  190. GsonRepositoryCollaborator collaborator = new GsonRepositoryCollaborator(collaboratorLogin, id, role1,
  191. new GsonRepositoryPermissions(false, false, false, false, false));
  192. mockPermissionsConversion(collaborator, sqPermissions);
  193. return collaborator;
  194. }
  195. private void mockGithubCollaboratorsFromApi(GsonRepositoryCollaborator... repositoryCollaborators) {
  196. Set<GsonRepositoryCollaborator> collaborators = Arrays.stream(repositoryCollaborators).collect(toSet());
  197. when(githubApplicationClient.getRepositoryCollaborators(DEVOPS_PROJECT_DESCRIPTOR.url(), authAppInstallationToken, ORGANIZATION_NAME, REPOSITORY_NAME)).thenReturn(
  198. collaborators);
  199. }
  200. private GsonRepositoryTeam mockGithubTeam(String name, int id, String role, String... sqPermissions) {
  201. GsonRepositoryTeam gsonRepositoryTeam = new GsonRepositoryTeam(name, id, name + "slug", role, new GsonRepositoryPermissions(false, false, false, false, false));
  202. mockPermissionsConversion(gsonRepositoryTeam, sqPermissions);
  203. return gsonRepositoryTeam;
  204. }
  205. private void mockTeamsFromApi(GsonRepositoryTeam... repositoryTeams) {
  206. when(githubApplicationClient.getRepositoryTeams(DEVOPS_PROJECT_DESCRIPTOR.url(), authAppInstallationToken, ORGANIZATION_NAME, REPOSITORY_NAME))
  207. .thenReturn(Arrays.stream(repositoryTeams).collect(toSet()));
  208. }
  209. private void mockPermissionsConversion(GsonRepositoryCollaborator collaborator, String... sqPermissions) {
  210. Set<GithubPermissionsMappingDto> githubPermissionsMappingDtos = mockPermissionsMappingsDtos();
  211. lenient().when(githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(githubPermissionsMappingDtos, collaborator.roleName(), collaborator.permissions()))
  212. .thenReturn(Arrays.stream(sqPermissions).collect(toSet()));
  213. }
  214. private void mockPermissionsConversion(GsonRepositoryTeam team, String... sqPermissions) {
  215. Set<GithubPermissionsMappingDto> githubPermissionsMappingDtos = mockPermissionsMappingsDtos();
  216. lenient().when(githubPermissionConverter.toSonarqubeRolesWithFallbackOnRepositoryPermissions(githubPermissionsMappingDtos, team.permission(), team.permissions()))
  217. .thenReturn(Arrays.stream(sqPermissions).collect(toSet()));
  218. }
  219. private Set<GithubPermissionsMappingDto> mockPermissionsMappingsDtos() {
  220. Set<GithubPermissionsMappingDto> githubPermissionsMappingDtos = Set.of(mock(GithubPermissionsMappingDto.class));
  221. when(dbClient.githubPermissionsMappingDao().findAll(any())).thenReturn(githubPermissionsMappingDtos);
  222. return githubPermissionsMappingDtos;
  223. }
  224. private void bindGroupsToUser(String... groupNames) {
  225. Set<GroupDto> groupDtos = Arrays.stream(groupNames)
  226. .map(groupName -> new GroupDto().setName(ORGANIZATION_NAME + "/" + groupName).setUuid("uuid_" + groupName))
  227. .collect(toSet());
  228. when(userSession.getGroups()).thenReturn(groupDtos);
  229. }
  230. @Test
  231. void createProjectAndBindToDevOpsPlatform_whenRepoNotFound_throws() {
  232. assertThatIllegalStateException().isThrownBy(
  233. () -> githubProjectCreator.createProjectAndBindToDevOpsPlatform(mock(), SCANNER_API_DEVOPS_AUTO_CONFIG, false, null, null))
  234. .withMessage("Impossible to find the repository 'orga2/repo1' on GitHub, using the devops config " + ALM_SETTING_KEY);
  235. }
  236. @Test
  237. void createProjectAndBindToDevOpsPlatformFromScanner_whenRepoFoundOnGitHub_successfullyCreatesProject() {
  238. // given
  239. mockGitHubRepository();
  240. ComponentCreationData componentCreationData = mockProjectCreation("generated_orga2/repo1");
  241. ProjectAlmSettingDao projectAlmSettingDao = mock();
  242. when(dbClient.projectAlmSettingDao()).thenReturn(projectAlmSettingDao);
  243. when(projectDefaultVisibility.get(any())).thenReturn(Visibility.PRIVATE);
  244. // when
  245. ComponentCreationData actualComponentCreationData = githubProjectCreator.createProjectAndBindToDevOpsPlatform(dbClient.openSession(true),
  246. SCANNER_API_DEVOPS_AUTO_CONFIG, false, null, null);
  247. // then
  248. assertThat(actualComponentCreationData).isEqualTo(componentCreationData);
  249. ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue();
  250. assertComponentCreationParametersContainsCorrectInformation(componentCreationParameters, "generated_orga2/repo1", SCANNER_API_DEVOPS_AUTO_CONFIG);
  251. assertThat(componentCreationParameters.isManaged()).isFalse();
  252. assertThat(componentCreationParameters.newComponent().isPrivate()).isTrue();
  253. verify(projectAlmSettingDao).insertOrUpdate(any(), projectAlmSettingDtoCaptor.capture(), eq(ALM_SETTING_KEY), eq(REPOSITORY_NAME), eq("generated_orga2/repo1"));
  254. ProjectAlmSettingDto projectAlmSettingDto = projectAlmSettingDtoCaptor.getValue();
  255. assertAlmSettingsDtoContainsCorrectInformation(almSettingDto, requireNonNull(componentCreationData.projectDto()), projectAlmSettingDto);
  256. }
  257. @Test
  258. void createProjectAndBindToDevOpsPlatformFromScanner_whenRepoFoundOnGitHubAndVisibilitySynchronizationEnabled_successfullyCreatesProjectAndSetsVisibility() {
  259. // given
  260. mockPublicGithubRepository();
  261. ComponentCreationData componentCreationData = mockProjectCreation("generated_orga2/repo1");
  262. ProjectAlmSettingDao projectAlmSettingDao = mock();
  263. when(dbClient.projectAlmSettingDao()).thenReturn(projectAlmSettingDao);
  264. when(gitHubSettings.isProvisioningEnabled()).thenReturn(true);
  265. when(gitHubSettings.isProjectVisibilitySynchronizationActivated()).thenReturn(true);
  266. // when
  267. ComponentCreationData actualComponentCreationData = githubProjectCreator.createProjectAndBindToDevOpsPlatform(dbClient.openSession(true),
  268. SCANNER_API_DEVOPS_AUTO_CONFIG, false, null, null);
  269. // then
  270. assertThat(actualComponentCreationData).isEqualTo(componentCreationData);
  271. ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue();
  272. assertThat(componentCreationParameters.newComponent().isPrivate()).isFalse();
  273. }
  274. @Test
  275. void createProjectAndBindToDevOpsPlatformFromScanner_whenRepoFoundOnGitHubAndVisibilitySynchronizationDisabled_successfullyCreatesProjectAndMakesProjectPrivate() {
  276. // given
  277. mockGitHubRepository();
  278. ComponentCreationData componentCreationData = mockProjectCreation("generated_orga2/repo1");
  279. ProjectAlmSettingDao projectAlmSettingDao = mock();
  280. when(dbClient.projectAlmSettingDao()).thenReturn(projectAlmSettingDao);
  281. when(gitHubSettings.isProvisioningEnabled()).thenReturn(true);
  282. when(gitHubSettings.isProjectVisibilitySynchronizationActivated()).thenReturn(false);
  283. // when
  284. ComponentCreationData actualComponentCreationData = githubProjectCreator.createProjectAndBindToDevOpsPlatform(dbClient.openSession(true),
  285. SCANNER_API_DEVOPS_AUTO_CONFIG, false, null, null);
  286. // then
  287. assertThat(actualComponentCreationData).isEqualTo(componentCreationData);
  288. ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue();
  289. assertThat(componentCreationParameters.newComponent().isPrivate()).isTrue();
  290. }
  291. @Test
  292. void createProjectAndBindToDevOpsPlatformFromApi_whenRepoFoundOnGitHub_successfullyCreatesProject() {
  293. // given
  294. String projectKey = "customProjectKey";
  295. mockGitHubRepository();
  296. ComponentCreationData componentCreationData = mockProjectCreation(projectKey);
  297. ProjectAlmSettingDao projectAlmSettingDao = mock();
  298. when(dbClient.projectAlmSettingDao()).thenReturn(projectAlmSettingDao);
  299. when(projectDefaultVisibility.get(any())).thenReturn(Visibility.PRIVATE);
  300. // when
  301. ComponentCreationData actualComponentCreationData = githubProjectCreator.createProjectAndBindToDevOpsPlatform(dbClient.openSession(true), ALM_IMPORT_API, false, projectKey,
  302. null);
  303. // then
  304. assertThat(actualComponentCreationData).isEqualTo(componentCreationData);
  305. ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue();
  306. assertComponentCreationParametersContainsCorrectInformation(componentCreationParameters, projectKey, ALM_IMPORT_API);
  307. assertThat(componentCreationParameters.isManaged()).isFalse();
  308. assertThat(componentCreationParameters.newComponent().isPrivate()).isTrue();
  309. verify(projectAlmSettingDao).insertOrUpdate(any(), projectAlmSettingDtoCaptor.capture(), eq(ALM_SETTING_KEY), eq(REPOSITORY_NAME), eq(projectKey));
  310. ProjectAlmSettingDto projectAlmSettingDto = projectAlmSettingDtoCaptor.getValue();
  311. assertAlmSettingsDtoContainsCorrectInformation(almSettingDto, requireNonNull(componentCreationData.projectDto()), projectAlmSettingDto);
  312. }
  313. @Captor
  314. private ArgumentCaptor<Collection<UserPermissionChange>> permissionChangesCaptor;
  315. @Test
  316. void createProjectAndBindToDevOpsPlatformFromApi_whenRepoFoundOnGitHubAutoProvisioningOnAndRepoPrivate_successfullyCreatesProject() {
  317. // given
  318. String projectKey = "customProjectKey";
  319. mockGitHubRepository();
  320. ComponentCreationData componentCreationData = mockProjectCreation(projectKey);
  321. ProjectAlmSettingDao projectAlmSettingDao = mock();
  322. when(dbClient.projectAlmSettingDao()).thenReturn(projectAlmSettingDao);
  323. when(gitHubSettings.isProvisioningEnabled()).thenReturn(true);
  324. // when
  325. ComponentCreationData actualComponentCreationData = githubProjectCreator.createProjectAndBindToDevOpsPlatform(dbClient.openSession(true), ALM_IMPORT_API, false, projectKey,
  326. null);
  327. // then
  328. assertThat(actualComponentCreationData).isEqualTo(componentCreationData);
  329. ComponentCreationParameters componentCreationParameters = componentCreationParametersCaptor.getValue();
  330. assertComponentCreationParametersContainsCorrectInformation(componentCreationParameters, projectKey, ALM_IMPORT_API);
  331. assertThat(componentCreationParameters.isManaged()).isTrue();
  332. assertThat(componentCreationParameters.newComponent().isPrivate()).isTrue();
  333. verifyScanPermissionWasAddedToUser(actualComponentCreationData);
  334. verifyProjectSyncTaskWasCreated(actualComponentCreationData);
  335. verify(projectAlmSettingDao).insertOrUpdate(any(), projectAlmSettingDtoCaptor.capture(), eq(ALM_SETTING_KEY), eq(REPOSITORY_NAME), eq(projectKey));
  336. ProjectAlmSettingDto projectAlmSettingDto = projectAlmSettingDtoCaptor.getValue();
  337. assertAlmSettingsDtoContainsCorrectInformation(almSettingDto, requireNonNull(componentCreationData.projectDto()), projectAlmSettingDto);
  338. }
  339. private void verifyProjectSyncTaskWasCreated(ComponentCreationData componentCreationData) {
  340. String projectUuid = requireNonNull(componentCreationData.projectDto()).getUuid();
  341. String mainBranchUuid = requireNonNull(componentCreationData.mainBranchDto()).getUuid();
  342. verify(managedProjectService).queuePermissionSyncTask(USER_UUID, mainBranchUuid, projectUuid);
  343. }
  344. private void verifyScanPermissionWasAddedToUser(ComponentCreationData actualComponentCreationData) {
  345. verify(permissionUpdater).apply(any(), permissionChangesCaptor.capture());
  346. UserPermissionChange permissionChange = permissionChangesCaptor.getValue().iterator().next();
  347. assertThat(permissionChange.getUserId().getUuid()).isEqualTo(userSession.getUuid());
  348. assertThat(permissionChange.getUserId().getLogin()).isEqualTo(userSession.getLogin());
  349. assertThat(permissionChange.getPermission()).isEqualTo(UserRole.SCAN);
  350. assertThat(permissionChange.getProjectUuid()).isEqualTo(actualComponentCreationData.projectDto().getUuid());
  351. }
  352. private void mockPublicGithubRepository() {
  353. GithubApplicationClient.Repository repository = mockGitHubRepository();
  354. when(repository.isPrivate()).thenReturn(false);
  355. }
  356. private GithubApplicationClient.Repository mockGitHubRepository() {
  357. GithubApplicationClient.Repository repository = mock();
  358. when(repository.getDefaultBranch()).thenReturn(MAIN_BRANCH_NAME);
  359. when(repository.getName()).thenReturn(REPOSITORY_NAME);
  360. when(repository.getFullName()).thenReturn(DEVOPS_PROJECT_DESCRIPTOR.repositoryIdentifier());
  361. lenient().when(repository.isPrivate()).thenReturn(true);
  362. when(githubApplicationClient.getRepository(DEVOPS_PROJECT_DESCRIPTOR.url(), devOpsAppInstallationToken, DEVOPS_PROJECT_DESCRIPTOR.repositoryIdentifier())).thenReturn(
  363. Optional.of(repository));
  364. when(projectKeyGenerator.generateUniqueProjectKey(repository.getFullName())).thenReturn("generated_" + DEVOPS_PROJECT_DESCRIPTOR.repositoryIdentifier());
  365. return repository;
  366. }
  367. private ComponentCreationData mockProjectCreation(String projectKey) {
  368. ComponentCreationData componentCreationData = mock();
  369. ProjectDto projectDto = mockProjectDto(projectKey);
  370. when(componentCreationData.projectDto()).thenReturn(projectDto);
  371. BranchDto branchDto = mock();
  372. when(componentCreationData.mainBranchDto()).thenReturn(branchDto);
  373. when(componentUpdater.createWithoutCommit(any(), componentCreationParametersCaptor.capture())).thenReturn(componentCreationData);
  374. return componentCreationData;
  375. }
  376. private static ProjectDto mockProjectDto(String projectKey) {
  377. ProjectDto projectDto = mock();
  378. when(projectDto.getName()).thenReturn(REPOSITORY_NAME);
  379. when(projectDto.getKey()).thenReturn(projectKey);
  380. when(projectDto.getUuid()).thenReturn("project-uuid-1");
  381. return projectDto;
  382. }
  383. private static void assertComponentCreationParametersContainsCorrectInformation(ComponentCreationParameters componentCreationParameters, String expectedKey,
  384. CreationMethod expectedCreationMethod) {
  385. assertThat(componentCreationParameters.creationMethod()).isEqualTo(expectedCreationMethod);
  386. assertThat(componentCreationParameters.mainBranchName()).isEqualTo(MAIN_BRANCH_NAME);
  387. assertThat(componentCreationParameters.userLogin()).isEqualTo(USER_LOGIN);
  388. assertThat(componentCreationParameters.userUuid()).isEqualTo(USER_UUID);
  389. NewComponent newComponent = componentCreationParameters.newComponent();
  390. assertThat(newComponent.isProject()).isTrue();
  391. assertThat(newComponent.qualifier()).isEqualTo(Qualifiers.PROJECT);
  392. assertThat(newComponent.key()).isEqualTo(expectedKey);
  393. assertThat(newComponent.name()).isEqualTo(REPOSITORY_NAME);
  394. }
  395. private static void assertAlmSettingsDtoContainsCorrectInformation(AlmSettingDto almSettingDto, ProjectDto projectDto, ProjectAlmSettingDto projectAlmSettingDto) {
  396. assertThat(projectAlmSettingDto.getAlmRepo()).isEqualTo(DEVOPS_PROJECT_DESCRIPTOR.repositoryIdentifier());
  397. assertThat(projectAlmSettingDto.getAlmSlug()).isNull();
  398. assertThat(projectAlmSettingDto.getAlmSettingUuid()).isEqualTo(almSettingDto.getUuid());
  399. assertThat(projectAlmSettingDto.getProjectUuid()).isEqualTo(projectDto.getUuid());
  400. assertThat(projectAlmSettingDto.getMonorepo()).isFalse();
  401. assertThat(projectAlmSettingDto.getSummaryCommentEnabled()).isTrue();
  402. }
  403. }