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.

ProjectDataLoaderTest.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 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.batch;
  21. import org.junit.Rule;
  22. import org.junit.Test;
  23. import org.junit.rules.ExpectedException;
  24. import org.sonar.api.resources.Qualifiers;
  25. import org.sonar.api.resources.Scopes;
  26. import org.sonar.api.web.UserRole;
  27. import org.sonar.core.permission.GlobalPermissions;
  28. import org.sonar.db.DbClient;
  29. import org.sonar.db.DbSession;
  30. import org.sonar.db.DbTester;
  31. import org.sonar.db.component.ComponentDto;
  32. import org.sonar.db.component.ResourceTypesRule;
  33. import org.sonar.db.organization.OrganizationDto;
  34. import org.sonar.db.source.FileSourceDto;
  35. import org.sonar.scanner.protocol.input.FileData;
  36. import org.sonar.scanner.protocol.input.MultiModuleProjectRepository;
  37. import org.sonar.scanner.protocol.input.ProjectRepositories;
  38. import org.sonar.scanner.protocol.input.SingleProjectRepository;
  39. import org.sonar.server.component.ComponentFinder;
  40. import org.sonar.server.exceptions.BadRequestException;
  41. import org.sonar.server.exceptions.ForbiddenException;
  42. import org.sonar.server.exceptions.NotFoundException;
  43. import org.sonar.server.tester.UserSessionRule;
  44. import static com.google.common.collect.ImmutableList.of;
  45. import static java.lang.String.format;
  46. import static org.assertj.core.api.Assertions.assertThat;
  47. import static org.junit.Assert.assertTrue;
  48. import static org.junit.Assert.fail;
  49. import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
  50. import static org.sonar.db.component.ComponentTesting.newFileDto;
  51. import static org.sonar.db.component.ComponentTesting.newModuleDto;
  52. import static org.sonar.db.permission.OrganizationPermission.SCAN;
  53. public class ProjectDataLoaderTest {
  54. @Rule
  55. public DbTester db = DbTester.create();
  56. @Rule
  57. public ExpectedException expectedException = ExpectedException.none();
  58. @Rule
  59. public UserSessionRule userSession = UserSessionRule.standalone();
  60. private DbClient dbClient = db.getDbClient();
  61. private DbSession dbSession = db.getSession();
  62. private int uuidCounter = 0;
  63. private ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT);
  64. private ProjectDataLoader underTest = new ProjectDataLoader(dbClient, userSession, new ComponentFinder(dbClient, resourceTypes));
  65. @Test
  66. public void throws_NotFoundException_when_branch_does_not_exist() {
  67. OrganizationDto organizationDto = db.organizations().insert();
  68. ComponentDto project = db.components().insertPrivateProject(organizationDto);
  69. userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
  70. expectedException.expect(NotFoundException.class);
  71. expectedException.expectMessage(format("Component '%s' on branch '%s' not found", project.getKey(), "unknown_branch"));
  72. underTest.load(ProjectDataQuery.create()
  73. .setProjectKey(project.getKey())
  74. .setBranch("unknown_branch"));
  75. }
  76. @Test
  77. public void return_file_data_from_single_project() {
  78. OrganizationDto organizationDto = db.organizations().insert();
  79. ComponentDto project = db.components().insertPrivateProject(organizationDto);
  80. userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
  81. ComponentDto file = db.components().insertComponent(newFileDto(project));
  82. dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(file).setSrcHash("123456"));
  83. db.commit();
  84. ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()));
  85. assertTrue(ref instanceof SingleProjectRepository);
  86. SingleProjectRepository singleProjectRepository = ((SingleProjectRepository) ref);
  87. assertThat(singleProjectRepository.fileData()).hasSize(1);
  88. FileData fileData = singleProjectRepository.fileDataByPath(file.path());
  89. assertThat(fileData).isNotNull();
  90. assertThat(fileData.hash()).isEqualTo("123456");
  91. }
  92. @Test
  93. public void return_file_data_from_multi_modules() {
  94. OrganizationDto organizationDto = db.organizations().insert();
  95. ComponentDto project = db.components().insertPrivateProject(organizationDto);
  96. userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
  97. ComponentDto module = db.components().insertComponent(newModuleDto(project));
  98. // File on project
  99. ComponentDto projectFile = db.components().insertComponent(newFileDto(project));
  100. dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456"));
  101. // File on module
  102. ComponentDto moduleFile = db.components().insertComponent(newFileDto(module));
  103. dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456"));
  104. dbSession.commit();
  105. ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()));
  106. assertTrue(ref instanceof MultiModuleProjectRepository);
  107. MultiModuleProjectRepository repository = ((MultiModuleProjectRepository) ref);
  108. assertThat(repository.fileData(project.getKey(), projectFile.path()).hash()).isEqualTo("123456");
  109. assertThat(repository.fileData(module.getKey(), moduleFile.path()).hash()).isEqualTo("789456");
  110. }
  111. @Test
  112. public void return_file_data_from_branch() {
  113. OrganizationDto organizationDto = db.organizations().insert();
  114. ComponentDto project = db.components().insertPrivateProject(organizationDto);
  115. ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
  116. userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
  117. ComponentDto moduleBranch = db.components().insertComponent(newModuleDto(branch));
  118. // File on branch
  119. ComponentDto projectFile = db.components().insertComponent(newFileDto(branch));
  120. dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456"));
  121. // File on moduleBranch branch
  122. ComponentDto moduleFile = db.components().insertComponent(newFileDto(moduleBranch));
  123. dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456"));
  124. dbSession.commit();
  125. ProjectRepositories ref = underTest.load(ProjectDataQuery.create()
  126. .setProjectKey(project.getKey())
  127. .setBranch("my_branch"));
  128. assertTrue(ref instanceof MultiModuleProjectRepository);
  129. MultiModuleProjectRepository repository = ((MultiModuleProjectRepository) ref);
  130. assertThat(repository.fileData(branch.getKey(), projectFile.path()).hash()).isEqualTo("123456");
  131. assertThat(repository.fileData(moduleBranch.getKey(), moduleFile.path()).hash()).isEqualTo("789456");
  132. }
  133. @Test
  134. public void fails_with_NPE_if_query_is_null() {
  135. expectedException.expect(NullPointerException.class);
  136. underTest.load(null);
  137. }
  138. @Test
  139. public void fails_with_NFE_if_query_is_empty() {
  140. expectedException.expect(NotFoundException.class);
  141. expectedException.expectMessage("Component key 'null' not found");
  142. underTest.load(ProjectDataQuery.create());
  143. }
  144. @Test
  145. public void throws_NotFoundException_if_component_does_not_exist() {
  146. String key = "theKey";
  147. expectedException.expect(NotFoundException.class);
  148. expectedException.expectMessage("Component key 'theKey' not found");
  149. underTest.load(ProjectDataQuery.create().setProjectKey(key));
  150. }
  151. @Test
  152. public void fails_with_BRE_if_component_is_not_a_project() {
  153. String[][] allScopesAndQualifierButProjectAndModule = {
  154. {Scopes.PROJECT, "fakeModuleUuid"},
  155. {Scopes.FILE, null},
  156. {Scopes.DIRECTORY, null}
  157. };
  158. OrganizationDto organizationDto = db.organizations().insert();
  159. for (String[] scopeAndQualifier : allScopesAndQualifierButProjectAndModule) {
  160. String scope = scopeAndQualifier[0];
  161. String moduleUuid = scopeAndQualifier[1];
  162. String key = "theKey_" + scope + "_" + moduleUuid;
  163. String uuid = "uuid_" + uuidCounter++;
  164. dbClient.componentDao().insert(dbSession, new ComponentDto()
  165. .setOrganizationUuid(organizationDto.getUuid())
  166. .setUuid(uuid)
  167. .setUuidPath(uuid + ".")
  168. .setRootUuid(uuid)
  169. .setProjectUuid(uuid)
  170. .setScope(scope)
  171. .setModuleUuid(moduleUuid)
  172. .setDbKey(key));
  173. dbSession.commit();
  174. try {
  175. underTest.load(ProjectDataQuery.create().setProjectKey(key));
  176. fail("A NotFoundException should have been raised because component is not project");
  177. } catch (BadRequestException e) {
  178. assertThat(e).hasMessage("Key '" + key + "' belongs to a component which is not a Project");
  179. }
  180. }
  181. }
  182. @Test
  183. public void throw_ForbiddenException_if_no_browse_permission_nor_scan_permission() {
  184. ComponentDto project = db.components().insertPrivateProject();
  185. userSession.logIn();
  186. expectedException.expect(ForbiddenException.class);
  187. expectedException.expectMessage("You're not authorized to execute any SonarQube analysis");
  188. underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()));
  189. }
  190. @Test
  191. public void throw_ForbiddenException_if_browse_permission_but_not_scan_permission() {
  192. ComponentDto project = db.components().insertPrivateProject();
  193. userSession.logIn().addProjectPermission(UserRole.USER, project);
  194. expectedException.expect(ForbiddenException.class);
  195. expectedException.expectMessage("You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server");
  196. underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()));
  197. }
  198. @Test
  199. public void issues_mode_is_allowed_if_user_has_browse_permission() {
  200. ComponentDto project = db.components().insertPrivateProject();
  201. userSession.logIn().addProjectPermission(UserRole.USER, project);
  202. ProjectRepositories repositories = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()).setIssuesMode(true));
  203. assertThat(repositories).isNotNull();
  204. }
  205. @Test
  206. public void issues_mode_is_forbidden_if_user_doesnt_have_browse_permission() {
  207. ComponentDto project = db.components().insertPrivateProject();
  208. userSession.logIn().addProjectPermission(GlobalPermissions.SCAN_EXECUTION, project);
  209. expectedException.expect(ForbiddenException.class);
  210. expectedException.expectMessage("You don't have the required permissions to access this project");
  211. underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()).setIssuesMode(true));
  212. }
  213. @Test
  214. public void scan_permission_on_organization_is_enough_even_without_scan_permission_on_project() {
  215. ComponentDto project = db.components().insertPrivateProject();
  216. userSession.logIn().addPermission(SCAN, project.getOrganizationUuid());
  217. userSession.logIn().addProjectPermission(UserRole.USER, project);
  218. ProjectRepositories repositories = underTest.load(ProjectDataQuery.create().setProjectKey(project.getKey()).setIssuesMode(true));
  219. assertThat(repositories).isNotNull();
  220. }
  221. private static FileSourceDto newFileSourceDto(ComponentDto file) {
  222. return new FileSourceDto()
  223. .setFileUuid(file.uuid())
  224. .setProjectUuid(file.projectUuid())
  225. .setDataHash("0263047cd758c68c27683625f072f010")
  226. .setLineHashes(of("8d7b3d6b83c0a517eac07e1aac94b773"))
  227. .setCreatedAt(System.currentTimeMillis())
  228. .setUpdatedAt(System.currentTimeMillis())
  229. .setRevision("123456789")
  230. .setSrcHash("123456");
  231. }
  232. }