]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8798 convert medium tests to unit tests
authorDaniel Schwarz <daniel.schwarz@sonarsource.com>
Fri, 28 Jul 2017 13:32:29 +0000 (15:32 +0200)
committerDaniel Schwarz <bartfastiel@users.noreply.github.com>
Wed, 9 Aug 2017 13:09:54 +0000 (15:09 +0200)
69 files changed:
server/sonar-db-core/src/test/java/org/sonar/db/CoreTestDb.java
server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsMediumTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsTest.java
server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonMediumTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionMediumTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionTest.java
server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java
server/sonar-server/src/test/java/org/sonar/server/ws/TestResponse.java
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_directory_facet.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_file_facet.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_module_facet.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_non_sticky_project_facet.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_sticky_project_facet.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/issues_on_different_projects.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/no_issue.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_authors.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_developer.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_directory_uuid.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_file_key.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_file_uuid.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_project_uuid.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_test_key.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_view_uuid.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_since_leak_period.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_directory_facet.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_file_facet.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_module_facet.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_non_sticky_project_facet.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_sticky_project_facet.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/issues_on_different_projects.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/no_issue.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_authors.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_developer.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_directory_uuid.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_file_key.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_file_uuid.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_project_uuid.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_test_key.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_view_uuid.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_since_leak_period.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_nominal.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_left.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_right.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_nominal.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_param_on_left.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_param_on_right.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/encode_html_description_of_custom_rule.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_deprecated_rule_rem_function_fields.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_when_activated.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_default_and_overridden_debt_infos.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_default_debt_infos.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_no_default_and_no_overridden_debt.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_overridden_debt_infos.json [deleted file]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_deprecated_rule_rem_function_fields.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_when_activated.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_default_and_overridden_debt_infos.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_default_debt_infos.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_no_default_and_no_overridden_debt.json [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_overridden_debt_infos.json [new file with mode: 0644]

index 307521236070a5d05cace2aa0be00896d50d012c..8476c8ef8c9447f3d644cad7c8dbb59dd9ba738b 100644 (file)
@@ -91,7 +91,6 @@ class CoreTestDb {
           ((H2Database) db).executeScript(schemaPath);
         } else {
           db.stop();
-
         }
       }
       isDefault = (schemaPath == null);
@@ -153,6 +152,7 @@ class CoreTestDb {
     InputStream input = null;
     try {
       URI uri = new URI(url);
+
       if (url.startsWith("file:")) {
         File file = new File(uri);
         input = FileUtils.openInputStream(file);
@@ -164,8 +164,8 @@ class CoreTestDb {
         }
 
         input = connection.getInputStream();
-
       }
+
       Properties props = new Properties();
       props.load(input);
       settings.addProperties(props);
@@ -179,6 +179,4 @@ class CoreTestDb {
       IOUtils.closeQuietly(input);
     }
   }
-
-
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderMediumTest.java
deleted file mode 100644 (file)
index 6a97dae..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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.sonar.server.batch;
-
-import com.google.common.collect.ImmutableMap;
-import java.util.Date;
-import java.util.Map;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.permission.GlobalPermissions;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.organization.OrganizationTesting;
-import org.sonar.db.property.PropertyDto;
-import org.sonar.db.qualityprofile.DefaultQProfileDto;
-import org.sonar.db.qualityprofile.QProfileDto;
-import org.sonar.db.source.FileSourceDao;
-import org.sonar.db.source.FileSourceDto;
-import org.sonar.db.source.FileSourceDto.Type;
-import org.sonar.scanner.protocol.input.FileData;
-import org.sonar.scanner.protocol.input.ProjectRepositories;
-import org.sonar.server.exceptions.ForbiddenException;
-import org.sonar.server.qualityprofile.QProfileName;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.sonar.api.utils.DateUtils.formatDateTime;
-import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
-import static org.sonar.server.qualityprofile.QProfileTesting.newQProfileDto;
-
-public class ProjectDataLoaderMediumTest {
-
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester().withEsIndexes().addXoo();
-
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
-
-  DbSession dbSession;
-  DbClient dbClient;
-
-  ProjectDataLoader underTest;
-
-  @Before
-  public void before() {
-    tester.clearDbAndIndexes();
-    dbClient = tester.get(DbClient.class);
-    dbSession = dbClient.openSession(false);
-    underTest = tester.get(ProjectDataLoader.class);
-  }
-
-  @After
-  public void after() {
-    dbSession.close();
-  }
-
-  @Test
-  public void return_project_settings_with_global_scan_permission() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-
-    Map<String, String> projectSettings = ref.settings(project.getDbKey());
-    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"));
-  }
-
-  @Test
-  public void return_project_settings_with_project_scan_permission() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn("john").addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-
-    Map<String, String> projectSettings = ref.settings(project.getDbKey());
-    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"));
-  }
-
-  @Test
-  public void not_returned_secured_settings_when_lgged_but_no_scan_permission() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn("john").addProjectPermission(UserRole.USER, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()).setIssuesMode(true));
-    Map<String, String> projectSettings = ref.settings(project.getDbKey());
-    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR"));
-  }
-
-  @Test
-  public void return_project_with_module_settings() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module);
-
-    // Module properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"));
-    assertThat(ref.settings(module.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"));
-  }
-
-  @Test
-  public void return_project_with_module_settings_inherited_from_project() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module);
-
-    // No property on module -> should have the same as project
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"));
-    assertThat(ref.settings(module.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"));
-  }
-
-  @Test
-  public void return_project_with_module_with_sub_module() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module);
-
-    // Module properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()));
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    dbClient.componentDao().insert(dbSession, subModule);
-
-    // Sub module properties
-    dbClient.propertiesDao().saveProperty(
-      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER-DAO").setResourceId(subModule.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"));
-    assertThat(ref.settings(module.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"));
-    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER-DAO",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"));
-  }
-
-  @Test
-  public void return_project_with_two_modules() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    ComponentDto module1 = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module1);
-
-    // Module 1 properties
-    dbClient.propertiesDao()
-      .saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module1.getId()));
-    // This property should not be found on the other module
-    dbClient.propertiesDao()
-      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module1.getId()));
-
-    ComponentDto module2 = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module2);
-
-    // Module 2 property
-    dbClient.propertiesDao()
-      .saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION").setResourceId(module2.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"));
-    assertThat(ref.settings(module1.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"));
-    assertThat(ref.settings(module2.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-APPLICATION",
-      "sonar.jira.login.secured", "john"));
-  }
-
-  @Test
-  public void return_provisioned_project_settings() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    // No snapshot attached on the project -> provisioned project
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john"));
-  }
-
-  @Test
-  public void return_sub_module_settings() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-    // No project properties
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module);
-    // No module properties
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, subModule);
-
-    // Sub module properties
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId()));
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId()));
-    dbClient.propertiesDao()
-      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEmpty();
-    assertThat(ref.settings(module.getDbKey())).isEmpty();
-    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"));
-  }
-
-  @Test
-  public void return_sub_module_settings_including_settings_from_parent_modules() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project property
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module);
-
-    // Module property
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId()));
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, subModule);
-
-    // Sub module properties
-    dbClient.propertiesDao()
-      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEmpty();
-    assertThat(ref.settings(module.getDbKey())).isEmpty();
-    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"));
-  }
-
-  @Test
-  public void return_sub_module_settings_only_inherited_from_project() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-    dbClient.propertiesDao()
-      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module);
-    // No module property
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, subModule);
-    // No sub module property
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEmpty();
-    assertThat(ref.settings(module.getDbKey())).isEmpty();
-    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"));
-  }
-
-  @Test
-  public void return_sub_module_settings_inherited_from_project_and_module() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // Project properties
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
-    dbClient.propertiesDao()
-      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module);
-
-    // Module property
-    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
-
-    ComponentDto subModule = ComponentTesting.newModuleDto(module);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, subModule);
-    // No sub module property
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getDbKey()));
-    assertThat(ref.settings(project.getDbKey())).isEmpty();
-    assertThat(ref.settings(module.getDbKey())).isEmpty();
-    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
-      "sonar.jira.project.key", "SONAR-SERVER",
-      "sonar.jira.login.secured", "john",
-      "sonar.coverage.exclusions", "**/*.java"));
-  }
-
-  @Test
-  public void fail_when_no_browse_permission_nor_scan_permission() {
-    userSessionRule.logIn();
-
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    dbClient.componentDao().insert(dbSession, project);
-    dbSession.commit();
-
-    try {
-      underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-      fail();
-    } catch (Exception e) {
-      assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage(Messages.NO_PERMISSION);
-    }
-  }
-
-  @Test
-  public void fail_when_not_preview_and_only_browse_permission_without_scan_permission() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    dbClient.componentDao().insert(dbSession, project);
-    dbSession.commit();
-
-    userSessionRule.logIn("john").addProjectPermission(UserRole.USER, project);
-
-    thrown.expect(ForbiddenException.class);
-    thrown.expectMessage("You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server. " +
-      "Please contact your SonarQube administrator.");
-    underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()).setIssuesMode(false));
-  }
-
-  @Test
-  public void fail_when_preview_and_only_scan_permission_without_browse_permission() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    dbClient.componentDao().insert(dbSession, project);
-    dbSession.commit();
-
-    userSessionRule.logIn("john").addProjectPermission(GlobalPermissions.SCAN_EXECUTION, project);
-
-    thrown.expect(ForbiddenException.class);
-    thrown.expectMessage("You don't have the required permissions to access this project. Please contact your SonarQube administrator.");
-    underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()).setIssuesMode(true));
-  }
-
-  @Test
-  public void return_file_data_from_single_project() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    ComponentDto file = ComponentTesting.newFileDto(project, null, "file");
-    dbClient.componentDao().insert(dbSession, file);
-    tester.get(FileSourceDao.class).insert(dbSession, newFileSourceDto(file).setSrcHash("123456"));
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-    assertThat(ref.fileDataByPath(project.getDbKey())).hasSize(1);
-    FileData fileData = ref.fileData(project.getDbKey(), file.path());
-    assertThat(fileData.hash()).isEqualTo("123456");
-  }
-
-  @Test
-  public void return_file_data_from_multi_modules() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // File on project
-    ComponentDto projectFile = ComponentTesting.newFileDto(project, null, "projectFile");
-    dbClient.componentDao().insert(dbSession, projectFile);
-    tester.get(FileSourceDao.class).insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456"));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    dbClient.componentDao().insert(dbSession, module);
-
-    // File on module
-    ComponentDto moduleFile = ComponentTesting.newFileDto(module, null, "moduleFile");
-    dbClient.componentDao().insert(dbSession, moduleFile);
-    tester.get(FileSourceDao.class).insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456"));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
-    assertThat(ref.fileData(project.getDbKey(), projectFile.path()).hash()).isEqualTo("123456");
-    assertThat(ref.fileData(module.getDbKey(), moduleFile.path()).hash()).isEqualTo("789456");
-  }
-
-  @Test
-  public void return_file_data_from_module() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
-    dbClient.componentDao().insert(dbSession, project);
-    addDefaultProfile();
-
-    // File on project
-    ComponentDto projectFile = ComponentTesting.newFileDto(project, null, "projectFile");
-    dbClient.componentDao().insert(dbSession, projectFile);
-    tester.get(FileSourceDao.class).insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456").setRevision("987654321"));
-
-    ComponentDto module = ComponentTesting.newModuleDto(project);
-    userSessionRule.logIn().addProjectPermission(SCAN_EXECUTION, project);
-    dbClient.componentDao().insert(dbSession, module);
-
-    // File on module
-    ComponentDto moduleFile = ComponentTesting.newFileDto(module, null, "moduleFile");
-    dbClient.componentDao().insert(dbSession, moduleFile);
-    tester.get(FileSourceDao.class).insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456").setRevision("123456789"));
-
-    dbSession.commit();
-
-    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(module.getDbKey()));
-    assertThat(ref.fileData(module.getDbKey(), moduleFile.path()).hash()).isEqualTo("789456");
-    assertThat(ref.fileData(module.getDbKey(), moduleFile.path()).revision()).isEqualTo("123456789");
-    assertThat(ref.fileData(project.getDbKey(), projectFile.path())).isNull();
-  }
-
-  private void addDefaultProfile() {
-    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
-    dbClient.organizationDao().insert(dbSession, organizationDto, false);
-    QProfileDto profileDto = newQProfileDto(organizationDto, QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
-      formatDateTime(new Date()));
-    dbClient.qualityProfileDao().insert(dbSession, profileDto);
-    dbClient.defaultQProfileDao().insertOrUpdate(dbSession, DefaultQProfileDto.from(profileDto));
-  }
-
-  private static FileSourceDto newFileSourceDto(ComponentDto file) {
-    return new FileSourceDto()
-      .setFileUuid(file.uuid())
-      .setProjectUuid(file.projectUuid())
-      .setDataHash("0263047cd758c68c27683625f072f010")
-      .setLineHashes("8d7b3d6b83c0a517eac07e1aac94b773")
-      .setCreatedAt(System.currentTimeMillis())
-      .setUpdatedAt(System.currentTimeMillis())
-      .setDataType(Type.SOURCE)
-      .setRevision("123456789")
-      .setSrcHash("123456");
-  }
-
-}
index 9b3e6580231d082ce06806876a643ad4af4e3b7d..3d9ed37b414f13c23fa4ca481a9ec2079dbe520a 100644 (file)
@@ -19,6 +19,9 @@
  */
 package org.sonar.server.batch;
 
+import com.google.common.collect.ImmutableMap;
+import java.util.Date;
+import java.util.Map;
 import org.junit.After;
 import org.junit.Rule;
 import org.junit.Test;
@@ -32,17 +35,30 @@ import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.organization.OrganizationTesting;
+import org.sonar.db.property.PropertyDto;
+import org.sonar.db.qualityprofile.DefaultQProfileDto;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.source.FileSourceDto;
+import org.sonar.db.source.FileSourceDto.Type;
+import org.sonar.scanner.protocol.input.FileData;
 import org.sonar.scanner.protocol.input.ProjectRepositories;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.qualityprofile.QProfileName;
+import org.sonar.server.tester.ServerTester;
 import org.sonar.server.tester.UserSessionRule;
 
 import static java.lang.String.format;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
+import static org.sonar.api.utils.DateUtils.formatDateTime;
+import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
 import static org.sonar.db.permission.OrganizationPermission.SCAN;
+import static org.sonar.server.qualityprofile.QProfileTesting.newQProfileDto;
 
 public class ProjectDataLoaderTest {
   @Rule
@@ -181,4 +197,545 @@ public class ProjectDataLoaderTest {
 
     assertThat(repositories).isNotNull();
   }
+
+
+  @Test
+  public void return_project_settings_with_global_scan_permission() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+
+    Map<String, String> projectSettings = ref.settings(project.getDbKey());
+    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"));
+  }
+
+  @Test
+  public void return_project_settings_with_project_scan_permission() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn("john").addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+
+    Map<String, String> projectSettings = ref.settings(project.getDbKey());
+    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"));
+  }
+
+  @Test
+  public void not_returned_secured_settings_when_lgged_but_no_scan_permission() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn("john").addProjectPermission(UserRole.USER, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()).setIssuesMode(true));
+    Map<String, String> projectSettings = ref.settings(project.getDbKey());
+    assertThat(projectSettings).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR"));
+  }
+
+  @Test
+  public void return_project_with_module_settings() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module);
+
+    // Module properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"));
+    assertThat(ref.settings(module.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"));
+  }
+
+  @Test
+  public void return_project_with_module_settings_inherited_from_project() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module);
+
+    // No property on module -> should have the same as project
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"));
+    assertThat(ref.settings(module.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"));
+  }
+
+  @Test
+  public void return_project_with_module_with_sub_module() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module);
+
+    // Module properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module.getId()));
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    dbClient.componentDao().insert(dbSession, subModule);
+
+    // Sub module properties
+    dbClient.propertiesDao().saveProperty(
+      dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER-DAO").setResourceId(subModule.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"));
+    assertThat(ref.settings(module.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"));
+    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER-DAO",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"));
+  }
+
+  @Test
+  public void return_project_with_two_modules() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    ComponentDto module1 = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module1);
+
+    // Module 1 properties
+    dbClient.propertiesDao()
+      .saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module1.getId()));
+    // This property should not be found on the other module
+    dbClient.propertiesDao()
+      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(module1.getId()));
+
+    ComponentDto module2 = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module2);
+
+    // Module 2 property
+    dbClient.propertiesDao()
+      .saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-APPLICATION").setResourceId(module2.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"));
+    assertThat(ref.settings(module1.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"));
+    assertThat(ref.settings(module2.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-APPLICATION",
+      "sonar.jira.login.secured", "john"));
+  }
+
+  @Test
+  public void return_provisioned_project_settings() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    // No snapshot attached on the project -> provisioned project
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john"));
+  }
+
+  @Test
+  public void return_sub_module_settings() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+    // No project properties
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module);
+    // No module properties
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, subModule);
+
+    // Sub module properties
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(subModule.getId()));
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(subModule.getId()));
+    dbClient.propertiesDao()
+      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEmpty();
+    assertThat(ref.settings(module.getDbKey())).isEmpty();
+    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"));
+  }
+
+  @Test
+  public void return_sub_module_settings_including_settings_from_parent_modules() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project property
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module);
+
+    // Module property
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(module.getId()));
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, subModule);
+
+    // Sub module properties
+    dbClient.propertiesDao()
+      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(subModule.getId()));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEmpty();
+    assertThat(ref.settings(module.getDbKey())).isEmpty();
+    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"));
+  }
+
+  @Test
+  public void return_sub_module_settings_only_inherited_from_project() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR").setResourceId(project.getId()));
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+    dbClient.propertiesDao()
+      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module);
+    // No module property
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, subModule);
+    // No sub module property
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEmpty();
+    assertThat(ref.settings(module.getDbKey())).isEmpty();
+    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"));
+  }
+
+  @Test
+  public void return_sub_module_settings_inherited_from_project_and_module() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // Project properties
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.login.secured").setValue("john").setResourceId(project.getId()));
+    dbClient.propertiesDao()
+      .saveProperty(dbSession, new PropertyDto().setKey("sonar.coverage.exclusions").setValue("**/*.java").setResourceId(project.getId()));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module);
+
+    // Module property
+    dbClient.propertiesDao().saveProperty(dbSession, new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR-SERVER").setResourceId(module.getId()));
+
+    ComponentDto subModule = ComponentTesting.newModuleDto(module);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, subModule);
+    // No sub module property
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(subModule.getDbKey()));
+    assertThat(ref.settings(project.getDbKey())).isEmpty();
+    assertThat(ref.settings(module.getDbKey())).isEmpty();
+    assertThat(ref.settings(subModule.getDbKey())).isEqualTo(ImmutableMap.of(
+      "sonar.jira.project.key", "SONAR-SERVER",
+      "sonar.jira.login.secured", "john",
+      "sonar.coverage.exclusions", "**/*.java"));
+  }
+
+  @Test
+  public void fail_when_no_browse_permission_nor_scan_permission() {
+    userSession.logIn();
+
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    dbClient.componentDao().insert(dbSession, project);
+    dbSession.commit();
+
+    try {
+      underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+      fail();
+    } catch (Exception e) {
+      assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage(Messages.NO_PERMISSION);
+    }
+  }
+
+  @Test
+  public void fail_when_not_preview_and_only_browse_permission_without_scan_permission() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    dbClient.componentDao().insert(dbSession, project);
+    dbSession.commit();
+
+    userSession.logIn("john").addProjectPermission(UserRole.USER, project);
+
+    expectedException.expect(ForbiddenException.class);
+    expectedException.expectMessage("You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server. " +
+      "Please contact your SonarQube administrator.");
+    underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()).setIssuesMode(false));
+  }
+
+  @Test
+  public void fail_when_preview_and_only_scan_permission_without_browse_permission() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    dbClient.componentDao().insert(dbSession, project);
+    dbSession.commit();
+
+    userSession.logIn("john").addProjectPermission(GlobalPermissions.SCAN_EXECUTION, project);
+
+    expectedException.expect(ForbiddenException.class);
+    expectedException.expectMessage("You don't have the required permissions to access this project. Please contact your SonarQube administrator.");
+    underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()).setIssuesMode(true));
+  }
+
+  @Test
+  public void return_file_data_from_single_project() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    ComponentDto file = ComponentTesting.newFileDto(project, null, "file");
+    dbClient.componentDao().insert(dbSession, file);
+    dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(file).setSrcHash("123456"));
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+    assertThat(ref.fileDataByPath(project.getDbKey())).hasSize(1);
+    FileData fileData = ref.fileData(project.getDbKey(), file.path());
+    assertThat(fileData.hash()).isEqualTo("123456");
+  }
+
+  @Test
+  public void return_file_data_from_multi_modules() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // File on project
+    ComponentDto projectFile = ComponentTesting.newFileDto(project, null, "projectFile");
+    dbClient.componentDao().insert(dbSession, projectFile);
+    dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456"));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    dbClient.componentDao().insert(dbSession, module);
+
+    // File on module
+    ComponentDto moduleFile = ComponentTesting.newFileDto(module, null, "moduleFile");
+    dbClient.componentDao().insert(dbSession, moduleFile);
+    dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456"));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(project.getDbKey()));
+    assertThat(ref.fileData(project.getDbKey(), projectFile.path()).hash()).isEqualTo("123456");
+    assertThat(ref.fileData(module.getDbKey(), moduleFile.path()).hash()).isEqualTo("789456");
+  }
+
+  @Test
+  public void return_file_data_from_module() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    ComponentDto project = ComponentTesting.newPrivateProjectDto(organizationDto);
+    dbClient.componentDao().insert(dbSession, project);
+    addDefaultProfile();
+
+    // File on project
+    ComponentDto projectFile = ComponentTesting.newFileDto(project, null, "projectFile");
+    dbClient.componentDao().insert(dbSession, projectFile);
+    dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(projectFile).setSrcHash("123456").setRevision("987654321"));
+
+    ComponentDto module = ComponentTesting.newModuleDto(project);
+    userSession.logIn().addProjectPermission(SCAN_EXECUTION, project);
+    dbClient.componentDao().insert(dbSession, module);
+
+    // File on module
+    ComponentDto moduleFile = ComponentTesting.newFileDto(module, null, "moduleFile");
+    dbClient.componentDao().insert(dbSession, moduleFile);
+    dbClient.fileSourceDao().insert(dbSession, newFileSourceDto(moduleFile).setSrcHash("789456").setRevision("123456789"));
+
+    dbSession.commit();
+
+    ProjectRepositories ref = underTest.load(ProjectDataQuery.create().setModuleKey(module.getDbKey()));
+    assertThat(ref.fileData(module.getDbKey(), moduleFile.path()).hash()).isEqualTo("789456");
+    assertThat(ref.fileData(module.getDbKey(), moduleFile.path()).revision()).isEqualTo("123456789");
+    assertThat(ref.fileData(project.getDbKey(), projectFile.path())).isNull();
+  }
+
+  private void addDefaultProfile() {
+    OrganizationDto organizationDto = OrganizationTesting.newOrganizationDto();
+    dbClient.organizationDao().insert(dbSession, organizationDto, false);
+    QProfileDto profileDto = newQProfileDto(organizationDto, QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+      formatDateTime(new Date()));
+    dbClient.qualityProfileDao().insert(dbSession, profileDto);
+    dbClient.defaultQProfileDao().insertOrUpdate(dbSession, DefaultQProfileDto.from(profileDto));
+  }
+
+  private static FileSourceDto newFileSourceDto(ComponentDto file) {
+    return new FileSourceDto()
+      .setFileUuid(file.uuid())
+      .setProjectUuid(file.projectUuid())
+      .setDataHash("0263047cd758c68c27683625f072f010")
+      .setLineHashes("8d7b3d6b83c0a517eac07e1aac94b773")
+      .setCreatedAt(System.currentTimeMillis())
+      .setUpdatedAt(System.currentTimeMillis())
+      .setDataType(Type.SOURCE)
+      .setRevision("123456789")
+      .setSrcHash("123456");
+  }
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/ws/SearchActionComponentsMediumTest.java
deleted file mode 100644 (file)
index fea4cd5..0000000
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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.sonar.server.issue.ws;
-
-import java.io.IOException;
-import java.util.List;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.server.ws.WebService;
-import org.sonar.api.utils.DateUtils;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.component.ComponentDto;
-import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.issue.IssueDto;
-import org.sonar.db.issue.IssueTesting;
-import org.sonar.db.organization.OrganizationDao;
-import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.organization.OrganizationTesting;
-import org.sonar.db.rule.RuleDao;
-import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleTesting;
-import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.organization.DefaultOrganization;
-import org.sonar.server.organization.DefaultOrganizationProvider;
-import org.sonar.server.permission.index.PermissionIndexer;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.view.index.ViewDoc;
-import org.sonar.server.view.index.ViewIndexer;
-import org.sonar.server.ws.WsActionTester;
-import org.sonar.server.ws.WsTester;
-import org.sonarqube.ws.Issues;
-import org.sonarqube.ws.Issues.SearchWsResponse;
-import org.sonarqube.ws.client.issue.IssuesWsParameters;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.api.utils.DateUtils.parseDateTime;
-import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
-import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
-import static org.sonar.db.component.ComponentTesting.newFileDto;
-import static org.sonar.db.component.ComponentTesting.newModuleDto;
-import static org.sonar.db.component.SnapshotTesting.newAnalysis;
-import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_SEARCH;
-import static org.sonarqube.ws.client.issue.IssuesWsParameters.CONTROLLER_ISSUES;
-
-/**
- * @deprecated use {@link SearchActionComponentsTest} instead
- */
-@Deprecated
-public class SearchActionComponentsMediumTest {
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester().withStartupTasks().withEsIndexes();
-
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
-
-  private DbClient db;
-  private DbSession session;
-  private WsTester wsTester;
-  private OrganizationDto defaultOrganization;
-  private OrganizationDto otherOrganization1;
-  private OrganizationDto otherOrganization2;
-
-  @Before
-  public void setUp() {
-    tester.clearDbAndIndexes();
-    db = tester.get(DbClient.class);
-    wsTester = tester.get(WsTester.class);
-    session = db.openSession(false);
-    OrganizationDao organizationDao = db.organizationDao();
-    DefaultOrganization defaultOrganization = tester.get(DefaultOrganizationProvider.class).get();
-    this.defaultOrganization = organizationDao.selectByUuid(session, defaultOrganization.getUuid()).get();
-    this.otherOrganization1 = OrganizationTesting.newOrganizationDto().setKey("my-org-1");
-    this.otherOrganization2 = OrganizationTesting.newOrganizationDto().setKey("my-org-2");
-    organizationDao.insert(session, this.otherOrganization1, false);
-    organizationDao.insert(session, this.otherOrganization2, false);
-    session.commit();
-  }
-
-  @After
-  public void after() {
-    session.close();
-  }
-
-  @Test
-  public void issues_on_different_projects() throws Exception {
-    RuleDto rule = newRule();
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    IssueDto issue = IssueTesting.newDto(rule, file, project)
-      .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
-      .setStatus("OPEN").setResolution("OPEN")
-      .setSeverity("MAJOR")
-      .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100"))
-      .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100"));
-    db.issueDao().insert(session, issue);
-
-    ComponentDto project2 = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P2").setDbKey("PK2"));
-    ComponentDto file2 = insertComponent(newFileDto(project2, null, "F2").setDbKey("FK2"));
-    IssueDto issue2 = IssueTesting.newDto(rule, file2, project2)
-      .setKee("92fd47d4-b650-4037-80bc-7b112bd4eac2")
-      .setStatus("OPEN").setResolution("OPEN")
-      .setSeverity("MAJOR")
-      .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100"))
-      .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100"));
-    db.issueDao().insert(session, issue2);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH).execute();
-    result.assertJson(this.getClass(), "issues_on_different_projects.json");
-  }
-
-  @Test
-  public void do_not_return_module_key_on_single_module_projects() throws IOException {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto module = insertComponent(newModuleDto("M1", project).setDbKey("MK1"));
-    ComponentDto file = insertComponent(newFileDto(module, null, "F1").setDbKey("FK1"));
-    RuleDto newRule = newRule();
-    IssueDto issueInModule = IssueTesting.newDto(newRule, file, project).setKee("ISSUE_IN_MODULE");
-    IssueDto issueInRootModule = IssueTesting.newDto(newRule, project, project).setKee("ISSUE_IN_ROOT_MODULE");
-    db.issueDao().insert(session, issueInModule, issueInRootModule);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    WsActionTester actionTester = new WsActionTester(tester.get(SearchAction.class));
-    SearchWsResponse searchResponse = actionTester.newRequest().executeProtobuf(SearchWsResponse.class);
-    assertThat(searchResponse.getIssuesCount()).isEqualTo(2);
-
-    for (Issues.Issue issue : searchResponse.getIssuesList()) {
-      assertThat(issue.getProject()).isEqualTo("PK1");
-      if (issue.getKey().equals("ISSUE_IN_MODULE")) {
-        assertThat(issue.getSubProject()).isEqualTo("MK1");
-      } else if (issue.getKey().equals("ISSUE_IN_ROOT_MODULE")) {
-        assertThat(issue.hasSubProject()).isFalse();
-      }
-    }
-  }
-
-  @Test
-  public void search_by_project_uuid() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    db.issueDao().insert(session, issue);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, project.uuid())
-      .execute()
-      .assertJson(this.getClass(), "search_by_project_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, "unknown")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid())
-      .execute()
-      .assertJson(this.getClass(), "search_by_project_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-  }
-
-  @Test
-  public void search_since_leak_period_on_project() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    db.snapshotDao().insert(session,
-      newAnalysis(project)
-        .setPeriodDate(parseDateTime("2015-09-03T00:00:00+0100").getTime()));
-    RuleDto rule = newRule();
-    IssueDto issueAfterLeak = IssueTesting.newDto(rule, file, project)
-      .setKee(UUID_EXAMPLE_01)
-      .setIssueCreationDate(parseDateTime("2015-09-04T00:00:00+0100"))
-      .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100"));
-    IssueDto issueBeforeLeak = IssueTesting.newDto(rule, file, project)
-      .setKee(UUID_EXAMPLE_02)
-      .setIssueCreationDate(parseDateTime("2014-09-04T00:00:00+0100"))
-      .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100"));
-    db.issueDao().insert(session, issueAfterLeak, issueBeforeLeak);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid())
-      .setParam(IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD, "true")
-      .execute()
-      .assertJson(this.getClass(), "search_since_leak_period.json");
-  }
-
-  @Test
-  public void search_since_leak_period_on_file_in_module_project() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto module = insertComponent(newModuleDto(project));
-    ComponentDto file = insertComponent(newFileDto(module, null, "F1").setDbKey("FK1"));
-    db.snapshotDao().insert(session,
-      newAnalysis(project).setPeriodDate(parseDateTime("2015-09-03T00:00:00+0100").getTime()));
-    RuleDto rule = newRule();
-    IssueDto issueAfterLeak = IssueTesting.newDto(rule, file, project)
-      .setKee(UUID_EXAMPLE_01)
-      .setIssueCreationDate(parseDateTime("2015-09-04T00:00:00+0100"))
-      .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100"));
-    IssueDto issueBeforeLeak = IssueTesting.newDto(rule, file, project)
-      .setKee(UUID_EXAMPLE_02)
-      .setIssueCreationDate(parseDateTime("2014-09-04T00:00:00+0100"))
-      .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100"));
-    db.issueDao().insert(session, issueAfterLeak, issueBeforeLeak);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid())
-      .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file.uuid())
-      .setParam(IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD, "true")
-      .execute()
-      .assertJson(this.getClass(), "search_since_leak_period.json");
-  }
-
-  @Test
-  public void project_facet_is_sticky() throws Exception {
-    ComponentDto project1 = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto project2 = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P2").setDbKey("PK2"));
-    ComponentDto project3 = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P3").setDbKey("PK3"));
-    ComponentDto file1 = insertComponent(newFileDto(project1, null, "F1").setDbKey("FK1"));
-    ComponentDto file2 = insertComponent(newFileDto(project2, null, "F2").setDbKey("FK2"));
-    ComponentDto file3 = insertComponent(newFileDto(project3, null, "F3").setDbKey("FK3"));
-    RuleDto rule = newRule();
-    IssueDto issue1 = IssueTesting.newDto(rule, file1, project1).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    IssueDto issue2 = IssueTesting.newDto(rule, file2, project2).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4");
-    IssueDto issue3 = IssueTesting.newDto(rule, file3, project3).setKee("7b1182fd-b650-4037-80bc-82fd47d4eac2");
-    db.issueDao().insert(session, issue1, issue2, issue3);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, project1.uuid())
-      .setParam(WebService.Param.FACETS, "projectUuids")
-      .execute()
-      .assertJson(this.getClass(), "display_sticky_project_facet.json");
-  }
-
-  @Test
-  public void search_by_file_uuid() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    db.issueDao().insert(session, issue);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file.uuid())
-      .execute()
-      .assertJson(this.getClass(), "search_by_file_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, "unknown")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, file.uuid())
-      .execute()
-      .assertJson(this.getClass(), "search_by_file_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-  }
-
-  @Test
-  public void search_by_file_key() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    ComponentDto unitTest = insertComponent(newFileDto(project, null, "F2").setQualifier(Qualifiers.UNIT_TEST_FILE).setDbKey("FK2"));
-    RuleDto rule = newRule();
-    IssueDto issueOnFile = IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    IssueDto issueOnTest = IssueTesting.newDto(rule, unitTest, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4");
-    db.issueDao().insert(session, issueOnFile, issueOnTest);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENTS, file.getDbKey())
-      .execute()
-      .assertJson(this.getClass(), "search_by_file_key.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENTS, unitTest.getDbKey())
-      .execute()
-      .assertJson(this.getClass(), "search_by_test_key.json");
-  }
-
-  @Test
-  public void display_file_facet() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P1").setDbKey("PK1"));
-    ComponentDto file1 = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    ComponentDto file2 = insertComponent(newFileDto(project, null, "F2").setDbKey("FK2"));
-    ComponentDto file3 = insertComponent(newFileDto(project, null, "F3").setDbKey("FK3"));
-    RuleDto newRule = newRule();
-    IssueDto issue1 = IssueTesting.newDto(newRule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    IssueDto issue2 = IssueTesting.newDto(newRule, file2, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4");
-    db.issueDao().insert(session, issue1, issue2);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid())
-      .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file1.uuid() + "," + file3.uuid())
-      .setParam(WebService.Param.FACETS, "fileUuids")
-      .execute()
-      .assertJson(this.getClass(), "display_file_facet.json");
-  }
-
-  @Test
-  public void search_by_directory_path() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto directory = insertComponent(ComponentTesting.newDirectory(project, "D1", "src/main/java/dir"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1").setPath(directory.path() + "/MyComponent.java"));
-    IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    db.issueDao().insert(session, issue);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory.uuid())
-      .execute()
-      .assertJson(this.getClass(), "search_by_file_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir")
-      .execute()
-      .assertJson(this.getClass(), "search_by_file_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-  }
-
-  @Test
-  public void search_by_directory_path_in_different_modules() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
-    ComponentDto module1 = insertComponent(newModuleDto("M1", project).setDbKey("MK1"));
-    ComponentDto module2 = insertComponent(newModuleDto("M2", project).setDbKey("MK2"));
-    ComponentDto directory1 = insertComponent(ComponentTesting.newDirectory(module1, "D1", "src/main/java/dir"));
-    ComponentDto directory2 = insertComponent(ComponentTesting.newDirectory(module2, "D2", "src/main/java/dir"));
-    ComponentDto file1 = insertComponent(newFileDto(module1, directory1, "F1").setDbKey("FK1").setPath(directory1.path() + "/MyComponent.java"));
-    insertComponent(newFileDto(module2, directory2, "F2").setDbKey("FK2").setPath(directory2.path() + "/MyComponent.java"));
-    RuleDto rule = newRule();
-    IssueDto issue1 = IssueTesting.newDto(rule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    db.issueDao().insert(session, issue1);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory1.uuid())
-      .execute()
-      .assertJson(this.getClass(), "search_by_directory_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory2.uuid())
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, module1.uuid())
-      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir")
-      .execute()
-      .assertJson(this.getClass(), "search_by_directory_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, module2.uuid())
-      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir")
-      .execute()
-      .assertJson(this.getClass(), "search_by_directory_uuid.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-  }
-
-  @Test
-  public void display_module_facet() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P1").setDbKey("PK1"));
-    ComponentDto module = insertComponent(newModuleDto("M1", project).setDbKey("MK1"));
-    ComponentDto subModule1 = insertComponent(newModuleDto("SUBM1", module).setDbKey("SUBMK1"));
-    ComponentDto subModule2 = insertComponent(newModuleDto("SUBM2", module).setDbKey("SUBMK2"));
-    ComponentDto subModule3 = insertComponent(newModuleDto("SUBM3", module).setDbKey("SUBMK3"));
-    ComponentDto file1 = insertComponent(newFileDto(subModule1, null, "F1").setDbKey("FK1"));
-    ComponentDto file2 = insertComponent(newFileDto(subModule2, null, "F2").setDbKey("FK2"));
-    RuleDto newRule = newRule();
-    IssueDto issue1 = IssueTesting.newDto(newRule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    IssueDto issue2 = IssueTesting.newDto(newRule, file2, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4");
-    db.issueDao().insert(session, issue1, issue2);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, module.uuid())
-      .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, subModule1.uuid() + "," + subModule3.uuid())
-      .setParam(WebService.Param.FACETS, "moduleUuids")
-      .execute()
-      .assertJson(this.getClass(), "display_module_facet.json");
-  }
-
-  @Test
-  public void display_directory_facet() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto directory = insertComponent(ComponentTesting.newDirectory(project, "D1", "src/main/java/dir"));
-    ComponentDto file = insertComponent(newFileDto(project, directory, "F1").setDbKey("FK1").setPath(directory.path() + "/MyComponent.java"));
-    IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
-    db.issueDao().insert(session, issue);
-    session.commit();
-    indexIssues();
-    indexPermissions();
-
-    userSessionRule.logIn("john");
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam("resolved", "false")
-      .setParam(WebService.Param.FACETS, "directories")
-      .execute();
-    result.assertJson(this.getClass(), "display_directory_facet.json");
-  }
-
-  @Test
-  public void search_by_view_uuid() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    ComponentDto view = insertComponent(ComponentTesting.newView(defaultOrganization, "V1").setDbKey("MyView"));
-    indexView(view.uuid(), newArrayList(project.uuid()));
-    indexPermissions();
-
-    insertIssue(IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
-
-    userSessionRule.logIn("john")
-      .registerComponents(project, file, view);
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, view.uuid())
-      .execute()
-      .assertJson(this.getClass(), "search_by_view_uuid.json");
-  }
-
-  @Test
-  public void search_by_sub_view_uuid() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    insertIssue(IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
-
-    ComponentDto view = insertComponent(ComponentTesting.newView(otherOrganization1, "V1").setDbKey("MyView"));
-    indexView(view.uuid(), newArrayList(project.uuid()));
-    ComponentDto subView = insertComponent(ComponentTesting.newSubView(view, "SV1", "MySubView"));
-    indexView(subView.uuid(), newArrayList(project.uuid()));
-    indexPermissions();
-
-    userSessionRule.logIn("john")
-      .registerComponents(project, file, view, subView);
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, subView.uuid())
-      .execute()
-      .assertJson(this.getClass(), "search_by_view_uuid.json");
-  }
-
-  @Test
-  public void search_by_sub_view_uuid_return_only_authorized_view() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    insertIssue(IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
-
-    ComponentDto view = insertComponent(ComponentTesting.newView(otherOrganization1, "V1").setDbKey("MyView"));
-    indexView(view.uuid(), newArrayList(project.uuid()));
-    ComponentDto subView = insertComponent(ComponentTesting.newSubView(view, "SV1", "MySubView"));
-    indexView(subView.uuid(), newArrayList(project.uuid()));
-
-    // User has wrong permission on the view, no issue will be returned
-    userSessionRule.logIn("john")
-      .registerComponents(project, file, view, subView);
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, subView.uuid())
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-  }
-
-  @Test
-  public void search_by_author() throws Exception {
-    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
-    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
-    RuleDto newRule = newRule();
-    IssueDto issue1 = IssueTesting.newDto(newRule, file, project).setAuthorLogin("leia").setKee("2bd4eac2-b650-4037-80bc-7b112bd4eac2");
-    IssueDto issue2 = IssueTesting.newDto(newRule, file, project).setAuthorLogin("luke@skywalker.name").setKee("82fd47d4-b650-4037-80bc-7b1182fd47d4");
-    indexPermissions();
-
-    db.issueDao().insert(session, issue1, issue2);
-    session.commit();
-    indexIssues();
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_AUTHORS, "leia")
-      .setParam(WebService.Param.FACETS, "authors")
-      .execute()
-      .assertJson(this.getClass(), "search_by_authors.json");
-
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam(IssuesWsParameters.PARAM_AUTHORS, "unknown")
-      .execute()
-      .assertJson(this.getClass(), "no_issue.json");
-
-  }
-
-  private RuleDto newRule() {
-    RuleDto rule = RuleTesting.newXooX1()
-      .setName("Rule name")
-      .setDescription("Rule desc")
-      .setStatus(RuleStatus.READY);
-    tester.get(RuleDao.class).insert(session, rule.getDefinition());
-    session.commit();
-    return rule;
-  }
-
-  private void indexPermissions() {
-    PermissionIndexer permissionIndexer = tester.get(PermissionIndexer.class);
-    permissionIndexer.indexOnStartup(permissionIndexer.getIndexTypes());
-  }
-
-  private IssueDto insertIssue(IssueDto issue) {
-    db.issueDao().insert(session, issue);
-    session.commit();
-    indexIssues();
-    return issue;
-  }
-
-  private ComponentDto insertComponent(ComponentDto component) {
-    db.componentDao().insert(session, component);
-    session.commit();
-    return component;
-  }
-
-  private void indexIssues() {
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
-  }
-
-  private void indexView(String viewUuid, List<String> projects) {
-    tester.get(ViewIndexer.class).index(new ViewDoc().setUuid(viewUuid).setProjects(projects));
-  }
-}
index 753ec3dc75ce3103226d4eb282ef1e48509a89bf..41e70c4732274ac6f3d4ecbc705c7bcdf7d3a99b 100644 (file)
  */
 package org.sonar.server.issue.ws;
 
-import java.util.Date;
+import java.io.IOException;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.resources.Languages;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.utils.DateUtils;
 import org.sonar.api.utils.Durations;
 import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
 import org.sonar.db.issue.IssueDto;
+import org.sonar.db.issue.IssueTesting;
+import org.sonar.db.organization.OrganizationDao;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.organization.OrganizationTesting;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleTesting;
 import org.sonar.server.es.EsTester;
+import org.sonar.server.es.StartupIndexer;
+import org.sonar.server.issue.ActionFinder;
+import org.sonar.server.issue.IssueFieldsSetter;
 import org.sonar.server.issue.IssueQueryFactory;
+import org.sonar.server.issue.TransitionService;
 import org.sonar.server.issue.index.IssueIndex;
 import org.sonar.server.issue.index.IssueIndexDefinition;
 import org.sonar.server.issue.index.IssueIndexer;
 import org.sonar.server.issue.index.IssueIteratorFactory;
+import org.sonar.server.issue.workflow.FunctionExecutor;
+import org.sonar.server.issue.workflow.IssueWorkflow;
 import org.sonar.server.permission.index.AuthorizationTypeSupport;
-import org.sonar.server.permission.index.PermissionIndexerTester;
+import org.sonar.server.permission.index.PermissionIndexer;
 import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.view.index.ViewDoc;
 import org.sonar.server.view.index.ViewIndexDefinition;
 import org.sonar.server.view.index.ViewIndexer;
 import org.sonar.server.ws.WsActionTester;
 import org.sonar.server.ws.WsResponseCommonFormat;
-import org.sonarqube.ws.Issues.Issue;
+import org.sonarqube.ws.Issues;
 import org.sonarqube.ws.Issues.SearchWsResponse;
+import org.sonarqube.ws.client.issue.IssuesWsParameters;
 
+import static com.google.common.collect.Lists.newArrayList;
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.api.utils.DateUtils.addDays;
-import static org.sonar.db.component.ComponentTesting.newProjectCopy;
-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_SINCE_LEAK_PERIOD;
+import static org.sonar.api.utils.DateUtils.parseDateTime;
+import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonar.core.util.Uuids.UUID_EXAMPLE_02;
+import static org.sonar.db.component.ComponentTesting.newFileDto;
+import static org.sonar.db.component.ComponentTesting.newModuleDto;
+import static org.sonar.db.component.SnapshotTesting.newAnalysis;
 
 public class SearchActionComponentsTest {
 
   @Rule
-  public ExpectedException expectedException = ExpectedException.none();
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
   @Rule
-  public UserSessionRule userSession = UserSessionRule.standalone();
+  public DbTester dbTester = DbTester.create();
   @Rule
-  public DbTester db = DbTester.create();
-  @Rule
-  public EsTester es = new EsTester(
-    new IssueIndexDefinition(new MapSettings().asConfig()),
-    new ViewIndexDefinition(new MapSettings().asConfig()));
+  public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings().asConfig()), new ViewIndexDefinition(new MapSettings().asConfig()));
+
+  private DbClient db = dbTester.getDbClient();
+  private DbSession session = dbTester.getSession();
+  private IssueIndex issueIndex = new IssueIndex(esTester.client(), System2.INSTANCE, userSessionRule, new AuthorizationTypeSupport(userSessionRule));
+  private IssueIndexer issueIndexer = new IssueIndexer(esTester.client(), db, new IssueIteratorFactory(db));
+  private ViewIndexer viewIndexer = new ViewIndexer(db, esTester.client());
+  private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(db, System2.INSTANCE, userSessionRule);
+  private IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter();
+  private IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter);
+  private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, db, new ActionFinder(userSessionRule), new TransitionService(userSessionRule, issueWorkflow));
+  private Languages languages = new Languages();
+  private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl());
+  private WsActionTester wsTester = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat));
+  private OrganizationDto defaultOrganization;
+  private OrganizationDto otherOrganization1;
+  private OrganizationDto otherOrganization2;
+  private StartupIndexer permissionIndexer = new PermissionIndexer(db, esTester.client(), issueIndexer);
+
+  @Before
+  public void setUp() {
+    session = db.openSession(false);
+    OrganizationDao organizationDao = db.organizationDao();
+    this.defaultOrganization = dbTester.getDefaultOrganization();
+    this.otherOrganization1 = OrganizationTesting.newOrganizationDto().setKey("my-org-1");
+    this.otherOrganization2 = OrganizationTesting.newOrganizationDto().setKey("my-org-2");
+    organizationDao.insert(session, this.otherOrganization1, false);
+    organizationDao.insert(session, this.otherOrganization2, false);
+    session.commit();
+  }
+
+  @After
+  public void after() {
+    session.close();
+  }
+
+  @Test
+  public void issues_on_different_projects() throws Exception {
+    RuleDto rule = newRule();
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    IssueDto issue = IssueTesting.newDto(rule, file, project)
+      .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
+      .setStatus("OPEN").setResolution("OPEN")
+      .setSeverity("MAJOR")
+      .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100"))
+      .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100"));
+    db.issueDao().insert(session, issue);
+
+    ComponentDto project2 = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P2").setDbKey("PK2"));
+    ComponentDto file2 = insertComponent(newFileDto(project2, null, "F2").setDbKey("FK2"));
+    IssueDto issue2 = IssueTesting.newDto(rule, file2, project2)
+      .setKee("92fd47d4-b650-4037-80bc-7b112bd4eac2")
+      .setStatus("OPEN").setResolution("OPEN")
+      .setSeverity("MAJOR")
+      .setIssueCreationDate(DateUtils.parseDateTime("2014-09-04T00:00:00+0100"))
+      .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100"));
+    db.issueDao().insert(session, issue2);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .execute()
+      .assertJson(this.getClass(), "issues_on_different_projects.json");
+  }
+
+  @Test
+  public void do_not_return_module_key_on_single_module_projects() throws IOException {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto module = insertComponent(newModuleDto("M1", project).setDbKey("MK1"));
+    ComponentDto file = insertComponent(newFileDto(module, null, "F1").setDbKey("FK1"));
+    RuleDto newRule = newRule();
+    IssueDto issueInModule = IssueTesting.newDto(newRule, file, project).setKee("ISSUE_IN_MODULE");
+    IssueDto issueInRootModule = IssueTesting.newDto(newRule, project, project).setKee("ISSUE_IN_ROOT_MODULE");
+    db.issueDao().insert(session, issueInModule, issueInRootModule);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    SearchWsResponse searchResponse = wsTester.newRequest().executeProtobuf(SearchWsResponse.class);
+    assertThat(searchResponse.getIssuesCount()).isEqualTo(2);
+
+    for (Issues.Issue issue : searchResponse.getIssuesList()) {
+      assertThat(issue.getProject()).isEqualTo("PK1");
+      if (issue.getKey().equals("ISSUE_IN_MODULE")) {
+        assertThat(issue.getSubProject()).isEqualTo("MK1");
+      } else if (issue.getKey().equals("ISSUE_IN_ROOT_MODULE")) {
+        assertThat(issue.hasSubProject()).isFalse();
+      }
+    }
+  }
+
+  @Test
+  public void search_by_project_uuid() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    db.issueDao().insert(session, issue);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, project.uuid())
+      .execute()
+      .assertJson(this.getClass(), "search_by_project_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, "unknown")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid())
+      .execute()
+      .assertJson(this.getClass(), "search_by_project_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+  }
+
+  @Ignore
+  @Test
+  public void search_since_leak_period_on_project() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    db.snapshotDao().insert(session,
+      newAnalysis(project)
+        .setPeriodDate(parseDateTime("2015-09-03T00:00:00+0100").getTime()));
+    RuleDto rule = newRule();
+    IssueDto issueAfterLeak = IssueTesting.newDto(rule, file, project)
+      .setKee(UUID_EXAMPLE_01)
+      .setIssueCreationDate(parseDateTime("2015-09-04T00:00:00+0100"))
+      .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100"));
+    IssueDto issueBeforeLeak = IssueTesting.newDto(rule, file, project)
+      .setKee(UUID_EXAMPLE_02)
+      .setIssueCreationDate(parseDateTime("2014-09-04T00:00:00+0100"))
+      .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100"));
+    db.issueDao().insert(session, issueAfterLeak, issueBeforeLeak);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid())
+      .setParam(IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD, "true")
+      .execute()
+      .assertJson(this.getClass(), "search_since_leak_period.json");
+  }
+
+  @Ignore
+  @Test
+  public void search_since_leak_period_on_file_in_module_project() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto module = insertComponent(newModuleDto(project));
+    ComponentDto file = insertComponent(newFileDto(module, null, "F1").setDbKey("FK1"));
+    db.snapshotDao().insert(session,
+      newAnalysis(project).setPeriodDate(parseDateTime("2015-09-03T00:00:00+0100").getTime()));
+    RuleDto rule = newRule();
+    IssueDto issueAfterLeak = IssueTesting.newDto(rule, file, project)
+      .setKee(UUID_EXAMPLE_01)
+      .setIssueCreationDate(parseDateTime("2015-09-04T00:00:00+0100"))
+      .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100"));
+    IssueDto issueBeforeLeak = IssueTesting.newDto(rule, file, project)
+      .setKee(UUID_EXAMPLE_02)
+      .setIssueCreationDate(parseDateTime("2014-09-04T00:00:00+0100"))
+      .setIssueUpdateDate(parseDateTime("2015-10-04T00:00:00+0100"));
+    db.issueDao().insert(session, issueAfterLeak, issueBeforeLeak);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid())
+      .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file.uuid())
+      .setParam(IssuesWsParameters.PARAM_SINCE_LEAK_PERIOD, "true")
+      .execute()
+      .assertJson(this.getClass(), "search_since_leak_period.json");
+  }
+
+  @Test
+  public void project_facet_is_sticky() throws Exception {
+    ComponentDto project1 = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto project2 = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P2").setDbKey("PK2"));
+    ComponentDto project3 = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P3").setDbKey("PK3"));
+    ComponentDto file1 = insertComponent(newFileDto(project1, null, "F1").setDbKey("FK1"));
+    ComponentDto file2 = insertComponent(newFileDto(project2, null, "F2").setDbKey("FK2"));
+    ComponentDto file3 = insertComponent(newFileDto(project3, null, "F3").setDbKey("FK3"));
+    RuleDto rule = newRule();
+    IssueDto issue1 = IssueTesting.newDto(rule, file1, project1).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    IssueDto issue2 = IssueTesting.newDto(rule, file2, project2).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4");
+    IssueDto issue3 = IssueTesting.newDto(rule, file3, project3).setKee("7b1182fd-b650-4037-80bc-82fd47d4eac2");
+    db.issueDao().insert(session, issue1, issue2, issue3);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_PROJECT_UUIDS, project1.uuid())
+      .setParam(WebService.Param.FACETS, "projectUuids")
+      .execute()
+      .assertJson(this.getClass(), "display_sticky_project_facet.json");
+  }
+
+  @Test
+  public void search_by_file_uuid() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    db.issueDao().insert(session, issue);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file.uuid())
+      .execute()
+      .assertJson(this.getClass(), "search_by_file_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, "unknown")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, file.uuid())
+      .execute()
+      .assertJson(this.getClass(), "search_by_file_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+  }
+
+  @Test
+  public void search_by_file_key() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    ComponentDto unitTest = insertComponent(newFileDto(project, null, "F2").setQualifier(Qualifiers.UNIT_TEST_FILE).setDbKey("FK2"));
+    RuleDto rule = newRule();
+    IssueDto issueOnFile = IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    IssueDto issueOnTest = IssueTesting.newDto(rule, unitTest, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4");
+    db.issueDao().insert(session, issueOnFile, issueOnTest);
+    session.commit();
+    indexIssues();
+    indexPermissions();
 
-  private IssueIndex index = new IssueIndex(es.client(), System2.INSTANCE, userSession, new AuthorizationTypeSupport(userSession));
-  private IssueIndexer issueIndexer = new IssueIndexer(es.client(), db.getDbClient(), new IssueIteratorFactory(db.getDbClient()));
-  private ViewIndexer viewIndexer = new ViewIndexer(db.getDbClient(), es.client());
-  private PermissionIndexerTester permissionIndexer = new PermissionIndexerTester(es, issueIndexer);
-  private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(db.getDbClient(), System2.INSTANCE, userSession);
-  private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSession, db.getDbClient(), null, null);
-  private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(new Languages()), new Languages(),
-    new AvatarResolverImpl());
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENTS, file.getDbKey())
+      .execute()
+      .assertJson(this.getClass(), "search_by_file_key.json");
 
-  private WsActionTester ws = new WsActionTester(new SearchAction(userSession, index, issueQueryFactory, searchResponseLoader, searchResponseFormat));
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENTS, unitTest.getDbKey())
+      .execute()
+      .assertJson(this.getClass(), "search_by_test_key.json");
+  }
 
   @Test
-  public void search_by_application_key() throws Exception {
-    ComponentDto project1 = db.components().insertPublicProject();
-    ComponentDto project2 = db.components().insertPublicProject();
-    ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
-    db.components().insertComponents(newProjectCopy("PC1", project1, application));
-    db.components().insertComponents(newProjectCopy("PC2", project2, application));
-    IssueDto issue1 = db.issues().insertIssue(i -> i.setProject(project1));
-    IssueDto issue2 = db.issues().insertIssue(i -> i.setProject(project2));
-    userSession.registerComponents(application, project1, project2);
-    permissionIndexer.allowOnlyAnyone(project1);
-    permissionIndexer.allowOnlyAnyone(project2);
-    indexIssuesAndViews();
-
-    SearchWsResponse result = ws.newRequest()
-      .setParam(PARAM_COMPONENT_KEYS, application.getDbKey())
-      .executeProtobuf(SearchWsResponse.class);
-
-    assertThat(result.getIssuesList()).extracting(Issue::getKey)
-      .containsExactlyInAnyOrder(issue1.getKey(), issue2.getKey());
+  public void display_file_facet() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P1").setDbKey("PK1"));
+    ComponentDto file1 = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    ComponentDto file2 = insertComponent(newFileDto(project, null, "F2").setDbKey("FK2"));
+    ComponentDto file3 = insertComponent(newFileDto(project, null, "F3").setDbKey("FK3"));
+    RuleDto newRule = newRule();
+    IssueDto issue1 = IssueTesting.newDto(newRule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    IssueDto issue2 = IssueTesting.newDto(newRule, file2, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4");
+    db.issueDao().insert(session, issue1, issue2);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, project.uuid())
+      .setParam(IssuesWsParameters.PARAM_FILE_UUIDS, file1.uuid() + "," + file3.uuid())
+      .setParam(WebService.Param.FACETS, "fileUuids")
+      .execute()
+      .assertJson(this.getClass(), "display_file_facet.json");
   }
 
   @Test
-  public void ignore_application_without_browse_permission() {
-    ComponentDto project = db.components().insertPublicProject();
-    ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
-    db.components().insertComponents(newProjectCopy("PC1", project, application));
-    db.issues().insertIssue(i -> i.setProject(project));
-    userSession.registerComponents(project);
-    permissionIndexer.allowOnlyAnyone(project);
-    indexIssuesAndViews();
-
-    SearchWsResponse result = ws.newRequest()
-      .setParam(PARAM_COMPONENT_KEYS, application.getDbKey())
-      .executeProtobuf(SearchWsResponse.class);
-
-    assertThat(result.getIssuesList()).isEmpty();
+  public void search_by_directory_path() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto directory = insertComponent(ComponentTesting.newDirectory(project, "D1", "src/main/java/dir"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1").setPath(directory.path() + "/MyComponent.java"));
+    IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    db.issueDao().insert(session, issue);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory.uuid())
+      .execute()
+      .assertJson(this.getClass(), "search_by_file_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, "unknown")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir")
+      .execute()
+      .assertJson(this.getClass(), "search_by_file_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
   }
 
   @Test
-  public void search_application_without_projects() {
-    ComponentDto project = db.components().insertPublicProject();
-    ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
-    db.issues().insertIssue(i -> i.setProject(project));
-    userSession.registerComponents(application, project);
-    permissionIndexer.allowOnlyAnyone(project);
-    indexIssuesAndViews();
-
-    SearchWsResponse result = ws.newRequest()
-      .setParam(PARAM_COMPONENT_KEYS, application.getDbKey())
-      .executeProtobuf(SearchWsResponse.class);
-
-    assertThat(result.getIssuesList()).isEmpty();
+  public void search_by_directory_path_in_different_modules() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
+    ComponentDto module1 = insertComponent(newModuleDto("M1", project).setDbKey("MK1"));
+    ComponentDto module2 = insertComponent(newModuleDto("M2", project).setDbKey("MK2"));
+    ComponentDto directory1 = insertComponent(ComponentTesting.newDirectory(module1, "D1", "src/main/java/dir"));
+    ComponentDto directory2 = insertComponent(ComponentTesting.newDirectory(module2, "D2", "src/main/java/dir"));
+    ComponentDto file1 = insertComponent(newFileDto(module1, directory1, "F1").setDbKey("FK1").setPath(directory1.path() + "/MyComponent.java"));
+    insertComponent(newFileDto(module2, directory2, "F2").setDbKey("FK2").setPath(directory2.path() + "/MyComponent.java"));
+    RuleDto rule = newRule();
+    IssueDto issue1 = IssueTesting.newDto(rule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    db.issueDao().insert(session, issue1);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory1.uuid())
+      .execute()
+      .assertJson(this.getClass(), "search_by_directory_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, directory2.uuid())
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, module1.uuid())
+      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir")
+      .execute()
+      .assertJson(this.getClass(), "search_by_directory_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, module2.uuid())
+      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java/dir")
+      .execute()
+      .assertJson(this.getClass(), "search_by_directory_uuid.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_DIRECTORIES, "src/main/java")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
   }
 
   @Test
-  public void search_by_application_and_by_leak() throws Exception {
-    Date now = new Date();
-    ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
-    // Project 1
-    ComponentDto project1 = db.components().insertPublicProject();
-    db.components().insertSnapshot(project1, s -> s.setPeriodDate(addDays(now, -14).getTime()));
-    db.components().insertComponents(newProjectCopy("PC1", project1, application));
-    IssueDto project1Issue1 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -10)));
-    IssueDto project1Issue2 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -20)));
-    // Project 2
-    ComponentDto project2 = db.components().insertPublicProject();
-    db.components().insertSnapshot(project2, s -> s.setPeriodDate(addDays(now, -25).getTime()));
-    db.components().insertComponents(newProjectCopy("PC2", project2, application));
-    IssueDto project2Issue1 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -15)));
-    IssueDto project2Issue2 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -30)));
-    // Permissions and index
-    userSession.registerComponents(application, project1, project2);
-    permissionIndexer.allowOnlyAnyone(project1);
-    permissionIndexer.allowOnlyAnyone(project2);
-    indexIssuesAndViews();
-
-    SearchWsResponse result = ws.newRequest()
-      .setParam(PARAM_COMPONENT_KEYS, application.getDbKey())
-      .setParam(PARAM_SINCE_LEAK_PERIOD, "true")
-      .executeProtobuf(SearchWsResponse.class);
-
-    assertThat(result.getIssuesList()).extracting(Issue::getKey)
-      .containsExactlyInAnyOrder(project1Issue1.getKey(), project2Issue1.getKey())
-      .doesNotContain(project1Issue2.getKey(), project2Issue2.getKey());
+  public void display_module_facet() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization2, "P1").setDbKey("PK1"));
+    ComponentDto module = insertComponent(newModuleDto("M1", project).setDbKey("MK1"));
+    ComponentDto subModule1 = insertComponent(newModuleDto("SUBM1", module).setDbKey("SUBMK1"));
+    ComponentDto subModule2 = insertComponent(newModuleDto("SUBM2", module).setDbKey("SUBMK2"));
+    ComponentDto subModule3 = insertComponent(newModuleDto("SUBM3", module).setDbKey("SUBMK3"));
+    ComponentDto file1 = insertComponent(newFileDto(subModule1, null, "F1").setDbKey("FK1"));
+    ComponentDto file2 = insertComponent(newFileDto(subModule2, null, "F2").setDbKey("FK2"));
+    RuleDto newRule = newRule();
+    IssueDto issue1 = IssueTesting.newDto(newRule, file1, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    IssueDto issue2 = IssueTesting.newDto(newRule, file2, project).setKee("2bd4eac2-b650-4037-80bc-7b1182fd47d4");
+    db.issueDao().insert(session, issue1, issue2);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, module.uuid())
+      .setParam(IssuesWsParameters.PARAM_MODULE_UUIDS, subModule1.uuid() + "," + subModule3.uuid())
+      .setParam(WebService.Param.FACETS, "moduleUuids")
+      .execute()
+      .assertJson(this.getClass(), "display_module_facet.json");
   }
 
   @Test
-  public void search_by_application_and_project() throws Exception {
-    ComponentDto project1 = db.components().insertPublicProject();
-    ComponentDto project2 = db.components().insertPublicProject();
-    ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
-    db.components().insertComponents(newProjectCopy("PC1", project1, application));
-    db.components().insertComponents(newProjectCopy("PC2", project2, application));
-    IssueDto issue1 = db.issues().insertIssue(i -> i.setProject(project1));
-    IssueDto issue2 = db.issues().insertIssue(i -> i.setProject(project2));
-    userSession.registerComponents(application, project1, project2);
-    permissionIndexer.allowOnlyAnyone(project1);
-    permissionIndexer.allowOnlyAnyone(project2);
-    indexIssuesAndViews();
-
-    SearchWsResponse result = ws.newRequest()
-      .setParam(PARAM_COMPONENT_KEYS, application.getDbKey())
-      .setParam(PARAM_PROJECT_KEYS, project1.getDbKey())
-      .executeProtobuf(SearchWsResponse.class);
-
-    assertThat(result.getIssuesList()).extracting(Issue::getKey)
-      .containsExactlyInAnyOrder(issue1.getKey())
-      .doesNotContain(issue2.getKey());
+  public void display_directory_facet() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto directory = insertComponent(ComponentTesting.newDirectory(project, "D1", "src/main/java/dir"));
+    ComponentDto file = insertComponent(newFileDto(project, directory, "F1").setDbKey("FK1").setPath(directory.path() + "/MyComponent.java"));
+    IssueDto issue = IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+    db.issueDao().insert(session, issue);
+    session.commit();
+    indexIssues();
+    indexPermissions();
+
+    userSessionRule.logIn("john");
+    wsTester.newRequest()
+      .setParam("resolved", "false")
+      .setParam(WebService.Param.FACETS, "directories")
+      .execute()
+      .assertJson(this.getClass(), "display_directory_facet.json");
   }
 
   @Test
-  public void search_by_application_and_project_and_leak() throws Exception {
-    Date now = new Date();
-    ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
-    // Project 1
-    ComponentDto project1 = db.components().insertPublicProject();
-    db.components().insertSnapshot(project1, s -> s.setPeriodDate(addDays(now, -14).getTime()));
-    db.components().insertComponents(newProjectCopy("PC1", project1, application));
-    IssueDto project1Issue1 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -10)));
-    IssueDto project1Issue2 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -20)));
-    // Project 2
-    ComponentDto project2 = db.components().insertPublicProject();
-    db.components().insertSnapshot(project2, s -> s.setPeriodDate(addDays(now, -25).getTime()));
-    db.components().insertComponents(newProjectCopy("PC2", project2, application));
-    IssueDto project2Issue1 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -15)));
-    IssueDto project2Issue2 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -30)));
-    // Permissions and index
-    userSession.registerComponents(application, project1, project2);
-    permissionIndexer.allowOnlyAnyone(project1);
-    permissionIndexer.allowOnlyAnyone(project2);
-    indexIssuesAndViews();
-
-    SearchWsResponse result = ws.newRequest()
-      .setParam(PARAM_COMPONENT_KEYS, application.getDbKey())
-      .setParam(PARAM_PROJECT_KEYS, project1.getDbKey())
-      .setParam(PARAM_SINCE_LEAK_PERIOD, "true")
-      .executeProtobuf(SearchWsResponse.class);
-
-    assertThat(result.getIssuesList()).extracting(Issue::getKey)
-      .containsExactlyInAnyOrder(project1Issue1.getKey())
-      .doesNotContain(project1Issue2.getKey(), project2Issue1.getKey(), project2Issue2.getKey());
+  public void search_by_view_uuid() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(otherOrganization1, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    ComponentDto view = insertComponent(ComponentTesting.newView(defaultOrganization, "V1").setDbKey("MyView"));
+    indexView(view.uuid(), newArrayList(project.uuid()));
+    indexPermissions();
+
+    insertIssue(IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
+
+    userSessionRule.logIn("john")
+      .registerComponents(project, file, view);
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, view.uuid())
+      .execute()
+      .assertJson(this.getClass(), "search_by_view_uuid.json");
   }
 
   @Test
-  public void search_by_application_and_by_leak_when_one_project_has_no_leak() throws Exception {
-    Date now = new Date();
-    ComponentDto application = db.components().insertApplication(db.getDefaultOrganization());
-    // Project 1
-    ComponentDto project1 = db.components().insertPublicProject();
-    db.components().insertSnapshot(project1, s -> s.setPeriodDate(addDays(now, -14).getTime()));
-    db.components().insertComponents(newProjectCopy("PC1", project1, application));
-    IssueDto project1Issue1 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -10)));
-    IssueDto project1Issue2 = db.issues().insertIssue(i -> i.setProject(project1).setIssueCreationDate(addDays(now, -20)));
-    // Project 2, without leak => no issue form it should be returned
-    ComponentDto project2 = db.components().insertPublicProject();
-    db.components().insertSnapshot(project2, s -> s.setPeriodDate(null));
-    db.components().insertComponents(newProjectCopy("PC2", project2, application));
-    IssueDto project2Issue1 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -15)));
-    IssueDto project2Issue2 = db.issues().insertIssue(i -> i.setProject(project2).setIssueCreationDate(addDays(now, -30)));
-    // Permissions and index
-    userSession.registerComponents(application, project1, project2);
-    permissionIndexer.allowOnlyAnyone(project1);
-    permissionIndexer.allowOnlyAnyone(project2);
-    indexIssuesAndViews();
-
-    SearchWsResponse result = ws.newRequest()
-      .setParam(PARAM_COMPONENT_KEYS, application.getDbKey())
-      .setParam(PARAM_SINCE_LEAK_PERIOD, "true")
-      .executeProtobuf(SearchWsResponse.class);
-
-    assertThat(result.getIssuesList()).extracting(Issue::getKey)
-      .containsExactlyInAnyOrder(project1Issue1.getKey())
-      .doesNotContain(project1Issue2.getKey(), project2Issue1.getKey(), project2Issue2.getKey());
+  public void search_by_sub_view_uuid() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    insertIssue(IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
+
+    ComponentDto view = insertComponent(ComponentTesting.newView(otherOrganization1, "V1").setDbKey("MyView"));
+    indexView(view.uuid(), newArrayList(project.uuid()));
+    ComponentDto subView = insertComponent(ComponentTesting.newSubView(view, "SV1", "MySubView"));
+    indexView(subView.uuid(), newArrayList(project.uuid()));
+    indexPermissions();
+
+    userSessionRule.logIn("john")
+      .registerComponents(project, file, view, subView);
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, subView.uuid())
+      .execute()
+      .assertJson(this.getClass(), "search_by_view_uuid.json");
+  }
+
+  @Test
+  public void search_by_sub_view_uuid_return_only_authorized_view() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    insertIssue(IssueTesting.newDto(newRule(), file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2"));
+
+    ComponentDto view = insertComponent(ComponentTesting.newView(otherOrganization1, "V1").setDbKey("MyView"));
+    indexView(view.uuid(), newArrayList(project.uuid()));
+    ComponentDto subView = insertComponent(ComponentTesting.newSubView(view, "SV1", "MySubView"));
+    indexView(subView.uuid(), newArrayList(project.uuid()));
+
+    // User has wrong permission on the view, no issue will be returned
+    userSessionRule.logIn("john")
+      .registerComponents(project, file, view, subView);
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_COMPONENT_UUIDS, subView.uuid())
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+  }
+
+  @Test
+  public void search_by_author() throws Exception {
+    ComponentDto project = insertComponent(ComponentTesting.newPublicProjectDto(defaultOrganization, "P1").setDbKey("PK1"));
+    ComponentDto file = insertComponent(newFileDto(project, null, "F1").setDbKey("FK1"));
+    RuleDto newRule = newRule();
+    IssueDto issue1 = IssueTesting.newDto(newRule, file, project).setAuthorLogin("leia").setKee("2bd4eac2-b650-4037-80bc-7b112bd4eac2");
+    IssueDto issue2 = IssueTesting.newDto(newRule, file, project).setAuthorLogin("luke@skywalker.name").setKee("82fd47d4-b650-4037-80bc-7b1182fd47d4");
+    indexPermissions();
+
+    db.issueDao().insert(session, issue1, issue2);
+    session.commit();
+    indexIssues();
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_AUTHORS, "leia")
+      .setParam(WebService.Param.FACETS, "authors")
+      .execute()
+      .assertJson(this.getClass(), "search_by_authors.json");
+
+    wsTester.newRequest()
+      .setParam(IssuesWsParameters.PARAM_AUTHORS, "unknown")
+      .execute()
+      .assertJson(this.getClass(), "no_issue.json");
+
+  }
+
+  private RuleDto newRule() {
+    RuleDto rule = RuleTesting.newXooX1()
+      .setName("Rule name")
+      .setDescription("Rule desc")
+      .setStatus(RuleStatus.READY);
+    dbTester.rules().insert(rule.getDefinition());
+    session.commit();
+    return rule;
+  }
+
+  private void indexPermissions() {
+    permissionIndexer.indexOnStartup(permissionIndexer.getIndexTypes());
+  }
+
+  private IssueDto insertIssue(IssueDto issue) {
+    db.issueDao().insert(session, issue);
+    session.commit();
+    indexIssues();
+    return issue;
+  }
+
+  private ComponentDto insertComponent(ComponentDto component) {
+    db.componentDao().insert(session, component);
+    session.commit();
+    return component;
+  }
+
+  private void indexIssues() {
+    issueIndexer.indexOnStartup(issueIndexer.getIndexTypes());
   }
 
-  private void indexIssuesAndViews() {
-    issueIndexer.indexOnStartup(null);
-    viewIndexer.indexOnStartup(null);
+  private void indexView(String viewUuid, List<String> projects) {
+    viewIndexer.index(new ViewDoc().setUuid(viewUuid).setProjects(projects));
   }
 }
index 96ec1feaf06858b135d41cac0f8ba12364a80dc3..9e8da6622b1233ba19792cc7b344623c3fd1eee4 100644 (file)
  */
 package org.sonar.server.issue.ws;
 
-import org.junit.After;
 import org.junit.Before;
-import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.issue.Issue;
+import org.sonar.api.resources.Languages;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.DateUtils;
+import org.sonar.api.utils.Durations;
+import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.ComponentTesting;
-import org.sonar.db.issue.IssueChangeDao;
 import org.sonar.db.issue.IssueChangeDto;
-import org.sonar.db.issue.IssueDao;
 import org.sonar.db.issue.IssueDto;
 import org.sonar.db.issue.IssueTesting;
 import org.sonar.db.organization.OrganizationDao;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.organization.OrganizationTesting;
 import org.sonar.db.permission.GroupPermissionDto;
-import org.sonar.db.rule.RuleDao;
 import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleTesting;
 import org.sonar.db.user.UserDto;
+import org.sonar.server.es.EsTester;
 import org.sonar.server.es.SearchOptions;
+import org.sonar.server.es.StartupIndexer;
+import org.sonar.server.issue.ActionFinder;
+import org.sonar.server.issue.IssueFieldsSetter;
 import org.sonar.server.issue.IssueQuery;
+import org.sonar.server.issue.IssueQueryFactory;
+import org.sonar.server.issue.TransitionService;
+import org.sonar.server.issue.index.IssueIndex;
+import org.sonar.server.issue.index.IssueIndexDefinition;
 import org.sonar.server.issue.index.IssueIndexer;
-import org.sonar.server.organization.DefaultOrganization;
-import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.issue.index.IssueIteratorFactory;
+import org.sonar.server.issue.workflow.FunctionExecutor;
+import org.sonar.server.issue.workflow.IssueWorkflow;
+import org.sonar.server.permission.index.AuthorizationTypeSupport;
 import org.sonar.server.permission.index.PermissionIndexer;
-import org.sonar.server.tester.ServerTester;
 import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
+import org.sonar.server.ws.TestResponse;
+import org.sonar.server.ws.WsActionTester;
+import org.sonar.server.ws.WsResponseCommonFormat;
 
 import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
-import static org.sonarqube.ws.client.issue.IssuesWsParameters.ACTION_SEARCH;
-import static org.sonarqube.ws.client.issue.IssuesWsParameters.CONTROLLER_ISSUES;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.DEPRECATED_FACET_MODE_DEBT;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.FACET_MODE_EFFORT;
 import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_ADDITIONAL_FIELDS;
@@ -72,46 +81,47 @@ import static org.sonarqube.ws.client.issue.IssuesWsParameters.PARAM_PAGE_SIZE;
 
 public class SearchActionMediumTest {
 
-  @ClassRule
-  public static ServerTester tester = new ServerTester().withStartupTasks().withEsIndexes();
-
   @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
+  @Rule
+  public DbTester dbTester = DbTester.create();
+  @Rule
+  public EsTester esTester = new EsTester(new IssueIndexDefinition(new MapSettings().asConfig()));
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
-  private DbClient db;
-  private DbSession session;
-  private WsTester wsTester;
+  private DbClient db = dbTester.getDbClient();
+  private DbSession session = dbTester.getSession();
+  private IssueIndex issueIndex = new IssueIndex(esTester.client(), System2.INSTANCE, userSessionRule, new AuthorizationTypeSupport(userSessionRule));
+  private IssueIndexer issueIndexer = new IssueIndexer(esTester.client(), db, new IssueIteratorFactory(db));
+  private IssueQueryFactory issueQueryFactory = new IssueQueryFactory(db, System2.INSTANCE, userSessionRule);
+  private IssueFieldsSetter issueFieldsSetter = new IssueFieldsSetter();
+  private IssueWorkflow issueWorkflow = new IssueWorkflow(new FunctionExecutor(issueFieldsSetter), issueFieldsSetter);
+  private SearchResponseLoader searchResponseLoader = new SearchResponseLoader(userSessionRule, db, new ActionFinder(userSessionRule), new TransitionService(userSessionRule, issueWorkflow));
+  private Languages languages = new Languages();
+  private SearchResponseFormat searchResponseFormat = new SearchResponseFormat(new Durations(), new WsResponseCommonFormat(languages), languages, new AvatarResolverImpl());
+  private WsActionTester wsTester = new WsActionTester(new SearchAction(userSessionRule, issueIndex, issueQueryFactory, searchResponseLoader, searchResponseFormat));
   private OrganizationDto defaultOrganization;
   private OrganizationDto otherOrganization1;
   private OrganizationDto otherOrganization2;
+  private StartupIndexer permissionIndexer = new PermissionIndexer(db, esTester.client(), issueIndexer);
 
   @Before
   public void setUp() {
-    tester.clearDbAndIndexes();
-    db = tester.get(DbClient.class);
-    wsTester = tester.get(WsTester.class);
-    session = db.openSession(false);
     OrganizationDao organizationDao = db.organizationDao();
-    DefaultOrganization defaultOrganization = tester.get(DefaultOrganizationProvider.class).get();
-    this.defaultOrganization = organizationDao.selectByUuid(session, defaultOrganization.getUuid()).get();
+    this.defaultOrganization = dbTester.getDefaultOrganization();
     this.otherOrganization1 = OrganizationTesting.newOrganizationDto().setKey("my-org-1");
     this.otherOrganization2 = OrganizationTesting.newOrganizationDto().setKey("my-org-2");
     organizationDao.insert(session, this.otherOrganization1, false);
     organizationDao.insert(session, this.otherOrganization2, false);
     session.commit();
-  }
-
-  @After
-  public void after() {
-    session.close();
+    issueWorkflow.start();
   }
 
   @Test
   public void empty_search() throws Exception {
-    WsTester.TestRequest request = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH);
-    WsTester.Result result = request.execute();
+    TestResponse result = wsTester.newRequest()
+      .execute();
 
     assertThat(result).isNotNull();
     result.assertJson(this.getClass(), "empty_result.json");
@@ -139,11 +149,10 @@ public class SearchActionMediumTest {
       .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100"));
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    issueIndexer.indexOnStartup(issueIndexer.getIndexTypes());
 
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH).execute();
-    result.assertJson(this.getClass(), "response_contains_all_fields_except_additional_fields.json");
+    wsTester.newRequest().execute()
+      .assertJson(this.getClass(), "response_contains_all_fields_except_additional_fields.json");
   }
 
   @Test
@@ -158,14 +167,14 @@ public class SearchActionMediumTest {
       .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
     db.issueDao().insert(session, issue);
 
-    tester.get(IssueChangeDao.class).insert(session,
+    db.issueChangeDao().insert(session,
       new IssueChangeDto().setIssueKey(issue.getKey())
         .setKey("COMMENT-ABCD")
         .setChangeData("*My comment*")
         .setChangeType(IssueChangeDto.TYPE_COMMENT)
         .setUserLogin("john")
         .setCreatedAt(DateUtils.parseDateTime("2014-09-09T12:00:00+0000").getTime()));
-    tester.get(IssueChangeDao.class).insert(session,
+    db.issueChangeDao().insert(session,
       new IssueChangeDto().setIssueKey(issue.getKey())
         .setKey("COMMENT-ABCE")
         .setChangeData("Another comment")
@@ -173,14 +182,13 @@ public class SearchActionMediumTest {
         .setUserLogin("fabrice")
         .setCreatedAt(DateUtils.parseDateTime("2014-09-10T12:00:00+0000").getTime()));
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john");
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("additionalFields", "comments,users")
-      .execute();
-    result.assertJson(this.getClass(), "issue_with_comments.json");
+      .execute()
+      .assertJson(this.getClass(), "issue_with_comments.json");
   }
 
   @Test
@@ -195,14 +203,14 @@ public class SearchActionMediumTest {
       .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
     db.issueDao().insert(session, issue);
 
-    tester.get(IssueChangeDao.class).insert(session,
+    db.issueChangeDao().insert(session,
       new IssueChangeDto().setIssueKey(issue.getKey())
         .setKey("COMMENT-ABCD")
         .setChangeData("*My comment*")
         .setChangeType(IssueChangeDto.TYPE_COMMENT)
         .setUserLogin("john")
         .setCreatedAt(DateUtils.parseDateTime("2014-09-09T12:00:00+0000").getTime()));
-    tester.get(IssueChangeDao.class).insert(session,
+    db.issueChangeDao().insert(session,
       new IssueChangeDto().setIssueKey(issue.getKey())
         .setKey("COMMENT-ABCE")
         .setChangeData("Another comment")
@@ -210,13 +218,12 @@ public class SearchActionMediumTest {
         .setUserLogin("fabrice")
         .setCreatedAt(DateUtils.parseDateTime("2014-09-10T19:10:03+0000").getTime()));
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john");
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH).setParam(PARAM_HIDE_COMMENTS, "true").execute();
+    TestResponse result = wsTester.newRequest().setParam(PARAM_HIDE_COMMENTS, "true").execute();
     result.assertJson(this.getClass(), "issue_with_comment_hidden.json");
-    assertThat(result.outputAsString()).doesNotContain("fabrice");
+    assertThat(result.getInput()).doesNotContain("fabrice");
   }
 
   @Test
@@ -233,13 +240,12 @@ public class SearchActionMediumTest {
       .setAssignee("simon");
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john");
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam("additionalFields", "_all").execute();
-    result.assertJson(this.getClass(), "load_additional_fields.json");
+    wsTester.newRequest()
+      .setParam("additionalFields", "_all").execute()
+      .assertJson(this.getClass(), "load_additional_fields.json");
   }
 
   @Test
@@ -257,14 +263,13 @@ public class SearchActionMediumTest {
       .setAssignee("simon");
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john")
       .addProjectPermission(ISSUE_ADMIN, project); // granted by Anyone
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .setParam("additionalFields", "_all").execute();
-    result.assertJson(this.getClass(), "load_additional_fields_with_issue_admin_permission.json");
+    wsTester.newRequest()
+      .setParam("additionalFields", "_all").execute()
+      .assertJson(this.getClass(), "load_additional_fields_with_issue_admin_permission.json");
   }
 
   @Test
@@ -285,12 +290,11 @@ public class SearchActionMediumTest {
       .setIssueUpdateDate(DateUtils.parseDateTime("2017-12-04T00:00:00+0100"));
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
-      .execute();
-    result.assertJson(this.getClass(), "issue_on_removed_file.json");
+    wsTester.newRequest()
+      .execute()
+      .assertJson(this.getClass(), "issue_on_removed_file.json");
   }
 
   @Test
@@ -301,14 +305,13 @@ public class SearchActionMediumTest {
     ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
     for (int i = 0; i < SearchOptions.MAX_LIMIT + 1; i++) {
       IssueDto issue = IssueTesting.newDto(rule, file, project);
-      tester.get(IssueDao.class).insert(session, issue);
+      db.issueDao().insert(session, issue);
     }
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH).setParam(PARAM_COMPONENTS, file.getDbKey()).execute();
-    result.assertJson(this.getClass(), "apply_paging_with_one_component.json");
+    wsTester.newRequest().setParam(PARAM_COMPONENTS, file.getDbKey()).execute()
+      .assertJson(this.getClass(), "apply_paging_with_one_component.json");
   }
 
   @Test
@@ -320,11 +323,10 @@ public class SearchActionMediumTest {
     IssueDto issue = IssueTesting.newDto(newRule(), file, project);
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH).setParam(PARAM_ADDITIONAL_FIELDS, "_all").execute();
-    result.assertJson(this.getClass(), "components_contains_sub_projects.json");
+    wsTester.newRequest().setParam(PARAM_ADDITIONAL_FIELDS, "_all").execute()
+      .assertJson(this.getClass(), "components_contains_sub_projects.json");
   }
 
   @Test
@@ -341,15 +343,14 @@ public class SearchActionMediumTest {
       .setSeverity("MAJOR");
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john");
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("resolved", "false")
       .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans,types")
-      .execute();
-    result.assertJson(this.getClass(), "display_facets.json");
+      .execute()
+      .assertJson(this.getClass(), "display_facets.json");
   }
 
   @Test
@@ -366,16 +367,15 @@ public class SearchActionMediumTest {
       .setSeverity("MAJOR");
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john");
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("resolved", "false")
       .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,languages,actionPlans")
       .setParam("facetMode", FACET_MODE_EFFORT)
-      .execute();
-    result.assertJson(this.getClass(), "display_facets_effort.json");
+      .execute()
+      .assertJson(this.getClass(), "display_facets_effort.json");
   }
 
   @Test
@@ -392,17 +392,16 @@ public class SearchActionMediumTest {
       .setSeverity("MAJOR");
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john");
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("resolved", "false")
       .setParam("severities", "MAJOR,MINOR")
       .setParam("languages", "xoo,polop,palap")
       .setParam(WebService.Param.FACETS, "statuses,severities,resolutions,projectUuids,rules,fileUuids,assignees,assigned_to_me,languages,actionPlans")
-      .execute();
-    result.assertJson(this.getClass(), "display_zero_facets.json");
+      .execute()
+      .assertJson(this.getClass(), "display_zero_facets.json");
   }
 
   @Test
@@ -411,7 +410,7 @@ public class SearchActionMediumTest {
     userSessionRule.logIn("foo[");
 
     // should not fail
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam(WebService.Param.FACETS, "assigned_to_me")
       .execute()
       .assertJson(this.getClass(), "assignedToMe_facet_must_escape_login_of_authenticated_user.json");
@@ -451,11 +450,10 @@ public class SearchActionMediumTest {
       .setSeverity("MAJOR");
     db.issueDao().insert(session, issue1, issue2, issue3);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john");
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("resolved", "false")
       .setParam("assignees", "__me__")
       .setParam(WebService.Param.FACETS, "assignees,assigned_to_me")
@@ -484,10 +482,9 @@ public class SearchActionMediumTest {
       .setKee("82fd47d4-4037-b650-80bc-7b112bd4eac2");
     db.issueDao().insert(session, issue1, issue2, issue3);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("resolved", "false")
       .setParam("assignees", "__me__")
       .execute()
@@ -527,11 +524,10 @@ public class SearchActionMediumTest {
       .setSeverity("MAJOR");
     db.issueDao().insert(session, issue1, issue2, issue3);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john-bob.polop");
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("resolved", "false")
       .setParam("assignees", "alice")
       .setParam(WebService.Param.FACETS, "assignees,assigned_to_me")
@@ -555,14 +551,13 @@ public class SearchActionMediumTest {
       .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac3")
       .setIssueUpdateDate(DateUtils.parseDateTime("2014-11-03T00:00:00+0100")));
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("sort", IssueQuery.SORT_BY_UPDATE_DATE)
       .setParam("asc", "false")
-      .execute();
-    result.assertJson(this.getClass(), "sort_by_updated_at.json");
+      .execute()
+      .assertJson(this.getClass(), "sort_by_updated_at.json");
   }
 
   @Test
@@ -573,18 +568,16 @@ public class SearchActionMediumTest {
     ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
     for (int i = 0; i < 12; i++) {
       IssueDto issue = IssueTesting.newDto(rule, file, project);
-      tester.get(IssueDao.class).insert(session, issue);
+      db.issueDao().insert(session, issue);
     }
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
-    WsTester.TestRequest request = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH);
-    request.setParam(WebService.Param.PAGE, "2");
-    request.setParam(WebService.Param.PAGE_SIZE, "9");
-
-    WsTester.Result result = request.execute();
-    result.assertJson(this.getClass(), "paging.json");
+    wsTester.newRequest()
+      .setParam(WebService.Param.PAGE, "2")
+      .setParam(WebService.Param.PAGE_SIZE, "9")
+      .execute()
+      .assertJson(this.getClass(), "paging.json");
   }
 
   @Test
@@ -595,18 +588,16 @@ public class SearchActionMediumTest {
     ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
     for (int i = 0; i < 12; i++) {
       IssueDto issue = IssueTesting.newDto(rule, file, project);
-      tester.get(IssueDao.class).insert(session, issue);
+      db.issueDao().insert(session, issue);
     }
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
-    WsTester.TestRequest request = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH);
-    request.setParam(WebService.Param.PAGE, "1");
-    request.setParam(WebService.Param.PAGE_SIZE, "-1");
-
-    WsTester.Result result = request.execute();
-    result.assertJson(this.getClass(), "paging_with_page_size_to_minus_one.json");
+    wsTester.newRequest()
+      .setParam(WebService.Param.PAGE, "1")
+      .setParam(WebService.Param.PAGE_SIZE, "-1")
+      .execute()
+      .assertJson(this.getClass(), "paging_with_page_size_to_minus_one.json");
   }
 
   @Test
@@ -617,26 +608,23 @@ public class SearchActionMediumTest {
     ComponentDto file = insertComponent(ComponentTesting.newFileDto(project, null, "FILE_ID").setDbKey("FILE_KEY"));
     for (int i = 0; i < 12; i++) {
       IssueDto issue = IssueTesting.newDto(rule, file, project);
-      tester.get(IssueDao.class).insert(session, issue);
+      db.issueDao().insert(session, issue);
     }
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
-    WsTester.TestRequest request = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH);
-    request.setParam(PARAM_PAGE_INDEX, "2");
-    request.setParam(PARAM_PAGE_SIZE, "9");
-
-    WsTester.Result result = request.execute();
-    result.assertJson(this.getClass(), "deprecated_paging.json");
+    wsTester.newRequest()
+      .setParam(PARAM_PAGE_INDEX, "2")
+      .setParam(PARAM_PAGE_SIZE, "9")
+      .execute()
+      .assertJson(this.getClass(), "deprecated_paging.json");
   }
 
   @Test
   public void default_page_size_is_100() throws Exception {
-    WsTester.TestRequest request = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH);
-
-    WsTester.Result result = request.execute();
-    result.assertJson(this.getClass(), "default_page_size_is_100.json");
+    wsTester.newRequest()
+      .execute()
+      .assertJson(this.getClass(), "default_page_size_is_100.json");
   }
 
   @Test
@@ -653,16 +641,15 @@ public class SearchActionMediumTest {
       .setSeverity("MAJOR");
     db.issueDao().insert(session, issue);
     session.commit();
-    IssueIndexer r = tester.get(IssueIndexer.class);
-    r.indexOnStartup(r.getIndexTypes());
+    indexIssues();
 
     userSessionRule.logIn("john");
-    WsTester.Result result = wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam("resolved", "false")
       .setParam(WebService.Param.FACETS, "severities")
       .setParam("facetMode", DEPRECATED_FACET_MODE_DEBT)
-      .execute();
-    result.assertJson(this.getClass(), "display_deprecated_debt_fields.json");
+      .execute()
+      .assertJson(this.getClass(), "display_deprecated_debt_fields.json");
   }
 
   @Test
@@ -670,7 +657,7 @@ public class SearchActionMediumTest {
     expectedException.expect(IllegalArgumentException.class);
     expectedException.expectMessage("Date 'wrong-date-input' cannot be parsed as either a date or date+time");
 
-    wsTester.newGetRequest(CONTROLLER_ISSUES, ACTION_SEARCH)
+    wsTester.newRequest()
       .setParam(PARAM_CREATED_AFTER, "wrong-date-input")
       .execute();
   }
@@ -680,16 +667,18 @@ public class SearchActionMediumTest {
       .setName("Rule name")
       .setDescription("Rule desc")
       .setStatus(RuleStatus.READY);
-    tester.get(RuleDao.class).insert(session, rule.getDefinition());
-    session.commit();
+    dbTester.rules().insert(rule.getDefinition());
     return rule;
   }
 
   private void indexPermissions() {
-    PermissionIndexer permissionIndexer = tester.get(PermissionIndexer.class);
     permissionIndexer.indexOnStartup(permissionIndexer.getIndexTypes());
   }
 
+  private void indexIssues() {
+    issueIndexer.indexOnStartup(issueIndexer.getIndexTypes());
+  }
+
   private void grantPermissionToAnyone(ComponentDto project, String permission) {
     db.groupPermissionDao().insert(session,
       new GroupPermissionDto()
@@ -706,5 +695,4 @@ public class SearchActionMediumTest {
     session.commit();
     return component;
   }
-
 }
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonMediumTest.java
deleted file mode 100644 (file)
index ddd99d7..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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.sonar.server.qualityprofile;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.MapDifference.ValueDifference;
-import org.assertj.core.data.MapEntry;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.rule.Severity;
-import org.sonar.api.server.rule.RuleParamType;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.qualityprofile.QProfileDto;
-import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleParamDto;
-import org.sonar.db.rule.RuleTesting;
-import org.sonar.server.qualityprofile.QProfileComparison.ActiveRuleDiff;
-import org.sonar.server.qualityprofile.QProfileComparison.QProfileComparisonResult;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class QProfileComparisonMediumTest {
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester().withEsIndexes().addXoo();
-
-  @Rule
-  public UserSessionRule userSession = UserSessionRule.forServerTester(tester).anonymous();
-
-  DbClient db;
-  DbSession dbSession;
-  RuleActivator ruleActivator;
-  QProfileComparison comparison;
-
-  RuleDto xooRule1;
-  RuleDto xooRule2;
-  QProfileDto left;
-  QProfileDto right;
-
-  @Before
-  public void before() {
-    tester.clearDbAndIndexes();
-    db = tester.get(DbClient.class);
-    dbSession = db.openSession(false);
-    ruleActivator = tester.get(RuleActivator.class);
-    comparison = tester.get(QProfileComparison.class);
-
-    xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR");
-    xooRule2 = RuleTesting.newXooX2().setSeverity("MAJOR");
-    db.ruleDao().insert(dbSession, xooRule1.getDefinition());
-    db.ruleDao().insert(dbSession, xooRule2.getDefinition());
-    db.ruleDao().insertRuleParam(dbSession, xooRule1.getDefinition(), RuleParamDto.createFor(xooRule1.getDefinition())
-      .setName("max").setType(RuleParamType.INTEGER.type()));
-    db.ruleDao().insertRuleParam(dbSession, xooRule1.getDefinition(), RuleParamDto.createFor(xooRule1.getDefinition())
-      .setName("min").setType(RuleParamType.INTEGER.type()));
-
-    left = QProfileTesting.newXooP1("org-123");
-    right = QProfileTesting.newXooP2("org-123");
-    db.qualityProfileDao().insert(dbSession, left, right);
-
-    dbSession.commit();
-  }
-
-  @After
-  public void after() {
-    dbSession.close();
-  }
-
-  @Test
-  public void compare_empty_profiles() {
-    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
-    assertThat(result.left().getKee()).isEqualTo(left.getKee());
-    assertThat(result.right().getKee()).isEqualTo(right.getKee());
-    assertThat(result.same()).isEmpty();
-    assertThat(result.inLeft()).isEmpty();
-    assertThat(result.inRight()).isEmpty();
-    assertThat(result.modified()).isEmpty();
-    assertThat(result.collectRuleKeys()).isEmpty();
-  }
-
-  @Test
-  public void compare_same() {
-    RuleActivation commonActivation = RuleActivation.create(xooRule1.getKey(), Severity.CRITICAL,
-      ImmutableMap.of("min", "7", "max", "42"));
-    ruleActivator.activate(dbSession, commonActivation, left);
-    ruleActivator.activate(dbSession, commonActivation, right);
-    dbSession.commit();
-
-    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
-    assertThat(result.left().getKee()).isEqualTo(left.getKee());
-    assertThat(result.right().getKee()).isEqualTo(right.getKee());
-    assertThat(result.same()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
-    assertThat(result.inLeft()).isEmpty();
-    assertThat(result.inRight()).isEmpty();
-    assertThat(result.modified()).isEmpty();
-    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
-  }
-
-  @Test
-  public void compare_only_left() {
-    RuleActivation activation = RuleActivation.create(xooRule1.getKey());
-    ruleActivator.activate(dbSession, activation, left);
-    dbSession.commit();
-
-    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
-    assertThat(result.left().getKee()).isEqualTo(left.getKee());
-    assertThat(result.right().getKee()).isEqualTo(right.getKee());
-    assertThat(result.same()).isEmpty();
-    assertThat(result.inLeft()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
-    assertThat(result.inRight()).isEmpty();
-    assertThat(result.modified()).isEmpty();
-    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
-  }
-
-  @Test
-  public void compare_only_right() {
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey()), right);
-    dbSession.commit();
-
-    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
-    assertThat(result.left().getKee()).isEqualTo(left.getKee());
-    assertThat(result.right().getKee()).isEqualTo(right.getKee());
-    assertThat(result.same()).isEmpty();
-    assertThat(result.inLeft()).isEmpty();
-    assertThat(result.inRight()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
-    assertThat(result.modified()).isEmpty();
-    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
-  }
-
-  @Test
-  public void compare_disjoint() {
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey()), left);
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule2.getKey()), right);
-    dbSession.commit();
-
-    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
-    assertThat(result.left().getKee()).isEqualTo(left.getKee());
-    assertThat(result.right().getKee()).isEqualTo(right.getKee());
-    assertThat(result.same()).isEmpty();
-    assertThat(result.inLeft()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
-    assertThat(result.inRight()).isNotEmpty().containsOnlyKeys(xooRule2.getKey());
-    assertThat(result.modified()).isEmpty();
-    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey(), xooRule2.getKey());
-  }
-
-  @Test
-  public void compare_modified_severity() {
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), Severity.CRITICAL, null), left);
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), Severity.BLOCKER, null), right);
-    dbSession.commit();
-
-    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
-    assertThat(result.left().getKee()).isEqualTo(left.getKee());
-    assertThat(result.right().getKee()).isEqualTo(right.getKee());
-    assertThat(result.same()).isEmpty();
-    assertThat(result.inLeft()).isEmpty();
-    assertThat(result.inRight()).isEmpty();
-    assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
-    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
-
-    ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey());
-    assertThat(activeRuleDiff.leftSeverity()).isEqualTo(Severity.CRITICAL);
-    assertThat(activeRuleDiff.rightSeverity()).isEqualTo(Severity.BLOCKER);
-    assertThat(activeRuleDiff.paramDifference().areEqual()).isTrue();
-  }
-
-  @Test
-  public void compare_modified_param() {
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), null, ImmutableMap.of("max", "20")), left);
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), null, ImmutableMap.of("max", "30")), right);
-    dbSession.commit();
-
-    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
-    assertThat(result.left().getKee()).isEqualTo(left.getKee());
-    assertThat(result.right().getKee()).isEqualTo(right.getKee());
-    assertThat(result.same()).isEmpty();
-    assertThat(result.inLeft()).isEmpty();
-    assertThat(result.inRight()).isEmpty();
-    assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
-    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
-
-    ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey());
-    assertThat(activeRuleDiff.leftSeverity()).isEqualTo(activeRuleDiff.rightSeverity()).isEqualTo(xooRule1.getSeverityString());
-    assertThat(activeRuleDiff.paramDifference().areEqual()).isFalse();
-    assertThat(activeRuleDiff.paramDifference().entriesDiffering()).isNotEmpty();
-    ValueDifference<String> paramDiff = activeRuleDiff.paramDifference().entriesDiffering().get("max");
-    assertThat(paramDiff.leftValue()).isEqualTo("20");
-    assertThat(paramDiff.rightValue()).isEqualTo("30");
-  }
-
-  @Test
-  public void compare_different_params() {
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), null, ImmutableMap.of("max", "20")), left);
-    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), null, ImmutableMap.of("min", "5")), right);
-    dbSession.commit();
-
-    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
-    assertThat(result.left().getKee()).isEqualTo(left.getKee());
-    assertThat(result.right().getKee()).isEqualTo(right.getKee());
-    assertThat(result.same()).isEmpty();
-    assertThat(result.inLeft()).isEmpty();
-    assertThat(result.inRight()).isEmpty();
-    assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
-    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
-
-    ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey());
-    assertThat(activeRuleDiff.leftSeverity()).isEqualTo(activeRuleDiff.rightSeverity()).isEqualTo(xooRule1.getSeverityString());
-    assertThat(activeRuleDiff.paramDifference().areEqual()).isFalse();
-    assertThat(activeRuleDiff.paramDifference().entriesDiffering()).isEmpty();
-    assertThat(activeRuleDiff.paramDifference().entriesOnlyOnLeft()).containsExactly(MapEntry.entry("max", "20"));
-    assertThat(activeRuleDiff.paramDifference().entriesOnlyOnRight()).containsExactly(MapEntry.entry("min", "5"));
-  }
-}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileComparisonTest.java
new file mode 100644 (file)
index 0000000..c7de68e
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.sonar.server.qualityprofile;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.MapDifference.ValueDifference;
+import org.assertj.core.data.MapEntry;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.rule.RuleParamType;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleParamDto;
+import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.es.EsTester;
+import org.sonar.server.qualityprofile.QProfileComparison.ActiveRuleDiff;
+import org.sonar.server.qualityprofile.QProfileComparison.QProfileComparisonResult;
+import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
+import org.sonar.server.rule.index.RuleIndex;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.util.IntegerTypeValidation;
+import org.sonar.server.util.TypeValidations;
+
+import static java.util.Collections.singletonList;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class QProfileComparisonTest {
+
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone().anonymous();
+  @Rule
+  public DbTester dbTester = DbTester.create();
+  @Rule
+  public EsTester esTester = new EsTester();
+
+  private DbClient db;
+  private DbSession dbSession;
+  private RuleActivator ruleActivator;
+  private QProfileComparison comparison;
+
+  private RuleDto xooRule1;
+  private RuleDto xooRule2;
+  private QProfileDto left;
+  private QProfileDto right;
+
+  @Before
+  public void before() {
+    db = dbTester.getDbClient();
+    dbSession = db.openSession(false);
+    ruleActivator = new RuleActivator(
+      System2.INSTANCE,
+      db,
+      new RuleIndex(esTester.client()),
+      new RuleActivatorContextFactory(db),
+      new TypeValidations(singletonList(new IntegerTypeValidation())),
+      new ActiveRuleIndexer(db, esTester.client()),
+      userSession
+    );
+    comparison = new QProfileComparison(db);
+
+    xooRule1 = RuleTesting.newXooX1().setSeverity("MINOR");
+    xooRule2 = RuleTesting.newXooX2().setSeverity("MAJOR");
+    db.ruleDao().insert(dbSession, xooRule1.getDefinition());
+    db.ruleDao().insert(dbSession, xooRule2.getDefinition());
+    db.ruleDao().insertRuleParam(dbSession, xooRule1.getDefinition(), RuleParamDto.createFor(xooRule1.getDefinition())
+      .setName("max").setType(RuleParamType.INTEGER.type()));
+    db.ruleDao().insertRuleParam(dbSession, xooRule1.getDefinition(), RuleParamDto.createFor(xooRule1.getDefinition())
+      .setName("min").setType(RuleParamType.INTEGER.type()));
+
+    left = QProfileTesting.newXooP1("org-123");
+    right = QProfileTesting.newXooP2("org-123");
+    db.qualityProfileDao().insert(dbSession, left, right);
+
+    dbSession.commit();
+  }
+
+  @After
+  public void after() {
+    dbSession.close();
+  }
+
+  @Test
+  public void compare_empty_profiles() {
+    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
+    assertThat(result.left().getKee()).isEqualTo(left.getKee());
+    assertThat(result.right().getKee()).isEqualTo(right.getKee());
+    assertThat(result.same()).isEmpty();
+    assertThat(result.inLeft()).isEmpty();
+    assertThat(result.inRight()).isEmpty();
+    assertThat(result.modified()).isEmpty();
+    assertThat(result.collectRuleKeys()).isEmpty();
+  }
+
+  @Test
+  public void compare_same() {
+    RuleActivation commonActivation = RuleActivation.create(xooRule1.getKey(), Severity.CRITICAL,
+      ImmutableMap.of("min", "7", "max", "42"));
+    ruleActivator.activate(dbSession, commonActivation, left);
+    ruleActivator.activate(dbSession, commonActivation, right);
+    dbSession.commit();
+
+    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
+    assertThat(result.left().getKee()).isEqualTo(left.getKee());
+    assertThat(result.right().getKee()).isEqualTo(right.getKee());
+    assertThat(result.same()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
+    assertThat(result.inLeft()).isEmpty();
+    assertThat(result.inRight()).isEmpty();
+    assertThat(result.modified()).isEmpty();
+    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
+  }
+
+  @Test
+  public void compare_only_left() {
+    RuleActivation activation = RuleActivation.create(xooRule1.getKey());
+    ruleActivator.activate(dbSession, activation, left);
+    dbSession.commit();
+
+    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
+    assertThat(result.left().getKee()).isEqualTo(left.getKee());
+    assertThat(result.right().getKee()).isEqualTo(right.getKee());
+    assertThat(result.same()).isEmpty();
+    assertThat(result.inLeft()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
+    assertThat(result.inRight()).isEmpty();
+    assertThat(result.modified()).isEmpty();
+    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
+  }
+
+  @Test
+  public void compare_only_right() {
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey()), right);
+    dbSession.commit();
+
+    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
+    assertThat(result.left().getKee()).isEqualTo(left.getKee());
+    assertThat(result.right().getKee()).isEqualTo(right.getKee());
+    assertThat(result.same()).isEmpty();
+    assertThat(result.inLeft()).isEmpty();
+    assertThat(result.inRight()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
+    assertThat(result.modified()).isEmpty();
+    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
+  }
+
+  @Test
+  public void compare_disjoint() {
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey()), left);
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule2.getKey()), right);
+    dbSession.commit();
+
+    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
+    assertThat(result.left().getKee()).isEqualTo(left.getKee());
+    assertThat(result.right().getKee()).isEqualTo(right.getKee());
+    assertThat(result.same()).isEmpty();
+    assertThat(result.inLeft()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
+    assertThat(result.inRight()).isNotEmpty().containsOnlyKeys(xooRule2.getKey());
+    assertThat(result.modified()).isEmpty();
+    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey(), xooRule2.getKey());
+  }
+
+  @Test
+  public void compare_modified_severity() {
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), Severity.CRITICAL, null), left);
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), Severity.BLOCKER, null), right);
+    dbSession.commit();
+
+    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
+    assertThat(result.left().getKee()).isEqualTo(left.getKee());
+    assertThat(result.right().getKee()).isEqualTo(right.getKee());
+    assertThat(result.same()).isEmpty();
+    assertThat(result.inLeft()).isEmpty();
+    assertThat(result.inRight()).isEmpty();
+    assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
+    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
+
+    ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey());
+    assertThat(activeRuleDiff.leftSeverity()).isEqualTo(Severity.CRITICAL);
+    assertThat(activeRuleDiff.rightSeverity()).isEqualTo(Severity.BLOCKER);
+    assertThat(activeRuleDiff.paramDifference().areEqual()).isTrue();
+  }
+
+  @Test
+  public void compare_modified_param() {
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), null, ImmutableMap.of("max", "20")), left);
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), null, ImmutableMap.of("max", "30")), right);
+    dbSession.commit();
+
+    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
+    assertThat(result.left().getKee()).isEqualTo(left.getKee());
+    assertThat(result.right().getKee()).isEqualTo(right.getKee());
+    assertThat(result.same()).isEmpty();
+    assertThat(result.inLeft()).isEmpty();
+    assertThat(result.inRight()).isEmpty();
+    assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
+    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
+
+    ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey());
+    assertThat(activeRuleDiff.leftSeverity()).isEqualTo(activeRuleDiff.rightSeverity()).isEqualTo(xooRule1.getSeverityString());
+    assertThat(activeRuleDiff.paramDifference().areEqual()).isFalse();
+    assertThat(activeRuleDiff.paramDifference().entriesDiffering()).isNotEmpty();
+    ValueDifference<String> paramDiff = activeRuleDiff.paramDifference().entriesDiffering().get("max");
+    assertThat(paramDiff.leftValue()).isEqualTo("20");
+    assertThat(paramDiff.rightValue()).isEqualTo("30");
+  }
+
+  @Test
+  public void compare_different_params() {
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), null, ImmutableMap.of("max", "20")), left);
+    ruleActivator.activate(dbSession, RuleActivation.create(xooRule1.getKey(), null, ImmutableMap.of("min", "5")), right);
+    dbSession.commit();
+
+    QProfileComparisonResult result = comparison.compare(dbSession, left, right);
+    assertThat(result.left().getKee()).isEqualTo(left.getKee());
+    assertThat(result.right().getKee()).isEqualTo(right.getKee());
+    assertThat(result.same()).isEmpty();
+    assertThat(result.inLeft()).isEmpty();
+    assertThat(result.inRight()).isEmpty();
+    assertThat(result.modified()).isNotEmpty().containsOnlyKeys(xooRule1.getKey());
+    assertThat(result.collectRuleKeys()).containsOnly(xooRule1.getKey());
+
+    ActiveRuleDiff activeRuleDiff = result.modified().get(xooRule1.getKey());
+    assertThat(activeRuleDiff.leftSeverity()).isEqualTo(activeRuleDiff.rightSeverity()).isEqualTo(xooRule1.getSeverityString());
+    assertThat(activeRuleDiff.paramDifference().areEqual()).isFalse();
+    assertThat(activeRuleDiff.paramDifference().entriesDiffering()).isEmpty();
+    assertThat(activeRuleDiff.paramDifference().entriesOnlyOnLeft()).containsExactly(MapEntry.entry("max", "20"));
+    assertThat(activeRuleDiff.paramDifference().entriesOnlyOnRight()).containsExactly(MapEntry.entry("min", "5"));
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java
deleted file mode 100644 (file)
index 4de309a..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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.sonar.server.qualityprofile.ws;
-
-import org.apache.commons.lang.StringUtils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.rule.Severity;
-import org.sonar.api.server.rule.RuleParamType;
-import org.sonar.api.server.rule.RulesDefinition;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.qualityprofile.ActiveRuleDto;
-import org.sonar.db.qualityprofile.ActiveRuleParamDto;
-import org.sonar.db.qualityprofile.QProfileDto;
-import org.sonar.db.rule.RuleDefinitionDto;
-import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleParamDto;
-import org.sonar.db.rule.RuleRepositoryDto;
-import org.sonar.server.qualityprofile.QProfileName;
-import org.sonar.server.qualityprofile.QProfileTesting;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
-
-import static java.util.Arrays.asList;
-
-public class CompareActionMediumTest {
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester().withEsIndexes().withStartupTasks().addXoo()
-    .addComponents(new RulesDefinition() {
-      @Override
-      public void define(Context context) {
-        context.createRepository("blah", "xoo")
-          .setName("Blah")
-          .done();
-      }
-    });
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
-
-  private DbClient db;
-
-  private WsTester wsTester;
-
-  private DbSession session;
-
-  @Before
-  public void setUp() {
-    tester.clearDbAndIndexes();
-    db = tester.get(DbClient.class);
-    session = db.openSession(false);
-
-    wsTester = new WsTester(tester.get(QProfilesWs.class));
-  }
-
-  @After
-  public void tearDown() {
-    session.close();
-  }
-
-  @Test
-  public void compare_nominal() throws Exception {
-    createRepository("blah", "xoo", "Blah");
-
-    RuleDefinitionDto rule1 = createRule("xoo", "rule1");
-    RuleDefinitionDto rule2 = createRule("xoo", "rule2");
-    RuleDefinitionDto rule3 = createRule("xoo", "rule3");
-    RuleDefinitionDto rule4 = createRuleWithParam("xoo", "rule4");
-    RuleDefinitionDto rule5 = createRule("xoo", "rule5");
-
-    /*
-     * Profile 1:
-     * - rule 1 active (on both profiles) => "same"
-     * - rule 2 active (only in this profile) => "inLeft"
-     * - rule 4 active with different parameters => "modified"
-     * - rule 5 active with different severity => "modified"
-     */
-    QProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234");
-    createActiveRule(rule1, profile1);
-    createActiveRule(rule2, profile1);
-    createActiveRuleWithParam(rule4, profile1, "polop");
-    createActiveRuleWithSeverity(rule5, profile1, Severity.MINOR);
-    session.commit();
-
-    /*
-     * Profile 1:
-     * - rule 1 active (on both profiles) => "same"
-     * - rule 3 active (only in this profile) => "inRight"
-     * - rule 4 active with different parameters => "modified"
-     */
-    QProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345");
-    createActiveRule(rule1, profile2);
-    createActiveRule(rule3, profile2);
-    createActiveRuleWithParam(rule4, profile2, "palap");
-    createActiveRuleWithSeverity(rule5, profile2, Severity.MAJOR);
-    session.commit();
-
-    wsTester.newGetRequest("api/qualityprofiles", "compare")
-      .setParam("leftKey", profile1.getKee())
-      .setParam("rightKey", profile2.getKee())
-      .execute().assertJson(this.getClass(), "compare_nominal.json");
-  }
-
-  @Test
-  public void compare_param_on_left() throws Exception {
-    RuleDefinitionDto rule1 = createRuleWithParam("xoo", "rule1");
-    createRepository("blah", "xoo", "Blah");
-    QProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234");
-    createActiveRuleWithParam(rule1, profile1, "polop");
-    QProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345");
-    createActiveRule(rule1, profile2);
-    session.commit();
-
-    wsTester.newGetRequest("api/qualityprofiles", "compare")
-      .setParam("leftKey", profile1.getKee())
-      .setParam("rightKey", profile2.getKee())
-      .execute().assertJson(this.getClass(), "compare_param_on_left.json");
-  }
-
-  @Test
-  public void compare_param_on_right() throws Exception {
-    RuleDefinitionDto rule1 = createRuleWithParam("xoo", "rule1");
-    createRepository("blah", "xoo", "Blah");
-    QProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234");
-    createActiveRule(rule1, profile1);
-    QProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345");
-    createActiveRuleWithParam(rule1, profile2, "polop");
-    session.commit();
-
-    wsTester.newGetRequest("api/qualityprofiles", "compare")
-      .setParam("leftKey", profile1.getKee())
-      .setParam("rightKey", profile2.getKee())
-      .execute().assertJson(this.getClass(), "compare_param_on_right.json");
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void fail_on_missing_left_param() throws Exception {
-    wsTester.newGetRequest("api/qualityprofiles", "compare")
-      .setParam("rightKey", "polop")
-      .execute();
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void fail_on_missing_right_param() throws Exception {
-    wsTester.newGetRequest("api/qualityprofiles", "compare")
-      .setParam("leftKey", "polop")
-      .execute();
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void fail_on_left_profile_not_found() throws Exception {
-    createProfile("xoo", "Right", "xoo-right-12345");
-    wsTester.newGetRequest("api/qualityprofiles", "compare")
-      .setParam("leftKey", "polop")
-      .setParam("rightKey", "xoo-right-12345")
-      .execute();
-  }
-
-  @Test(expected = IllegalArgumentException.class)
-  public void fail_on_right_profile_not_found() throws Exception {
-    createProfile("xoo", "Left", "xoo-left-12345");
-    wsTester.newGetRequest("api/qualityprofiles", "compare")
-      .setParam("leftKey", "xoo-left-12345")
-      .setParam("rightKey", "polop")
-      .execute();
-  }
-
-  private QProfileDto createProfile(String lang, String name, String key) {
-    QProfileDto profile = QProfileTesting.newQProfileDto("org-123", new QProfileName(lang, name), key);
-    db.qualityProfileDao().insert(session, profile);
-    session.commit();
-    return profile;
-  }
-
-  private RuleDefinitionDto createRule(String lang, String id) {
-    RuleDto rule = RuleDto.createFor(RuleKey.of("blah", id))
-      .setName(StringUtils.capitalize(id))
-      .setLanguage(lang)
-      .setSeverity(Severity.BLOCKER)
-      .setStatus(RuleStatus.READY);
-    RuleDefinitionDto ruleDefinition = rule.getDefinition();
-    db.ruleDao().insert(session, ruleDefinition);
-    RuleParamDto param = RuleParamDto.createFor(ruleDefinition).setName("param_" + id).setType(RuleParamType.STRING.toString());
-    db.ruleDao().insertRuleParam(session, ruleDefinition, param);
-    return ruleDefinition;
-  }
-
-  private RuleDefinitionDto createRuleWithParam(String lang, String id) {
-    RuleDefinitionDto rule = createRule(lang, id);
-    RuleParamDto param = RuleParamDto.createFor(rule)
-      .setName("param_" + id)
-      .setType(RuleParamType.STRING.toString());
-    db.ruleDao().insertRuleParam(session, rule, param);
-    return rule;
-  }
-
-  private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QProfileDto profile) {
-    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule)
-      .setSeverity(rule.getSeverityString());
-    db.activeRuleDao().insert(session, activeRule);
-    return activeRule;
-  }
-
-  private ActiveRuleDto createActiveRuleWithParam(RuleDefinitionDto rule, QProfileDto profile, String value) {
-    ActiveRuleDto activeRule = createActiveRule(rule, profile);
-    RuleParamDto paramDto = db.ruleDao().selectRuleParamsByRuleKey(session, rule.getKey()).get(0);
-    ActiveRuleParamDto activeRuleParam = ActiveRuleParamDto.createFor(paramDto).setValue(value);
-    db.activeRuleDao().insertParam(session, activeRule, activeRuleParam);
-    return activeRule;
-  }
-
-  private ActiveRuleDto createActiveRuleWithSeverity(RuleDefinitionDto rule, QProfileDto profile, String severity) {
-    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule)
-      .setSeverity(severity);
-    db.activeRuleDao().insert(session, activeRule);
-    return activeRule;
-  }
-
-  private void createRepository(String repositoryKey, String repositoryLanguage, String repositoryName) {
-    RuleRepositoryDto dto = new RuleRepositoryDto(repositoryKey, repositoryLanguage, repositoryName);
-    db.ruleRepositoryDao().insert(session, asList(dto));
-    session.commit();
-  }
-}
index 6f00aa6f86df4f2dfe2b917eba671d0216cf9819..01e23d558518a3798d4e19d7f15ea3b9babd5617 100644 (file)
  */
 package org.sonar.server.qualityprofile.ws;
 
+import org.apache.commons.lang.StringUtils;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.resources.Languages;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
+import org.sonar.api.server.rule.RuleParamType;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
+import org.sonar.db.qualityprofile.ActiveRuleDto;
+import org.sonar.db.qualityprofile.ActiveRuleParamDto;
 import org.sonar.db.qualityprofile.QProfileDto;
 import org.sonar.db.qualityprofile.QualityProfileTesting;
+import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleParamDto;
+import org.sonar.db.rule.RuleRepositoryDto;
+import org.sonar.server.language.LanguageTesting;
 import org.sonar.server.qualityprofile.QProfileComparison;
+import org.sonar.server.qualityprofile.QProfileName;
+import org.sonar.server.qualityprofile.QProfileTesting;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 
+import static java.util.Arrays.asList;
+
 public class CompareActionTest {
 
   @Rule
@@ -42,10 +60,12 @@ public class CompareActionTest {
   public ExpectedException thrown = ExpectedException.none();
   private WsActionTester wsTester;
   private CompareAction underTest;
+  private DbClient db = dbTester.getDbClient();
+  private DbSession session = dbTester.getSession();
 
   @Before
   public void before() {
-    underTest = new CompareAction(dbTester.getDbClient(), new QProfileComparison(dbTester.getDbClient()), new Languages());
+    underTest = new CompareAction(dbTester.getDbClient(), new QProfileComparison(dbTester.getDbClient()), new Languages(LanguageTesting.newLanguage("xoo", "Xoo")));
     wsTester = new WsActionTester(underTest);
   }
 
@@ -63,4 +83,168 @@ public class CompareActionTest {
     thrown.expectMessage("Cannot compare quality profiles of different organizations.");
     request.execute();
   }
+
+  @Test
+  public void compare_nominal() throws Exception {
+    createRepository("blah", "xoo", "Blah");
+
+    RuleDefinitionDto rule1 = createRule("xoo", "rule1");
+    RuleDefinitionDto rule2 = createRule("xoo", "rule2");
+    RuleDefinitionDto rule3 = createRule("xoo", "rule3");
+    RuleDefinitionDto rule4 = createRuleWithParam("xoo", "rule4");
+    RuleDefinitionDto rule5 = createRule("xoo", "rule5");
+
+    /*
+     * Profile 1:
+     * - rule 1 active (on both profiles) => "same"
+     * - rule 2 active (only in this profile) => "inLeft"
+     * - rule 4 active with different parameters => "modified"
+     * - rule 5 active with different severity => "modified"
+     */
+    QProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234");
+    createActiveRule(rule1, profile1);
+    createActiveRule(rule2, profile1);
+    createActiveRuleWithParam(rule4, profile1, "polop");
+    createActiveRuleWithSeverity(rule5, profile1, Severity.MINOR);
+    session.commit();
+
+    /*
+     * Profile 1:
+     * - rule 1 active (on both profiles) => "same"
+     * - rule 3 active (only in this profile) => "inRight"
+     * - rule 4 active with different parameters => "modified"
+     */
+    QProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345");
+    createActiveRule(rule1, profile2);
+    createActiveRule(rule3, profile2);
+    createActiveRuleWithParam(rule4, profile2, "palap");
+    createActiveRuleWithSeverity(rule5, profile2, Severity.MAJOR);
+    session.commit();
+
+    wsTester.newRequest()
+      .setParam("leftKey", profile1.getKee())
+      .setParam("rightKey", profile2.getKee())
+      .execute().assertJson(this.getClass(), "compare_nominal.json");
+  }
+
+  @Test
+  public void compare_param_on_left() throws Exception {
+    RuleDefinitionDto rule1 = createRuleWithParam("xoo", "rule1");
+    createRepository("blah", "xoo", "Blah");
+    QProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234");
+    createActiveRuleWithParam(rule1, profile1, "polop");
+    QProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345");
+    createActiveRule(rule1, profile2);
+    session.commit();
+
+    wsTester.newRequest()
+      .setParam("leftKey", profile1.getKee())
+      .setParam("rightKey", profile2.getKee())
+      .execute().assertJson(this.getClass(), "compare_param_on_left.json");
+  }
+
+  @Test
+  public void compare_param_on_right() throws Exception {
+    RuleDefinitionDto rule1 = createRuleWithParam("xoo", "rule1");
+    createRepository("blah", "xoo", "Blah");
+    QProfileDto profile1 = createProfile("xoo", "Profile 1", "xoo-profile-1-01234");
+    createActiveRule(rule1, profile1);
+    QProfileDto profile2 = createProfile("xoo", "Profile 2", "xoo-profile-2-12345");
+    createActiveRuleWithParam(rule1, profile2, "polop");
+    session.commit();
+
+    wsTester.newRequest()
+      .setParam("leftKey", profile1.getKee())
+      .setParam("rightKey", profile2.getKee())
+      .execute().assertJson(this.getClass(), "compare_param_on_right.json");
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void fail_on_missing_left_param() throws Exception {
+    wsTester.newRequest()
+      .setParam("rightKey", "polop")
+      .execute();
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void fail_on_missing_right_param() throws Exception {
+    wsTester.newRequest()
+      .setParam("leftKey", "polop")
+      .execute();
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void fail_on_left_profile_not_found() throws Exception {
+    createProfile("xoo", "Right", "xoo-right-12345");
+    wsTester.newRequest()
+      .setParam("leftKey", "polop")
+      .setParam("rightKey", "xoo-right-12345")
+      .execute();
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void fail_on_right_profile_not_found() throws Exception {
+    createProfile("xoo", "Left", "xoo-left-12345");
+    wsTester.newRequest()
+      .setParam("leftKey", "xoo-left-12345")
+      .setParam("rightKey", "polop")
+      .execute();
+  }
+
+  private QProfileDto createProfile(String lang, String name, String key) {
+    QProfileDto profile = QProfileTesting.newQProfileDto("org-123", new QProfileName(lang, name), key);
+    db.qualityProfileDao().insert(session, profile);
+    session.commit();
+    return profile;
+  }
+
+  private RuleDefinitionDto createRule(String lang, String id) {
+    RuleDto rule = RuleDto.createFor(RuleKey.of("blah", id))
+      .setName(StringUtils.capitalize(id))
+      .setLanguage(lang)
+      .setSeverity(Severity.BLOCKER)
+      .setStatus(RuleStatus.READY);
+    RuleDefinitionDto ruleDefinition = rule.getDefinition();
+    db.ruleDao().insert(session, ruleDefinition);
+    RuleParamDto param = RuleParamDto.createFor(ruleDefinition).setName("param_" + id).setType(RuleParamType.STRING.toString());
+    db.ruleDao().insertRuleParam(session, ruleDefinition, param);
+    return ruleDefinition;
+  }
+
+  private RuleDefinitionDto createRuleWithParam(String lang, String id) {
+    RuleDefinitionDto rule = createRule(lang, id);
+    RuleParamDto param = RuleParamDto.createFor(rule)
+      .setName("param_" + id)
+      .setType(RuleParamType.STRING.toString());
+    db.ruleDao().insertRuleParam(session, rule, param);
+    return rule;
+  }
+
+  private ActiveRuleDto createActiveRule(RuleDefinitionDto rule, QProfileDto profile) {
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule)
+      .setSeverity(rule.getSeverityString());
+    db.activeRuleDao().insert(session, activeRule);
+    return activeRule;
+  }
+
+  private ActiveRuleDto createActiveRuleWithParam(RuleDefinitionDto rule, QProfileDto profile, String value) {
+    ActiveRuleDto activeRule = createActiveRule(rule, profile);
+    RuleParamDto paramDto = db.ruleDao().selectRuleParamsByRuleKey(session, rule.getKey()).get(0);
+    ActiveRuleParamDto activeRuleParam = ActiveRuleParamDto.createFor(paramDto).setValue(value);
+    db.activeRuleDao().insertParam(session, activeRule, activeRuleParam);
+    return activeRule;
+  }
+
+  private ActiveRuleDto createActiveRuleWithSeverity(RuleDefinitionDto rule, QProfileDto profile, String severity) {
+    ActiveRuleDto activeRule = ActiveRuleDto.createFor(profile, rule)
+      .setSeverity(severity);
+    db.activeRuleDao().insert(session, activeRule);
+    return activeRule;
+  }
+
+  private void createRepository(String repositoryKey, String repositoryLanguage, String repositoryName) {
+    RuleRepositoryDto dto = new RuleRepositoryDto(repositoryKey, repositoryLanguage, repositoryName);
+    db.ruleRepositoryDao().insert(session, asList(dto));
+    session.commit();
+  }
 }
index 172e67b4f6888763a1bdcfe83aa09aab9d94f1b7..f51b8ddcbe003cf302026651fd74292899918725 100644 (file)
@@ -22,44 +22,47 @@ package org.sonar.server.qualityprofile.ws;
 import com.google.common.collect.ImmutableSet;
 import java.util.Collections;
 import java.util.Optional;
-import org.junit.After;
 import org.junit.Before;
-import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
+import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.server.ws.WebService.Param;
+import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
 import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.organization.OrganizationTesting;
-import org.sonar.db.qualityprofile.ActiveRuleDao;
 import org.sonar.db.qualityprofile.ActiveRuleDto;
 import org.sonar.db.qualityprofile.ActiveRuleKey;
 import org.sonar.db.qualityprofile.QProfileDto;
 import org.sonar.db.rule.RuleDefinitionDto;
 import org.sonar.db.rule.RuleTesting;
+import org.sonar.server.es.EsTester;
 import org.sonar.server.es.SearchOptions;
 import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.organization.DefaultOrganizationProvider;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.qualityprofile.QProfileName;
 import org.sonar.server.qualityprofile.QProfileTesting;
+import org.sonar.server.qualityprofile.RuleActivator;
+import org.sonar.server.qualityprofile.RuleActivatorContextFactory;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
 import org.sonar.server.rule.index.RuleIndex;
+import org.sonar.server.rule.index.RuleIndexDefinition;
 import org.sonar.server.rule.index.RuleIndexer;
 import org.sonar.server.rule.index.RuleQuery;
-import org.sonar.server.tester.ServerTester;
+import org.sonar.server.rule.ws.RuleQueryFactory;
+import org.sonar.server.rule.ws.RuleWsSupport;
 import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
+import org.sonar.server.util.TypeValidations;
+import org.sonar.server.ws.WsActionTester;
 
+import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
-import static org.sonar.server.qualityprofile.ws.QProfilesWs.API_ENDPOINT;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_ACTIVATE_RULE;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_ACTIVATE_RULES;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_DEACTIVATE_RULE;
-import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_DEACTIVATE_RULES;
 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_PROFILE;
 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RESET;
 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_RULE;
@@ -71,37 +74,36 @@ import static org.sonarqube.ws.client.rule.RulesWsParameters.PARAM_QPROFILE;
 
 public class QProfilesWsMediumTest {
 
-  @ClassRule
-  public static ServerTester tester = new ServerTester().withEsIndexes();
-
   @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester)
+  public UserSessionRule userSessionRule = UserSessionRule.standalone()
     .logIn().setRoot();
-
-  private DbClient dbClient;
-  private DbSession dbSession;
-  private RuleIndexer ruleIndexer = tester.get(RuleIndexer.class);
-  private ActiveRuleIndexer activeRuleIndexer = tester.get(ActiveRuleIndexer.class);
+  @Rule
+  public EsTester esTester = new EsTester(new RuleIndexDefinition(new MapSettings().asConfig()));
+  @Rule
+  public DbTester dbTester = DbTester.create();
+
+  private DbClient dbClient = dbTester.getDbClient();
+  private DbSession dbSession = dbTester.getSession();
+  private RuleIndex ruleIndex = new RuleIndex(esTester.client());
+  private RuleIndexer ruleIndexer = new RuleIndexer(esTester.client(), dbClient);
+  private ActiveRuleIndexer activeRuleIndexer = new ActiveRuleIndexer(dbClient, esTester.client());
+  private RuleActivatorContextFactory ruleActivatorContextFactory = new RuleActivatorContextFactory(dbClient);
+  private TypeValidations typeValidations = new TypeValidations(asList());
+  private RuleActivator ruleActivator = new RuleActivator(System2.INSTANCE, dbClient, ruleIndex, ruleActivatorContextFactory, typeValidations, activeRuleIndexer, userSessionRule);
+  private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
+  private QProfileWsSupport qProfileWsSupport = new QProfileWsSupport(dbClient, userSessionRule, defaultOrganizationProvider);
+  private RuleWsSupport ruleWsSupport = new RuleWsSupport(dbClient, userSessionRule, defaultOrganizationProvider);
+  private RuleQueryFactory ruleQueryFactory = new RuleQueryFactory(dbClient, ruleWsSupport);
   private OrganizationDto organization;
 
-  private WsTester ws;
+  private WsActionTester wsDeactivateRule = new WsActionTester(new DeactivateRuleAction(dbClient, ruleActivator, userSessionRule, qProfileWsSupport));
+  private WsActionTester wsDeactivateRules = new WsActionTester(new DeactivateRulesAction(ruleQueryFactory, userSessionRule, ruleActivator, qProfileWsSupport, dbClient));
+  private WsActionTester wsActivateRule = new WsActionTester(new ActivateRuleAction(dbClient, ruleActivator, userSessionRule, qProfileWsSupport));
+  private WsActionTester wsActivateRules = new WsActionTester(new ActivateRulesAction(ruleQueryFactory, userSessionRule, ruleActivator, qProfileWsSupport, dbClient));
 
   @Before
-  public void setUp() {
-    tester.clearDbAndIndexes();
-    dbClient = tester.get(DbClient.class);
-    ws = tester.get(WsTester.class);
-    dbSession = dbClient.openSession(false);
-
-    ruleIndexer = tester.get(RuleIndexer.class);
-    activeRuleIndexer = tester.get(ActiveRuleIndexer.class);
-    organization = OrganizationTesting.newOrganizationDto().setKey("org-123");
-    dbClient.organizationDao().insert(dbSession, organization, false);
-  }
-
-  @After
-  public void after() {
-    dbSession.close();
+  public void setUp() throws Exception {
+    organization = dbTester.organizations().insert();
   }
 
   @Test
@@ -116,10 +118,10 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(1);
 
     // 1. Deactivate Rule
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_DEACTIVATE_RULE);
-    request.setParam(PARAM_PROFILE, profile.getKee());
-    request.setParam(PARAM_RULE, rule.getKey().toString());
-    request.execute();
+    wsDeactivateRule.newRequest().setMethod("POST")
+      .setParam(PARAM_PROFILE, profile.getKee())
+      .setParam(PARAM_RULE, rule.getKey().toString())
+      .execute();
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -144,9 +146,9 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(4);
 
     // 1. Deactivate Rule
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_DEACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, profile.getKee());
-    WsTester.Result result = request.execute();
+    wsDeactivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, profile.getKee())
+      .execute();
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -170,9 +172,9 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
 
     // 1. Deactivate Rule
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_DEACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, profile.getKee());
-    WsTester.Result result = request.execute();
+    wsDeactivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, profile.getKee())
+      .execute();
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -194,10 +196,10 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(2);
 
     // 1. Deactivate Rule
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_DEACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, profile.getKee());
-    request.setParam(Param.TEXT_QUERY, "hello");
-    WsTester.Result result = request.execute();
+    wsDeactivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, profile.getKee())
+      .setParam(Param.TEXT_QUERY, "hello")
+      .execute();
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -214,10 +216,10 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
 
     // 1. Activate Rule
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULE);
-    request.setParam(PARAM_PROFILE, profile.getKee());
-    request.setParam(PARAM_RULE, rule.getKey().toString());
-    WsTester.Result result = request.execute();
+    wsActivateRule.newRequest().setMethod("POST")
+      .setParam(PARAM_PROFILE, profile.getKee())
+      .setParam(PARAM_RULE, rule.getKey().toString())
+      .execute();
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -235,10 +237,10 @@ public class QProfilesWsMediumTest {
 
     try {
       // 1. Activate Rule
-      WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULE);
-      request.setParam(PARAM_PROFILE, profile.getKee());
-      request.setParam(PARAM_RULE, rule.getKey().toString());
-      request.execute();
+      wsActivateRule.newRequest().setMethod("POST")
+        .setParam(PARAM_PROFILE, profile.getKee())
+        .setParam(PARAM_RULE, rule.getKey().toString())
+        .execute();
       dbSession.clearCache();
       fail();
     } catch (BadRequestException e) {
@@ -256,11 +258,11 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
 
     // 1. Activate Rule
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULE);
-    request.setParam(PARAM_PROFILE, profile.getKee());
-    request.setParam(PARAM_RULE, rule.getKey().toString());
-    request.setParam(PARAM_SEVERITY, "MINOR");
-    WsTester.Result result = request.execute();
+    wsActivateRule.newRequest().setMethod("POST")
+      .setParam(PARAM_PROFILE, profile.getKee())
+      .setParam(PARAM_RULE, rule.getKey().toString())
+      .setParam(PARAM_SEVERITY, "MINOR")
+      .execute();
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -284,10 +286,11 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
 
     // 1. Activate Rule
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, profile.getKee());
-    request.setParam(PARAM_LANGUAGES, "java");
-    request.execute().assertJson(getClass(), "bulk_activate_rule.json");
+    wsActivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, profile.getKee())
+      .setParam(PARAM_LANGUAGES, "java")
+      .execute()
+      .assertJson(getClass(), "bulk_activate_rule.json");
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -308,10 +311,11 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, php.getKee())).isEmpty();
 
     // 1. Activate Rule
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, php.getKee());
-    request.setParam(PARAM_LANGUAGES, "php");
-    request.execute().assertJson(getClass(), "bulk_activate_rule_not_all.json");
+    wsActivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, php.getKee())
+      .setParam(PARAM_LANGUAGES, "php")
+      .execute()
+      .assertJson(getClass(), "bulk_activate_rule_not_all.json");
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -331,20 +335,20 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
 
     // 1. Activate Rule with query returning 0 hits
-    WsTester.TestRequest request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, profile.getKee());
-    request.setParam(Param.TEXT_QUERY, "php");
-    request.execute();
+    wsActivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, profile.getKee())
+      .setParam(Param.TEXT_QUERY, "php")
+      .execute();
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).hasSize(0);
 
     // 1. Activate Rule with query returning 1 hits
-    request = ws.newPostRequest(QProfilesWs.API_ENDPOINT, ACTION_ACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, profile.getKee());
-    request.setParam(Param.TEXT_QUERY, "world");
-    request.execute();
+    wsActivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, profile.getKee())
+      .setParam(Param.TEXT_QUERY, "world")
+      .execute();
     dbSession.commit();
 
     // 2. Assert ActiveRule in DAO
@@ -362,20 +366,20 @@ public class QProfilesWsMediumTest {
     assertThat(dbClient.activeRuleDao().selectByProfileUuid(dbSession, profile.getKee())).isEmpty();
 
     // 2. Assert ActiveRule with BLOCKER severity
-    assertThat(tester.get(RuleIndex.class).search(
+    assertThat(ruleIndex.search(
       new RuleQuery().setSeverities(ImmutableSet.of("BLOCKER")),
       new SearchOptions()).getIds()).hasSize(2);
 
     // 1. Activate Rule with query returning 2 hits
-    WsTester.TestRequest request = ws.newPostRequest(API_ENDPOINT, ACTION_ACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, profile.getKee());
-    request.setParam(PARAM_TARGET_SEVERITY, "MINOR");
-    request.execute();
+    wsActivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, profile.getKee())
+      .setParam(PARAM_TARGET_SEVERITY, "MINOR")
+      .execute();
     dbSession.commit();
 
     // 2. Assert ActiveRule with MINOR severity
-    assertThat(tester.get(ActiveRuleDao.class).selectByRuleId(dbSession, organization, rule0.getId()).get(0).getSeverityString()).isEqualTo("MINOR");
-    assertThat(tester.get(RuleIndex.class).searchAll(new RuleQuery()
+    assertThat(dbClient.activeRuleDao().selectByRuleId(dbSession, organization, rule0.getId()).get(0).getSeverityString()).isEqualTo("MINOR");
+    assertThat(ruleIndex.searchAll(new RuleQuery()
       .setQProfile(profile)
       .setKey(rule0.getKey().toString())
       .setActiveSeverities(Collections.singleton("MINOR"))
@@ -393,11 +397,12 @@ public class QProfilesWsMediumTest {
     dbSession.commit();
 
     // 1. Activate Rule
-    WsTester.TestRequest request = ws.newPostRequest(API_ENDPOINT, ACTION_ACTIVATE_RULES);
-    request.setParam(PARAM_TARGET_PROFILE, javaProfile.getKee());
-    request.setParam(PARAM_QPROFILE, javaProfile.getKee());
-    request.setParam("activation", "false");
-    request.execute().assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json");
+    wsActivateRules.newRequest().setMethod("POST")
+      .setParam(PARAM_TARGET_PROFILE, javaProfile.getKee())
+      .setParam(PARAM_QPROFILE, javaProfile.getKee())
+      .setParam("activation", "false")
+      .execute()
+      .assertJson(getClass(), "does_not_return_warnings_when_bulk_activate_on_profile_and_rules_exist_on_another_language_than_profile.json");
     dbSession.clearCache();
 
     // 2. Assert ActiveRule in DAO
@@ -427,11 +432,11 @@ public class QProfilesWsMediumTest {
     assertThat(activeRuleDto.get().getSeverityString()).isEqualTo(Severity.MINOR);
 
     // 1. reset child rule
-    WsTester.TestRequest request = ws.newPostRequest(API_ENDPOINT, ACTION_ACTIVATE_RULE);
-    request.setParam(PARAM_PROFILE, subProfile.getKee());
-    request.setParam(PARAM_RULE, rule.getKey().toString());
-    request.setParam(PARAM_RESET, "true");
-    request.execute();
+    wsActivateRule.newRequest().setMethod("POST")
+      .setParam(PARAM_PROFILE, subProfile.getKee())
+      .setParam(PARAM_RULE, rule.getKey().toString())
+      .setParam(PARAM_RESET, "true")
+      .execute();
     dbSession.clearCache();
 
     // 2. assert rule child rule is NOT minor
index 1530907b0e32913becce3031ef9d467819b7b986..52c0b76a466c52ce1cba3253ba9c64eccb50f6cd 100644 (file)
@@ -75,7 +75,7 @@ public class RegisterRulesMediumTest {
     .addComponents(RULE_DEFS);
 
   @org.junit.Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(TESTER);
+  public UserSessionRule userSessionRule = UserSessionRule.standalone();
 
   private DbClient db = TESTER.get(DbClient.class);
   private DbSession dbSession = TESTER.get(DbClient.class).openSession(false);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/rule/ws/ShowActionMediumTest.java
deleted file mode 100644 (file)
index 889552c..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 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.sonar.server.rule.ws;
-
-import java.util.Date;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.rules.RuleType;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.qualityprofile.ActiveRuleDao;
-import org.sonar.db.qualityprofile.ActiveRuleDto;
-import org.sonar.db.qualityprofile.ActiveRuleParamDto;
-import org.sonar.db.qualityprofile.QualityProfileDao;
-import org.sonar.db.qualityprofile.QProfileDto;
-import org.sonar.db.rule.RuleDao;
-import org.sonar.db.rule.RuleDefinitionDto;
-import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleDto.Format;
-import org.sonar.db.rule.RuleParamDto;
-import org.sonar.db.rule.RuleTesting;
-import org.sonar.server.organization.DefaultOrganizationProvider;
-import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
-import org.sonar.server.rule.NewCustomRule;
-import org.sonar.server.rule.RuleCreator;
-import org.sonar.server.rule.index.RuleIndexer;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
-
-import static com.google.common.collect.Sets.newHashSet;
-import static org.sonar.api.rule.Severity.MINOR;
-import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
-
-public class ShowActionMediumTest {
-
-  @ClassRule
-  public static ServerTester tester = new ServerTester().withEsIndexes();
-
-  DefaultOrganizationProvider defaultOrganizationProvider = tester.get(DefaultOrganizationProvider.class);
-
-  @Rule
-  public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester).logIn()
-    .addPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganizationProvider.get().getUuid());
-
-  private WsTester wsTester;
-  private RuleIndexer ruleIndexer;
-  private RuleDao ruleDao;
-  private DbSession session;
-  private OrganizationDto defaultOrganization;
-
-  @Before
-  public void setUp() {
-    tester.clearDbAndIndexes();
-    wsTester = tester.get(WsTester.class);
-    ruleIndexer = tester.get(RuleIndexer.class);
-    ruleDao = tester.get(RuleDao.class);
-    session = tester.get(DbClient.class).openSession(false);
-    defaultOrganization = tester.get(DbClient.class).organizationDao().selectByUuid(session, defaultOrganizationProvider.get().getUuid()).get();
-  }
-
-  @After
-  public void after() {
-    session.close();
-  }
-
-  @Test
-  public void show_rule() throws Exception {
-    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), defaultOrganization)
-      .setName("Rule S001")
-      .setDescription("Rule S001 <b>description</b>")
-      .setDescriptionFormat(Format.HTML)
-      .setSeverity(MINOR)
-      .setStatus(RuleStatus.BETA)
-      .setConfigKey("InternalKeyS001")
-      .setLanguage("xoo")
-      .setTags(newHashSet("tag1", "tag2"))
-      .setSystemTags(newHashSet("systag1", "systag2"))
-      .setType(RuleType.BUG);
-    RuleDefinitionDto definition = ruleDto.getDefinition();
-    ruleDao.insert(session, definition);
-    ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
-    RuleParamDto param = RuleParamDto.createFor(definition).setName("regex").setType("STRING").setDescription("Reg *exp*").setDefaultValue(".*");
-    ruleDao.insertRuleParam(session, definition, param);
-    session.commit();
-    session.clearCache();
-
-    WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "show")
-      .setParam("key", ruleDto.getKey().toString());
-    request.execute().assertJson(getClass(), "show_rule.json");
-  }
-
-  @Test
-  public void show_rule_with_default_debt_infos() throws Exception {
-    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), defaultOrganization)
-      .setName("Rule S001")
-      .setDescription("Rule S001 <b>description</b>")
-      .setSeverity(MINOR)
-      .setStatus(RuleStatus.BETA)
-      .setConfigKey("InternalKeyS001")
-      .setLanguage("xoo")
-      .setDefRemediationFunction("LINEAR_OFFSET")
-      .setDefRemediationGapMultiplier("5d")
-      .setDefRemediationBaseEffort("10h")
-      .setRemediationFunction(null)
-      .setRemediationGapMultiplier(null)
-      .setRemediationBaseEffort(null);
-    ruleDao.insert(session, ruleDto.getDefinition());
-    ruleDao.insertOrUpdate(session, ruleDto.getMetadata());
-    session.commit();
-    session.clearCache();
-
-    WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "show")
-      .setParam("key", ruleDto.getKey().toString());
-    WsTester.Result response = request.execute();
-
-    response.assertJson(getClass(), "show_rule_with_default_debt_infos.json");
-  }
-
-  @Test
-  public void show_rule_with_overridden_debt() throws Exception {
-    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), defaultOrganization)
-      .setName("Rule S001")
-      .setDescription("Rule S001 <b>description</b>")
-      .setSeverity(MINOR)
-      .setStatus(RuleStatus.BETA)
-      .setConfigKey("InternalKeyS001")
-      .setLanguage("xoo")
-      .setDefRemediationFunction(null)
-      .setDefRemediationGapMultiplier(null)
-      .setDefRemediationBaseEffort(null)
-      .setRemediationFunction("LINEAR_OFFSET")
-      .setRemediationGapMultiplier("5d")
-      .setRemediationBaseEffort("10h");
-    ruleDao.insert(session, ruleDto.getDefinition());
-    ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
-    session.commit();
-    session.clearCache();
-
-    WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "show")
-      .setParam("key", ruleDto.getKey().toString());
-    request.execute().assertJson(getClass(), "show_rule_with_overridden_debt_infos.json");
-  }
-
-  @Test
-  public void show_rule_with_default_and_overridden_debt_infos() throws Exception {
-    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), defaultOrganization)
-      .setName("Rule S001")
-      .setDescription("Rule S001 <b>description</b>")
-      .setSeverity(MINOR)
-      .setStatus(RuleStatus.BETA)
-      .setConfigKey("InternalKeyS001")
-      .setLanguage("xoo")
-      .setDefRemediationFunction("LINEAR")
-      .setDefRemediationGapMultiplier("5min")
-      .setDefRemediationBaseEffort(null)
-      .setRemediationFunction("LINEAR_OFFSET")
-      .setRemediationGapMultiplier("5d")
-      .setRemediationBaseEffort("10h");
-    ruleDao.insert(session, ruleDto.getDefinition());
-    ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
-    session.commit();
-    session.clearCache();
-
-    WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "show")
-      .setParam("key", ruleDto.getKey().toString());
-    request.execute().assertJson(getClass(), "show_rule_with_default_and_overridden_debt_infos.json");
-  }
-
-  @Test
-  public void show_rule_with_no_default_and_no_overridden_debt() throws Exception {
-    RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("java", "S001"))
-      .setName("Rule S001")
-      .setDescription("Rule S001 <b>description</b>")
-      .setDescriptionFormat(Format.HTML)
-      .setSeverity(MINOR)
-      .setStatus(RuleStatus.BETA)
-      .setConfigKey("InternalKeyS001")
-      .setLanguage("xoo")
-      .setDefRemediationFunction(null)
-      .setDefRemediationGapMultiplier(null)
-      .setDefRemediationBaseEffort(null);
-    ruleDao.insert(session, ruleDto);
-    session.commit();
-    session.clearCache();
-
-    WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "show")
-      .setParam("key", ruleDto.getKey().toString());
-    request.execute().assertJson(getClass(), "show_rule_with_no_default_and_no_overridden_debt.json");
-  }
-
-  @Test
-  public void encode_html_description_of_custom_rule() throws Exception {
-    // Template rule
-    RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001"));
-    ruleDao.insert(session, templateRule.getDefinition());
-    session.commit();
-
-    // Custom rule
-    NewCustomRule customRule = NewCustomRule.createForCustomRule("MY_CUSTOM", templateRule.getKey())
-      .setName("My custom")
-      .setSeverity(MINOR)
-      .setStatus(RuleStatus.READY)
-      .setMarkdownDescription("<div>line1\nline2</div>");
-    RuleKey customRuleKey = tester.get(RuleCreator.class).create(session, customRule);
-    session.clearCache();
-
-    WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "show")
-      .setParam("key", customRuleKey.toString());
-    request.execute().assertJson(getClass(), "encode_html_description_of_custom_rule.json");
-  }
-
-  @Test
-  public void show_deprecated_rule_rem_function_fields() throws Exception {
-    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), defaultOrganization)
-      .setName("Rule S001")
-      .setDescription("Rule S001 <b>description</b>")
-      .setSeverity(MINOR)
-      .setStatus(RuleStatus.BETA)
-      .setConfigKey("InternalKeyS001")
-      .setLanguage("xoo")
-      .setDefRemediationFunction("LINEAR_OFFSET")
-      .setDefRemediationGapMultiplier("6d")
-      .setDefRemediationBaseEffort("11h")
-      .setRemediationFunction("LINEAR_OFFSET")
-      .setRemediationGapMultiplier("5d")
-      .setRemediationBaseEffort("10h");
-    ruleDao.insert(session, ruleDto.getDefinition());
-    ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
-    session.commit();
-
-    WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "show")
-      .setParam("key", ruleDto.getKey().toString());
-    request.execute().assertJson(getClass(), "show_deprecated_rule_rem_function_fields.json");
-  }
-
-  @Test
-  public void show_rule_when_activated() throws Exception {
-    RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("java", "S001"))
-      .setName("Rule S001")
-      .setDescription("Rule S001 <b>description</b>")
-      .setDescriptionFormat(Format.HTML)
-      .setSeverity(MINOR)
-      .setStatus(RuleStatus.BETA)
-      .setLanguage("xoo")
-      .setType(RuleType.BUG)
-      .setCreatedAt(new Date().getTime())
-      .setUpdatedAt(new Date().getTime());
-    ruleDao.insert(session, ruleDto);
-    session.commit();
-    ruleIndexer.commitAndIndex(session, ruleDto.getKey());
-    RuleParamDto regexParam = RuleParamDto.createFor(ruleDto).setName("regex").setType("STRING").setDescription("Reg *exp*").setDefaultValue(".*");
-    ruleDao.insertRuleParam(session, ruleDto, regexParam);
-
-    QProfileDto profile = new QProfileDto()
-      .setRulesProfileUuid("profile")
-      .setKee("profile")
-      .setOrganizationUuid(defaultOrganizationProvider.get().getUuid())
-      .setName("Profile")
-      .setLanguage("xoo");
-    tester.get(QualityProfileDao.class).insert(session, profile);
-    ActiveRuleDto activeRuleDto = new ActiveRuleDto()
-      .setProfileId(profile.getId())
-      .setRuleId(ruleDto.getId())
-      .setSeverity(MINOR)
-      .setCreatedAt(new Date().getTime())
-      .setUpdatedAt(new Date().getTime());
-    tester.get(ActiveRuleDao.class).insert(session, activeRuleDto);
-    tester.get(ActiveRuleDao.class).insertParam(session, activeRuleDto, new ActiveRuleParamDto()
-      .setRulesParameterId(regexParam.getId())
-      .setKey(regexParam.getName())
-      .setValue(".*?"));
-    session.commit();
-
-    ActiveRuleIndexer activeRuleIndexer = tester.get(ActiveRuleIndexer.class);
-    activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
-
-    WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "show")
-      .setParam("key", ruleDto.getKey().toString())
-      .setParam("actives", "true");
-    request.execute().assertJson(getClass(), "show_rule_when_activated.json");
-  }
-
-}
index 7859a14ac6853438d0b914564855e2a1a3e0bc54..f7bf4dca6ad3c364a844a6fec2e983f00f13f60c 100644 (file)
@@ -21,6 +21,7 @@
 package org.sonar.server.rule.ws;
 
 import java.io.IOException;
+import java.util.Date;
 import java.util.List;
 import java.util.function.Consumer;
 import org.junit.Before;
@@ -30,29 +31,47 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.Mockito;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.resources.Languages;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rules.RuleType;
+import org.sonar.api.utils.System2;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.qualityprofile.ActiveRuleDto;
+import org.sonar.db.qualityprofile.ActiveRuleParamDto;
 import org.sonar.db.qualityprofile.QProfileDto;
+import org.sonar.db.rule.RuleDao;
 import org.sonar.db.rule.RuleDefinitionDto;
+import org.sonar.db.rule.RuleDto;
+import org.sonar.db.rule.RuleDto.Format;
 import org.sonar.db.rule.RuleMetadataDto;
+import org.sonar.db.rule.RuleParamDto;
+import org.sonar.db.rule.RuleTesting;
 import org.sonar.server.es.EsClient;
 import org.sonar.server.es.EsTester;
+import org.sonar.server.es.StartupIndexer;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.language.LanguageTesting;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.organization.TestDefaultOrganizationProvider;
 import org.sonar.server.qualityprofile.QProfileTesting;
 import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;
+import org.sonar.server.rule.NewCustomRule;
+import org.sonar.server.rule.RuleCreator;
 import org.sonar.server.rule.index.RuleIndexDefinition;
 import org.sonar.server.rule.index.RuleIndexer;
 import org.sonar.server.text.MacroInterpreter;
+import org.sonar.server.util.TypeValidations;
 import org.sonar.server.ws.TestResponse;
 import org.sonar.server.ws.WsAction;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.Rules;
 import org.sonarqube.ws.Rules.Rule;
 
+import static com.google.common.collect.Sets.newHashSet;
+import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -60,6 +79,7 @@ import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.sonar.api.rule.Severity.MINOR;
 import static org.sonar.db.rule.RuleTesting.setTags;
 import static org.sonar.server.rule.ws.ShowAction.PARAM_KEY;
 import static org.sonar.server.rule.ws.ShowAction.PARAM_ORGANIZATION;
@@ -67,6 +87,8 @@ import static org.sonarqube.ws.MediaTypes.PROTOBUF;
 
 public class ShowActionTest {
 
+  public static final String INTERPRETED = "interpreted";
+
   @org.junit.Rule
   public DbTester dbTester = DbTester.create();
   @org.junit.Rule
@@ -80,7 +102,7 @@ public class ShowActionTest {
 
   private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
   private MacroInterpreter macroInterpreter = mock(MacroInterpreter.class);
-  private Languages languages = new Languages();
+  private Languages languages = new Languages(LanguageTesting.newLanguage("xoo", "Xoo"));
   private RuleMapper mapper = new RuleMapper(languages, macroInterpreter);
   private ActiveRuleCompleter activeRuleCompleter = mock(ActiveRuleCompleter.class);
   private WsAction underTest = new ShowAction(dbClient, mapper, activeRuleCompleter, defaultOrganizationProvider);
@@ -90,7 +112,7 @@ public class ShowActionTest {
 
   @Before
   public void before() {
-    doReturn("interpreted").when(macroInterpreter).interpret(anyString());
+    doReturn(INTERPRETED).when(macroInterpreter).interpret(anyString());
   }
 
   @Test
@@ -213,6 +235,250 @@ public class ShowActionTest {
       .execute();
   }
 
+  @Test
+  public void show_rule() throws Exception {
+    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization())
+      .setName("Rule S001")
+      .setDescription("Rule S001 <b>description</b>")
+      .setDescriptionFormat(Format.HTML)
+      .setSeverity(MINOR)
+      .setStatus(RuleStatus.BETA)
+      .setConfigKey("InternalKeyS001")
+      .setLanguage("xoo")
+      .setTags(newHashSet("tag1", "tag2"))
+      .setSystemTags(newHashSet("systag1", "systag2"))
+      .setType(RuleType.BUG);
+    RuleDefinitionDto definition = ruleDto.getDefinition();
+    RuleDao ruleDao = dbClient.ruleDao();
+    DbSession session = dbTester.getSession();
+    ruleDao.insert(session, definition);
+    ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
+    RuleParamDto param = RuleParamDto.createFor(definition).setName("regex").setType("STRING").setDescription("Reg *exp*").setDefaultValue(".*");
+    ruleDao.insertRuleParam(session, definition, param);
+    session.commit();
+    session.clearCache();
+
+    actionTester.newRequest()
+      .setParam("key", ruleDto.getKey().toString())
+      .execute().assertJson(getClass(), "show_rule.json");
+  }
+
+  @Test
+  public void show_rule_with_default_debt_infos() throws Exception {
+    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization())
+      .setName("Rule S001")
+      .setDescription("Rule S001 <b>description</b>")
+      .setSeverity(MINOR)
+      .setStatus(RuleStatus.BETA)
+      .setConfigKey("InternalKeyS001")
+      .setLanguage("xoo")
+      .setDefRemediationFunction("LINEAR_OFFSET")
+      .setDefRemediationGapMultiplier("5d")
+      .setDefRemediationBaseEffort("10h")
+      .setRemediationFunction(null)
+      .setRemediationGapMultiplier(null)
+      .setRemediationBaseEffort(null);
+    RuleDao ruleDao = dbClient.ruleDao();
+    DbSession session = dbTester.getSession();
+    ruleDao.insert(session, ruleDto.getDefinition());
+    ruleDao.insertOrUpdate(session, ruleDto.getMetadata());
+    session.commit();
+    session.clearCache();
+
+    actionTester.newRequest()
+      .setParam("key", ruleDto.getKey().toString())
+      .execute()
+      .assertJson(getClass(), "show_rule_with_default_debt_infos.json");
+  }
+
+  @Test
+  public void show_rule_with_overridden_debt() throws Exception {
+    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization())
+      .setName("Rule S001")
+      .setDescription("Rule S001 <b>description</b>")
+      .setSeverity(MINOR)
+      .setStatus(RuleStatus.BETA)
+      .setConfigKey("InternalKeyS001")
+      .setLanguage("xoo")
+      .setDefRemediationFunction(null)
+      .setDefRemediationGapMultiplier(null)
+      .setDefRemediationBaseEffort(null)
+      .setRemediationFunction("LINEAR_OFFSET")
+      .setRemediationGapMultiplier("5d")
+      .setRemediationBaseEffort("10h");
+    RuleDao ruleDao = dbClient.ruleDao();
+    DbSession session = dbTester.getSession();
+    ruleDao.insert(session, ruleDto.getDefinition());
+    ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
+    session.commit();
+    session.clearCache();
+
+    actionTester.newRequest()
+      .setParam("key", ruleDto.getKey().toString())
+      .execute().assertJson(getClass(), "show_rule_with_overridden_debt_infos.json");
+  }
+
+  @Test
+  public void show_rule_with_default_and_overridden_debt_infos() throws Exception {
+    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization())
+      .setName("Rule S001")
+      .setDescription("Rule S001 <b>description</b>")
+      .setSeverity(MINOR)
+      .setStatus(RuleStatus.BETA)
+      .setConfigKey("InternalKeyS001")
+      .setLanguage("xoo")
+      .setDefRemediationFunction("LINEAR")
+      .setDefRemediationGapMultiplier("5min")
+      .setDefRemediationBaseEffort(null)
+      .setRemediationFunction("LINEAR_OFFSET")
+      .setRemediationGapMultiplier("5d")
+      .setRemediationBaseEffort("10h");
+    RuleDao ruleDao = dbClient.ruleDao();
+    DbSession session = dbTester.getSession();
+    ruleDao.insert(session, ruleDto.getDefinition());
+    ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
+    session.commit();
+    session.clearCache();
+
+    actionTester.newRequest()
+      .setParam("key", ruleDto.getKey().toString())
+      .execute().assertJson(getClass(), "show_rule_with_default_and_overridden_debt_infos.json");
+  }
+
+  @Test
+  public void show_rule_with_no_default_and_no_overridden_debt() throws Exception {
+    RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("java", "S001"))
+      .setName("Rule S001")
+      .setDescription("Rule S001 <b>description</b>")
+      .setDescriptionFormat(Format.HTML)
+      .setSeverity(MINOR)
+      .setStatus(RuleStatus.BETA)
+      .setConfigKey("InternalKeyS001")
+      .setLanguage("xoo")
+      .setDefRemediationFunction(null)
+      .setDefRemediationGapMultiplier(null)
+      .setDefRemediationBaseEffort(null);
+    RuleDao ruleDao = dbClient.ruleDao();
+    DbSession session = dbTester.getSession();
+    ruleDao.insert(session, ruleDto);
+    session.commit();
+    session.clearCache();
+
+    actionTester.newRequest()
+      .setParam("key", ruleDto.getKey().toString())
+      .execute().assertJson(getClass(), "show_rule_with_no_default_and_no_overridden_debt.json");
+  }
+
+  @Test
+  public void encode_html_description_of_custom_rule() throws Exception {
+    // Template rule
+    RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001"));
+    RuleDao ruleDao = dbClient.ruleDao();
+    DbSession session = dbTester.getSession();
+    ruleDao.insert(session, templateRule.getDefinition());
+    session.commit();
+
+    // Custom rule
+    NewCustomRule customRule = NewCustomRule.createForCustomRule("MY_CUSTOM", templateRule.getKey())
+      .setName("My custom")
+      .setSeverity(MINOR)
+      .setStatus(RuleStatus.READY)
+      .setMarkdownDescription("<div>line1\nline2</div>");
+    RuleKey customRuleKey = new RuleCreator(System2.INSTANCE, ruleIndexer, dbClient, new TypeValidations(asList()), TestDefaultOrganizationProvider.from(dbTester)).create(session, customRule);
+    session.clearCache();
+
+    doReturn("&lt;div&gt;line1<br/>line2&lt;/div&gt;").when(macroInterpreter).interpret("<div>line1\nline2</div>");
+
+    Rules.ShowResponse result = actionTester.newRequest()
+      .setParam("key", customRuleKey.toString())
+      .executeProtobuf(Rules.ShowResponse.class);
+
+    Mockito.verify(macroInterpreter).interpret("&lt;div&gt;line1<br/>line2&lt;/div&gt;");
+
+    assertThat(result.getRule().getKey()).isEqualTo("java:MY_CUSTOM");
+    assertThat(result.getRule().getHtmlDesc()).isEqualTo(INTERPRETED);
+    assertThat(result.getRule().getTemplateKey()).isEqualTo("java:S001");
+  }
+
+  @Test
+  public void show_deprecated_rule_rem_function_fields() throws Exception {
+    RuleDto ruleDto = RuleTesting.newDto(RuleKey.of("java", "S001"), dbTester.getDefaultOrganization())
+      .setName("Rule S001")
+      .setDescription("Rule S001 <b>description</b>")
+      .setSeverity(MINOR)
+      .setStatus(RuleStatus.BETA)
+      .setConfigKey("InternalKeyS001")
+      .setLanguage("xoo")
+      .setDefRemediationFunction("LINEAR_OFFSET")
+      .setDefRemediationGapMultiplier("6d")
+      .setDefRemediationBaseEffort("11h")
+      .setRemediationFunction("LINEAR_OFFSET")
+      .setRemediationGapMultiplier("5d")
+      .setRemediationBaseEffort("10h");
+    RuleDao ruleDao = dbClient.ruleDao();
+    DbSession session = dbTester.getSession();
+    ruleDao.insert(session, ruleDto.getDefinition());
+    ruleDao.insertOrUpdate(session, ruleDto.getMetadata().setRuleId(ruleDto.getId()));
+    session.commit();
+
+    actionTester.newRequest()
+      .setParam("key", ruleDto.getKey().toString())
+      .execute().assertJson(getClass(), "show_deprecated_rule_rem_function_fields.json");
+  }
+
+  @Test
+  public void show_rule_when_activated() throws Exception {
+    RuleDefinitionDto ruleDto = RuleTesting.newRule(RuleKey.of("java", "S001"))
+      .setName("Rule S001")
+      .setDescription("Rule S001 <b>description</b>")
+      .setDescriptionFormat(Format.HTML)
+      .setSeverity(MINOR)
+      .setStatus(RuleStatus.BETA)
+      .setLanguage("xoo")
+      .setType(RuleType.BUG)
+      .setCreatedAt(new Date().getTime())
+      .setUpdatedAt(new Date().getTime());
+    RuleDao ruleDao = dbClient.ruleDao();
+    DbSession session = dbTester.getSession();
+    ruleDao.insert(session, ruleDto);
+    session.commit();
+    ruleIndexer.commitAndIndex(session, ruleDto.getKey());
+    RuleParamDto regexParam = RuleParamDto.createFor(ruleDto).setName("regex").setType("STRING").setDescription("Reg *exp*").setDefaultValue(".*");
+    ruleDao.insertRuleParam(session, ruleDto, regexParam);
+
+    QProfileDto profile = new QProfileDto()
+      .setRulesProfileUuid("profile")
+      .setKee("profile")
+      .setOrganizationUuid(defaultOrganizationProvider.get().getUuid())
+      .setName("Profile")
+      .setLanguage("xoo");
+    dbClient.qualityProfileDao().insert(session, profile);
+    ActiveRuleDto activeRuleDto = new ActiveRuleDto()
+      .setProfileId(profile.getId())
+      .setRuleId(ruleDto.getId())
+      .setSeverity(MINOR)
+      .setCreatedAt(new Date().getTime())
+      .setUpdatedAt(new Date().getTime());
+    dbClient.activeRuleDao().insert(session, activeRuleDto);
+    dbClient.activeRuleDao().insertParam(session, activeRuleDto, new ActiveRuleParamDto()
+      .setRulesParameterId(regexParam.getId())
+      .setKey(regexParam.getName())
+      .setValue(".*?"));
+    session.commit();
+
+    StartupIndexer activeRuleIndexer = new ActiveRuleIndexer(dbClient, esClient);
+    activeRuleIndexer.indexOnStartup(activeRuleIndexer.getIndexTypes());
+
+    ActiveRuleCompleter activeRuleCompleter = new ActiveRuleCompleter(dbClient, languages);
+    WsAction underTest = new ShowAction(dbClient, mapper, activeRuleCompleter, defaultOrganizationProvider);
+    WsActionTester actionTester = new WsActionTester(underTest);
+
+    actionTester.newRequest()
+      .setParam("key", ruleDto.getKey().toString())
+      .setParam("actives", "true")
+      .execute().assertJson(getClass(), "show_rule_when_activated.json");
+  }
+
   private void assertEqual(RuleDefinitionDto rule, RuleMetadataDto ruleMetadata, Rule resultRule) {
     assertThat(resultRule.getKey()).isEqualTo(rule.getKey().toString());
     assertThat(resultRule.getRepo()).isEqualTo(rule.getRepositoryKey());
index 8383654fb06f9e61eb9b6a551bcd363af6c25bd5..12a892587dbc70897b2d6578b2dd185ae5dd3434 100644 (file)
@@ -32,7 +32,6 @@ import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.permission.OrganizationPermission;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
-import org.sonar.server.user.ThreadLocalUserSession;
 import org.sonar.server.user.UserSession;
 
 import static com.google.common.base.Preconditions.checkNotNull;
@@ -46,12 +45,7 @@ import static com.google.common.base.Preconditions.checkState;
  * unless you purposely want to have side effects between each tests.
  * </p>
  * <p>
- * {@code UserSessionRule} is intended to be used either standalone (in which case use the static factory method
- * {@link #standalone()} or with {@link ServerTester} (in which case use static factory method
- * {@link #forServerTester(ServerTester)}).
- * </p>
- * <p>
- * In both cases, one can define user session behavior which should apply on all tests directly on the property, eg.:
+ * One can define user session behavior which should apply on all tests directly on the property, eg.:
  * <pre>
  * {@literal @}Rule
  * public UserSessionRule userSession = UserSessionRule.standalone().login("admin").setOrganizationPermissions(OrganizationPermissions.SYSTEM_ADMIN);
@@ -70,7 +64,7 @@ import static com.google.common.base.Preconditions.checkState;
  * </pre>
  * </p>
  * <p>
- * {@code UserSessionRule}, being standalone or associated to a {@link ServerTester}, emulates by default an anonymous
+ * {@code UserSessionRule}, emulates by default an anonymous
  * session. Therefore, call {@code UserSessionRule.standalone()} is equivalent to calling
  * {@code UserSessionRule.standalone().anonymous()}.
  * </p>
@@ -83,21 +77,14 @@ import static com.google.common.base.Preconditions.checkState;
 public class UserSessionRule implements TestRule, UserSession {
   private static final String DEFAULT_LOGIN = "default_login";
 
-  @CheckForNull
-  private final ServerTester serverTester;
   private UserSession currentUserSession;
 
-  private UserSessionRule(@Nullable ServerTester serverTester) {
-    this.serverTester = serverTester;
+  private UserSessionRule() {
     anonymous();
   }
 
   public static UserSessionRule standalone() {
-    return new UserSessionRule(null);
-  }
-
-  public static UserSessionRule forServerTester(ServerTester serverTester) {
-    return new UserSessionRule(Preconditions.checkNotNull(serverTester));
+    return new UserSessionRule();
   }
 
   /**
@@ -177,13 +164,9 @@ public class UserSessionRule implements TestRule, UserSession {
 
   protected void after() {
     this.currentUserSession = null;
-    if (serverTester != null) {
-      serverTester.get(ThreadLocalUserSession.class).unload();
-    }
   }
 
   public void set(UserSession userSession) {
-    checkState(serverTester == null, "Can set a specific session and use ServerTester at the same time");
     checkNotNull(userSession);
     setCurrentUserSession(userSession);
   }
@@ -239,9 +222,6 @@ public class UserSessionRule implements TestRule, UserSession {
 
   private void setCurrentUserSession(UserSession userSession) {
     this.currentUserSession = Preconditions.checkNotNull(userSession);
-    if (serverTester != null) {
-      serverTester.get(ThreadLocalUserSession.class).set(currentUserSession);
-    }
   }
 
   @Override
index b15b4d980364bb923ca0e450ebefdb24bc6711d0..acfdeeb22ec0b5a1eedb82548eb982b9ed861d5c 100644 (file)
@@ -23,8 +23,10 @@ import com.google.protobuf.GeneratedMessage;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.lang.reflect.Method;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import javax.annotation.CheckForNull;
+import org.sonar.test.JsonAssert;
 
 public class TestResponse {
 
@@ -65,4 +67,25 @@ public class TestResponse {
   public String getHeader(String headerKey) {
     return dumbResponse.getHeader(headerKey);
   }
+
+  public void assertJson(String expectedJson) throws Exception {
+    JsonAssert.assertJson(getInput()).isSimilarTo(expectedJson);
+  }
+
+  /**
+   * Compares JSON response with JSON file available in classpath. For example if class
+   * is org.foo.BarTest and filename is index.json, then file must be located
+   * at src/test/resources/org/foo/BarTest/index.json.
+   *
+   * @param clazz                the test class
+   * @param expectedJsonFilename name of the file containing the expected JSON
+   */
+  public void assertJson(Class clazz, String expectedJsonFilename) throws Exception {
+    String path = clazz.getSimpleName() + "/" + expectedJsonFilename;
+    URL url = clazz.getResource(path);
+    if (url == null) {
+      throw new IllegalStateException("Cannot find " + path);
+    }
+    JsonAssert.assertJson(getInput()).isSimilarTo(url);
+  }
 }
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_directory_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_directory_facet.json
deleted file mode 100644 (file)
index 1df736c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "facets": [
-    {
-      "property": "directories",
-      "values": [
-        {
-          "val": "src/main/java/dir",
-          "count": 1
-        }
-      ]
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_file_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_file_facet.json
deleted file mode 100644 (file)
index 87e6919..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-  "total": 1,
-  "p": 1,
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ],
-  "components": [
-    { "key": "PK1" },
-    { "key": "FK1" },
-    { "key": "FK2" },
-    { "key": "FK3" }
-  ],
-  "facets": [
-    {
-      "property": "fileUuids",
-      "values": [
-        {
-          "val": "F1",
-          "count": 1
-        },
-        {
-          "val": "F2",
-          "count": 1
-        },
-        {
-          "val": "F3",
-          "count": 0
-        }
-      ]
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_module_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_module_facet.json
deleted file mode 100644 (file)
index e5b71f6..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ],
-  "components": [
-    { "key": "PK1" },
-    { "key": "MK1" },
-    { "key": "SUBMK1" },
-    { "key": "SUBMK2" },
-    { "key": "SUBMK3" },
-    { "key": "FK1" }
-  ],
-  "facets": [
-    {
-      "property": "moduleUuids",
-      "values": [
-        {
-          "val": "SUBM1",
-          "count": 1
-        },
-        {
-          "val": "SUBM2",
-          "count": 1
-        },
-        {
-          "val": "SUBM3",
-          "count": 0
-        }
-      ]
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_non_sticky_project_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_non_sticky_project_facet.json
deleted file mode 100644 (file)
index 8c3d41a..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-  "total": 1,
-  "p": 1,
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ],
-  "components": [
-    { "key": "PK1" },
-    { "key": "FK1" }
-  ],
-  "facets": [
-    {
-      "property": "projectUuids",
-      "values": [
-        {
-          "val": "ABCD",
-          "count": 1
-        }
-      ]
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_sticky_project_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/display_sticky_project_facet.json
deleted file mode 100644 (file)
index 6865bd9..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ],
-  "components": [
-    { "key": "PK1" },
-    { "key": "PK2" },
-    { "key": "PK3" },
-    { "key": "FK1" }
-  ],
-  "facets": [
-    {
-      "property": "projectUuids",
-      "values": [
-        {
-          "val": "P1",
-          "count": 1
-        },
-        {
-          "val": "P2",
-          "count": 1
-        },
-        {
-          "val": "P3",
-          "count": 1
-        }
-      ]
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/issues_on_different_projects.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/issues_on_different_projects.json
deleted file mode 100644 (file)
index e88fc95..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1",
-      "status": "OPEN",
-      "resolution": "OPEN",
-      "severity": "MAJOR",
-      "updateDate": "2017-12-04T00:00:00+0100"
-    },
-    {
-      "key": "92fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK2",
-      "project": "PK2",
-      "rule": "xoo:x1",
-      "status": "OPEN",
-      "resolution": "OPEN",
-      "severity": "MAJOR",
-      "updateDate": "2017-12-04T00:00:00+0100"
-    }
-  ],
-  "components": [
-    {
-      "key": "FK1",
-      "enabled" : true
-    },
-    {
-      "key": "PK1",
-      "enabled" : true
-    },
-    {
-      "key": "FK2",
-      "enabled" : true
-    },
-    {
-      "key": "PK2",
-      "enabled" : true
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/no_issue.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/no_issue.json
deleted file mode 100644 (file)
index ce8bbfb..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "total": 0,
-  "issues": []
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_authors.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_authors.json
deleted file mode 100644 (file)
index 4dbdc16..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "total": 1,
-  "p": 1,
-  "issues": [
-    {
-      "key": "2bd4eac2-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1",
-      "author": "leia"
-    }
-  ],
-  "facets": [
-    {
-      "property": "authors",
-      "values": [
-        {
-          "val": "leia",
-          "count": 1
-        },
-        {
-          "val": "luke@skywalker.name",
-          "count": 1
-        }
-      ]
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_developer.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_developer.json
deleted file mode 100644 (file)
index d1b2e41..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "2bd4eac2-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1",
-      "author": "vader"
-    },
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b1182fd47d4",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1",
-      "author": "anakin@skywalker.name"
-    }
-    
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_directory_uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_directory_uuid.json
deleted file mode 100644 (file)
index a7d0246..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_file_key.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_file_key.json
deleted file mode 100644 (file)
index a7d0246..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_file_uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_file_uuid.json
deleted file mode 100644 (file)
index a7d0246..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_project_uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_project_uuid.json
deleted file mode 100644 (file)
index a7d0246..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_test_key.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_test_key.json
deleted file mode 100644 (file)
index 1807eeb..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "2bd4eac2-b650-4037-80bc-7b1182fd47d4",
-      "component": "FK2",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_view_uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_by_view_uuid.json
deleted file mode 100644 (file)
index a7d0246..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_since_leak_period.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsMediumTest/search_since_leak_period.json
deleted file mode 100644 (file)
index 0cdf5b8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "issues": [
-    {
-      "key": "AU-Tpxb--iU5OvuD2FLy",
-      "component": "FK1",
-      "project": "PK1",
-      "rule": "xoo:x1"
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_directory_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_directory_facet.json
new file mode 100644 (file)
index 0000000..1df736c
--- /dev/null
@@ -0,0 +1,13 @@
+{
+  "facets": [
+    {
+      "property": "directories",
+      "values": [
+        {
+          "val": "src/main/java/dir",
+          "count": 1
+        }
+      ]
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_file_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_file_facet.json
new file mode 100644 (file)
index 0000000..87e6919
--- /dev/null
@@ -0,0 +1,37 @@
+{
+  "total": 1,
+  "p": 1,
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ],
+  "components": [
+    { "key": "PK1" },
+    { "key": "FK1" },
+    { "key": "FK2" },
+    { "key": "FK3" }
+  ],
+  "facets": [
+    {
+      "property": "fileUuids",
+      "values": [
+        {
+          "val": "F1",
+          "count": 1
+        },
+        {
+          "val": "F2",
+          "count": 1
+        },
+        {
+          "val": "F3",
+          "count": 0
+        }
+      ]
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_module_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_module_facet.json
new file mode 100644 (file)
index 0000000..e5b71f6
--- /dev/null
@@ -0,0 +1,37 @@
+{
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ],
+  "components": [
+    { "key": "PK1" },
+    { "key": "MK1" },
+    { "key": "SUBMK1" },
+    { "key": "SUBMK2" },
+    { "key": "SUBMK3" },
+    { "key": "FK1" }
+  ],
+  "facets": [
+    {
+      "property": "moduleUuids",
+      "values": [
+        {
+          "val": "SUBM1",
+          "count": 1
+        },
+        {
+          "val": "SUBM2",
+          "count": 1
+        },
+        {
+          "val": "SUBM3",
+          "count": 0
+        }
+      ]
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_non_sticky_project_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_non_sticky_project_facet.json
new file mode 100644 (file)
index 0000000..8c3d41a
--- /dev/null
@@ -0,0 +1,27 @@
+{
+  "total": 1,
+  "p": 1,
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ],
+  "components": [
+    { "key": "PK1" },
+    { "key": "FK1" }
+  ],
+  "facets": [
+    {
+      "property": "projectUuids",
+      "values": [
+        {
+          "val": "ABCD",
+          "count": 1
+        }
+      ]
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_sticky_project_facet.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/display_sticky_project_facet.json
new file mode 100644 (file)
index 0000000..6865bd9
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ],
+  "components": [
+    { "key": "PK1" },
+    { "key": "PK2" },
+    { "key": "PK3" },
+    { "key": "FK1" }
+  ],
+  "facets": [
+    {
+      "property": "projectUuids",
+      "values": [
+        {
+          "val": "P1",
+          "count": 1
+        },
+        {
+          "val": "P2",
+          "count": 1
+        },
+        {
+          "val": "P3",
+          "count": 1
+        }
+      ]
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/issues_on_different_projects.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/issues_on_different_projects.json
new file mode 100644 (file)
index 0000000..e88fc95
--- /dev/null
@@ -0,0 +1,42 @@
+{
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1",
+      "status": "OPEN",
+      "resolution": "OPEN",
+      "severity": "MAJOR",
+      "updateDate": "2017-12-04T00:00:00+0100"
+    },
+    {
+      "key": "92fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK2",
+      "project": "PK2",
+      "rule": "xoo:x1",
+      "status": "OPEN",
+      "resolution": "OPEN",
+      "severity": "MAJOR",
+      "updateDate": "2017-12-04T00:00:00+0100"
+    }
+  ],
+  "components": [
+    {
+      "key": "FK1",
+      "enabled" : true
+    },
+    {
+      "key": "PK1",
+      "enabled" : true
+    },
+    {
+      "key": "FK2",
+      "enabled" : true
+    },
+    {
+      "key": "PK2",
+      "enabled" : true
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/no_issue.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/no_issue.json
new file mode 100644 (file)
index 0000000..ce8bbfb
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "total": 0,
+  "issues": []
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_authors.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_authors.json
new file mode 100644 (file)
index 0000000..4dbdc16
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "total": 1,
+  "p": 1,
+  "issues": [
+    {
+      "key": "2bd4eac2-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1",
+      "author": "leia"
+    }
+  ],
+  "facets": [
+    {
+      "property": "authors",
+      "values": [
+        {
+          "val": "leia",
+          "count": 1
+        },
+        {
+          "val": "luke@skywalker.name",
+          "count": 1
+        }
+      ]
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_developer.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_developer.json
new file mode 100644 (file)
index 0000000..d1b2e41
--- /dev/null
@@ -0,0 +1,19 @@
+{
+  "issues": [
+    {
+      "key": "2bd4eac2-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1",
+      "author": "vader"
+    },
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b1182fd47d4",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1",
+      "author": "anakin@skywalker.name"
+    }
+    
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_directory_uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_directory_uuid.json
new file mode 100644 (file)
index 0000000..a7d0246
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_file_key.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_file_key.json
new file mode 100644 (file)
index 0000000..a7d0246
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_file_uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_file_uuid.json
new file mode 100644 (file)
index 0000000..a7d0246
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_project_uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_project_uuid.json
new file mode 100644 (file)
index 0000000..a7d0246
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_test_key.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_test_key.json
new file mode 100644 (file)
index 0000000..1807eeb
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "issues": [
+    {
+      "key": "2bd4eac2-b650-4037-80bc-7b1182fd47d4",
+      "component": "FK2",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_view_uuid.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_by_view_uuid.json
new file mode 100644 (file)
index 0000000..a7d0246
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "issues": [
+    {
+      "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_since_leak_period.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionComponentsTest/search_since_leak_period.json
new file mode 100644 (file)
index 0000000..0cdf5b8
--- /dev/null
@@ -0,0 +1,10 @@
+{
+  "issues": [
+    {
+      "key": "AU-Tpxb--iU5OvuD2FLy",
+      "component": "FK1",
+      "project": "PK1",
+      "rule": "xoo:x1"
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_nominal.json
deleted file mode 100644 (file)
index 1d0ef29..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-{
-   "left" : {
-      "key" : "xoo-profile-1-01234",
-      "name" : "Profile 1"
-   },
-   "right" : {
-      "key" : "xoo-profile-2-12345",
-      "name" : "Profile 2"
-   },
-   "same" : [
-      {
-         "key" : "blah:rule1",
-         "pluginKey" : "blah",
-         "pluginName" : "Blah",
-         "languageKey": "xoo",
-         "languageName": "Xoo",
-         "name" : "Rule1",
-         "severity" : "BLOCKER"
-      }
-   ],
-   "inLeft" : [
-      {
-         "key" : "blah:rule2",
-         "pluginKey" : "blah",
-         "pluginName" : "Blah",
-         "languageKey": "xoo",
-         "languageName": "Xoo",
-         "name" : "Rule2",
-         "severity" : "BLOCKER"
-      }
-   ],
-   "inRight" : [
-      {
-         "key" : "blah:rule3",
-         "pluginKey" : "blah",
-         "pluginName" : "Blah",
-         "languageKey": "xoo",
-         "languageName": "Xoo",
-         "name" : "Rule3",
-         "severity" : "BLOCKER"
-      }
-   ],
-   "modified" : [
-      {
-         "key" : "blah:rule4",
-         "pluginKey" : "blah",
-         "pluginName" : "Blah",
-         "languageKey": "xoo",
-         "languageName": "Xoo",
-         "name" : "Rule4",
-         "left" : {
-            "severity" : "BLOCKER",
-            "params" : {
-               "param_rule4" : "polop"
-            }
-         },
-         "right" : {
-            "severity" : "BLOCKER",
-            "params" : {
-               "param_rule4" : "palap"
-            }
-         }
-      },
-      {
-         "key" : "blah:rule5",
-         "pluginKey" : "blah",
-         "pluginName" : "Blah",
-         "languageKey": "xoo",
-         "languageName": "Xoo",
-         "name" : "Rule5",
-         "left" : {
-            "severity" : "MINOR"
-         },
-         "right" : {
-            "severity" : "MAJOR"
-         }
-      }
-   ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_left.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_left.json
deleted file mode 100644 (file)
index afe92f1..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-   "left" : {
-      "key" : "xoo-profile-1-01234",
-      "name" : "Profile 1"
-   },
-   "right" : {
-      "key" : "xoo-profile-2-12345",
-      "name" : "Profile 2"
-   },
-   "same" : [],
-   "inLeft" : [],
-   "inRight" : [],
-   "modified" : [
-      {
-         "key" : "blah:rule1",
-         "pluginKey" : "blah",
-         "pluginName" : "Blah",
-         "languageKey": "xoo",
-         "languageName": "Xoo",
-         "name" : "Rule1",
-         "left" : {
-            "severity" : "BLOCKER",
-            "params" : {
-               "param_rule1" : "polop"
-            }
-         },
-         "right" : {
-            "severity" : "BLOCKER"
-         }
-      }
-   ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_right.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionMediumTest/compare_param_on_right.json
deleted file mode 100644 (file)
index ec90227..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-{
-   "left" : {
-      "key" : "xoo-profile-1-01234",
-      "name" : "Profile 1"
-   },
-   "right" : {
-      "key" : "xoo-profile-2-12345",
-      "name" : "Profile 2"
-   },
-   "same" : [],
-   "inLeft" : [],
-   "inRight" : [],
-   "modified" : [
-      {
-         "key" : "blah:rule1",
-         "pluginKey" : "blah",
-         "pluginName" : "Blah",
-         "languageKey": "xoo",
-         "languageName": "Xoo",
-         "name" : "Rule1",
-         "left" : {
-            "severity" : "BLOCKER"
-         },
-         "right" : {
-            "severity" : "BLOCKER",
-            "params" : {
-               "param_rule1" : "polop"
-            }
-         }
-      }
-   ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_nominal.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_nominal.json
new file mode 100644 (file)
index 0000000..1d0ef29
--- /dev/null
@@ -0,0 +1,79 @@
+{
+   "left" : {
+      "key" : "xoo-profile-1-01234",
+      "name" : "Profile 1"
+   },
+   "right" : {
+      "key" : "xoo-profile-2-12345",
+      "name" : "Profile 2"
+   },
+   "same" : [
+      {
+         "key" : "blah:rule1",
+         "pluginKey" : "blah",
+         "pluginName" : "Blah",
+         "languageKey": "xoo",
+         "languageName": "Xoo",
+         "name" : "Rule1",
+         "severity" : "BLOCKER"
+      }
+   ],
+   "inLeft" : [
+      {
+         "key" : "blah:rule2",
+         "pluginKey" : "blah",
+         "pluginName" : "Blah",
+         "languageKey": "xoo",
+         "languageName": "Xoo",
+         "name" : "Rule2",
+         "severity" : "BLOCKER"
+      }
+   ],
+   "inRight" : [
+      {
+         "key" : "blah:rule3",
+         "pluginKey" : "blah",
+         "pluginName" : "Blah",
+         "languageKey": "xoo",
+         "languageName": "Xoo",
+         "name" : "Rule3",
+         "severity" : "BLOCKER"
+      }
+   ],
+   "modified" : [
+      {
+         "key" : "blah:rule4",
+         "pluginKey" : "blah",
+         "pluginName" : "Blah",
+         "languageKey": "xoo",
+         "languageName": "Xoo",
+         "name" : "Rule4",
+         "left" : {
+            "severity" : "BLOCKER",
+            "params" : {
+               "param_rule4" : "polop"
+            }
+         },
+         "right" : {
+            "severity" : "BLOCKER",
+            "params" : {
+               "param_rule4" : "palap"
+            }
+         }
+      },
+      {
+         "key" : "blah:rule5",
+         "pluginKey" : "blah",
+         "pluginName" : "Blah",
+         "languageKey": "xoo",
+         "languageName": "Xoo",
+         "name" : "Rule5",
+         "left" : {
+            "severity" : "MINOR"
+         },
+         "right" : {
+            "severity" : "MAJOR"
+         }
+      }
+   ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_param_on_left.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_param_on_left.json
new file mode 100644 (file)
index 0000000..afe92f1
--- /dev/null
@@ -0,0 +1,32 @@
+{
+   "left" : {
+      "key" : "xoo-profile-1-01234",
+      "name" : "Profile 1"
+   },
+   "right" : {
+      "key" : "xoo-profile-2-12345",
+      "name" : "Profile 2"
+   },
+   "same" : [],
+   "inLeft" : [],
+   "inRight" : [],
+   "modified" : [
+      {
+         "key" : "blah:rule1",
+         "pluginKey" : "blah",
+         "pluginName" : "Blah",
+         "languageKey": "xoo",
+         "languageName": "Xoo",
+         "name" : "Rule1",
+         "left" : {
+            "severity" : "BLOCKER",
+            "params" : {
+               "param_rule1" : "polop"
+            }
+         },
+         "right" : {
+            "severity" : "BLOCKER"
+         }
+      }
+   ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_param_on_right.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/CompareActionTest/compare_param_on_right.json
new file mode 100644 (file)
index 0000000..ec90227
--- /dev/null
@@ -0,0 +1,32 @@
+{
+   "left" : {
+      "key" : "xoo-profile-1-01234",
+      "name" : "Profile 1"
+   },
+   "right" : {
+      "key" : "xoo-profile-2-12345",
+      "name" : "Profile 2"
+   },
+   "same" : [],
+   "inLeft" : [],
+   "inRight" : [],
+   "modified" : [
+      {
+         "key" : "blah:rule1",
+         "pluginKey" : "blah",
+         "pluginName" : "Blah",
+         "languageKey": "xoo",
+         "languageName": "Xoo",
+         "name" : "Rule1",
+         "left" : {
+            "severity" : "BLOCKER"
+         },
+         "right" : {
+            "severity" : "BLOCKER",
+            "params" : {
+               "param_rule1" : "polop"
+            }
+         }
+      }
+   ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/encode_html_description_of_custom_rule.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/encode_html_description_of_custom_rule.json
deleted file mode 100644 (file)
index 4e595e1..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "rule": {
-    "key": "java:MY_CUSTOM",
-    "htmlDesc": "&lt;div&gt;line1<br/>line2&lt;/div&gt;",
-    "templateKey": "java:S001"
-  }
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_deprecated_rule_rem_function_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_deprecated_rule_rem_function_fields.json
deleted file mode 100644 (file)
index c519f28..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-  "rule": {
-    "internalKey": "InternalKeyS001",
-    "isTemplate": false,
-    "key": "java:S001",
-    "lang": "xoo",
-    "name": "Rule S001",
-    "repo": "java",
-    "severity": "MINOR",
-    "status": "BETA",
-    "remFnType": "LINEAR_OFFSET",
-    "remFnGapMultiplier": "5d",
-    "remFnBaseEffort": "10h",
-    "defaultRemFnType": "LINEAR_OFFSET",
-    "defaultRemFnGapMultiplier": "6d",
-    "defaultRemFnBaseEffort": "11h",
-    "remFnOverloaded": true,
-    "gapDescription": "java.S001.effortToFix",
-    "debtRemFnType": "LINEAR_OFFSET",
-    "debtRemFnCoeff": "5d",
-    "debtRemFnOffset": "10h",
-    "defaultDebtRemFnType": "LINEAR_OFFSET",
-    "defaultDebtRemFnCoeff": "6d",
-    "defaultDebtRemFnOffset": "11h",
-    "debtOverloaded": true,
-    "effortToFixDescription": "java.S001.effortToFix"
-  }
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule.json
deleted file mode 100644 (file)
index ebc65b2..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "rule": {
-    "key": "java:S001",
-    "repo": "java",
-    "name": "Rule S001",
-    "htmlDesc": "Rule S001 <b>description</b>",
-    "severity": "MINOR",
-    "status": "BETA",
-    "isTemplate": false,
-    "tags": ["tag1", "tag2"],
-    "sysTags": ["systag1", "systag2"],
-    "type": "BUG",
-    "lang": "xoo",
-    "params": [
-      {
-        "key": "regex",
-        "htmlDesc": "Reg <strong>exp</strong>",
-        "defaultValue": ".*"
-      }
-    ]
-  }
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_when_activated.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_when_activated.json
deleted file mode 100644 (file)
index 4298bb2..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "rule": {
-    "key": "java:S001",
-    "params": [
-      {
-        "key": "regex",
-        "htmlDesc": "Reg \u003cstrong\u003eexp\u003c/strong\u003e",
-        "defaultValue": ".*",
-        "type": "STRING"
-      }
-    ]
-  },
-  "actives": [
-    {
-      "qProfile": "profile",
-      "inherit": "NONE",
-      "severity": "MINOR",
-      "params": [
-        {
-          "key": "regex",
-          "value": ".*?"
-        }
-      ]
-    }
-  ]
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_default_and_overridden_debt_infos.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_default_and_overridden_debt_infos.json
deleted file mode 100644 (file)
index 899a1d8..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "rule": {
-    "key": "java:S001",
-    "repo": "java",
-    "name": "Rule S001",
-    "htmlDesc": "Rule S001 <b>description</b>",
-    "severity": "MINOR",
-    "status": "BETA",
-    "isTemplate": false,
-    "remFnType": "LINEAR_OFFSET",
-    "remFnGapMultiplier": "5d",
-    "remFnBaseEffort": "10h",
-    "defaultRemFnType": "LINEAR",
-    "defaultRemFnGapMultiplier": "5min",
-    "debtOverloaded": true,
-    "lang": "xoo"
-  }
-}
-
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_default_debt_infos.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_default_debt_infos.json
deleted file mode 100644 (file)
index 2c57873..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "rule": {
-    "remFnType": "LINEAR_OFFSET",
-    "remFnGapMultiplier": "5d",
-    "remFnBaseEffort": "10h",
-    "defaultRemFnType": "LINEAR_OFFSET",
-    "defaultRemFnGapMultiplier": "5d",
-    "defaultRemFnBaseEffort": "10h",
-    "debtOverloaded": false,
-    "gapDescription": "java.S001.effortToFix",
-    "htmlDesc": "Rule S001 <b>description</b>",
-    "internalKey": "InternalKeyS001",
-    "isTemplate": false,
-    "key": "java:S001",
-    "lang": "xoo",
-    "name": "Rule S001",
-    "repo": "java",
-    "severity": "MINOR",
-    "status": "BETA"
-  }
-}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_no_default_and_no_overridden_debt.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_no_default_and_no_overridden_debt.json
deleted file mode 100644 (file)
index 9b211f0..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "rule": {
-    "key": "java:S001",
-    "repo": "java",
-    "name": "Rule S001",
-    "htmlDesc": "Rule S001 <b>description</b>",
-    "severity": "MINOR",
-    "status": "BETA",
-    "isTemplate": false,
-    "debtOverloaded": false,
-    "lang": "xoo"
-  }
-}
-
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_overridden_debt_infos.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionMediumTest/show_rule_with_overridden_debt_infos.json
deleted file mode 100644 (file)
index 42ef8d0..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "rule": {
-    "key": "java:S001",
-    "repo": "java",
-    "name": "Rule S001",
-    "htmlDesc": "Rule S001 <b>description</b>",
-    "severity": "MINOR",
-    "status": "BETA",
-    "isTemplate": false,
-    "remFnType": "LINEAR_OFFSET",
-    "remFnGapMultiplier": "5d",
-    "remFnBaseEffort": "10h",
-    "debtOverloaded": true,
-    "lang": "xoo"
-  }
-}
-
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_deprecated_rule_rem_function_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_deprecated_rule_rem_function_fields.json
new file mode 100644 (file)
index 0000000..c519f28
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "rule": {
+    "internalKey": "InternalKeyS001",
+    "isTemplate": false,
+    "key": "java:S001",
+    "lang": "xoo",
+    "name": "Rule S001",
+    "repo": "java",
+    "severity": "MINOR",
+    "status": "BETA",
+    "remFnType": "LINEAR_OFFSET",
+    "remFnGapMultiplier": "5d",
+    "remFnBaseEffort": "10h",
+    "defaultRemFnType": "LINEAR_OFFSET",
+    "defaultRemFnGapMultiplier": "6d",
+    "defaultRemFnBaseEffort": "11h",
+    "remFnOverloaded": true,
+    "gapDescription": "java.S001.effortToFix",
+    "debtRemFnType": "LINEAR_OFFSET",
+    "debtRemFnCoeff": "5d",
+    "debtRemFnOffset": "10h",
+    "defaultDebtRemFnType": "LINEAR_OFFSET",
+    "defaultDebtRemFnCoeff": "6d",
+    "defaultDebtRemFnOffset": "11h",
+    "debtOverloaded": true,
+    "effortToFixDescription": "java.S001.effortToFix"
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule.json
new file mode 100644 (file)
index 0000000..191f2e6
--- /dev/null
@@ -0,0 +1,22 @@
+{
+  "rule": {
+    "key": "java:S001",
+    "repo": "java",
+    "name": "Rule S001",
+    "htmlDesc": "interpreted",
+    "severity": "MINOR",
+    "status": "BETA",
+    "isTemplate": false,
+    "tags": ["tag1", "tag2"],
+    "sysTags": ["systag1", "systag2"],
+    "type": "BUG",
+    "lang": "xoo",
+    "params": [
+      {
+        "key": "regex",
+        "htmlDesc": "Reg <strong>exp</strong>",
+        "defaultValue": ".*"
+      }
+    ]
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_when_activated.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_when_activated.json
new file mode 100644 (file)
index 0000000..4298bb2
--- /dev/null
@@ -0,0 +1,26 @@
+{
+  "rule": {
+    "key": "java:S001",
+    "params": [
+      {
+        "key": "regex",
+        "htmlDesc": "Reg \u003cstrong\u003eexp\u003c/strong\u003e",
+        "defaultValue": ".*",
+        "type": "STRING"
+      }
+    ]
+  },
+  "actives": [
+    {
+      "qProfile": "profile",
+      "inherit": "NONE",
+      "severity": "MINOR",
+      "params": [
+        {
+          "key": "regex",
+          "value": ".*?"
+        }
+      ]
+    }
+  ]
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_default_and_overridden_debt_infos.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_default_and_overridden_debt_infos.json
new file mode 100644 (file)
index 0000000..ef3917d
--- /dev/null
@@ -0,0 +1,19 @@
+{
+  "rule": {
+    "key": "java:S001",
+    "repo": "java",
+    "name": "Rule S001",
+    "htmlDesc": "interpreted",
+    "severity": "MINOR",
+    "status": "BETA",
+    "isTemplate": false,
+    "remFnType": "LINEAR_OFFSET",
+    "remFnGapMultiplier": "5d",
+    "remFnBaseEffort": "10h",
+    "defaultRemFnType": "LINEAR",
+    "defaultRemFnGapMultiplier": "5min",
+    "debtOverloaded": true,
+    "lang": "xoo"
+  }
+}
+
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_default_debt_infos.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_default_debt_infos.json
new file mode 100644 (file)
index 0000000..db25bfe
--- /dev/null
@@ -0,0 +1,21 @@
+{
+  "rule": {
+    "remFnType": "LINEAR_OFFSET",
+    "remFnGapMultiplier": "5d",
+    "remFnBaseEffort": "10h",
+    "defaultRemFnType": "LINEAR_OFFSET",
+    "defaultRemFnGapMultiplier": "5d",
+    "defaultRemFnBaseEffort": "10h",
+    "debtOverloaded": false,
+    "gapDescription": "java.S001.effortToFix",
+    "htmlDesc": "interpreted",
+    "internalKey": "InternalKeyS001",
+    "isTemplate": false,
+    "key": "java:S001",
+    "lang": "xoo",
+    "name": "Rule S001",
+    "repo": "java",
+    "severity": "MINOR",
+    "status": "BETA"
+  }
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_no_default_and_no_overridden_debt.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_no_default_and_no_overridden_debt.json
new file mode 100644 (file)
index 0000000..893cba6
--- /dev/null
@@ -0,0 +1,14 @@
+{
+  "rule": {
+    "key": "java:S001",
+    "repo": "java",
+    "name": "Rule S001",
+    "htmlDesc": "interpreted",
+    "severity": "MINOR",
+    "status": "BETA",
+    "isTemplate": false,
+    "debtOverloaded": false,
+    "lang": "xoo"
+  }
+}
+
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_overridden_debt_infos.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/ShowActionTest/show_rule_with_overridden_debt_infos.json
new file mode 100644 (file)
index 0000000..9f59737
--- /dev/null
@@ -0,0 +1,17 @@
+{
+  "rule": {
+    "key": "java:S001",
+    "repo": "java",
+    "name": "Rule S001",
+    "htmlDesc": "interpreted",
+    "severity": "MINOR",
+    "status": "BETA",
+    "isTemplate": false,
+    "remFnType": "LINEAR_OFFSET",
+    "remFnGapMultiplier": "5d",
+    "remFnBaseEffort": "10h",
+    "debtOverloaded": true,
+    "lang": "xoo"
+  }
+}
+