aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-server
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2018-06-13 18:49:50 +0200
committersonartech <sonartech@sonarsource.com>2018-06-29 09:10:15 +0200
commitf94bc6f1b9be3b9180aef88abe1804b4aaaa194a (patch)
treea22ee4820b2fc108aab7a2a1689b8a0cd73dadbf /server/sonar-server
parente5bd169a6e017334ae77832adb7eaea766138e28 (diff)
downloadsonarqube-f94bc6f1b9be3b9180aef88abe1804b4aaaa194a.tar.gz
sonarqube-f94bc6f1b9be3b9180aef88abe1804b4aaaa194a.zip
SONAR-10813 Define project branches in an application
Diffstat (limited to 'server/sonar-server')
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/branch/ws/DeleteAction.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java3
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java4
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListener.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListeners.java10
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListenersImpl.java11
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/branch/ws/DeleteActionTest.java42
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ws/TreeActionTest.java125
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java70
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java54
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java133
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ProjectLifeCycleListenersImplTest.java76
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java58
14 files changed, 434 insertions, 170 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/branch/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/branch/ws/DeleteAction.java
index cde6921b059..1da2eb87f33 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/branch/ws/DeleteAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/branch/ws/DeleteAction.java
@@ -30,13 +30,16 @@ import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.server.component.ComponentCleanerService;
import org.sonar.server.component.ComponentFinder;
+import org.sonar.server.project.ProjectLifeCycleListeners;
import org.sonar.server.user.UserSession;
+import static java.util.Collections.singleton;
import static org.sonar.server.branch.ws.BranchesWs.addBranchParam;
import static org.sonar.server.branch.ws.BranchesWs.addProjectParam;
import static org.sonar.server.branch.ws.ProjectBranchesParameters.ACTION_DELETE;
import static org.sonar.server.branch.ws.ProjectBranchesParameters.PARAM_BRANCH;
import static org.sonar.server.branch.ws.ProjectBranchesParameters.PARAM_PROJECT;
+import static org.sonar.server.project.Project.from;
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
public class DeleteAction implements BranchWsAction {
@@ -44,12 +47,15 @@ public class DeleteAction implements BranchWsAction {
private final UserSession userSession;
private final ComponentCleanerService componentCleanerService;
private final ComponentFinder componentFinder;
+ private final ProjectLifeCycleListeners projectLifeCycleListeners;
- public DeleteAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, ComponentCleanerService componentCleanerService) {
+ public DeleteAction(DbClient dbClient, ComponentFinder componentFinder, UserSession userSession, ComponentCleanerService componentCleanerService,
+ ProjectLifeCycleListeners projectLifeCycleListeners) {
this.dbClient = dbClient;
this.componentFinder = componentFinder;
this.userSession = userSession;
this.componentCleanerService = componentCleanerService;
+ this.projectLifeCycleListeners = projectLifeCycleListeners;
}
@Override
@@ -84,6 +90,7 @@ public class DeleteAction implements BranchWsAction {
}
ComponentDto branchComponent = componentFinder.getByKeyAndBranch(dbSession, projectKey, branchKey);
componentCleanerService.deleteBranch(dbSession, branchComponent);
+ projectLifeCycleListeners.onProjectBranchesDeleted(singleton(from(project)));
response.noContent();
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java
index ef86ba3c9c7..558ac7d492a 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/TreeAction.java
@@ -67,8 +67,8 @@ import static org.sonar.server.component.ws.ComponentDtoToWsComponent.componentD
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001;
-import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
+import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_TREE;
@@ -252,7 +252,7 @@ public class TreeAction implements ComponentsWsAction {
ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyResourceUuid());
if (referenceComponent != null) {
wsComponent.setRefId(referenceComponent.uuid());
- wsComponent.setRefKey(referenceComponent.getDbKey());
+ wsComponent.setRefKey(referenceComponent.getKey());
}
return wsComponent;
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
index 29e881db26b..7e5c5c1ca51 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/issue/index/IssueIndex.java
@@ -316,6 +316,7 @@ public class IssueIndex {
if (onApplicationBranch) {
filters.put("__view", createViewFilter(singletonList(query.branchUuid())));
} else {
+ filters.put("__is_main_branch", createTermFilter(IssueIndexDefinition.FIELD_ISSUE_IS_MAIN_BRANCH, Boolean.toString(true)));
filters.put("__view", createViewFilter(viewUuids));
}
}
@@ -328,7 +329,7 @@ public class IssueIndex {
BoolQueryBuilder viewsFilter = boolQuery();
for (String viewUuid : viewUuids) {
- viewsFilter.should(QueryBuilders.termsLookupQuery(IssueIndexDefinition.FIELD_ISSUE_PROJECT_UUID,
+ viewsFilter.should(QueryBuilders.termsLookupQuery(IssueIndexDefinition.FIELD_ISSUE_BRANCH_UUID,
new TermsLookup(
ViewIndexDefinition.INDEX_TYPE_VIEW.getIndex(),
ViewIndexDefinition.INDEX_TYPE_VIEW.getType(),
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
index 3adddc09965..2f1ffe9ac6e 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
@@ -111,8 +111,8 @@ import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriods.snapshotToWsPer
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001;
-import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
+import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
@@ -388,7 +388,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyResourceUuid());
if (referenceComponent != null) {
wsComponent.setRefId(referenceComponent.uuid());
- wsComponent.setRefKey(referenceComponent.getDbKey());
+ wsComponent.setRefKey(referenceComponent.getKey());
}
Measures.Measure.Builder measureBuilder = Measures.Measure.newBuilder();
for (Map.Entry<MetricDto, ComponentTreeData.Measure> entry : measures.entrySet()) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListener.java b/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListener.java
index 9b3c092b3db..05630721431 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListener.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListener.java
@@ -30,6 +30,11 @@ public interface ProjectLifeCycleListener {
void onProjectsDeleted(Set<Project> projects);
/**
+ * This method is called after the specified projects have been deleted.
+ */
+ void onProjectBranchesDeleted(Set<Project> projects);
+
+ /**
* This method is called after the specified projects' keys have been modified.
*/
void onProjectsRekeyed(Set<RekeyedProject> rekeyedProjects);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListeners.java b/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListeners.java
index 9b2c7b76d59..86158036742 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListeners.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListeners.java
@@ -33,6 +33,16 @@ public interface ProjectLifeCycleListeners {
void onProjectsDeleted(Set<Project> projects);
/**
+ * This method is called after the specified project branches have been deleted and will call method
+ * {@link ProjectLifeCycleListener#onProjectBranchesDeleted(Set)} of all known
+ * {@link ProjectLifeCycleListener} implementations.
+ * <p>
+ * This method ensures all {@link ProjectLifeCycleListener} implementations are called, even if one or more of
+ * them fail with an exception.
+ */
+ void onProjectBranchesDeleted(Set<Project> projects);
+
+ /**
* This method is called after the specified project's key has been changed and will call method
* {@link ProjectLifeCycleListener#onProjectsRekeyed(Set) onProjectsRekeyed(Set)} of all known
* {@link ProjectLifeCycleListener} implementations.
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListenersImpl.java b/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListenersImpl.java
index 0ca49891b2e..f2665ea67a5 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListenersImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ProjectLifeCycleListenersImpl.java
@@ -58,6 +58,17 @@ public class ProjectLifeCycleListenersImpl implements ProjectLifeCycleListeners
}
@Override
+ public void onProjectBranchesDeleted(Set<Project> projects) {
+ checkNotNull(projects, "projects can't be null");
+ if (projects.isEmpty()) {
+ return;
+ }
+
+ Arrays.stream(listeners)
+ .forEach(safelyCallListener(listener -> listener.onProjectBranchesDeleted(projects)));
+ }
+
+ @Override
public void onProjectsRekeyed(Set<RekeyedProject> rekeyedProjects) {
checkNotNull(rekeyedProjects, "rekeyedProjects can't be null");
if (rekeyedProjects.isEmpty()) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/branch/ws/DeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/branch/ws/DeleteActionTest.java
index 691087c4690..7797be99415 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/branch/ws/DeleteActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/branch/ws/DeleteActionTest.java
@@ -34,9 +34,12 @@ import org.sonar.server.component.ComponentFinder;
import org.sonar.server.component.TestComponentFinder;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
+import org.sonar.server.project.Project;
+import org.sonar.server.project.ProjectLifeCycleListeners;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
+import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
@@ -51,20 +54,26 @@ public class DeleteActionTest {
private ComponentCleanerService componentCleanerService = mock(ComponentCleanerService.class);
private ComponentFinder componentFinder = TestComponentFinder.from(db);
+ private ProjectLifeCycleListeners projectLifeCycleListeners = mock(ProjectLifeCycleListeners.class);
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
- public WsActionTester tester = new WsActionTester(new DeleteAction(db.getDbClient(), componentFinder, userSession, componentCleanerService));
+ public WsActionTester tester = new WsActionTester(new DeleteAction(db.getDbClient(), componentFinder, userSession, componentCleanerService, projectLifeCycleListeners));
@Test
- public void test_definition() {
- WebService.Action definition = tester.getDef();
- assertThat(definition.key()).isEqualTo("delete");
- assertThat(definition.isPost()).isTrue();
- assertThat(definition.isInternal()).isFalse();
- assertThat(definition.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("project", "branch");
- assertThat(definition.since()).isEqualTo("6.6");
+ public void delete_branch() {
+ ComponentDto project = db.components().insertMainBranch();
+ ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch1"));
+ userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
+
+ tester.newRequest()
+ .setParam("project", project.getKey())
+ .setParam("branch", "branch1")
+ .execute();
+
+ verifyDeletedKey(branch.getDbKey());
+ verify(projectLifeCycleListeners).onProjectBranchesDeleted(singleton(Project.from(project)));
}
@Test
@@ -139,16 +148,13 @@ public class DeleteActionTest {
}
@Test
- public void delete_branch() {
- ComponentDto project = db.components().insertMainBranch();
- ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch1"));
- userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
-
- tester.newRequest()
- .setParam("project", project.getKey())
- .setParam("branch", "branch1")
- .execute();
- verifyDeletedKey(branch.getDbKey());
+ public void definition() {
+ WebService.Action definition = tester.getDef();
+ assertThat(definition.key()).isEqualTo("delete");
+ assertThat(definition.isPost()).isTrue();
+ assertThat(definition.isInternal()).isFalse();
+ assertThat(definition.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("project", "branch");
+ assertThat(definition.since()).isEqualTo("6.6");
}
private void verifyDeletedKey(String key) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/TreeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/TreeActionTest.java
index 4452efaa621..d3c21cd19b0 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/TreeActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/TreeActionTest.java
@@ -40,7 +40,6 @@ import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.component.ResourceTypesRule;
@@ -53,11 +52,13 @@ import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import org.sonar.test.JsonAssert;
import org.sonarqube.ws.Components;
+import org.sonarqube.ws.Components.Component;
import org.sonarqube.ws.Components.TreeWsResponse;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.FILE;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.UNIT_TEST_FILE;
@@ -87,7 +88,6 @@ public class TreeActionTest {
private ResourceTypesRule resourceTypes = new ResourceTypesRule()
.setRootQualifiers(PROJECT)
.setLeavesQualifiers(FILE, UNIT_TEST_FILE);
- private ComponentDbTester componentDb = new ComponentDbTester(db);
private DbClient dbClient = db.getDbClient();
private WsActionTester ws = new WsActionTester(new TreeAction(dbClient, new ComponentFinder(dbClient, resourceTypes), resourceTypes, userSession, Mockito.mock(I18n.class)));
@@ -142,16 +142,16 @@ public class TreeActionTest {
@Test
public void return_children() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
- componentDb.insertProjectAndSnapshot(project);
+ db.components().insertProjectAndSnapshot(project);
ComponentDto module = newModuleDto("module-uuid-1", project);
- componentDb.insertComponent(module);
- componentDb.insertComponent(newFileDto(project, 1));
+ db.components().insertComponent(module);
+ db.components().insertComponent(newFileDto(project, 1));
for (int i = 2; i <= 9; i++) {
- componentDb.insertComponent(newFileDto(module, i));
+ db.components().insertComponent(newFileDto(module, i));
}
ComponentDto directory = newDirectory(module, "directory-path-1");
- componentDb.insertComponent(directory);
- componentDb.insertComponent(newFileDto(module, directory, 10));
+ db.components().insertComponent(directory);
+ db.components().insertComponent(newFileDto(module, directory, 10));
db.commit();
logInWithBrowsePermission(project);
@@ -172,16 +172,16 @@ public class TreeActionTest {
@Test
public void return_descendants() {
ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid");
- SnapshotDto projectSnapshot = componentDb.insertProjectAndSnapshot(project);
+ SnapshotDto projectSnapshot = db.components().insertProjectAndSnapshot(project);
ComponentDto module = newModuleDto("module-uuid-1", project);
- componentDb.insertComponent(module);
- componentDb.insertComponent(newFileDto(project, 10));
+ db.components().insertComponent(module);
+ db.components().insertComponent(newFileDto(project, 10));
for (int i = 2; i <= 9; i++) {
- componentDb.insertComponent(newFileDto(module, i));
+ db.components().insertComponent(newFileDto(module, i));
}
ComponentDto directory = newDirectory(module, "directory-path-1");
- componentDb.insertComponent(directory);
- componentDb.insertComponent(newFileDto(module, directory, 1));
+ db.components().insertComponent(directory);
+ db.components().insertComponent(newFileDto(module, directory, 1));
db.commit();
logInWithBrowsePermission(project);
@@ -202,10 +202,10 @@ public class TreeActionTest {
@Test
public void filter_descendants_by_qualifier() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
- componentDb.insertProjectAndSnapshot(project);
- componentDb.insertComponent(newFileDto(project, 1));
- componentDb.insertComponent(newFileDto(project, 2));
- componentDb.insertComponent(newModuleDto("module-uuid-1", project));
+ db.components().insertProjectAndSnapshot(project);
+ db.components().insertComponent(newFileDto(project, 1));
+ db.components().insertComponent(newFileDto(project, 2));
+ db.components().insertComponent(newModuleDto("module-uuid-1", project));
db.commit();
logInWithBrowsePermission(project);
@@ -220,14 +220,14 @@ public class TreeActionTest {
@Test
public void return_leaves() {
ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid");
- componentDb.insertProjectAndSnapshot(project);
+ db.components().insertProjectAndSnapshot(project);
ComponentDto module = newModuleDto("module-uuid-1", project);
- componentDb.insertComponent(module);
- componentDb.insertComponent(newFileDto(project, 1));
- componentDb.insertComponent(newFileDto(module, 2));
+ db.components().insertComponent(module);
+ db.components().insertComponent(newFileDto(project, 1));
+ db.components().insertComponent(newFileDto(module, 2));
ComponentDto directory = newDirectory(project, "directory-path-1");
- componentDb.insertComponent(directory);
- componentDb.insertComponent(newFileDto(module, directory, 3));
+ db.components().insertComponent(directory);
+ db.components().insertComponent(newFileDto(module, directory, 3));
db.commit();
logInWithBrowsePermission(project);
@@ -244,12 +244,12 @@ public class TreeActionTest {
@Test
public void sort_descendants_by_qualifier() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
- componentDb.insertProjectAndSnapshot(project);
- componentDb.insertComponent(newFileDto(project, 1));
- componentDb.insertComponent(newFileDto(project, 2));
+ db.components().insertProjectAndSnapshot(project);
+ db.components().insertComponent(newFileDto(project, 1));
+ db.components().insertComponent(newFileDto(project, 2));
ComponentDto module = newModuleDto("module-uuid-1", project);
- componentDb.insertComponent(module);
- componentDb.insertComponent(newDirectory(project, "path/directory/", "directory-uuid-1"));
+ db.components().insertComponent(module);
+ db.components().insertComponent(newDirectory(project, "path/directory/", "directory-uuid-1"));
db.commit();
logInWithBrowsePermission(project);
@@ -262,14 +262,14 @@ public class TreeActionTest {
}
@Test
- public void return_children_of_a_view() {
+ public void project_reference_from_portfolio() {
OrganizationDto organizationDto = db.organizations().insert();
ComponentDto view = newView(organizationDto, "view-uuid");
- componentDb.insertViewAndSnapshot(view);
+ db.components().insertViewAndSnapshot(view);
ComponentDto project = newPrivateProjectDto(organizationDto, "project-uuid-1").setName("project-name").setDbKey("project-key-1");
- componentDb.insertProjectAndSnapshot(project);
- componentDb.insertComponent(newProjectCopy("project-uuid-1-copy", project, view));
- componentDb.insertComponent(newSubView(view, "sub-view-uuid", "sub-view-key").setName("sub-view-name"));
+ db.components().insertProjectAndSnapshot(project);
+ db.components().insertComponent(newProjectCopy("project-uuid-1-copy", project, view));
+ db.components().insertComponent(newSubView(view, "sub-view-uuid", "sub-view-key").setName("sub-view-name"));
db.commit();
userSession.logIn()
.registerComponents(view, project);
@@ -285,8 +285,31 @@ public class TreeActionTest {
}
@Test
+ public void project_branch_reference_from_application_branch() {
+ ComponentDto application = db.components().insertMainBranch(c -> c.setQualifier(APP).setDbKey("app-key"));
+ ComponentDto applicationBranch = db.components().insertProjectBranch(application, a -> a.setKey("app-branch"));
+ ComponentDto project = db.components().insertPrivateProject(p -> p.setDbKey("project-key"));
+ ComponentDto projectBranch = db.components().insertProjectBranch(project, b -> b.setKey("project-branch"));
+ ComponentDto techProjectBranch = db.components().insertComponent(newProjectCopy(projectBranch, applicationBranch)
+ .setDbKey(applicationBranch.getKey() + applicationBranch.getBranch() + projectBranch.getDbKey()));
+ logInWithBrowsePermission(application);
+
+ TreeWsResponse result = ws.newRequest()
+ .setParam(MeasuresWsParameters.PARAM_COMPONENT, applicationBranch.getKey())
+ .setParam(MeasuresWsParameters.PARAM_BRANCH, applicationBranch.getBranch())
+ .executeProtobuf(TreeWsResponse.class);
+
+ assertThat(result.getBaseComponent())
+ .extracting(Component::getKey, Component::getBranch)
+ .containsExactlyInAnyOrder(applicationBranch.getKey(), applicationBranch.getBranch());
+ assertThat(result.getComponentsList())
+ .extracting(Component::getKey, Component::getBranch, Component::getRefId, Component::getRefKey)
+ .containsExactlyInAnyOrder(tuple(techProjectBranch.getKey(), projectBranch.getBranch(), projectBranch.uuid(), project.getKey()));
+ }
+
+ @Test
public void response_is_empty_on_provisioned_projects() {
- ComponentDto project = componentDb.insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid"));
+ ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid"));
logInWithBrowsePermission(project);
TreeWsResponse response = ws.newRequest()
@@ -302,10 +325,10 @@ public class TreeActionTest {
@Test
public void return_projects_composing_a_view() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
- componentDb.insertProjectAndSnapshot(project);
+ db.components().insertProjectAndSnapshot(project);
ComponentDto view = newView(db.getDefaultOrganization(), "view-uuid");
- componentDb.insertViewAndSnapshot(view);
- componentDb.insertComponent(newProjectCopy("project-copy-uuid", project, view));
+ db.components().insertViewAndSnapshot(view);
+ db.components().insertComponent(newProjectCopy("project-copy-uuid", project, view));
userSession.logIn()
.registerComponents(project, view);
@@ -332,9 +355,9 @@ public class TreeActionTest {
.setParam(PARAM_BRANCH, branchKey)
.executeProtobuf(TreeWsResponse.class);
- assertThat(response.getBaseComponent()).extracting(Components.Component::getKey, Components.Component::getBranch)
+ assertThat(response.getBaseComponent()).extracting(Component::getKey, Component::getBranch)
.containsExactlyInAnyOrder(module.getKey(), branchKey);
- assertThat(response.getComponentsList()).extracting(Components.Component::getKey, Components.Component::getBranch)
+ assertThat(response.getComponentsList()).extracting(Component::getKey, Component::getBranch)
.containsExactlyInAnyOrder(
tuple(directory.getKey(), branchKey),
tuple(file.getKey(), branchKey));
@@ -355,9 +378,9 @@ public class TreeActionTest {
.setParam(PARAM_PULL_REQUEST, pullRequestId)
.executeProtobuf(TreeWsResponse.class);
- assertThat(response.getBaseComponent()).extracting(Components.Component::getKey, Components.Component::getPullRequest)
+ assertThat(response.getBaseComponent()).extracting(Component::getKey, Component::getPullRequest)
.containsExactlyInAnyOrder(module.getKey(), pullRequestId);
- assertThat(response.getComponentsList()).extracting(Components.Component::getKey, Components.Component::getPullRequest)
+ assertThat(response.getComponentsList()).extracting(Component::getKey, Component::getPullRequest)
.containsExactlyInAnyOrder(
tuple(directory.getKey(), pullRequestId),
tuple(file.getKey(), pullRequestId));
@@ -393,7 +416,7 @@ public class TreeActionTest {
@Test
public void fail_when_not_enough_privileges() {
- ComponentDto project = componentDb.insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
+ ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
userSession.logIn()
.addProjectPermission(UserRole.CODEVIEWER, project);
db.commit();
@@ -409,7 +432,7 @@ public class TreeActionTest {
public void fail_when_page_size_above_500() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("'ps' value (501) must be less than 500");
- componentDb.insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid"));
+ db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid"));
db.commit();
ws.newRequest()
@@ -422,7 +445,7 @@ public class TreeActionTest {
public void fail_when_search_query_has_less_than_3_characters() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("'q' length (2) is shorter than the minimum authorized (3)");
- componentDb.insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
+ db.components().insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
db.commit();
ws.newRequest()
@@ -434,7 +457,7 @@ public class TreeActionTest {
@Test
public void fail_when_sort_is_unknown() {
expectedException.expect(IllegalArgumentException.class);
- componentDb.insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid"));
+ db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid"));
db.commit();
ws.newRequest()
@@ -446,7 +469,7 @@ public class TreeActionTest {
@Test
public void fail_when_strategy_is_unknown() {
expectedException.expect(IllegalArgumentException.class);
- componentDb.insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
+ db.components().insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
db.commit();
ws.newRequest()
@@ -466,8 +489,8 @@ public class TreeActionTest {
@Test
public void fail_when_base_component_is_removed() {
- ComponentDto project = componentDb.insertComponent(newPrivateProjectDto(db.getDefaultOrganization()));
- componentDb.insertComponent(ComponentTesting.newFileDto(project).setDbKey("file-key").setEnabled(false));
+ ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization()));
+ db.components().insertComponent(ComponentTesting.newFileDto(project).setDbKey("file-key").setEnabled(false));
logInWithBrowsePermission(project);
expectedException.expect(NotFoundException.class);
@@ -532,7 +555,7 @@ public class TreeActionTest {
ComponentDto project = newPrivateProjectDto(organizationDto, "MY_PROJECT_ID")
.setDbKey("MY_PROJECT_KEY")
.setName("Project Name");
- componentDb.insertProjectAndSnapshot(project);
+ db.components().insertProjectAndSnapshot(project);
Date now = new Date();
JsonParser jsonParser = new JsonParser();
JsonElement jsonTree = jsonParser.parse(IOUtils.toString(getClass().getResource("tree-example.json"), UTF_8));
@@ -540,7 +563,7 @@ public class TreeActionTest {
for (JsonElement componentAsJsonElement : components) {
JsonObject componentAsJsonObject = componentAsJsonElement.getAsJsonObject();
String uuid = getJsonField(componentAsJsonObject, "id");
- componentDb.insertComponent(newChildComponent(uuid, project, project)
+ db.components().insertComponent(newChildComponent(uuid, project, project)
.setDbKey(getJsonField(componentAsJsonObject, "key"))
.setName(getJsonField(componentAsJsonObject, "name"))
.setLanguage(getJsonField(componentAsJsonObject, "language"))
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
index b02ac50d17d..db95f8711dc 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/index/IssueIndexTest.java
@@ -307,6 +307,25 @@ public class IssueIndexTest {
}
@Test
+ public void do_not_return_issues_from_project_branch_when_filtering_by_portfolios() {
+ ComponentDto portfolio = db.components().insertPrivateApplication(db.getDefaultOrganization());
+ ComponentDto project = db.components().insertMainBranch();
+ ComponentDto projectBranch = db.components().insertProjectBranch(project);
+ ComponentDto fileOnProjectBranch = db.components().insertComponent(newFileDto(projectBranch));
+ indexView(portfolio.uuid(), singletonList(project.uuid()));
+
+ IssueDoc issueOnProject = newDoc(project);
+ IssueDoc issueOnProjectBranch = newDoc(projectBranch);
+ IssueDoc issueOnFileOnProjectBranch = newDoc(fileOnProjectBranch);
+ indexIssues(issueOnProject, issueOnFileOnProjectBranch, issueOnProjectBranch);
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(portfolio.uuid())), issueOnProject.key());
+ assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(portfolio.uuid())).projectUuids(singletonList(project.uuid())),
+ issueOnProject.key());
+ assertThatSearchReturnsEmpty(IssueQuery.builder().viewUuids(singletonList(portfolio.uuid())).projectUuids(singletonList(projectBranch.uuid())));
+ }
+
+ @Test
public void filter_one_issue_by_project_and_branch() {
ComponentDto project = db.components().insertPrivateProject();
ComponentDto branch = db.components().insertProjectBranch(project);
@@ -379,20 +398,19 @@ public class IssueIndexTest {
}
@Test
- public void filter_by_application() {
+ public void filter_by_main_application() {
ComponentDto application1 = db.components().insertPrivateApplication(db.getDefaultOrganization());
ComponentDto application2 = db.components().insertPrivateApplication(db.getDefaultOrganization());
ComponentDto project1 = db.components().insertPrivateProject();
ComponentDto file = db.components().insertComponent(newFileDto(project1));
ComponentDto project2 = db.components().insertPrivateProject();
+ indexView(application1.uuid(), singletonList(project1.uuid()));
+ indexView(application2.uuid(), singletonList(project2.uuid()));
IssueDoc issueOnProject1 = newDoc(project1);
IssueDoc issueOnFile = newDoc(file);
IssueDoc issueOnProject2 = newDoc(project2);
-
indexIssues(issueOnProject1, issueOnFile, issueOnProject2);
- indexView(application1.uuid(), singletonList(project1.uuid()));
- indexView(application2.uuid(), singletonList(project2.uuid()));
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(application1.uuid())), issueOnProject1.key(), issueOnFile.key());
assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(application2.uuid())), issueOnProject2.key());
@@ -404,24 +422,23 @@ public class IssueIndexTest {
}
@Test
- public void filter_by_application_and_branch() {
+ public void filter_by_application_branch() {
ComponentDto application = db.components().insertMainBranch(c -> c.setQualifier(APP));
ComponentDto branch1 = db.components().insertProjectBranch(application);
ComponentDto branch2 = db.components().insertProjectBranch(application);
ComponentDto project1 = db.components().insertPrivateProject();
ComponentDto file = db.components().insertComponent(newFileDto(project1));
ComponentDto project2 = db.components().insertPrivateProject();
+ indexView(branch1.uuid(), singletonList(project1.uuid()));
+ indexView(branch2.uuid(), singletonList(project2.uuid()));
IssueDoc issueOnProject1 = newDoc(project1);
IssueDoc issueOnFile = newDoc(file);
IssueDoc issueOnProject2 = newDoc(project2);
indexIssues(issueOnProject1, issueOnFile, issueOnProject2);
- indexView(branch1.uuid(), singletonList(project1.uuid()));
- indexView(branch2.uuid(), singletonList(project2.uuid()));
-
- assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(branch1.uuid())).branchUuid(branch1.uuid()).mainBranch(false), issueOnProject1.key(),
- issueOnFile.key());
+ assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(branch1.uuid())).branchUuid(branch1.uuid()).mainBranch(false),
+ issueOnProject1.key(), issueOnFile.key());
assertThatSearchReturnsOnly(
IssueQuery.builder().viewUuids(singletonList(branch1.uuid())).projectUuids(singletonList(project1.uuid())).branchUuid(branch1.uuid()).mainBranch(false),
issueOnProject1.key(), issueOnFile.key());
@@ -431,6 +448,39 @@ public class IssueIndexTest {
}
@Test
+ public void filter_by_application_branch_having_project_branches() {
+ ComponentDto application = db.components().insertMainBranch(c -> c.setQualifier(APP).setDbKey("app"));
+ ComponentDto applicationBranch1 = db.components().insertProjectBranch(application, a -> a.setKey("app-branch1"));
+ ComponentDto applicationBranch2 = db.components().insertProjectBranch(application, a -> a.setKey("app-branch2"));
+ ComponentDto project1 = db.components().insertPrivateProject(p -> p.setDbKey("prj1"));
+ ComponentDto project1Branch1 = db.components().insertProjectBranch(project1);
+ ComponentDto fileOnProject1Branch1 = db.components().insertComponent(newFileDto(project1Branch1));
+ ComponentDto project1Branch2 = db.components().insertProjectBranch(project1);
+ ComponentDto project2 = db.components().insertPrivateProject(p -> p.setDbKey("prj2"));
+ indexView(applicationBranch1.uuid(), asList(project1Branch1.uuid(), project2.uuid()));
+ indexView(applicationBranch2.uuid(), singletonList(project1Branch2.uuid()));
+
+ IssueDoc issueOnProject1 = newDoc(project1);
+ IssueDoc issueOnProject1Branch1 = newDoc(project1Branch1);
+ IssueDoc issueOnFileOnProject1Branch1 = newDoc(fileOnProject1Branch1);
+ IssueDoc issueOnProject1Branch2 = newDoc(project1Branch2);
+ IssueDoc issueOnProject2 = newDoc(project2);
+ indexIssues(issueOnProject1, issueOnProject1Branch1, issueOnFileOnProject1Branch1, issueOnProject1Branch2, issueOnProject2);
+
+ assertThatSearchReturnsOnly(IssueQuery.builder().viewUuids(singletonList(applicationBranch1.uuid())).branchUuid(applicationBranch1.uuid()).mainBranch(false),
+ issueOnProject1Branch1.key(), issueOnFileOnProject1Branch1.key(), issueOnProject2.key());
+ assertThatSearchReturnsOnly(
+ IssueQuery.builder().viewUuids(singletonList(applicationBranch1.uuid())).projectUuids(singletonList(project1.uuid())).branchUuid(applicationBranch1.uuid()).mainBranch(false),
+ issueOnProject1Branch1.key(), issueOnFileOnProject1Branch1.key());
+ assertThatSearchReturnsOnly(
+ IssueQuery.builder().viewUuids(singletonList(applicationBranch1.uuid())).fileUuids(singletonList(fileOnProject1Branch1.uuid())).branchUuid(applicationBranch1.uuid())
+ .mainBranch(false),
+ issueOnFileOnProject1Branch1.key());
+ assertThatSearchReturnsEmpty(
+ IssueQuery.builder().viewUuids(singletonList(applicationBranch1.uuid())).projectUuids(singletonList("unknown")).branchUuid(applicationBranch1.uuid()).mainBranch(false));
+ }
+
+ @Test
public void filter_by_created_after_by_projects() {
Date now = new Date();
OrganizationDto organizationDto = newOrganizationDto();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java
index d5298d24369..2a601ec3767 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java
@@ -78,6 +78,7 @@ import static org.sonar.db.issue.IssueTesting.newIssue;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_COMPONENT_KEYS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PROJECT_KEYS;
+import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PROJECT_UUIDS;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PULL_REQUEST;
import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD;
@@ -688,26 +689,49 @@ public class SearchActionComponentsTest {
@Test
public void search_by_application_key_and_branch() {
- ComponentDto application = db.components().insertMainBranch(c -> c.setQualifier(APP));
- ComponentDto applicationBranch = db.components().insertProjectBranch(application);
- ComponentDto project1 = db.components().insertPrivateProject();
- ComponentDto project2 = db.components().insertPrivateProject();
- db.components().insertComponents(newProjectCopy(project1, applicationBranch));
- db.components().insertComponents(newProjectCopy(project2, applicationBranch));
+ ComponentDto application = db.components().insertMainBranch(c -> c.setQualifier(APP).setDbKey("app"));
+ ComponentDto applicationBranch1 = db.components().insertProjectBranch(application, a -> a.setKey("app-branch1"));
+ ComponentDto applicationBranch2 = db.components().insertProjectBranch(application, a -> a.setKey("app-branch2"));
+ ComponentDto project1 = db.components().insertPrivateProject(p -> p.setDbKey("prj1"));
+ ComponentDto project1Branch1 = db.components().insertProjectBranch(project1);
+ ComponentDto fileOnProject1Branch1 = db.components().insertComponent(newFileDto(project1Branch1));
+ ComponentDto project1Branch2 = db.components().insertProjectBranch(project1);
+ ComponentDto project2 = db.components().insertPrivateProject(p -> p.setDbKey("prj2"));
+ db.components().insertComponents(newProjectCopy(project1Branch1, applicationBranch1));
+ db.components().insertComponents(newProjectCopy(project2, applicationBranch1));
+ db.components().insertComponents(newProjectCopy(project1Branch2, applicationBranch2));
+
RuleDefinitionDto rule = db.rules().insert();
- IssueDto issue1 = db.issues().insert(rule, project1, project1);
- IssueDto issue2 = db.issues().insert(rule, project2, project2);
+ IssueDto issueOnProject1 = db.issues().insert(rule, project1, project1);
+ IssueDto issueOnProject1Branch1 = db.issues().insert(rule, project1Branch1, project1Branch1);
+ IssueDto issueOnFileOnProject1Branch1 = db.issues().insert(rule, project1Branch1, fileOnProject1Branch1);
+ IssueDto issueOnProject1Branch2 = db.issues().insert(rule, project1Branch2, project1Branch2);
+ IssueDto issueOnProject2 = db.issues().insert(rule, project2, project2);
allowAnyoneOnProjects(project1, project2, application);
userSession.addProjectPermission(USER, application);
indexIssuesAndViews();
- SearchWsResponse result = ws.newRequest()
- .setParam(PARAM_COMPONENT_KEYS, applicationBranch.getKey())
- .setParam(PARAM_BRANCH, applicationBranch.getBranch())
- .executeProtobuf(SearchWsResponse.class);
-
- assertThat(result.getIssuesList()).extracting(Issue::getKey)
- .containsExactlyInAnyOrder(issue1.getKey(), issue2.getKey());
+ // All issues on applicationBranch1
+ assertThat(ws.newRequest()
+ .setParam(PARAM_COMPONENT_KEYS, applicationBranch1.getKey())
+ .setParam(PARAM_BRANCH, applicationBranch1.getBranch())
+ .executeProtobuf(SearchWsResponse.class).getIssuesList())
+ .extracting(Issue::getKey, Issue::getComponent, Issue::getProject, Issue::getBranch, Issue::hasBranch)
+ .containsExactlyInAnyOrder(
+ tuple(issueOnProject1Branch1.getKey(), project1Branch1.getKey(), project1Branch1.getKey(), project1Branch1.getBranch(), true),
+ tuple(issueOnFileOnProject1Branch1.getKey(), fileOnProject1Branch1.getKey(), project1Branch1.getKey(), project1Branch1.getBranch(), true),
+ tuple(issueOnProject2.getKey(), project2.getKey(), project2.getKey(), "", false));
+
+ // Issues on project1Branch1
+ assertThat(ws.newRequest()
+ .setParam(PARAM_COMPONENT_KEYS, applicationBranch1.getKey())
+ .setParam(PARAM_PROJECT_UUIDS, project1.uuid())
+ .setParam(PARAM_BRANCH, applicationBranch1.getBranch())
+ .executeProtobuf(SearchWsResponse.class).getIssuesList())
+ .extracting(Issue::getKey, Issue::getComponent, Issue::getBranch)
+ .containsExactlyInAnyOrder(
+ tuple(issueOnProject1Branch1.getKey(), project1Branch1.getKey(), project1Branch1.getBranch()),
+ tuple(issueOnFileOnProject1Branch1.getKey(), fileOnProject1Branch1.getKey(), project1Branch1.getBranch()));
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
index 424c2607084..49af088982e 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
@@ -33,7 +33,6 @@ import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.component.SnapshotDto;
@@ -49,7 +48,6 @@ import org.sonar.server.i18n.I18nRule;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Common;
-import org.sonarqube.ws.Measures;
import org.sonarqube.ws.Measures.ComponentTreeWsResponse;
import org.sonarqube.ws.Measures.PeriodValue;
@@ -63,6 +61,7 @@ import static org.sonar.api.measures.Metric.ValueType.DISTRIB;
import static org.sonar.api.measures.Metric.ValueType.FLOAT;
import static org.sonar.api.measures.Metric.ValueType.INT;
import static org.sonar.api.measures.Metric.ValueType.RATING;
+import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.DIRECTORY;
import static org.sonar.api.resources.Qualifiers.FILE;
import static org.sonar.api.resources.Qualifiers.PROJECT;
@@ -94,6 +93,8 @@ import static org.sonar.server.measure.ws.ComponentTreeAction.METRIC_SORT;
import static org.sonar.server.measure.ws.ComponentTreeAction.NAME_SORT;
import static org.sonar.server.measure.ws.ComponentTreeAction.WITH_MEASURES_ONLY_METRIC_SORT_FILTER;
import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonarqube.ws.Measures.Component;
+import static org.sonarqube.ws.Measures.Measure;
public class ComponentTreeActionTest {
@Rule
@@ -107,7 +108,6 @@ public class ComponentTreeActionTest {
private ResourceTypesRule resourceTypes = new ResourceTypesRule()
.setRootQualifiers(PROJECT)
.setLeavesQualifiers(FILE, UNIT_TEST_FILE);
- private ComponentDbTester componentDb = new ComponentDbTester(db);
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
@@ -123,21 +123,21 @@ public class ComponentTreeActionTest {
SnapshotDto analysis = db.components().insertSnapshot(project, s -> s.setPeriodDate(parseDateTime("2016-01-11T10:49:50+0100").getTime())
.setPeriodMode("previous_version")
.setPeriodParam("1.0-SNAPSHOT"));
- ComponentDto file1 = componentDb.insertComponent(newFileDto(project, null)
+ ComponentDto file1 = db.components().insertComponent(newFileDto(project, null)
.setUuid("AVIwDXE-bJbJqrw6wFv5")
.setDbKey("com.sonarsource:java-markdown:src/main/java/com/sonarsource/markdown/impl/ElementImpl.java")
.setName("ElementImpl.java")
.setLanguage("java")
.setQualifier(FILE)
.setPath("src/main/java/com/sonarsource/markdown/impl/ElementImpl.java"));
- ComponentDto file2 = componentDb.insertComponent(newFileDto(project, null)
+ ComponentDto file2 = db.components().insertComponent(newFileDto(project, null)
.setUuid("AVIwDXE_bJbJqrw6wFwJ")
.setDbKey("com.sonarsource:java-markdown:src/test/java/com/sonarsource/markdown/impl/ElementImplTest.java")
.setName("ElementImplTest.java")
.setLanguage("java")
.setQualifier(UNIT_TEST_FILE)
.setPath("src/test/java/com/sonarsource/markdown/impl/ElementImplTest.java"));
- ComponentDto dir = componentDb.insertComponent(newDirectory(project, "src/main/java/com/sonarsource/markdown/impl")
+ ComponentDto dir = db.components().insertComponent(newDirectory(project, "src/main/java/com/sonarsource/markdown/impl")
.setUuid("AVIwDXE-bJbJqrw6wFv8")
.setDbKey("com.sonarsource:java-markdown:src/main/java/com/sonarsource/markdown/impl")
.setQualifier(DIRECTORY));
@@ -194,9 +194,9 @@ public class ComponentTreeActionTest {
.setPeriodDate(System.currentTimeMillis()));
userSession.anonymous().addProjectPermission(UserRole.USER, project);
ComponentDto directory = newDirectory(project, "directory-uuid", "path/to/directory").setName("directory-1");
- componentDb.insertComponent(directory);
+ db.components().insertComponent(directory);
ComponentDto file = newFileDto(directory, null, "file-uuid").setName("file-1");
- componentDb.insertComponent(file);
+ db.components().insertComponent(file);
MetricDto ncloc = insertNclocMetric();
MetricDto coverage = insertCoverageMetric();
db.commit();
@@ -212,7 +212,7 @@ public class ComponentTreeActionTest {
assertThat(response.getComponentsList().get(0).getMeasuresList()).extracting("metric").containsOnly("coverage");
// file measures
- List<Measures.Measure> fileMeasures = response.getComponentsList().get(1).getMeasuresList();
+ List<Measure> fileMeasures = response.getComponentsList().get(1).getMeasuresList();
assertThat(fileMeasures).extracting("metric").containsOnly("ncloc", "coverage");
assertThat(fileMeasures).extracting("value").containsOnly("5", "15.5");
assertThat(response.getPeriods().getPeriodsList()).extracting("mode").containsOnly("last_version");
@@ -224,9 +224,9 @@ public class ComponentTreeActionTest {
SnapshotDto projectSnapshot = db.components().insertSnapshot(project);
userSession.anonymous().addProjectPermission(UserRole.USER, project);
ComponentDto directory = newDirectory(project, "directory-uuid", "path/to/directory").setName("directory-1");
- componentDb.insertComponent(directory);
+ db.components().insertComponent(directory);
ComponentDto file = newFileDto(directory, null, "file-uuid").setName("file-1");
- componentDb.insertComponent(file);
+ db.components().insertComponent(file);
MetricDto coverage = insertCoverageMetric();
dbClient.metricDao().insert(dbSession, MetricTesting.newMetricDto()
.setKey("ncloc")
@@ -252,9 +252,9 @@ public class ComponentTreeActionTest {
// directory measures
assertThat(response.getComponentsList().get(0).getMeasuresList()).extracting("metric").containsOnly("coverage");
// file measures
- List<Measures.Measure> fileMeasures = response.getComponentsList().get(1).getMeasuresList();
+ List<Measure> fileMeasures = response.getComponentsList().get(1).getMeasuresList();
assertThat(fileMeasures)
- .extracting(Measures.Measure::getMetric, Measures.Measure::getValue, Measures.Measure::getBestValue, Measures.Measure::hasBestValue)
+ .extracting(Measure::getMetric, Measure::getValue, Measure::getBestValue, Measure::hasBestValue)
.containsExactlyInAnyOrder(tuple("ncloc", "100", true, true),
tuple("coverage", "15.5", false, false),
tuple("new_violations", "", false, false));
@@ -294,9 +294,9 @@ public class ComponentTreeActionTest {
.executeProtobuf(ComponentTreeWsResponse.class);
// file measures
- List<Measures.Measure> fileMeasures = response.getComponentsList().get(0).getMeasuresList();
+ List<Measure> fileMeasures = response.getComponentsList().get(0).getMeasuresList();
assertThat(fileMeasures)
- .extracting(Measures.Measure::getMetric, m -> m.getPeriods().getPeriodsValueList())
+ .extracting(Measure::getMetric, m -> m.getPeriods().getPeriodsValueList())
.containsExactlyInAnyOrder(
tuple(matchingBestValue.getKey(), singletonList(PeriodValue.newBuilder().setIndex(1).setValue("100").setBestValue(true).build())),
tuple(doesNotMatchBestValue.getKey(), singletonList(PeriodValue.newBuilder().setIndex(1).setValue("10").setBestValue(false).build())),
@@ -312,9 +312,9 @@ public class ComponentTreeActionTest {
.setPeriodMode("previous_version")
.setPeriodParam("1.0-SNAPSHOT"));
ComponentDto directory = newDirectory(project, "directory-uuid", "path/to/directory").setName("directory-1");
- componentDb.insertComponent(directory);
+ db.components().insertComponent(directory);
ComponentDto file = newFileDto(directory, null, "file-uuid").setName("file-1");
- componentDb.insertComponent(file);
+ db.components().insertComponent(file);
MetricDto metric = dbClient.metricDao().insert(dbSession, newMetricDto()
.setKey(NEW_SECURITY_RATING_KEY)
.setOptimizedBestValue(true)
@@ -339,15 +339,15 @@ public class ComponentTreeActionTest {
public void load_measures_multi_sort_with_metric_key_and_paginated() {
ComponentDto project = db.components().insertPrivateProject();
SnapshotDto projectSnapshot = db.components().insertSnapshot(project);
- ComponentDto file9 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-9").setName("file-1"));
- ComponentDto file8 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-8").setName("file-1"));
- ComponentDto file7 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-7").setName("file-1"));
- ComponentDto file6 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-6").setName("file-1"));
- ComponentDto file5 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-5").setName("file-1"));
- ComponentDto file4 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-4").setName("file-1"));
- ComponentDto file3 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-3").setName("file-1"));
- ComponentDto file2 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-2").setName("file-1"));
- ComponentDto file1 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-1").setName("file-1"));
+ ComponentDto file9 = db.components().insertComponent(newFileDto(project, null, "file-uuid-9").setName("file-1"));
+ ComponentDto file8 = db.components().insertComponent(newFileDto(project, null, "file-uuid-8").setName("file-1"));
+ ComponentDto file7 = db.components().insertComponent(newFileDto(project, null, "file-uuid-7").setName("file-1"));
+ ComponentDto file6 = db.components().insertComponent(newFileDto(project, null, "file-uuid-6").setName("file-1"));
+ ComponentDto file5 = db.components().insertComponent(newFileDto(project, null, "file-uuid-5").setName("file-1"));
+ ComponentDto file4 = db.components().insertComponent(newFileDto(project, null, "file-uuid-4").setName("file-1"));
+ ComponentDto file3 = db.components().insertComponent(newFileDto(project, null, "file-uuid-3").setName("file-1"));
+ ComponentDto file2 = db.components().insertComponent(newFileDto(project, null, "file-uuid-2").setName("file-1"));
+ ComponentDto file1 = db.components().insertComponent(newFileDto(project, null, "file-uuid-1").setName("file-1"));
MetricDto coverage = insertCoverageMetric();
db.commit();
db.measures().insertLiveMeasure(file1, coverage, m -> m.setValue(1.0d));
@@ -381,10 +381,10 @@ public class ComponentTreeActionTest {
public void sort_by_metric_value() {
ComponentDto project = db.components().insertPrivateProject();
SnapshotDto projectSnapshot = db.components().insertSnapshot(project);
- ComponentDto file4 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-4"));
- ComponentDto file3 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-3"));
- ComponentDto file1 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-1"));
- ComponentDto file2 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-2"));
+ ComponentDto file4 = db.components().insertComponent(newFileDto(project, null, "file-uuid-4"));
+ ComponentDto file3 = db.components().insertComponent(newFileDto(project, null, "file-uuid-3"));
+ ComponentDto file1 = db.components().insertComponent(newFileDto(project, null, "file-uuid-1"));
+ ComponentDto file2 = db.components().insertComponent(newFileDto(project, null, "file-uuid-2"));
MetricDto ncloc = newMetricDto().setKey("ncloc").setValueType(INT.name()).setDirection(1);
dbClient.metricDao().insert(dbSession, ncloc);
db.commit();
@@ -411,10 +411,10 @@ public class ComponentTreeActionTest {
ComponentDto file2 = newFileDto(project, null, "file-uuid-2");
ComponentDto file3 = newFileDto(project, null, "file-uuid-3");
ComponentDto file4 = newFileDto(project, null, "file-uuid-4");
- componentDb.insertComponent(file1);
- componentDb.insertComponent(file2);
- componentDb.insertComponent(file3);
- componentDb.insertComponent(file4);
+ db.components().insertComponent(file1);
+ db.components().insertComponent(file2);
+ db.components().insertComponent(file3);
+ db.components().insertComponent(file4);
MetricDto ncloc = newMetricDto().setKey("ncloc").setValueType(INT.name()).setDirection(1);
dbClient.metricDao().insert(dbSession, ncloc);
db.measures().insertLiveMeasure(file1, ncloc, m -> m.setData((String) null).setValue(1.0d).setVariation(null));
@@ -442,9 +442,9 @@ public class ComponentTreeActionTest {
public void sort_by_metric_period() {
ComponentDto project = db.components().insertPrivateProject();
SnapshotDto projectSnapshot = db.components().insertSnapshot(project);
- ComponentDto file3 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-3"));
- ComponentDto file1 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-1"));
- ComponentDto file2 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-2"));
+ ComponentDto file3 = db.components().insertComponent(newFileDto(project, null, "file-uuid-3"));
+ ComponentDto file1 = db.components().insertComponent(newFileDto(project, null, "file-uuid-1"));
+ ComponentDto file2 = db.components().insertComponent(newFileDto(project, null, "file-uuid-2"));
MetricDto ncloc = newMetricDto().setKey("ncloc").setValueType(INT.name()).setDirection(1);
dbClient.metricDao().insert(dbSession, ncloc);
db.commit();
@@ -467,10 +467,10 @@ public class ComponentTreeActionTest {
public void remove_components_without_measure_on_the_metric_period_sort() {
ComponentDto project = db.components().insertPrivateProject();
SnapshotDto projectSnapshot = db.components().insertSnapshot(project);
- ComponentDto file4 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-4"));
- ComponentDto file3 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-3"));
- ComponentDto file2 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-2"));
- ComponentDto file1 = componentDb.insertComponent(newFileDto(project, null, "file-uuid-1"));
+ ComponentDto file4 = db.components().insertComponent(newFileDto(project, null, "file-uuid-4"));
+ ComponentDto file3 = db.components().insertComponent(newFileDto(project, null, "file-uuid-3"));
+ ComponentDto file2 = db.components().insertComponent(newFileDto(project, null, "file-uuid-2"));
+ ComponentDto file1 = db.components().insertComponent(newFileDto(project, null, "file-uuid-1"));
MetricDto ncloc = newMetricDto().setKey("new_ncloc").setValueType(INT.name()).setDirection(1);
dbClient.metricDao().insert(dbSession, ncloc);
db.measures().insertLiveMeasure(file1, ncloc, m -> m.setData((String) null).setValue(null).setVariation(1.0d));
@@ -499,7 +499,7 @@ public class ComponentTreeActionTest {
resourceTypes.setLeavesQualifiers();
ComponentDto project = db.components().insertPrivateProject();
db.components().insertSnapshot(project);
- componentDb.insertComponent(newFileDto(project, null));
+ db.components().insertComponent(newFileDto(project, null));
insertNclocMetric();
ComponentTreeWsResponse result = ws.newRequest()
@@ -526,12 +526,12 @@ public class ComponentTreeActionTest {
.setParam(PARAM_COMPONENT, file.getKey())
.setParam(PARAM_BRANCH, file.getBranch())
.setParam(PARAM_METRIC_KEYS, complexity.getKey())
- .executeProtobuf(Measures.ComponentTreeWsResponse.class);
+ .executeProtobuf(ComponentTreeWsResponse.class);
- assertThat(response.getBaseComponent()).extracting(Measures.Component::getKey, Measures.Component::getBranch)
+ assertThat(response.getBaseComponent()).extracting(Component::getKey, Component::getBranch)
.containsExactlyInAnyOrder(file.getKey(), file.getBranch());
assertThat(response.getBaseComponent().getMeasuresList())
- .extracting(Measures.Measure::getMetric, m -> parseDouble(m.getValue()))
+ .extracting(Measure::getMetric, m -> parseDouble(m.getValue()))
.containsExactlyInAnyOrder(tuple(complexity.getKey(), measure.getValue()));
}
@@ -549,12 +549,12 @@ public class ComponentTreeActionTest {
.setParam(PARAM_COMPONENT, file.getKey())
.setParam(PARAM_PULL_REQUEST, "pr-123")
.setParam(PARAM_METRIC_KEYS, complexity.getKey())
- .executeProtobuf(Measures.ComponentTreeWsResponse.class);
+ .executeProtobuf(ComponentTreeWsResponse.class);
- assertThat(response.getBaseComponent()).extracting(Measures.Component::getKey, Measures.Component::getPullRequest)
+ assertThat(response.getBaseComponent()).extracting(Component::getKey, Component::getPullRequest)
.containsExactlyInAnyOrder(file.getKey(), "pr-123");
assertThat(response.getBaseComponent().getMeasuresList())
- .extracting(Measures.Measure::getMetric, m -> parseDouble(m.getValue()))
+ .extracting(Measure::getMetric, m -> parseDouble(m.getValue()))
.containsExactlyInAnyOrder(tuple(complexity.getKey(), measure.getValue()));
}
@@ -562,7 +562,7 @@ public class ComponentTreeActionTest {
public void return_deprecated_id_in_the_response() {
ComponentDto project = db.components().insertPrivateProject();
SnapshotDto analysis = db.components().insertSnapshot(project);
- ComponentDto file = componentDb.insertComponent(newFileDto(project));
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
MetricDto ncloc = insertNclocMetric();
db.measures().insertLiveMeasure(file, ncloc, m -> m.setValue(2d));
@@ -572,7 +572,7 @@ public class ComponentTreeActionTest {
.executeProtobuf(ComponentTreeWsResponse.class);
assertThat(response.getBaseComponent().getId()).isEqualTo(project.uuid());
- assertThat(response.getComponentsList()).extracting(Measures.Component::getId)
+ assertThat(response.getComponentsList()).extracting(Component::getId)
.containsExactlyInAnyOrder(file.uuid());
}
@@ -626,7 +626,7 @@ public class ComponentTreeActionTest {
}
@Test
- public void reference_component() {
+ public void project_reference_from_portfolio() {
ComponentDto project = db.components().insertPrivateProject();
ComponentDto view = db.components().insertPrivatePortfolio(db.getDefaultOrganization());
SnapshotDto viewAnalysis = db.components().insertSnapshot(view);
@@ -640,11 +640,38 @@ public class ComponentTreeActionTest {
.executeProtobuf(ComponentTreeWsResponse.class);
assertThat(result.getComponentsList())
- .extracting(Measures.Component::getKey, Measures.Component::getRefId, Measures.Component::getRefKey)
+ .extracting(Component::getKey, Component::getRefId, Component::getRefKey)
.containsExactlyInAnyOrder(tuple(projectCopy.getKey(), project.uuid(), project.getKey()));
}
@Test
+ public void project_branch_reference_from_application_branch() {
+ MetricDto ncloc = insertNclocMetric();
+ ComponentDto application = db.components().insertMainBranch(c -> c.setQualifier(APP).setDbKey("app-key"));
+ ComponentDto applicationBranch = db.components().insertProjectBranch(application, a -> a.setKey("app-branch"));
+ ComponentDto project = db.components().insertPrivateProject(p -> p.setDbKey("project-key"));
+ ComponentDto projectBranch = db.components().insertProjectBranch(project, b -> b.setKey("project-branch"));
+ ComponentDto techProjectBranch = db.components().insertComponent(newProjectCopy(projectBranch, applicationBranch)
+ .setDbKey(applicationBranch.getKey() + applicationBranch.getBranch() + projectBranch.getDbKey()));
+ SnapshotDto applicationBranchAnalysis = db.components().insertSnapshot(applicationBranch);
+ db.measures().insertLiveMeasure(applicationBranch, ncloc, m -> m.setValue(5d));
+ db.measures().insertLiveMeasure(techProjectBranch, ncloc, m -> m.setValue(1d));
+
+ ComponentTreeWsResponse result = ws.newRequest()
+ .setParam(PARAM_COMPONENT, applicationBranch.getKey())
+ .setParam(PARAM_BRANCH, applicationBranch.getBranch())
+ .setParam(PARAM_METRIC_KEYS, ncloc.getKey())
+ .executeProtobuf(ComponentTreeWsResponse.class);
+
+ assertThat(result.getBaseComponent())
+ .extracting(Component::getKey, Component::getBranch)
+ .containsExactlyInAnyOrder(applicationBranch.getKey(), applicationBranch.getBranch());
+ assertThat(result.getComponentsList())
+ .extracting(Component::getKey, Component::getBranch, Component::getRefId, Component::getRefKey)
+ .containsExactlyInAnyOrder(tuple(techProjectBranch.getKey(), projectBranch.getBranch(), projectBranch.uuid(), project.getKey()));
+ }
+
+ @Test
public void fail_when_metric_keys_parameter_is_empty() {
ComponentDto project = db.components().insertPrivateProject();
db.components().insertSnapshot(project);
@@ -854,7 +881,7 @@ public class ComponentTreeActionTest {
public void fail_when_component_is_removed() {
ComponentDto project = db.components().insertPrivateProject();
db.components().insertSnapshot(project);
- ComponentDto file = componentDb.insertComponent(newFileDto(project).setDbKey("file-key").setEnabled(false));
+ ComponentDto file = db.components().insertComponent(newFileDto(project).setDbKey("file-key").setEnabled(false));
userSession.anonymous().addProjectPermission(UserRole.USER, project);
insertNclocMetric();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ProjectLifeCycleListenersImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ProjectLifeCycleListenersImplTest.java
index 933e9a3ddc1..c1bf5acf7fa 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ProjectLifeCycleListenersImplTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ProjectLifeCycleListenersImplTest.java
@@ -128,6 +128,82 @@ public class ProjectLifeCycleListenersImplTest {
inOrder.verifyNoMoreInteractions();
}
+ @Test
+ public void onProjectBranchesDeleted_throws_NPE_if_set_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("projects can't be null");
+
+ underTestWithListeners.onProjectBranchesDeleted(null);
+ }
+
+ @Test
+ public void onProjectBranchesDeleted_throws_NPE_if_set_is_null_even_if_no_listeners() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("projects can't be null");
+
+ underTestNoListeners.onProjectBranchesDeleted(null);
+ }
+
+ @Test
+ public void onProjectBranchesDeleted_has_no_effect_if_set_is_empty() {
+ underTestNoListeners.onProjectBranchesDeleted(Collections.emptySet());
+
+ underTestWithListeners.onProjectBranchesDeleted(Collections.emptySet());
+ verifyZeroInteractions(listener1, listener2, listener3);
+ }
+
+ @Test
+ @UseDataProvider("oneOrManyProjects")
+ public void onProjectBranchesDeleted_does_not_fail_if_there_is_no_listener(Set<Project> projects) {
+ underTestNoListeners.onProjectBranchesDeleted(projects);
+ }
+
+ @Test
+ @UseDataProvider("oneOrManyProjects")
+ public void onProjectBranchesDeleted_calls_all_listeners_in_order_of_addition_to_constructor(Set<Project> projects) {
+ InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
+
+ underTestWithListeners.onProjectBranchesDeleted(projects);
+
+ inOrder.verify(listener1).onProjectBranchesDeleted(same(projects));
+ inOrder.verify(listener2).onProjectBranchesDeleted(same(projects));
+ inOrder.verify(listener3).onProjectBranchesDeleted(same(projects));
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ @UseDataProvider("oneOrManyProjects")
+ public void onProjectBranchesDeleted_calls_all_listeners_even_if_one_throws_an_Exception(Set<Project> projects) {
+ InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
+ doThrow(new RuntimeException("Faking listener2 throwing an exception"))
+ .when(listener2)
+ .onProjectBranchesDeleted(any());
+
+ underTestWithListeners.onProjectBranchesDeleted(projects);
+
+ inOrder.verify(listener1).onProjectBranchesDeleted(same(projects));
+ inOrder.verify(listener2).onProjectBranchesDeleted(same(projects));
+ inOrder.verify(listener3).onProjectBranchesDeleted(same(projects));
+ inOrder.verifyNoMoreInteractions();
+ }
+
+ @Test
+ @UseDataProvider("oneOrManyProjects")
+ public void onProjectBranchesDeleted_calls_all_listeners_even_if_one_throws_an_Error(Set<Project> projects) {
+ InOrder inOrder = Mockito.inOrder(listener1, listener2, listener3);
+ doThrow(new Error("Faking listener2 throwing an Error"))
+ .when(listener2)
+ .onProjectBranchesDeleted(any());
+
+ underTestWithListeners.onProjectBranchesDeleted(projects);
+
+ inOrder.verify(listener1).onProjectBranchesDeleted(same(projects));
+ inOrder.verify(listener2).onProjectBranchesDeleted(same(projects));
+ inOrder.verify(listener3).onProjectBranchesDeleted(same(projects));
+ inOrder.verifyNoMoreInteractions();
+ }
+
+
@DataProvider
public static Object[][] oneOrManyProjects() {
return new Object[][] {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java b/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java
index 4b5b12b437d..a36042baf76 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/view/index/ViewIndexerTest.java
@@ -56,6 +56,8 @@ import static com.google.common.collect.Lists.newArrayList;
import static java.util.Arrays.asList;
import static java.util.Collections.emptySet;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.db.component.ComponentTesting.newProjectCopy;
import static org.sonar.server.view.index.ViewIndexDefinition.INDEX_TYPE_VIEW;
@@ -65,18 +67,15 @@ public class ViewIndexerTest {
@Rule
public TestRule safeguardTimeout = new DisableOnDebug(Timeout.seconds(60));
-
@Rule
- public DbTester dbTester = DbTester.create(system2);
-
+ public DbTester db = DbTester.create();
@Rule
public EsTester es = EsTester.create();
-
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
- private DbClient dbClient = dbTester.getDbClient();
- private DbSession dbSession = dbTester.getSession();
+ private DbClient dbClient = db.getDbClient();
+ private DbSession dbSession = db.getSession();
private IssueIndexer issueIndexer = new IssueIndexer(es.client(), dbClient, new IssueIteratorFactory(dbClient));
private PermissionIndexer permissionIndexer = new PermissionIndexer(dbClient, es.client(), issueIndexer);
private ViewIndexer underTest = new ViewIndexer(dbClient, es.client());
@@ -89,7 +88,7 @@ public class ViewIndexerTest {
@Test
public void index_on_startup() {
- dbTester.prepareDbUnit(getClass(), "index.xml");
+ db.prepareDbUnit(getClass(), "index.xml");
underTest.indexOnStartup(emptySet());
@@ -106,7 +105,7 @@ public class ViewIndexerTest {
@Test
public void index_root_view() {
- dbTester.prepareDbUnit(getClass(), "index.xml");
+ db.prepareDbUnit(getClass(), "index.xml");
underTest.index("EFGH");
@@ -133,9 +132,9 @@ public class ViewIndexerTest {
@Test
public void index_application() {
- ComponentDto application = dbTester.components().insertApplication(dbTester.getDefaultOrganization());
- ComponentDto project = dbTester.components().insertPrivateProject();
- dbTester.components().insertComponent(newProjectCopy("PC1", project, application));
+ ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
+ ComponentDto project = db.components().insertPrivateProject();
+ db.components().insertComponent(newProjectCopy("PC1", project, application));
underTest.index(application.uuid());
List<ViewDoc> result = es.getDocuments(ViewIndexDefinition.INDEX_TYPE_VIEW, ViewDoc.class);
@@ -148,9 +147,9 @@ public class ViewIndexerTest {
@Test
public void index_application_on_startup() {
- ComponentDto application = dbTester.components().insertApplication(dbTester.getDefaultOrganization());
- ComponentDto project = dbTester.components().insertPrivateProject();
- dbTester.components().insertComponent(newProjectCopy("PC1", project, application));
+ ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
+ ComponentDto project = db.components().insertPrivateProject();
+ db.components().insertComponent(newProjectCopy("PC1", project, application));
underTest.indexOnStartup(emptySet());
List<ViewDoc> result = es.getDocuments(ViewIndexDefinition.INDEX_TYPE_VIEW, ViewDoc.class);
@@ -162,6 +161,31 @@ public class ViewIndexerTest {
}
@Test
+ public void index_application_branch() {
+ ComponentDto application = db.components().insertMainBranch(c -> c.setQualifier(APP).setDbKey("app"));
+ ComponentDto applicationBranch1 = db.components().insertProjectBranch(application, a -> a.setKey("app-branch1"));
+ ComponentDto applicationBranch2 = db.components().insertProjectBranch(application, a -> a.setKey("app-branch2"));
+ ComponentDto project1 = db.components().insertPrivateProject(p -> p.setDbKey("prj1"));
+ ComponentDto project1Branch = db.components().insertProjectBranch(project1);
+ ComponentDto project2 = db.components().insertPrivateProject(p -> p.setDbKey("prj2"));
+ ComponentDto project2Branch = db.components().insertProjectBranch(project2);
+ ComponentDto project3 = db.components().insertPrivateProject(p -> p.setDbKey("prj3"));
+ ComponentDto project3Branch = db.components().insertProjectBranch(project3);
+ db.components().insertComponent(newProjectCopy(project1Branch, applicationBranch1));
+ db.components().insertComponent(newProjectCopy(project2Branch, applicationBranch1));
+ // Technical project of applicationBranch2 should be ignored
+ db.components().insertComponent(newProjectCopy(project3Branch, applicationBranch2));
+
+ underTest.index(applicationBranch1.uuid());
+
+ List<ViewDoc> result = es.getDocuments(ViewIndexDefinition.INDEX_TYPE_VIEW, ViewDoc.class);
+ assertThat(result)
+ .extracting(ViewDoc::uuid, ViewDoc::projects)
+ .containsExactlyInAnyOrder(
+ tuple(applicationBranch1.uuid(), asList(project1Branch.uuid(), project2Branch.uuid())));
+ }
+
+ @Test
public void clear_views_lookup_cache_on_index_view_uuid() {
IssueIndex issueIndex = new IssueIndex(es.client(), System2.INSTANCE, userSessionRule, new AuthorizationTypeSupport(userSessionRule));
IssueIndexer issueIndexer = new IssueIndexer(es.client(), dbClient, new IssueIteratorFactory(dbClient));
@@ -170,11 +194,11 @@ public class ViewIndexerTest {
RuleDto rule = RuleTesting.newXooX1();
dbClient.ruleDao().insert(dbSession, rule.getDefinition());
- ComponentDto project1 = addProjectWithIssue(rule, dbTester.organizations().insert());
+ ComponentDto project1 = addProjectWithIssue(rule, db.organizations().insert());
issueIndexer.indexOnStartup(issueIndexer.getIndexTypes());
permissionIndexer.indexOnStartup(permissionIndexer.getIndexTypes());
- OrganizationDto organizationDto = dbTester.organizations().insert();
+ OrganizationDto organizationDto = db.organizations().insert();
ComponentDto view = ComponentTesting.newView(organizationDto, "ABCD");
ComponentDto techProject1 = newProjectCopy("CDEF", project1, view);
dbClient.componentDao().insert(dbSession, view, techProject1);
@@ -250,7 +274,7 @@ public class ViewIndexerTest {
private ComponentDto addProjectWithIssue(RuleDto rule, OrganizationDto org) {
ComponentDto project = ComponentTesting.newPublicProjectDto(org);
ComponentDto file = ComponentTesting.newFileDto(project, null);
- dbTester.components().insertComponents(project, file);
+ db.components().insertComponents(project, file);
IssueDto issue = IssueTesting.newDto(rule, file, project);
dbClient.issueDao().insert(dbSession, issue);