]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-8694 separate the concerns of ComponentIndexTests
authorDaniel Schwarz <daniel.schwarz@sonarsource.com>
Thu, 26 Jan 2017 10:10:31 +0000 (11:10 +0100)
committerDaniel Schwarz <bartfastiel@users.noreply.github.com>
Fri, 27 Jan 2017 15:57:10 +0000 (16:57 +0100)
server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexCombinationTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureFuzzyTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureKeyTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePartialTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexLoginTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexScoreTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexSearchFeatureRule.java
server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexTest.java

diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexCombinationTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexCombinationTest.java
new file mode 100644 (file)
index 0000000..b202818
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.component.index;
+
+import java.util.stream.IntStream;
+import org.junit.Test;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.db.component.ComponentDto;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ComponentIndexCombinationTest extends ComponentIndexTest {
+
+  @Test
+  public void return_empty_list_if_no_fields_match_query() {
+    indexProject("struts", "Apache Struts");
+
+    assertThat(index.search(new ComponentIndexQuery("missing"))).isEmpty();
+  }
+
+  @Test
+  public void should_not_return_components_that_do_not_match_at_all() {
+    indexProject("banana", "Banana Project 1");
+
+    assertNoSearchResults("Apple");
+  }
+
+  @Test
+  public void filter_results_by_qualifier() {
+    ComponentDto project = indexProject("struts", "Apache Struts");
+    indexFile(project, "src/main/java/StrutsManager.java", "StrutsManager.java");
+
+    assertSearchResults(new ComponentIndexQuery("struts").setQualifier(Qualifiers.PROJECT), project);
+  }
+
+  @Test
+  public void should_limit_the_number_of_results() {
+    IntStream.rangeClosed(0, 10).forEach(i -> indexProject("sonarqube" + i, "SonarQube" + i));
+
+    assertSearch(new ComponentIndexQuery("sonarqube").setLimit(5)).hasSize(5);
+  }
+
+  @Test
+  public void should_not_support_wildcards() {
+    indexProject("theKey", "the name");
+
+    assertNoSearchResults("*t*");
+    assertNoSearchResults("th?Key");
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureFuzzyTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureFuzzyTest.java
new file mode 100644 (file)
index 0000000..abb0cbf
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.component.index;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.db.component.ComponentDto;
+
+public class ComponentIndexFeatureFuzzyTest extends ComponentIndexTest {
+
+  @Before
+  public void before() {
+    features.set(ComponentIndexSearchFeature.FUZZY, ComponentIndexSearchFeature.FUZZY_PREFIX);
+  }
+
+  @Test
+  public void should_find_item_despite_missing_character() {
+    ComponentDto project = indexProject("key-1", "SonarQube");
+
+    assertSearchResults("SonrQube", project);
+  }
+
+  @Test
+  public void should_find_item_despite_missing_character_and_lowercase() {
+    ComponentDto project = indexProject("key-1", "SonarQube");
+
+    assertSearchResults("sonrqube", project);
+  }
+
+  @Test
+  public void should_find_item_despite_two_missing_characters_and_lowercase() {
+    ComponentDto project = indexProject("key-1", "SonarQube");
+
+    assertSearchResults("sonqube", project);
+  }
+
+  @Test
+  public void missing_characters_should_reduce_score() {
+    assertResultOrder("SonarQube.java",
+      "sonarqube.java",
+      "sonaqube.java",
+      "sonqube.java");
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureKeyTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeatureKeyTest.java
new file mode 100644 (file)
index 0000000..103c26f
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.component.index;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.db.component.ComponentDto;
+
+public class ComponentIndexFeatureKeyTest extends ComponentIndexTest {
+
+  @Before
+  public void before() {
+    features.set(ComponentIndexSearchFeature.KEY);
+  }
+
+  @Test
+  public void should_search_projects_by_exact_case_insensitive_key() {
+    ComponentDto project1 = indexProject("keyOne", "Project One");
+    indexProject("keyTwo", "Project Two");
+
+    assertSearchResults("keyOne", project1);
+    assertSearchResults("keyone", project1);
+    assertSearchResults("KEYone", project1);
+  }
+
+  @Test
+  public void should_search_project_with_dot_in_key() {
+    ComponentDto project = indexProject("org.sonarqube", "SonarQube");
+
+    assertSearchResults("org.sonarqube", project);
+    assertNoSearchResults("orgsonarqube");
+  }
+
+  @Test
+  public void should_search_project_with_dash_in_key() {
+    ComponentDto project = indexProject("org-sonarqube", "SonarQube");
+
+    assertSearchResults("org-sonarqube", project);
+    assertNoSearchResults("orgsonarqube");
+  }
+
+  @Test
+  public void should_search_project_with_colon_in_key() {
+    ComponentDto project = indexProject("org:sonarqube", "Quality Product");
+
+    assertSearchResults("org:sonarqube", project);
+    assertNoSearchResults("orgsonarqube");
+    assertNoSearchResults("org-sonarqube");
+    assertNoSearchResults("org_sonarqube");
+  }
+
+  @Test
+  public void should_search_project_with_all_special_characters_in_key() {
+    ComponentDto project = indexProject("org.sonarqube:sonar-sérvèr_ç", "SonarQube");
+
+    assertSearchResults("org.sonarqube:sonar-sérvèr_ç", project);
+  }
+
+  @Test
+  public void should_not_return_results_when_searching_by_partial_key() {
+    indexProject("theKey", "some name");
+
+    assertNoSearchResults("theke");
+    assertNoSearchResults("hekey");
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePartialTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexFeaturePartialTest.java
new file mode 100644 (file)
index 0000000..c49001c
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.component.index;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.db.component.ComponentDto;
+
+public class ComponentIndexFeaturePartialTest extends ComponentIndexTest {
+
+  @Before
+  public void before() {
+    features.set(ComponentIndexSearchFeature.PARTIAL);
+  }
+
+  @Test
+  public void search_projects_by_exact_name() {
+    ComponentDto struts = indexProject("struts", "Apache Struts");
+    indexProject("sonarqube", "SonarQube");
+
+    assertSearchResults("Apache Struts", struts);
+    assertSearchResults("APACHE STRUTS", struts);
+    assertSearchResults("APACHE struTS", struts);
+  }
+
+  @Test
+  public void search_file_with_long_name() {
+    ComponentDto project = indexProject("struts", "Apache Struts");
+    ComponentDto file1 = indexFile(project, "src/main/java/DefaultRubyComponentServiceTestManagerFactory.java", "DefaultRubyComponentServiceTestManagerFactory.java");
+
+    assertSearchResults("DefaultRubyComponentServiceTestManagerFactory", file1);
+    assertSearchResults("DefaultRubyComponentServiceTestManagerFactory.java", file1);
+    assertSearchResults("RubyComponentServiceTestManager", file1);
+    assertSearchResults("te", file1);
+  }
+
+  @Test
+  public void should_search_by_name_with_two_characters() {
+    ComponentDto project = indexProject("struts", "Apache Struts");
+
+    assertSearchResults("st", project);
+    assertSearchResults("tr", project);
+  }
+
+  @Test
+  public void search_projects_by_partial_name() {
+    ComponentDto struts = indexProject("struts", "Apache Struts");
+
+    assertSearchResults("truts", struts);
+    assertSearchResults("pache", struts);
+    assertSearchResults("apach", struts);
+    assertSearchResults("che stru", struts);
+  }
+
+  @Test
+  public void search_projects_and_files_by_partial_name() {
+    ComponentDto project = indexProject("struts", "Apache Struts");
+    ComponentDto file1 = indexFile(project, "src/main/java/StrutsManager.java", "StrutsManager.java");
+    indexFile(project, "src/main/java/Foo.java", "Foo.java");
+
+    assertSearchResults("struts", project, file1);
+    assertSearchResults("Struts", project, file1);
+    assertSearchResults("StrutsManager", file1);
+    assertSearchResults("STRUTSMAN", file1);
+    assertSearchResults("utsManag", file1);
+  }
+
+  @Test
+  public void should_find_file_by_file_extension() {
+    ComponentDto project = indexProject("struts", "Apache Struts");
+    ComponentDto file1 = indexFile(project, "src/main/java/StrutsManager.java", "StrutsManager.java");
+    ComponentDto file2 = indexFile(project, "src/main/java/Foo.java", "Foo.java");
+
+    assertSearchResults(".java", file1, file2);
+    assertSearchResults("manager.java", file1);
+
+    // do not match
+    assertNoSearchResults("somethingStrutsManager.java");
+  }
+
+  @Test
+  public void should_search_for_word_and_suffix() {
+    assertFileMatches("plugin java", "AbstractPluginFactory.java");
+  }
+
+  @Test
+  public void should_search_for_word_and_suffix_in_any_order() {
+    assertFileMatches("java plugin", "AbstractPluginFactory.java");
+  }
+
+  @Test
+  public void should_search_for_two_words() {
+    assertFileMatches("abstract factory", "AbstractPluginFactory.java");
+  }
+
+  @Test
+  public void should_search_for_two_words_in_any_order() {
+    assertFileMatches("factory abstract", "AbstractPluginFactory.java");
+  }
+
+  @Test
+  public void should_find_item_with_at_least_one_matching_word() {
+    assertFileMatches("abstract object", "AbstractPluginFactory.java");
+  }
+
+  @Test
+  public void should_require_at_least_one_matching_word() {
+    assertNoFileMatches("monitor object", "AbstractPluginFactory.java");
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexLoginTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexLoginTest.java
new file mode 100644 (file)
index 0000000..8ef13a7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.component.index;
+
+import java.util.Collections;
+import org.junit.Test;
+import org.sonar.db.component.ComponentDto;
+
+import static java.util.Collections.emptyList;
+
+public class ComponentIndexLoginTest extends ComponentIndexTest {
+
+  @Test
+  public void should_respect_confidentiallity() {
+    indexer.index(newProject("sonarqube", "Quality Product"));
+
+    // do not give any permissions to that project
+
+    assertNoSearchResults("sonarqube");
+    assertNoSearchResults("Quality Product");
+  }
+
+  @Test
+  public void should_find_project_for_which_the_user_has_direct_permission() {
+    login();
+
+    ComponentDto project = newProject("sonarqube", "Quality Product");
+    indexer.index(project);
+
+    // give the user explicit access
+    authorizationIndexerTester.indexProjectPermission(project.uuid(),
+      emptyList(),
+      Collections.singletonList((long) TEST_USER_ID));
+
+    assertSearchResults("sonarqube", project);
+  }
+
+  @Test
+  public void should_find_project_for_which_the_user_has_indirect_permission_through_group() {
+    login();
+
+    ComponentDto project = newProject("sonarqube", "Quality Product");
+    indexer.index(project);
+
+    // give the user implicit access (though group)
+    authorizationIndexerTester.indexProjectPermission(project.uuid(),
+      Collections.singletonList(TEST_USER_GROUP),
+      emptyList());
+
+    assertSearchResults("sonarqube", project);
+  }
+
+  protected void login() {
+    userSession.login("john").setUserId(TEST_USER_ID).setUserGroups(TEST_USER_GROUP);
+  }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexScoreTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/index/ComponentIndexScoreTest.java
new file mode 100644 (file)
index 0000000..d4adf4e
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.component.index;
+
+import org.junit.Test;
+import org.sonar.db.component.ComponentDto;
+
+public class ComponentIndexScoreTest extends ComponentIndexTest {
+
+  @Test
+  public void should_order_results_by_score() {
+    assertResultOrder("struts",
+      "Struts",
+      "Apache Struts",
+      "Apache Struts Two");
+  }
+
+  @Test
+  public void should_prefer_components_without_prefix() {
+    assertResultOrder("File.java",
+      "File.java",
+      "MyFile.java");
+  }
+
+  @Test
+  public void should_prefer_components_without_suffix() {
+    assertResultOrder("File",
+      "File",
+      "Filex");
+  }
+
+  @Test
+  public void should_prefer_key_matching_over_name_matching() {
+    ComponentDto project1 = indexProject("quality", "SonarQube");
+    ComponentDto project2 = indexProject("sonarqube", "Quality Product");
+
+    assertExactResults("sonarqube", project2, project1);
+  }
+
+  @Test
+  public void should_prefer_prefix_to_partial() {
+    assertResultOrder("corem",
+      "CoreMetrics.java",
+      "ScoreMatrix.java");
+  }
+}
index 0527752e124af7dfe87dd1184d0ce0b7002624ab..0021dcefe0bb29751de05e725394dd7d5523a0d0 100644 (file)
@@ -34,4 +34,7 @@ public class ComponentIndexSearchFeatureRule extends ExternalResource {
     return features;
   }
 
+  public void set(ComponentIndexSearchFeature... features) {
+    this.features = features;
+  }
 }
index 42a7ec81b68c5ef10cc218fe8efa8d98df925e27..bc2f9746f4c64e76142499c7c9aa543c952c6813 100644 (file)
@@ -24,13 +24,10 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 import org.assertj.core.api.AbstractListAssert;
 import org.junit.Before;
 import org.junit.Rule;
-import org.junit.Test;
 import org.sonar.api.config.MapSettings;
-import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.security.DefaultGroups;
 import org.sonar.api.utils.System2;
 import org.sonar.db.DbTester;
@@ -45,10 +42,10 @@ import org.sonar.server.tester.UserSessionRule;
 import static java.util.Collections.emptyList;
 import static org.assertj.core.api.Assertions.assertThat;
 
-public class ComponentIndexTest {
+public abstract class ComponentIndexTest {
 
-  private static final Integer TEST_USER_ID = 42;
-  private static final String TEST_USER_GROUP = "TestUsers";
+  protected static final Integer TEST_USER_ID = 42;
+  protected static final String TEST_USER_GROUP = "TestUsers";
 
   @Rule
   public EsTester es = new EsTester(new ComponentIndexDefinition(new MapSettings()));
@@ -64,8 +61,8 @@ public class ComponentIndexTest {
 
   protected PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es);
 
-  private ComponentIndex index;
-  private ComponentIndexer indexer;
+  protected ComponentIndex index;
+  protected ComponentIndexer indexer;
   private OrganizationDto organization;
 
   @Before
@@ -75,313 +72,20 @@ public class ComponentIndexTest {
     organization = OrganizationTesting.newOrganizationDto();
   }
 
-  @Test
-  public void return_empty_list_if_no_fields_match_query() {
-    indexProject("struts", "Apache Struts");
-
-    assertThat(index.search(new ComponentIndexQuery("missing"))).isEmpty();
-  }
-
-  @Test
-  public void should_not_return_components_that_do_not_match_at_all() {
-    indexProject("banana", "Banana Project 1");
-
-    assertNoSearchResults("Apple");
-  }
-
-  @Test
-  public void search_projects_by_exact_name() {
-    ComponentDto struts = indexProject("struts", "Apache Struts");
-    indexProject("sonarqube", "SonarQube");
-
-    assertSearchResults("Apache Struts", struts);
-    assertSearchResults("APACHE STRUTS", struts);
-    assertSearchResults("APACHE struTS", struts);
-  }
-
-  @Test
-  public void search_file_with_long_name() {
-    ComponentDto project = indexProject("struts", "Apache Struts");
-    ComponentDto file1 = indexFile(project, "src/main/java/DefaultRubyComponentServiceTestManagerFactory.java", "DefaultRubyComponentServiceTestManagerFactory.java");
-
-    assertSearchResults("DefaultRubyComponentServiceTestManagerFactory", file1);
-    assertSearchResults("DefaultRubyComponentServiceTestManagerFactory.java", file1);
-    assertSearchResults("RubyComponentServiceTestManager", file1);
-    assertSearchResults("te", file1);
-  }
-
-  @Test
-  public void should_search_by_name_with_two_characters() {
-    ComponentDto project = indexProject("struts", "Apache Struts");
-
-    assertSearchResults("st", project);
-    assertSearchResults("tr", project);
-  }
-
-  @Test
-  public void search_projects_by_partial_name() {
-    ComponentDto struts = indexProject("struts", "Apache Struts");
-
-    assertSearchResults("truts", struts);
-    assertSearchResults("pache", struts);
-    assertSearchResults("apach", struts);
-    assertSearchResults("che stru", struts);
-  }
-
-  @Test
-  public void search_projects_and_files_by_partial_name() {
-    ComponentDto project = indexProject("struts", "Apache Struts");
-    ComponentDto file1 = indexFile(project, "src/main/java/StrutsManager.java", "StrutsManager.java");
-    indexFile(project, "src/main/java/Foo.java", "Foo.java");
-
-    assertSearchResults("struts", project, file1);
-    assertSearchResults("Struts", project, file1);
-    assertSearchResults("StrutsManager", file1);
-    assertSearchResults("STRUTSMAN", file1);
-    assertSearchResults("utsManag", file1);
-  }
-
-  @Test
-  public void should_find_file_by_file_extension() {
-    ComponentDto project = indexProject("struts", "Apache Struts");
-    ComponentDto file1 = indexFile(project, "src/main/java/StrutsManager.java", "StrutsManager.java");
-    ComponentDto file2 = indexFile(project, "src/main/java/Foo.java", "Foo.java");
-
-    assertSearchResults(".java", file1, file2);
-    assertSearchResults("manager.java", file1);
-
-    // do not match
-    assertNoSearchResults("somethingStrutsManager.java");
-  }
-
-  @Test
-  public void should_search_projects_by_exact_case_insensitive_key() {
-    ComponentDto project1 = indexProject("keyOne", "Project One");
-    indexProject("keyTwo", "Project Two");
-
-    assertSearchResults("keyOne", project1);
-    assertSearchResults("keyone", project1);
-    assertSearchResults("KEYone", project1);
-  }
-
-  @Test
-  public void should_search_project_with_dot_in_key() {
-    ComponentDto project = indexProject("org.sonarqube", "SonarQube");
-
-    assertSearchResults("org.sonarqube", project);
-    assertNoSearchResults("orgsonarqube");
-  }
-
-  @Test
-  public void should_search_project_with_dash_in_key() {
-    ComponentDto project = indexProject("org-sonarqube", "SonarQube");
-
-    assertSearchResults("org-sonarqube", project);
-    assertNoSearchResults("orgsonarqube");
-  }
-
-  @Test
-  public void should_search_project_with_colon_in_key() {
-    ComponentDto project = indexProject("org:sonarqube", "Quality Product");
-
-    assertSearchResults("org:sonarqube", project);
-    assertNoSearchResults("orgsonarqube");
-    assertNoSearchResults("org-sonarqube");
-    assertNoSearchResults("org_sonarqube");
-  }
-
-  @Test
-  public void should_search_project_with_all_special_characters_in_key() {
-    ComponentDto project = indexProject("org.sonarqube:sonar-sérvèr_ç", "SonarQube");
-
-    assertSearchResults("org.sonarqube:sonar-sérvèr_ç", project);
-  }
-
-  @Test
-  public void should_not_return_results_when_searching_by_partial_key() {
-    indexProject("theKey", "some name");
-
-    assertNoSearchResults("theke");
-    assertNoSearchResults("hekey");
-  }
-
-  @Test
-  public void filter_results_by_qualifier() {
-    ComponentDto project = indexProject("struts", "Apache Struts");
-    indexFile(project, "src/main/java/StrutsManager.java", "StrutsManager.java");
-
-    assertSearchResults(new ComponentIndexQuery("struts").setQualifier(Qualifiers.PROJECT), project);
-  }
-
-  @Test
-  public void should_prefer_key_matching_over_name_matching() {
-    ComponentDto project1 = indexProject("quality", "SonarQube");
-    ComponentDto project2 = indexProject("sonarqube", "Quality Product");
-
-    assertExactResults("sonarqube", project2, project1);
-  }
-
-  @Test
-  public void should_limit_the_number_of_results() {
-    IntStream.rangeClosed(0, 10).forEach(i -> indexProject("sonarqube" + i, "SonarQube" + i));
-
-    assertSearch(new ComponentIndexQuery("sonarqube").setLimit(5)).hasSize(5);
-  }
-
-  @Test
-  public void should_not_support_wildcards() {
-    indexProject("theKey", "the name");
-
-    assertNoSearchResults("*t*");
-    assertNoSearchResults("th?Key");
-  }
-
-  @Test
-  public void should_find_item_despite_missing_character() {
-    ComponentDto project = indexProject("key-1", "SonarQube");
-
-    assertSearchResults("SonrQube", project);
-  }
-
-  @Test
-  public void should_find_item_despite_missing_character_and_lowercase() {
-    ComponentDto project = indexProject("key-1", "SonarQube");
-
-    assertSearchResults("sonrqube", project);
-  }
-
-  @Test
-  public void should_find_item_despite_two_missing_characters_and_lowercase() {
-    ComponentDto project = indexProject("key-1", "SonarQube");
-
-    assertSearchResults("sonqube", project);
-  }
-
-  @Test
-  public void should_search_for_word_and_suffix() {
-    assertFileMatches("plugin java", "AbstractPluginFactory.java");
-  }
-
-  @Test
-  public void should_search_for_word_and_suffix_in_any_order() {
-    assertFileMatches("java plugin", "AbstractPluginFactory.java");
-  }
-
-  @Test
-  public void should_search_for_two_words() {
-    assertFileMatches("abstract factory", "AbstractPluginFactory.java");
-  }
-
-  @Test
-  public void should_search_for_two_words_in_any_order() {
-    assertFileMatches("factory abstract", "AbstractPluginFactory.java");
-  }
-
-  @Test
-  public void should_find_item_with_at_least_one_matching_word() {
-    assertFileMatches("abstract object", "AbstractPluginFactory.java");
-  }
-
-  @Test
-  public void should_require_at_least_one_matching_word() {
-    assertNoFileMatches("monitor object", "AbstractPluginFactory.java");
-  }
-
-  @Test
-  public void should_order_results_by_score() {
-    assertResultOrder("struts",
-      "Struts",
-      "Apache Struts",
-      "Apache Struts Two");
-  }
-
-  @Test
-  public void should_score_fuzzy_results() {
-    assertResultOrder("corem",
-      "CoreMetrics.java",
-      "ScoreMatrix.java");
-  }
-
-  @Test
-  public void should_prefer_components_without_prefix() {
-    assertResultOrder("File.java",
-      "File.java",
-      "MyFile.java");
-  }
-
-  @Test
-  public void should_prefer_components_without_suffix() {
-    assertResultOrder("File",
-      "File",
-      "Filex");
-  }
-
-  @Test
-  public void missing_characters_should_reduce_score() {
-    assertResultOrder("SonarQube.java",
-      "sonarqube.java",
-      "sonaqube.java",
-      "sonqube.java");
-  }
-
-  @Test
-  public void should_respect_confidentiallity() {
-    indexer.index(newProject("sonarqube", "Quality Product"));
-
-    // do not give any permissions to that project
-
-    assertNoSearchResults("sonarqube");
-    assertNoSearchResults("Quality Product");
-  }
-
-  @Test
-  public void should_find_project_for_which_the_user_has_direct_permission() {
-    login();
-
-    ComponentDto project = newProject("sonarqube", "Quality Product");
-    indexer.index(project);
-
-    // give the user explicit access
-    authorizationIndexerTester.indexProjectPermission(project.uuid(),
-      emptyList(),
-      Collections.singletonList((long) TEST_USER_ID));
-
-    assertSearchResults("sonarqube", project);
-  }
-
-  @Test
-  public void should_find_project_for_which_the_user_has_indirect_permission_through_group() {
-    login();
-
-    ComponentDto project = newProject("sonarqube", "Quality Product");
-    indexer.index(project);
-
-    // give the user implicit access (though group)
-    authorizationIndexerTester.indexProjectPermission(project.uuid(),
-      Collections.singletonList(TEST_USER_GROUP),
-      emptyList());
-
-    assertSearchResults("sonarqube", project);
-  }
-
-  private void login() {
-    userSession.login("john").setUserId(TEST_USER_ID).setUserGroups(TEST_USER_GROUP);
-  }
-
-  private void assertFileMatches(String query, String... fileNames) {
+  protected void assertFileMatches(String query, String... fileNames) {
     ComponentDto[] files = Arrays.stream(fileNames)
       .map(this::indexFile)
       .toArray(ComponentDto[]::new);
     assertSearch(query).containsExactlyInAnyOrder(uuids(files));
   }
 
-  private void assertNoFileMatches(String query, String... fileNames) {
+  protected void assertNoFileMatches(String query, String... fileNames) {
     Arrays.stream(fileNames)
       .forEach(this::indexFile);
     assertSearch(query).isEmpty();
   }
 
-  private void assertResultOrder(String query, String... resultsInOrder) {
+  protected void assertResultOrder(String query, String... resultsInOrder) {
     ComponentDto project = indexProject("key-1", "Quality Product");
     List<ComponentDto> files = Arrays.stream(resultsInOrder)
       .map(r -> ComponentTesting.newFileDto(project).setName(r))
@@ -396,7 +100,7 @@ public class ComponentIndexTest {
     assertExactResults(query, files.toArray(new ComponentDto[0]));
   }
 
-  private AbstractListAssert<?, ? extends List<? extends String>, String> assertSearch(String query) {
+  protected AbstractListAssert<?, ? extends List<? extends String>, String> assertSearch(String query) {
     return assertSearch(new ComponentIndexQuery(query));
   }
 
@@ -404,41 +108,41 @@ public class ComponentIndexTest {
     return assertThat(index.search(query, features.get()));
   }
 
-  private void assertSearchResults(String query, ComponentDto... expectedComponents) {
+  protected void assertSearchResults(String query, ComponentDto... expectedComponents) {
     assertSearchResults(new ComponentIndexQuery(query), expectedComponents);
   }
 
-  private void assertSearchResults(ComponentIndexQuery query, ComponentDto... expectedComponents) {
+  protected void assertSearchResults(ComponentIndexQuery query, ComponentDto... expectedComponents) {
     assertSearch(query).containsOnly(uuids(expectedComponents));
   }
 
-  private void assertExactResults(String query, ComponentDto... expectedComponents) {
+  protected void assertExactResults(String query, ComponentDto... expectedComponents) {
     assertSearch(query).containsExactly(uuids(expectedComponents));
   }
 
-  private void assertNoSearchResults(String query) {
+  protected void assertNoSearchResults(String query) {
     assertSearchResults(query);
   }
 
-  private ComponentDto indexProject(String key, String name) {
+  protected ComponentDto indexProject(String key, String name) {
     return index(
       ComponentTesting.newProjectDto(organization, "UUID_" + key)
         .setKey(key)
         .setName(name));
   }
 
-  private ComponentDto newProject(String key, String name) {
+  protected ComponentDto newProject(String key, String name) {
     return ComponentTesting.newProjectDto(organization, "UUID_" + key)
       .setKey(key)
       .setName(name);
   }
 
-  private ComponentDto indexFile(String fileName) {
+  protected ComponentDto indexFile(String fileName) {
     ComponentDto project = indexProject("key-1", "SonarQube");
     return indexFile(project, "src/main/java/" + fileName, fileName);
   }
 
-  private ComponentDto indexFile(ComponentDto project, String fileKey, String fileName) {
+  protected ComponentDto indexFile(ComponentDto project, String fileKey, String fileName) {
     return index(
       ComponentTesting.newFileDto(project)
         .setKey(fileKey)
@@ -453,7 +157,7 @@ public class ComponentIndexTest {
     return dto;
   }
 
-  private static String[] uuids(ComponentDto... expectedComponents) {
+  protected static String[] uuids(ComponentDto... expectedComponents) {
     return Arrays.stream(expectedComponents).map(ComponentDto::uuid).toArray(String[]::new);
   }
 }