aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java131
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java12
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceMediumTest.java242
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java56
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java14
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java4
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java10
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java4
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb16
14 files changed, 451 insertions, 52 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
new file mode 100644
index 00000000000..534ae2f4689
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ComponentService.java
@@ -0,0 +1,131 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.component;
+
+import com.google.common.collect.ImmutableMap;
+import org.sonar.api.ServerComponent;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.preview.PreviewCache;
+import org.sonar.core.resource.ResourceKeyUpdaterDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.permission.InternalPermissionService;
+import org.sonar.server.user.UserSession;
+
+import javax.annotation.CheckForNull;
+
+import java.util.Date;
+
+public class ComponentService implements ServerComponent {
+
+ private final DbClient dbClient;
+
+ private final ResourceKeyUpdaterDao resourceKeyUpdaterDao;
+ private final InternalPermissionService permissionService;
+ private final PreviewCache previewCache;
+
+ public ComponentService(DbClient dbClient, ResourceKeyUpdaterDao resourceKeyUpdaterDao, InternalPermissionService permissionService, PreviewCache previewCache) {
+ this.dbClient = dbClient;
+ this.resourceKeyUpdaterDao = resourceKeyUpdaterDao;
+ this.permissionService = permissionService;
+ this.previewCache = previewCache;
+ }
+
+ public ComponentDto getByKey(String key) {
+ DbSession session = dbClient.openSession(false);
+ try {
+ return dbClient.componentDao().getByKey(session, key);
+ } finally {
+ session.close();
+ }
+ }
+
+ @CheckForNull
+ public ComponentDto getNullableByKey(String key) {
+ DbSession session = dbClient.openSession(false);
+ try {
+ return dbClient.componentDao().getNullableByKey(session, key);
+ } finally {
+ session.close();
+ }
+ }
+
+ public ComponentDto getByKey(DbSession session, String key) {
+ return dbClient.componentDao().getByKey(session, key);
+ }
+
+ public void updateKey(String projectOrModuleKey, String newKey) {
+ UserSession.get().checkComponentPermission(UserRole.ADMIN, projectOrModuleKey);
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ ComponentDto projectOrModule = getByKey(projectOrModuleKey);
+ ComponentDto oldRootProject = dbClient.componentDao().getRootProjectByKey(projectOrModuleKey, session);
+
+ resourceKeyUpdaterDao.updateKey(projectOrModule.getId(), newKey);
+ session.commit();
+
+ ComponentDto newRootProject = dbClient.componentDao().getRootProjectByKey(newKey, session);
+ updateIssuesIndex(session, oldRootProject.key(), newRootProject.key());
+
+ previewCache.reportResourceModification(newRootProject.key());
+
+ session.commit();
+ } finally {
+ session.close();
+ }
+ }
+
+ public void bulkUpdateKey(String projectKey, String stringToReplace, String replacementString) {
+ UserSession.get().checkProjectPermission(UserRole.ADMIN, projectKey);
+
+ DbSession session = dbClient.openSession(false);
+ try {
+ ComponentDto project = getByKey(projectKey);
+
+ resourceKeyUpdaterDao.bulkUpdateKey(project.getId(), stringToReplace, replacementString);
+ session.commit();
+
+ ComponentDto newProject = dbClient.componentDao().getById(project.getId(), session);
+ updateIssuesIndex(session, projectKey, newProject.key());
+
+ previewCache.reportResourceModification(newProject.key());
+
+ session.commit();
+ } finally {
+ session.close();
+ }
+ }
+
+ private void updateIssuesIndex(DbSession session, String oldKey, String newKey) {
+ // Remove permission on old project key
+ permissionService.synchronizePermissions(session, oldKey);
+
+ // Add permission on new project key
+ permissionService.synchronizePermissions(session, newKey);
+
+ // Reindex issues on new project key
+ dbClient.issueDao().synchronizeAfter(session, new Date(0),
+ ImmutableMap.of("project", newKey));
+ }
+
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java
index 94de74f57e4..de8be6e9791 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/DefaultRubyComponentService.java
@@ -43,12 +43,14 @@ public class DefaultRubyComponentService implements RubyComponentService {
private final ResourceDao resourceDao;
private final DefaultComponentFinder finder;
private final ResourceIndexerDao resourceIndexerDao;
+ private final ComponentService componentService;
private final I18n i18n;
- public DefaultRubyComponentService(ResourceDao resourceDao, DefaultComponentFinder finder, ResourceIndexerDao resourceIndexerDao, I18n i18n) {
+ public DefaultRubyComponentService(ResourceDao resourceDao, DefaultComponentFinder finder, ResourceIndexerDao resourceIndexerDao, ComponentService componentService, I18n i18n) {
this.resourceDao = resourceDao;
this.finder = finder;
this.resourceIndexerDao = resourceIndexerDao;
+ this.componentService = componentService;
this.i18n = i18n;
}
@@ -114,6 +116,14 @@ public class DefaultRubyComponentService implements RubyComponentService {
return resourceDao.selectProvisionedProjects(query.qualifiers());
}
+ public void updateKey(String projectOrModuleKey, String newKey) {
+ componentService.updateKey(projectOrModuleKey, newKey);
+ }
+
+ public void bulkUpdateKey(String projectKey, String stringToReplace, String replacementString) {
+ componentService.bulkUpdateKey(projectKey, stringToReplace, replacementString);
+ }
+
static ComponentQuery toQuery(Map<String, Object> props) {
ComponentQuery.Builder builder = ComponentQuery.builder()
.keys(RubyUtils.toStrings(props.get("keys")))
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
index a765263734e..b55ff650787 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ServerComponents.java
@@ -79,6 +79,7 @@ import org.sonar.server.authentication.ws.AuthenticationWs;
import org.sonar.server.batch.*;
import org.sonar.server.charts.ChartFactory;
import org.sonar.server.component.ComponentCleanerService;
+import org.sonar.server.component.ComponentService;
import org.sonar.server.component.DefaultComponentFinder;
import org.sonar.server.component.DefaultRubyComponentService;
import org.sonar.server.component.db.ComponentDao;
@@ -474,6 +475,7 @@ class ServerComponents {
// components
pico.addSingleton(DefaultComponentFinder.class);
pico.addSingleton(DefaultRubyComponentService.class);
+ pico.addSingleton(ComponentService.class);
pico.addSingleton(ComponentDao.class);
pico.addSingleton(ResourcesWs.class);
pico.addSingleton(ComponentsWs.class);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java
index adfc9545ece..f0cc57a8ab9 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/UploadReportActionMediumTest.java
@@ -170,7 +170,7 @@ public class UploadReportActionMediumTest {
.setProjectId_unit_test_only(project.getId())
.setKey("MyComponent");
db.componentDao().insert(session, resource);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(resource));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(resource, project));
RuleDto rule = RuleTesting.newXooX1();
tester.get(RuleDao.class).insert(session, rule);
@@ -218,7 +218,7 @@ public class UploadReportActionMediumTest {
.setProjectId_unit_test_only(project.getId())
.setKey("MyComponent");
db.componentDao().insert(session, resource);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(resource));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(resource, project));
RuleDto rule = RuleTesting.newXooX1();
tester.get(RuleDao.class).insert(session, rule);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceMediumTest.java
new file mode 100644
index 00000000000..9415fd8e9d5
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentServiceMediumTest.java
@@ -0,0 +1,242 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.server.component;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.sonar.api.security.DefaultGroups;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.component.ComponentDto;
+import org.sonar.core.issue.db.IssueDto;
+import org.sonar.core.permission.PermissionFacade;
+import org.sonar.core.persistence.DbSession;
+import org.sonar.core.rule.RuleDto;
+import org.sonar.server.component.db.ComponentDao;
+import org.sonar.server.component.db.SnapshotDao;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.issue.IssueQuery;
+import org.sonar.server.issue.IssueTesting;
+import org.sonar.server.issue.index.IssueAuthorizationIndex;
+import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.rule.RuleTesting;
+import org.sonar.server.rule.db.RuleDao;
+import org.sonar.server.search.IndexClient;
+import org.sonar.server.search.QueryContext;
+import org.sonar.server.tester.ServerTester;
+import org.sonar.server.user.MockUserSession;
+
+import java.util.Date;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class ComponentServiceMediumTest {
+
+ @ClassRule
+ public static ServerTester tester = new ServerTester();
+
+ DbClient db;
+ IndexClient indexClient;
+ DbSession session;
+
+ ComponentService service;
+
+ ComponentDto project;
+ RuleDto rule;
+
+ @Before
+ public void setUp() throws Exception {
+ tester.clearDbAndIndexes();
+ db = tester.get(DbClient.class);
+ indexClient = tester.get(IndexClient.class);
+ session = db.openSession(false);
+ service = tester.get(ComponentService.class);
+
+ project = ComponentTesting.newProjectDto().setKey("sample:root");
+ tester.get(ComponentDao.class).insert(session, project);
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForProject(project));
+
+ // project can be seen by anyone
+ tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
+ db.issueAuthorizationDao().synchronizeAfter(session, new Date(0));
+
+ rule = RuleTesting.newXooX1();
+ tester.get(RuleDao.class).insert(session, rule);
+
+ session.commit();
+ }
+
+ @After
+ public void after() {
+ session.close();
+ }
+
+ @Test
+ public void get_by_key() throws Exception {
+ assertThat(service.getByKey(project.getKey())).isNotNull();
+ }
+
+ @Test
+ public void get_nullable_by_key() throws Exception {
+ assertThat(service.getNullableByKey(project.getKey())).isNotNull();
+ assertThat(service.getNullableByKey("unknown")).isNull();
+ }
+
+ @Test
+ public void update_project_key() throws Exception {
+ ComponentDto file = ComponentTesting.newFileDto(project).setKey("sample:root:src/File.xoo");
+ tester.get(ComponentDao.class).insert(session, file);
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project));
+
+ IssueDto issue = IssueTesting.newDto(rule, file, project);
+ db.issueDao().insert(session, issue);
+
+ session.commit();
+
+ MockUserSession.set().setLogin("john").addComponentPermission(UserRole.ADMIN, project.key(), project.key());
+ service.updateKey(project.key(), "sample2:root");
+ session.commit();
+
+ // Check project key has been updated
+ assertThat(service.getNullableByKey(project.key())).isNull();
+ assertThat(service.getNullableByKey("sample2:root")).isNotNull();
+
+ // Check file key has been updated
+ assertThat(service.getNullableByKey(file.key())).isNull();
+ assertThat(service.getNullableByKey("sample2:root:src/File.xoo")).isNotNull();
+
+ // Check issue have been updated
+ assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).componentKey()).isEqualTo("sample2:root:src/File.xoo");
+ assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).projectKey()).isEqualTo("sample2:root");
+
+ // Check that no new issue has been added
+ assertThat(tester.get(IssueIndex.class).search(IssueQuery.builder().build(), new QueryContext()).getTotal()).isEqualTo(1);
+
+ // Check Issue Authorization index
+ assertThat(tester.get(IssueAuthorizationIndex.class).getNullableByKey(project.getKey())).isNull();
+ assertThat(tester.get(IssueAuthorizationIndex.class).getNullableByKey("sample2:root")).isNotNull();
+
+ // Check dry run cache have been updated
+ assertThat(db.propertiesDao().selectProjectProperties("sample2:root", session)).hasSize(1);
+ }
+
+ @Test
+ public void update_module_key() throws Exception {
+ ComponentDto module = ComponentTesting.newModuleDto(project).setKey("sample:root:module");
+ tester.get(ComponentDao.class).insert(session, module);
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(module, project));
+
+ ComponentDto file = ComponentTesting.newFileDto(module).setKey("sample:root:module:src/File.xoo");
+ tester.get(ComponentDao.class).insert(session, file);
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project));
+
+ IssueDto issue = IssueTesting.newDto(rule, file, project);
+ db.issueDao().insert(session, issue);
+
+ session.commit();
+
+ MockUserSession.set().setLogin("john").addComponentPermission(UserRole.ADMIN, project.key(), module.key());
+ service.updateKey(module.key(), "sample:root2:module");
+ session.commit();
+
+ // Project key has not changed
+ assertThat(service.getNullableByKey(project.key())).isNotNull();
+
+ // Check module key has been updated
+ assertThat(service.getNullableByKey(module.key())).isNull();
+ assertThat(service.getNullableByKey("sample:root2:module")).isNotNull();
+
+ // Check file key has been updated
+ assertThat(service.getNullableByKey(file.key())).isNull();
+ assertThat(service.getNullableByKey("sample:root2:module:src/File.xoo")).isNotNull();
+
+ // Check issue have been updated
+ assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).componentKey()).isEqualTo("sample:root2:module:src/File.xoo");
+ assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).projectKey()).isEqualTo(project.key());
+
+ // Check Issue Authorization index
+ assertThat(tester.get(IssueAuthorizationIndex.class).getNullableByKey(project.getKey())).isNotNull();
+
+ // Check dry run cache have been updated -> on a module it's the project cache that is updated
+ assertThat(db.propertiesDao().selectProjectProperties(project.key(), session)).hasSize(1);
+ }
+
+ @Test(expected = ForbiddenException.class)
+ public void fail_to_update_project_key_without_admin_permission() throws Exception {
+ MockUserSession.set().setLogin("john").addComponentPermission(UserRole.USER, project.key(), project.key());
+ service.updateKey(project.key(), "sample2:root");
+ }
+
+ @Test
+ public void bulk_update_project_key() throws Exception {
+ ComponentDto module = ComponentTesting.newModuleDto(project).setKey("sample:root:module");
+ tester.get(ComponentDao.class).insert(session, module);
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(module, project));
+
+ ComponentDto file = ComponentTesting.newFileDto(module).setKey("sample:root:module:src/File.xoo");
+ tester.get(ComponentDao.class).insert(session, file);
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project));
+
+ IssueDto issue = IssueTesting.newDto(rule, file, project);
+ db.issueDao().insert(session, issue);
+
+ session.commit();
+
+ MockUserSession.set().setLogin("john").addProjectPermissions(UserRole.ADMIN, project.key());
+ service.bulkUpdateKey("sample:root", "sample", "sample2");
+ session.commit();
+
+ // Check project key has been updated
+ assertThat(service.getNullableByKey(project.key())).isNull();
+ assertThat(service.getNullableByKey("sample2:root")).isNotNull();
+
+ // Check module key has been updated
+ assertThat(service.getNullableByKey(module.key())).isNull();
+ assertThat(service.getNullableByKey("sample2:root:module")).isNotNull();
+
+ // Check file key has been updated
+ assertThat(service.getNullableByKey(file.key())).isNull();
+ assertThat(service.getNullableByKey("sample2:root:module:src/File.xoo")).isNotNull();
+
+ // Check issue have been updated
+ assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).componentKey()).isEqualTo("sample2:root:module:src/File.xoo");
+ assertThat(tester.get(IssueIndex.class).getNullableByKey(issue.getKey()).projectKey()).isEqualTo("sample2:root");
+
+ // Check that no new issue has been added
+ assertThat(tester.get(IssueIndex.class).search(IssueQuery.builder().build(), new QueryContext()).getTotal()).isEqualTo(1);
+
+ // Check Issue Authorization index
+ assertThat(tester.get(IssueAuthorizationIndex.class).getNullableByKey(project.getKey())).isNull();
+ assertThat(tester.get(IssueAuthorizationIndex.class).getNullableByKey("sample2:root")).isNotNull();
+
+ // Check dry run cache have been updated
+ assertThat(db.propertiesDao().selectProjectProperties("sample2:root", session)).hasSize(1);
+ }
+
+ @Test(expected = ForbiddenException.class)
+ public void fail_to_bulk_update_project_key_without_admin_permission() throws Exception {
+ MockUserSession.set().setLogin("john").addProjectPermissions(UserRole.USER, project.key());
+ service.bulkUpdateKey("sample:root", "sample", "sample2");
+ }
+
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java
index 493ca99d789..d729e8329e9 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ComponentTesting.java
@@ -45,7 +45,7 @@ public class ComponentTesting {
.setName("Module")
.setLongName("Module")
.setSubProjectId(subProjectOrProject.getId())
- .setScope(Scopes.FILE)
+ .setScope(Scopes.PROJECT)
.setQualifier(Qualifiers.MODULE)
.setPath("module")
.setLanguage(null)
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java
index 4acd2671ed2..28e52b6217a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/DefaultRubyComponentServiceTest.java
@@ -42,26 +42,26 @@ import static com.google.common.collect.Maps.newHashMap;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class DefaultRubyComponentServiceTest {
- private ResourceDao resourceDao;
- private DefaultComponentFinder finder;
- private ResourceIndexerDao resourceIndexerDao;
- private I18n i18n;
- private DefaultRubyComponentService componentService;
+ ResourceDao resourceDao;
+ DefaultComponentFinder finder;
+ ResourceIndexerDao resourceIndexerDao;
+ ComponentService componentService;
+ I18n i18n;
+
+ DefaultRubyComponentService service;
@Before
public void before() {
resourceDao = mock(ResourceDao.class);
finder = mock(DefaultComponentFinder.class);
resourceIndexerDao = mock(ResourceIndexerDao.class);
+ componentService = mock(ComponentService.class);
i18n = mock(I18n.class);
- componentService = new DefaultRubyComponentService(resourceDao, finder, resourceIndexerDao, i18n);
+ service = new DefaultRubyComponentService(resourceDao, finder, resourceIndexerDao, componentService, i18n);
}
@Test
@@ -69,7 +69,7 @@ public class DefaultRubyComponentServiceTest {
Component<?> component = mock(Component.class);
when(resourceDao.findByKey("struts")).thenReturn(component);
- assertThat(componentService.findByKey("struts")).isEqualTo(component);
+ assertThat(service.findByKey("struts")).isEqualTo(component);
}
@Test
@@ -82,7 +82,7 @@ public class DefaultRubyComponentServiceTest {
when(component.getId()).thenReturn(componentId);
when(resourceDao.findByKey(componentKey)).thenReturn(null).thenReturn(component);
- componentService.createComponent(componentKey, componentName, qualifier);
+ service.createComponent(componentKey, componentName, qualifier);
ArgumentCaptor<ResourceDto> resourceCaptor = ArgumentCaptor.forClass(ResourceDto.class);
verify(resourceDao).insertOrUpdate(resourceCaptor.capture());
@@ -103,7 +103,7 @@ public class DefaultRubyComponentServiceTest {
String qualifier = Qualifiers.PROJECT;
when(resourceDao.findByKey(componentKey)).thenReturn(null);
- componentService.createComponent(componentKey, componentName, qualifier);
+ service.createComponent(componentKey, componentName, qualifier);
}
@Test(expected = BadRequestException.class)
@@ -113,19 +113,19 @@ public class DefaultRubyComponentServiceTest {
String qualifier = Qualifiers.PROJECT;
when(resourceDao.findByKey(componentKey)).thenReturn(mock(ComponentDto.class));
- componentService.createComponent(componentKey, componentName, qualifier);
+ service.createComponent(componentKey, componentName, qualifier);
}
@Test(expected = BadRequestException.class)
public void should_throw_if_malformed_key1() {
- componentService.createComponent("1234", "New Project", Qualifiers.PROJECT);
+ service.createComponent("1234", "New Project", Qualifiers.PROJECT);
}
@Test(expected = NotFoundException.class)
public void should_throw_if_updating_unknown_component() {
final long componentId = 1234l;
when(resourceDao.getResource(componentId)).thenReturn(null);
- componentService.updateComponent(componentId, "key", "name");
+ service.updateComponent(componentId, "key", "name");
}
@Test
@@ -137,7 +137,7 @@ public class DefaultRubyComponentServiceTest {
when(resourceDao.getResource(componentId)).thenReturn(resource);
when(resource.setKey(newKey)).thenReturn(resource);
when(resource.setName(newName)).thenReturn(resource);
- componentService.updateComponent(componentId, newKey, newName);
+ service.updateComponent(componentId, newKey, newName);
verify(resource).setKey(newKey);
verify(resource).setName(newName);
verify(resourceDao).insertOrUpdate(resource);
@@ -150,7 +150,7 @@ public class DefaultRubyComponentServiceTest {
final String newName = "newName";
ResourceDto resource = mock(ResourceDto.class);
when(resourceDao.getResource(componentId)).thenReturn(resource);
- componentService.updateComponent(componentId, newKey, newName);
+ service.updateComponent(componentId, newKey, newName);
}
@Test
@@ -166,7 +166,7 @@ public class DefaultRubyComponentServiceTest {
map.put("sort", "NAME");
map.put("asc", true);
- componentService.find(map);
+ service.find(map);
verify(resourceDao).selectProjectsByQualifiers(anyListOf(String.class));
verify(finder).find(any(ComponentQuery.class), anyListOf(Component.class));
}
@@ -184,7 +184,7 @@ public class DefaultRubyComponentServiceTest {
map.put("sort", "NAME");
map.put("asc", true);
- componentService.findWithUncompleteProjects(map);
+ service.findWithUncompleteProjects(map);
verify(resourceDao).selectProjectsIncludingNotCompletedOnesByQualifiers(anyListOf(String.class));
verify(finder).find(any(ComponentQuery.class), anyListOf(Component.class));
}
@@ -202,7 +202,7 @@ public class DefaultRubyComponentServiceTest {
map.put("sort", "NAME");
map.put("asc", true);
- componentService.findGhostsProjects(map);
+ service.findGhostsProjects(map);
verify(resourceDao).selectGhostsProjects(anyListOf(String.class));
verify(finder).find(any(ComponentQuery.class), anyListOf(Component.class));
}
@@ -214,7 +214,7 @@ public class DefaultRubyComponentServiceTest {
Map<String, Object> map = newHashMap();
map.put("qualifiers", qualifiers);
- componentService.findProvisionedProjects(map);
+ service.findProvisionedProjects(map);
verify(resourceDao).selectProvisionedProjects(anyListOf(String.class));
}
@@ -255,4 +255,16 @@ public class DefaultRubyComponentServiceTest {
assertThat(query.sort()).isEqualTo(ComponentQuery.SORT_BY_NAME);
assertThat(query.asc()).isTrue();
}
+
+ @Test
+ public void update_key() {
+ service.updateKey("oldKey", "newKey");
+ verify(componentService).updateKey("oldKey", "newKey");
+ }
+
+ @Test
+ public void bulk_update_key() {
+ service.bulkUpdateKey("oldKey", "old", "new");
+ verify(componentService).bulkUpdateKey("oldKey", "old", "new");
+ }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java b/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java
index 1ec6081f08d..845728744e5 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/SnapshotTesting.java
@@ -25,10 +25,20 @@ import org.sonar.core.component.SnapshotDto;
public class SnapshotTesting {
- public static SnapshotDto createForComponent(ComponentDto component) {
+ /**
+ * When project is null, that means that the component is a project
+ */
+ public static SnapshotDto createForComponent(ComponentDto component, ComponentDto project) {
return new SnapshotDto()
.setResourceId(component.getId())
- .setRootProjectId(component.subProjectId())
+ .setRootProjectId(project.getId())
+ .setLast(true);
+ }
+
+ public static SnapshotDto createForProject(ComponentDto project) {
+ return new SnapshotDto()
+ .setResourceId(project.getId())
+ .setRootProjectId(project.getId())
.setLast(true);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java
index dc59a5187a4..d21e8100baa 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueBulkChangeServiceMediumTest.java
@@ -91,14 +91,14 @@ public class IssueBulkChangeServiceMediumTest {
.setQualifier(Qualifiers.PROJECT)
.setScope(Scopes.PROJECT);
tester.get(ComponentDao.class).insert(session, project);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(project));
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForProject(project));
file = new ComponentDto()
.setSubProjectId(project.getId())
.setKey("MyComponent")
.setLongName("My Component");
tester.get(ComponentDao.class).insert(session, file);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file));
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project));
// project can be seen by anyone
tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
index c2fe8dddf1d..b935d1fe797 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/IssueServiceMediumTest.java
@@ -96,14 +96,14 @@ public class IssueServiceMediumTest {
.setQualifier(Qualifiers.PROJECT)
.setScope(Scopes.PROJECT);
tester.get(ComponentDao.class).insert(session, project);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(project));
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForProject(project));
file = new ComponentDto()
.setSubProjectId(project.getId())
.setKey("MyComponent")
.setLongName("My Component");
tester.get(ComponentDao.class).insert(session, file);
- tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file));
+ tester.get(SnapshotDao.class).insert(session, SnapshotTesting.createForComponent(file, project));
// project can be seen by anyone
tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java
index 00ac616f8b3..823f7ae17f8 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexMediumTest.java
@@ -639,7 +639,7 @@ public class IssueIndexMediumTest {
.setSubProjectId(project.getId())
.setKey("MyComponent");
db.componentDao().insert(session, resource);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(resource));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(resource, project));
List<String> issueKeys = newArrayList();
for (int i = 0; i < numberOfIssues; i++) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
index 4ba6aef26d4..2416470c478 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
@@ -84,7 +84,7 @@ public class SearchActionMediumTest {
project = new ComponentDto()
.setKey("MyProject");
db.componentDao().insert(session, project);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(project));
+ db.snapshotDao().insert(session, SnapshotTesting.createForProject(project));
// project can be seen by anyone
tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
@@ -94,7 +94,7 @@ public class SearchActionMediumTest {
.setKey("MyComponent")
.setSubProjectId(project.getId());
db.componentDao().insert(session, file);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file, project));
UserDto john = new UserDto().setLogin("john").setName("John").setEmail("john@email.com");
db.userDao().insert(session, john);
@@ -266,7 +266,7 @@ public class SearchActionMediumTest {
.setKey("ProjectHavingModule")
.setScope("PRJ");
db.componentDao().insert(session, project);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(project));
+ db.snapshotDao().insert(session, SnapshotTesting.createForProject(project));
// project can be seen by anyone
tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
@@ -277,14 +277,14 @@ public class SearchActionMediumTest {
.setScope("PRJ")
.setSubProjectId(project.getId());
db.componentDao().insert(session, module);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(module));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(module, project));
ComponentDto file = new ComponentDto()
.setKey("FileLinkedToModule")
.setScope("FIL")
.setSubProjectId(module.getId());
db.componentDao().insert(session, file);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file, project));
IssueDto issue = IssueTesting.newDto(rule, file, project);
db.issueDao().insert(session, issue);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java
index 4afc1f1c786..d7ebf51e461 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/platform/BackendCleanupMediumTest.java
@@ -77,13 +77,13 @@ public class BackendCleanupMediumTest {
project = new ComponentDto()
.setKey("MyProject");
tester.get(ComponentDao.class).insert(session, project);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(project));
+ db.snapshotDao().insert(session, SnapshotTesting.createForProject(project));
file = new ComponentDto()
.setProjectId_unit_test_only(project.getId())
.setKey("MyComponent");
tester.get(ComponentDao.class).insert(session, file);
- db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file));
+ db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file, project));
// project can be seen by anyone
tester.get(PermissionFacade.class).insertGroupPermission(project.getId(), DefaultGroups.ANYONE, UserRole.USER, session);
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb
index 150b37a3e7e..09148fc3bec 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/app/controllers/project_controller.rb
@@ -164,13 +164,9 @@ class ProjectController < ApplicationController
elsif Project.by_key(new_key)
flash[:error] = message('update_key.cant_update_x_because_resource_already_exist_with_key_x', :params => [project.key, new_key])
else
- begin
- java_facade.updateResourceKey(project.id, new_key)
- reportProjectModification(project.id)
+ call_backend do
+ Internal.component_api.updateKey(project.key, new_key)
flash[:notice] = message('update_key.key_updated')
- rescue Exception => e
- flash[:error] = message('update_key.error_occured_while_renaming_key_of_x',
- :params => [project.key, Api::Utils.exception_message(e, :backtrace => false)])
end
end
@@ -207,13 +203,9 @@ class ProjectController < ApplicationController
replacement_string = params[:replacement_string].strip
unless string_to_replace.blank? || replacement_string.blank?
- begin
- java_facade.bulkUpdateKey(project.id, string_to_replace, replacement_string)
- reportProjectModification(project.id)
+ call_backend do
+ Internal.component_api.bulkUpdateKey(project.key, string_to_replace, replacement_string)
flash[:notice] = message('update_key.key_updated')
- rescue Exception => e
- flash[:error] = message('update_key.error_occured_while_renaming_key_of_x',
- :params => [project.key, Api::Utils.exception_message(e, :backtrace => false)])
end
end