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.

ComponentServiceUpdateKeyTest.java 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 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.component;
  21. import org.junit.Rule;
  22. import org.junit.Test;
  23. import org.sonar.api.utils.System2;
  24. import org.sonar.api.web.UserRole;
  25. import org.sonar.db.DbClient;
  26. import org.sonar.db.DbSession;
  27. import org.sonar.db.DbTester;
  28. import org.sonar.db.component.ComponentDbTester;
  29. import org.sonar.db.component.ComponentDto;
  30. import org.sonar.db.component.ComponentTesting;
  31. import org.sonar.db.project.ProjectDto;
  32. import org.sonar.server.es.ProjectIndexer;
  33. import org.sonar.server.es.TestProjectIndexers;
  34. import org.sonar.server.exceptions.ForbiddenException;
  35. import org.sonar.server.project.ProjectLifeCycleListeners;
  36. import org.sonar.server.tester.UserSessionRule;
  37. import static org.assertj.core.api.Assertions.assertThat;
  38. import static org.assertj.core.api.Assertions.assertThatThrownBy;
  39. import static org.mockito.Mockito.mock;
  40. public class ComponentServiceUpdateKeyTest {
  41. private final System2 system2 = System2.INSTANCE;
  42. @Rule
  43. public final UserSessionRule userSession = UserSessionRule.standalone();
  44. @Rule
  45. public final DbTester db = DbTester.create(system2);
  46. private ComponentDbTester componentDb = new ComponentDbTester(db);
  47. private DbClient dbClient = db.getDbClient();
  48. private DbSession dbSession = db.getSession();
  49. private TestProjectIndexers projectIndexers = new TestProjectIndexers();
  50. private ProjectLifeCycleListeners projectLifeCycleListeners = mock(ProjectLifeCycleListeners.class);
  51. private ComponentService underTest = new ComponentService(dbClient, userSession, projectIndexers, projectLifeCycleListeners);
  52. @Test
  53. public void update_project_key() {
  54. ComponentDto project = insertSampleProject();
  55. ComponentDto file = componentDb.insertComponent(ComponentTesting.newFileDto(project, null).setDbKey("sample:root:src/File.xoo"));
  56. ComponentDto inactiveFile = componentDb.insertComponent(ComponentTesting.newFileDto(project, null).setDbKey("sample:root:src/InactiveFile.xoo").setEnabled(false));
  57. dbSession.commit();
  58. logInAsProjectAdministrator(project);
  59. underTest.updateKey(dbSession, componentDb.getProjectDto(project), "sample2:root");
  60. dbSession.commit();
  61. // Check project key has been updated
  62. assertThat(db.getDbClient().componentDao().selectByKey(dbSession, project.getDbKey())).isEmpty();
  63. assertThat(db.getDbClient().componentDao().selectByKey(dbSession, "sample2:root")).isNotNull();
  64. // Check file key has been updated
  65. assertThat(db.getDbClient().componentDao().selectByKey(dbSession, file.getDbKey())).isEmpty();
  66. assertThat(db.getDbClient().componentDao().selectByKey(dbSession, "sample2:root:src/File.xoo")).isNotNull();
  67. assertThat(db.getDbClient().componentDao().selectByKey(dbSession, "sample2:root:src/InactiveFile.xoo")).isNotNull();
  68. assertThat(dbClient.componentDao().selectByKey(dbSession, inactiveFile.getDbKey())).isEmpty();
  69. assertThat(projectIndexers.hasBeenCalled(project.uuid(), ProjectIndexer.Cause.PROJECT_KEY_UPDATE)).isTrue();
  70. }
  71. @Test
  72. public void update_provisioned_project_key() {
  73. ComponentDto provisionedProject = insertProject("provisionedProject");
  74. dbSession.commit();
  75. logInAsProjectAdministrator(provisionedProject);
  76. underTest.updateKey(dbSession, componentDb.getProjectDto(provisionedProject), "provisionedProject2");
  77. dbSession.commit();
  78. assertComponentKeyHasBeenUpdated(provisionedProject.getDbKey(), "provisionedProject2");
  79. assertThat(projectIndexers.hasBeenCalled(provisionedProject.uuid(), ProjectIndexer.Cause.PROJECT_KEY_UPDATE)).isTrue();
  80. }
  81. @Test
  82. public void fail_to_update_project_key_without_admin_permission() {
  83. ComponentDto project = insertSampleProject();
  84. userSession.logIn("john").addProjectPermission(UserRole.USER, project);
  85. ProjectDto projectDto = componentDb.getProjectDto(project);
  86. assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto, "sample2:root"))
  87. .isInstanceOf(ForbiddenException.class);
  88. }
  89. @Test
  90. public void fail_if_old_key_and_new_key_are_the_same() {
  91. ComponentDto project = insertSampleProject();
  92. ComponentDto anotherProject = componentDb.insertPrivateProject();
  93. logInAsProjectAdministrator(project);
  94. ProjectDto projectDto = componentDb.getProjectDto(project);
  95. String anotherProjectDbKey = anotherProject.getDbKey();
  96. assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto,
  97. anotherProjectDbKey))
  98. .isInstanceOf(IllegalArgumentException.class)
  99. .hasMessage("Impossible to update key: a component with key \"" + anotherProjectDbKey + "\" already exists.");
  100. }
  101. @Test
  102. public void fail_if_new_key_is_empty() {
  103. ComponentDto project = insertSampleProject();
  104. logInAsProjectAdministrator(project);
  105. ProjectDto projectDto = componentDb.getProjectDto(project);
  106. assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto, ""))
  107. .isInstanceOf(IllegalArgumentException.class)
  108. .hasMessage("Malformed key for ''. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
  109. }
  110. @Test
  111. public void fail_if_new_key_is_not_formatted_correctly() {
  112. ComponentDto project = insertSampleProject();
  113. logInAsProjectAdministrator(project);
  114. ProjectDto projectDto = componentDb.getProjectDto(project);
  115. assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto, "sample?root"))
  116. .isInstanceOf(IllegalArgumentException.class)
  117. .hasMessage("Malformed key for 'sample?root'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
  118. }
  119. private ComponentDto insertSampleProject() {
  120. return insertProject("sample:root");
  121. }
  122. private ComponentDto insertProject(String key) {
  123. return componentDb.insertPrivateProject(c -> c.setDbKey(key));
  124. }
  125. private void assertComponentKeyHasBeenUpdated(String oldKey, String newKey) {
  126. assertThat(dbClient.componentDao().selectByKey(dbSession, oldKey)).isEmpty();
  127. assertThat(dbClient.componentDao().selectByKey(dbSession, newKey)).isPresent();
  128. }
  129. private void logInAsProjectAdministrator(ComponentDto provisionedProject) {
  130. userSession.logIn("john").addProjectPermission(UserRole.ADMIN, provisionedProject);
  131. }
  132. }