aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2018-02-06 13:58:34 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2018-02-07 16:43:01 +0100
commitbb56ae4237f712cb6060dcff1b82edb549767ae0 (patch)
tree26c673912a7bfcc8c6fc80c9502a772d2c262e70
parenta403ed93afa3982c3651799a00166a44a5b7872a (diff)
downloadsonarqube-bb56ae4237f712cb6060dcff1b82edb549767ae0.tar.gz
sonarqube-bb56ae4237f712cb6060dcff1b82edb549767ae0.zip
SONAR-10302 Auto issue assignment is now based on org membership
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoader.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndex.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoaderTest.java30
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexTest.java60
-rw-r--r--tests/src/test/java/org/sonarqube/tests/Category6Suite.java2
-rw-r--r--tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueAssignTest.java176
-rw-r--r--tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueSuite.java44
7 files changed, 212 insertions, 111 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoader.java b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoader.java
index 44092180e59..aeb3e9dfa72 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoader.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoader.java
@@ -27,6 +27,7 @@ import java.util.Map;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.core.util.stream.MoreCollectors;
+import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolder;
import org.sonar.server.user.index.UserDoc;
import org.sonar.server.user.index.UserIndex;
import org.sonar.server.util.cache.CacheLoader;
@@ -37,15 +38,18 @@ import org.sonar.server.util.cache.CacheLoader;
public class ScmAccountToUserLoader implements CacheLoader<String, String> {
private static final Logger LOGGER = Loggers.get(ScmAccountToUserLoader.class);
+
private final UserIndex index;
+ private final AnalysisMetadataHolder analysisMetadataHolder;
- public ScmAccountToUserLoader(UserIndex index) {
+ public ScmAccountToUserLoader(UserIndex index, AnalysisMetadataHolder analysisMetadataHolder) {
this.index = index;
+ this.analysisMetadataHolder = analysisMetadataHolder;
}
@Override
public String load(String scmAccount) {
- List<UserDoc> users = index.getAtMostThreeActiveUsersForScmAccount(scmAccount);
+ List<UserDoc> users = index.getAtMostThreeActiveUsersForScmAccount(scmAccount, analysisMetadataHolder.getOrganization().getUuid());
if (users.size() == 1) {
return users.get(0).login();
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndex.java b/server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndex.java
index 15f59ce0f5c..c33452c9cd2 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndex.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/user/index/UserIndex.java
@@ -81,13 +81,14 @@ public class UserIndex {
* Returns the active users (at most 3) who are associated to the given SCM account. This method can be used
* to detect user conflicts.
*/
- public List<UserDoc> getAtMostThreeActiveUsersForScmAccount(String scmAccount) {
+ public List<UserDoc> getAtMostThreeActiveUsersForScmAccount(String scmAccount, String organizationUuid) {
List<UserDoc> result = new ArrayList<>();
if (!StringUtils.isEmpty(scmAccount)) {
SearchRequestBuilder request = esClient.prepareSearch(UserIndexDefinition.INDEX_TYPE_USER)
.setQuery(boolQuery().must(matchAllQuery()).filter(
boolQuery()
.must(termQuery(FIELD_ACTIVE, true))
+ .must(termQuery(FIELD_ORGANIZATION_UUIDS, organizationUuid))
.should(termQuery(FIELD_LOGIN, scmAccount))
.should(matchQuery(SORTABLE_ANALYZER.subField(FIELD_EMAIL), scmAccount))
.should(matchQuery(SORTABLE_ANALYZER.subField(FIELD_SCM_ACCOUNTS), scmAccount))))
diff --git a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoaderTest.java
index 99523d36d41..c19b136fe43 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoaderTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/computation/task/projectanalysis/issue/ScmAccountToUserLoaderTest.java
@@ -20,28 +20,39 @@
package org.sonar.server.computation.task.projectanalysis.issue;
import java.util.Collections;
+import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.System2;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.server.computation.task.projectanalysis.analysis.AnalysisMetadataHolderRule;
+import org.sonar.server.computation.task.projectanalysis.analysis.Organization;
import org.sonar.server.es.EsTester;
import org.sonar.server.user.index.UserDoc;
import org.sonar.server.user.index.UserIndex;
import org.sonar.server.user.index.UserIndexDefinition;
import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
public class ScmAccountToUserLoaderTest {
- @org.junit.Rule
+ private static final String ORGANIZATION_UUID = "my-organization";
+
+ @Rule
public EsTester esTester = new EsTester(new UserIndexDefinition(new MapSettings().asConfig()));
- @org.junit.Rule
+ @Rule
public LogTester logTester = new LogTester();
+ @Rule
+ public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule()
+ .setOrganization(Organization.from(new OrganizationDto().setUuid(ORGANIZATION_UUID).setKey("Key").setName("Name").setDefaultQualityGateUuid("QGate")));
+
@Test
public void load_login_for_scm_account() {
UserDoc user = new UserDoc()
@@ -49,11 +60,12 @@ public class ScmAccountToUserLoaderTest {
.setName("Charlie")
.setEmail("charlie@hebdo.com")
.setActive(true)
- .setScmAccounts(asList("charlie", "jesuis@charlie.com"));
+ .setScmAccounts(asList("charlie", "jesuis@charlie.com"))
+ .setOrganizationUuids(singletonList(ORGANIZATION_UUID));
esTester.putDocuments(UserIndexDefinition.INDEX_TYPE_USER.getIndex(), UserIndexDefinition.INDEX_TYPE_USER.getType(), user);
UserIndex index = new UserIndex(esTester.client(), System2.INSTANCE);
- ScmAccountToUserLoader underTest = new ScmAccountToUserLoader(index);
+ ScmAccountToUserLoader underTest = new ScmAccountToUserLoader(index, analysisMetadataHolder);
assertThat(underTest.load("missing")).isNull();
assertThat(underTest.load("jesuis@charlie.com")).isEqualTo("charlie");
@@ -66,18 +78,20 @@ public class ScmAccountToUserLoaderTest {
.setName("Charlie")
.setEmail("charlie@hebdo.com")
.setActive(true)
- .setScmAccounts(asList("charlie", "jesuis@charlie.com"));
+ .setScmAccounts(asList("charlie", "jesuis@charlie.com"))
+ .setOrganizationUuids(singletonList(ORGANIZATION_UUID));
esTester.putDocuments(UserIndexDefinition.INDEX_TYPE_USER.getIndex(), UserIndexDefinition.INDEX_TYPE_USER.getType(), user1);
UserDoc user2 = new UserDoc()
.setLogin("another.charlie")
.setName("Another Charlie")
.setActive(true)
- .setScmAccounts(asList("charlie"));
+ .setScmAccounts(singletonList("charlie"))
+ .setOrganizationUuids(singletonList(ORGANIZATION_UUID));
esTester.putDocuments(UserIndexDefinition.INDEX_TYPE_USER.getIndex(), UserIndexDefinition.INDEX_TYPE_USER.getType(), user2);
UserIndex index = new UserIndex(esTester.client(), System2.INSTANCE);
- ScmAccountToUserLoader underTest = new ScmAccountToUserLoader(index);
+ ScmAccountToUserLoader underTest = new ScmAccountToUserLoader(index, analysisMetadataHolder);
assertThat(underTest.load("charlie")).isNull();
assertThat(logTester.logs(LoggerLevel.WARN)).contains("Multiple users share the SCM account 'charlie': another.charlie, charlie");
@@ -86,7 +100,7 @@ public class ScmAccountToUserLoaderTest {
@Test
public void load_by_multiple_scm_accounts_is_not_supported_yet() {
UserIndex index = new UserIndex(esTester.client(), System2.INSTANCE);
- ScmAccountToUserLoader underTest = new ScmAccountToUserLoader(index);
+ ScmAccountToUserLoader underTest = new ScmAccountToUserLoader(index, analysisMetadataHolder);
try {
underTest.loadAll(Collections.emptyList());
fail();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexTest.java
index 3ed10b6452a..45af16daf7b 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/user/index/UserIndexTest.java
@@ -33,11 +33,13 @@ import org.sonar.server.es.SearchOptions;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.server.user.index.UserIndexDefinition.INDEX_TYPE_USER;
public class UserIndexTest {
+ private static final String ORGANIZATION_UUID = "my-organization";
private static final String USER1_LOGIN = "user1";
private static final String USER2_LOGIN = "user2";
private static final long DATE_1 = 1_500_000_000_000L;
@@ -91,24 +93,24 @@ public class UserIndexTest {
esTester.putDocuments(INDEX_TYPE_USER, user2);
esTester.putDocuments(INDEX_TYPE_USER, user3);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(user1.scmAccounts().get(0))).extractingResultOf("login").containsOnly(user1.login());
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(user1.login())).extractingResultOf("login").containsOnly(user1.login());
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(user1.scmAccounts().get(0), ORGANIZATION_UUID)).extractingResultOf("login").containsOnly(user1.login());
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(user1.login(), ORGANIZATION_UUID)).extractingResultOf("login").containsOnly(user1.login());
// both users share the same email
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(user1.email())).extracting(UserDoc::login).containsOnly(user1.login(), user2.login());
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(user1.email(), ORGANIZATION_UUID)).extracting(UserDoc::login).containsOnly(user1.login(), user2.login());
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("")).isEmpty();
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("unknown")).isEmpty();
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("", ORGANIZATION_UUID)).isEmpty();
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("unknown", ORGANIZATION_UUID)).isEmpty();
}
@Test
public void getAtMostThreeActiveUsersForScmAccount_ignores_inactive_user() {
String scmAccount = "scmA";
- UserDoc user = newUser(USER1_LOGIN, asList(scmAccount)).setActive(false);
+ UserDoc user = newUser(USER1_LOGIN, singletonList(scmAccount)).setActive(false);
esTester.putDocuments(INDEX_TYPE_USER, user);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(user.login())).isEmpty();
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(scmAccount)).isEmpty();
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(user.login(), ORGANIZATION_UUID)).isEmpty();
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(scmAccount, ORGANIZATION_UUID)).isEmpty();
}
@Test
@@ -124,37 +126,47 @@ public class UserIndexTest {
esTester.putDocuments(INDEX_TYPE_USER, user4);
// restrict results to 3 users
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(email)).hasSize(3);
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount(email, ORGANIZATION_UUID)).hasSize(3);
}
@Test
public void getAtMostThreeActiveUsersForScmAccount_is_case_sensitive_for_login() {
- UserDoc user = newUser("the_login", asList("John.Smith"));
+ UserDoc user = newUser("the_login", singletonList("John.Smith"));
esTester.putDocuments(INDEX_TYPE_USER, user);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("the_login")).hasSize(1);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("the_Login")).isEmpty();
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("the_login", ORGANIZATION_UUID)).hasSize(1);
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("the_Login", ORGANIZATION_UUID)).isEmpty();
}
@Test
public void getAtMostThreeActiveUsersForScmAccount_is_case_insensitive_for_email() {
- UserDoc user = newUser("the_login", "the_EMAIL@corp.com", asList("John.Smith"));
+ UserDoc user = newUser("the_login", "the_EMAIL@corp.com", singletonList("John.Smith"));
esTester.putDocuments(INDEX_TYPE_USER, user);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("the_EMAIL@corp.com")).hasSize(1);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("the_email@corp.com")).hasSize(1);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("email")).isEmpty();
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("the_EMAIL@corp.com", ORGANIZATION_UUID)).hasSize(1);
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("the_email@corp.com", ORGANIZATION_UUID)).hasSize(1);
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("email", ORGANIZATION_UUID)).isEmpty();
}
@Test
public void getAtMostThreeActiveUsersForScmAccount_is_case_insensitive_for_scm_account() {
- UserDoc user = newUser("the_login", asList("John.Smith"));
+ UserDoc user = newUser("the_login", singletonList("John.Smith"));
esTester.putDocuments(INDEX_TYPE_USER, user);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("John.Smith")).hasSize(1);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("JOHN.SMIth")).hasSize(1);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("JOHN.SMITH")).hasSize(1);
- assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("JOHN")).isEmpty();
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("John.Smith", ORGANIZATION_UUID)).hasSize(1);
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("JOHN.SMIth", ORGANIZATION_UUID)).hasSize(1);
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("JOHN.SMITH", ORGANIZATION_UUID)).hasSize(1);
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("JOHN", ORGANIZATION_UUID)).isEmpty();
+ }
+
+ @Test
+ public void getAtMostThreeActiveUsersForScmAccount_search_only_user_within_given_organization() {
+ UserDoc user1 = newUser("user1", singletonList("same_scm")).setOrganizationUuids(singletonList(ORGANIZATION_UUID));
+ UserDoc user2 = newUser("user2", singletonList("same_scm")).setOrganizationUuids(singletonList("another_organization"));
+ esTester.putDocuments(INDEX_TYPE_USER, user1);
+ esTester.putDocuments(INDEX_TYPE_USER, user2);
+
+ assertThat(underTest.getAtMostThreeActiveUsersForScmAccount("same_scm", ORGANIZATION_UUID)).extractingResultOf("login").containsOnly(user1.login());
}
@Test
@@ -201,7 +213,8 @@ public class UserIndexTest {
.setName(login.toUpperCase(Locale.ENGLISH))
.setEmail(login + "@mail.com")
.setActive(true)
- .setScmAccounts(scmAccounts);
+ .setScmAccounts(scmAccounts)
+ .setOrganizationUuids(singletonList(ORGANIZATION_UUID));
}
private static UserDoc newUser(String login, String email, List<String> scmAccounts) {
@@ -210,6 +223,7 @@ public class UserIndexTest {
.setName(login.toUpperCase(Locale.ENGLISH))
.setEmail(email)
.setActive(true)
- .setScmAccounts(scmAccounts);
+ .setScmAccounts(scmAccounts)
+ .setOrganizationUuids(singletonList(ORGANIZATION_UUID));
}
}
diff --git a/tests/src/test/java/org/sonarqube/tests/Category6Suite.java b/tests/src/test/java/org/sonarqube/tests/Category6Suite.java
index 27db0db9d0d..dd8ecd2876b 100644
--- a/tests/src/test/java/org/sonarqube/tests/Category6Suite.java
+++ b/tests/src/test/java/org/sonarqube/tests/Category6Suite.java
@@ -29,7 +29,6 @@ import org.sonarqube.tests.authorization.PermissionTemplateTest;
import org.sonarqube.tests.ce.ReportFailureNotificationTest;
import org.sonarqube.tests.issue.IssueNotificationsTest;
import org.sonarqube.tests.issue.IssueTagsTest;
-import org.sonarqube.tests.issue.OrganizationIssueAssignTest;
import org.sonarqube.tests.issue.OrganizationIssuesPageTest;
import org.sonarqube.tests.qualityProfile.BuiltInQualityProfilesTest;
import org.sonarqube.tests.qualityProfile.CustomQualityProfilesTest;
@@ -53,7 +52,6 @@ import static util.ItUtils.xooPlugin;
@RunWith(Suite.class)
@Suite.SuiteClasses({
OrganizationIdentityProviderTest.class,
- OrganizationIssueAssignTest.class,
OrganizationIssuesPageTest.class,
OrganizationQualityProfilesUiTest.class,
BuiltInQualityProfilesTest.class,
diff --git a/tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueAssignTest.java b/tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueAssignTest.java
index 4e76ba14180..01e8e141431 100644
--- a/tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueAssignTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueAssignTest.java
@@ -21,24 +21,22 @@ package org.sonarqube.tests.issue;
import com.sonar.orchestrator.Orchestrator;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
-import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.sonarqube.qa.util.Tester;
import org.sonarqube.qa.util.pageobjects.issues.IssuesPage;
-import org.sonarqube.tests.Category6Suite;
import org.sonarqube.ws.Issues;
import org.sonarqube.ws.Issues.Issue;
-import org.sonarqube.ws.Organizations;
+import org.sonarqube.ws.Organizations.Organization;
+import org.sonarqube.ws.Projects.CreateWsResponse.Project;
+import org.sonarqube.ws.Qualityprofiles.CreateWsResponse.QualityProfile;
import org.sonarqube.ws.Users.CreateWsResponse.User;
import org.sonarqube.ws.client.issues.AssignRequest;
import org.sonarqube.ws.client.issues.BulkChangeRequest;
import org.sonarqube.ws.client.issues.SearchRequest;
-import org.sonarqube.ws.client.qualityprofiles.AddProjectRequest;
-import org.sonarqube.ws.client.projects.CreateRequest;
-import util.issue.IssueRule;
import static java.lang.String.format;
import static java.util.Collections.singletonList;
@@ -46,101 +44,120 @@ import static org.assertj.core.api.Assertions.assertThat;
import static util.ItUtils.expectHttpError;
import static util.ItUtils.restoreProfile;
import static util.ItUtils.runProjectAnalysis;
-import static util.ItUtils.setServerProperty;
public class OrganizationIssueAssignTest {
private final static String SAMPLE_PROJECT_KEY = "sample";
@ClassRule
- public static Orchestrator orchestrator = Category6Suite.ORCHESTRATOR;
+ public static Orchestrator orchestrator = OrganizationIssueSuite.ORCHESTRATOR;
@Rule
public Tester tester = new Tester(orchestrator);
- @Rule
- public IssueRule issueRule = IssueRule.from(orchestrator);
-
- private Organizations.Organization org1;
- private Organizations.Organization org2;
- private User user;
-
- @Before
- public void setUp() {
- org1 = tester.organizations().generate();
- org2 = tester.organizations().generate();
- user = tester.users().generate();
- restoreProfile(orchestrator, getClass().getResource("/organization/IssueAssignTest/one-issue-per-file-profile.xml"), org1.getKey());
- }
-
@Test
- public void auto_assign_issues_to_user_if_default_assignee_is_member_of_project_organization() {
- tester.organizations().addMember(org1, user);
+ public void auto_assign_issues_to_default_assignee_if_member_of_project_organization() {
+ Organization organization = tester.organizations().generate();
+ User user = tester.users().generateMember(organization);
+ provisionProjectAndAssociateItToQProfile(SAMPLE_PROJECT_KEY, organization);
+ tester.settings().setProjectSetting("sample", "sonar.issues.defaultAssigneeLogin", user.getLogin());
- provisionProject(SAMPLE_PROJECT_KEY, org1.getKey());
- setServerProperty(orchestrator, "sample", "sonar.issues.defaultAssigneeLogin", user.getLogin());
+ analyseProject(SAMPLE_PROJECT_KEY, organization);
- analyseProject(SAMPLE_PROJECT_KEY, org1.getKey());
-
- assertThat(issueRule.getRandomIssue().getAssignee()).isEqualTo(user.getLogin());
+ assertThat(getRandomIssue().getAssignee()).isEqualTo(user.getLogin());
}
@Test
- public void does_not_auto_assign_issues_to_user_if_default_assignee_is_not_member_of_project_organization() {
- tester.organizations().addMember(org2, user);
- provisionProject(SAMPLE_PROJECT_KEY, org1.getKey());
- setServerProperty(orchestrator, "sample", "sonar.issues.defaultAssigneeLogin", user.getLogin());
+ public void do_not_auto_assign_issues_to_default_assignee_if_not_member_of_project_organization() {
+ Organization organization1 = tester.organizations().generate();
+ Organization organization2 = tester.organizations().generate();
+ User user = tester.users().generateMember(organization2);
+ provisionProjectAndAssociateItToQProfile(SAMPLE_PROJECT_KEY, organization1);
+ tester.settings().setProjectSetting("sample", "sonar.issues.defaultAssigneeLogin", user.getLogin());
+
+ analyseProject(SAMPLE_PROJECT_KEY, organization1);
- analyseProject(SAMPLE_PROJECT_KEY, org1.getKey());
+ assertThat(getRandomIssue().hasAssignee()).isFalse();
+ }
- assertThat(issueRule.getRandomIssue().hasAssignee()).isFalse();
+ /**
+ * SONAR-10302
+ */
+ @Test
+ public void do_not_auto_assign_issues_to_user_if_assignee_is_not_member_of_project_organization() {
+ Organization organization1 = tester.organizations().generate();
+ Organization organization2 = tester.organizations().generate();
+ User fabrice = tester.users().generateMember(organization1, u -> u.setScmAccount(singletonList("fabrice")));
+ // Simon is not member of project's organization, no issue should be assigned to him
+ User simon = tester.users().generateMember(organization2, u -> u.setScmAccount(singletonList("simon")));
+ provisionProjectAndAssociateItToQProfile(SAMPLE_PROJECT_KEY, organization1);
+
+ analyseProject(SAMPLE_PROJECT_KEY, organization1);
+
+ Set<String> assignees = tester.wsClient().issues().search(new SearchRequest().setComponentKeys(singletonList(SAMPLE_PROJECT_KEY))).getIssuesList()
+ .stream()
+ .map(Issue::getAssignee)
+ .filter(s -> !s.isEmpty())
+ .collect(Collectors.toSet());
+ assertThat(assignees)
+ .containsOnly(fabrice.getLogin())
+ .doesNotContain(simon.getLogin());
}
@Test
public void assign_issue_to_user_being_member_of_same_organization_as_project_issue_organization() {
- tester.organizations().addMember(org1, user);
- provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, org1.getKey());
- Issue issue = issueRule.getRandomIssue();
+ Organization organization = tester.organizations().generate();
+ User user = tester.users().generateMember(organization);
+ provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, organization);
+ Issue issue = getRandomIssue();
assignIssueTo(issue, user);
- assertThat(issueRule.getByKey(issue.getKey()).getAssignee()).isEqualTo(user.getLogin());
+ assertThat(getByKey(issue.getKey()).getAssignee()).isEqualTo(user.getLogin());
}
@Test
public void fail_to_assign_issue_to_user_not_being_member_of_same_organization_as_project_issue_organization() {
- tester.organizations().addMember(org2, user);
- provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, org1.getKey());
- Issue issue = issueRule.getRandomIssue();
+ Organization organization1 = tester.organizations().generate();
+ Organization organization2 = tester.organizations().generate();
+ User user = tester.users().generateMember(organization2);
+ provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, organization1);
+ Issue issue = getRandomIssue();
expectHttpError(400,
- format("User '%s' is not member of organization '%s'", user.getLogin(), org1.getKey()),
+ format("User '%s' is not member of organization '%s'", user.getLogin(), organization1.getKey()),
() -> assignIssueTo(issue, user));
}
@Test
public void bulk_assign_issues_to_user_being_only_member_of_same_organization_as_project_issue_organization() {
- restoreProfile(orchestrator, getClass().getResource("/organization/IssueAssignTest/one-issue-per-file-profile.xml"), org2.getKey());
+ Organization organization1 = tester.organizations().generate();
+ Organization organization2 = tester.organizations().generate();
// User is only member of org1, not of org2
- tester.organizations().addMember(org1, user);
- provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, org1.getKey());
- provisionAndAnalyseProject("sample2", org2.getKey());
- List<String> issues = issueRule.search(new SearchRequest()).getIssuesList().stream().map(Issue::getKey).collect(Collectors.toList());
+ User user = tester.users().generateMember(organization1);
+
+ restoreProfile(orchestrator, getClass().getResource("/organization/IssueAssignTest/one-issue-per-file-profile.xml"), organization2.getKey());
+
+ provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, organization1);
+ provisionAndAnalyseProject("sample2", organization2);
+ List<String> issues = tester.wsClient().issues().search(new SearchRequest()).getIssuesList().stream().map(Issue::getKey).collect(Collectors.toList());
Issues.BulkChangeWsResponse response = tester.wsClient().issues()
.bulkChange(new BulkChangeRequest().setIssues(issues).setAssign(singletonList(user.getLogin())));
assertThat(response.getIgnored()).isGreaterThan(0);
- assertThat(issueRule.search(new SearchRequest().setProjects(singletonList("sample"))).getIssuesList()).extracting(Issue::getAssignee)
+ assertThat(tester.wsClient().issues().search(new SearchRequest().setProjects(singletonList("sample"))).getIssuesList()).extracting(Issue::getAssignee)
.containsOnly(user.getLogin());
- assertThat(issueRule.search(new SearchRequest().setProjects(singletonList("sample2"))).getIssuesList()).extracting(Issue::hasAssignee)
+ assertThat(tester.wsClient().issues().search(new SearchRequest().setProjects(singletonList("sample2"))).getIssuesList()).extracting(Issue::hasAssignee)
.containsOnly(false);
}
@Test
public void single_assign_search_show_only_members_in_global_issues() {
- tester.organizations().addMember(org1, user);
+ Organization organization = tester.organizations().generate();
+ User user = tester.users().generateMember(organization);
User otherUser = tester.users().generate();
- provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, org1.getKey());
+ provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, organization);
+
IssuesPage page = tester.openBrowser().logIn().submitCredentials(user.getLogin()).openIssues();
page.getFirstIssue()
.shouldAllowAssign()
@@ -150,10 +167,11 @@ public class OrganizationIssueAssignTest {
@Test
public void bulk_assign_search_only_members_of_organization_in_project_issues() {
- tester.organizations().addMember(org1, user);
+ Organization organization = tester.organizations().generate();
+ User user = tester.users().generateMember(organization);
User otherUser = tester.users().generate();
+ provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, organization);
- provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, org1.getKey());
IssuesPage page = tester.openBrowser()
.logIn().submitCredentials(user.getLogin())
.openComponentIssues(SAMPLE_PROJECT_KEY);
@@ -165,9 +183,10 @@ public class OrganizationIssueAssignTest {
@Test
public void bulk_assign_search_all_users_in_global_issues() {
- tester.organizations().addMember(org1, user);
+ Organization organization = tester.organizations().generate();
+ User user = tester.users().generateMember(organization);
User otherUser = tester.users().generate();
- provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, org1.getKey());
+ provisionAndAnalyseProject(SAMPLE_PROJECT_KEY, organization);
IssuesPage page = tester.openBrowser()
.logIn().submitCredentials(user.getLogin())
.openIssues();
@@ -177,37 +196,44 @@ public class OrganizationIssueAssignTest {
.bulkChangeAssigneeSearchCount(otherUser.getLogin(), 1);
}
- private void provisionAndAnalyseProject(String projectKey, String organization) {
- provisionProject(projectKey, organization);
+ private void provisionAndAnalyseProject(String projectKey, Organization organization) {
+ provisionProjectAndAssociateItToQProfile(projectKey, organization);
analyseProject(projectKey, organization);
}
- private void provisionProject(String projectKey, String organization) {
- tester.wsClient().projects().create(
- new CreateRequest()
- .setProject(projectKey)
- .setName(projectKey)
- .setOrganization(organization));
+ private void provisionProjectAndAssociateItToQProfile(String projectKey, Organization organization) {
+ Project project = tester.projects().provision(organization, p -> p.setProject(projectKey));
+ QualityProfile profile = tester.qProfiles().createXooProfile(organization);
+ tester.qProfiles()
+ .activateRule(profile, "xoo:OneIssuePerLine")
+ .assignQProfileToProject(profile, project);
}
- private void analyseProject(String projectKey, String organization) {
- addQualityProfileToProject(organization, projectKey);
+ private void analyseProject(String projectKey, Organization organization) {
runProjectAnalysis(orchestrator, "issue/xoo-with-scm",
"sonar.projectKey", projectKey,
- "sonar.organization", organization,
+ "sonar.organization", organization.getKey(),
"sonar.login", "admin",
"sonar.password", "admin",
"sonar.scm.disabled", "false",
"sonar.scm.provider", "xoo");
}
- private void addQualityProfileToProject(String organization, String projectKey) {
- tester.wsClient().qualityprofiles().addProject(
- new AddProjectRequest()
- .setProject(projectKey)
- .setOrganization(organization)
- .setLanguage("xoo")
- .setQualityProfile("one-issue-per-file-profile"));
+ private Issues.Issue getByKey(String issueKey) {
+ return tester.wsClient().issues().search(
+ new SearchRequest()
+ .setComponentKeys(singletonList(SAMPLE_PROJECT_KEY))
+ .setIssues(singletonList(issueKey)))
+ .getIssuesList()
+ .get(0);
+ }
+
+ private Issues.Issue getRandomIssue() {
+ return tester.wsClient().issues().search(
+ new SearchRequest()
+ .setComponentKeys(singletonList(SAMPLE_PROJECT_KEY)))
+ .getIssuesList()
+ .get(0);
}
private Issues.AssignResponse assignIssueTo(Issue issue, User u) {
diff --git a/tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueSuite.java b/tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueSuite.java
new file mode 100644
index 00000000000..2babb0d1985
--- /dev/null
+++ b/tests/src/test/java/org/sonarqube/tests/issue/OrganizationIssueSuite.java
@@ -0,0 +1,44 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.sonarqube.tests.issue;
+
+import com.sonar.orchestrator.Orchestrator;
+import org.junit.ClassRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+import static util.ItUtils.xooPlugin;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ OrganizationIssueAssignTest.class
+})
+public class OrganizationIssueSuite {
+
+ @ClassRule
+ public static final Orchestrator ORCHESTRATOR = Orchestrator.builderEnv()
+ .addPlugin(xooPlugin())
+
+ // reduce memory for Elasticsearch to 128M
+ .setServerProperty("sonar.search.javaOpts", "-Xms128m -Xmx128m")
+
+ .build();
+
+}