import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
+import org.sonar.api.resources.ResourceType;
+import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Arrays.stream;
+import static java.util.Collections.emptyList;
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import static org.sonar.api.web.UserRole.USER;
private final ComponentIndex index;
private final FavoriteFinder favoriteFinder;
private final UserSession userSession;
+ private final ResourceTypes resourceTypes;
private DbClient dbClient;
- public SuggestionsAction(DbClient dbClient, ComponentIndex index, FavoriteFinder favoriteFinder, UserSession userSession) {
+ public SuggestionsAction(DbClient dbClient, ComponentIndex index, FavoriteFinder favoriteFinder, UserSession userSession, ResourceTypes resourceTypes) {
this.dbClient = dbClient;
this.index = index;
this.favoriteFinder = favoriteFinder;
this.userSession = userSession;
+ this.resourceTypes = resourceTypes;
}
@Override
return Arrays.stream(query.split(DefaultIndexSettings.SEARCH_TERM_TOKENIZER_PATTERN));
}
- private static List<String> getQualifiers(@Nullable String more) {
+ private List<String> getQualifiers(@Nullable String more) {
+ Set<String> availableQualifiers = resourceTypes.getAll().stream().map(ResourceType::getQualifier).collect(MoreCollectors.toSet());
if (more == null) {
- return stream(SuggestionCategory.values()).map(SuggestionCategory::getQualifier).collect(Collectors.toList());
+ return stream(SuggestionCategory.values())
+ .map(SuggestionCategory::getQualifier)
+ .filter(availableQualifiers::contains)
+ .collect(Collectors.toList());
}
- return singletonList(SuggestionCategory.getByName(more).getQualifier());
+
+ String qualifier = SuggestionCategory.getByName(more).getQualifier();
+ return availableQualifiers.contains(qualifier) ?
+ singletonList(qualifier)
+ : emptyList();
}
private SuggestionsWsResponse.Builder buildResponse(Set<String> recentlyBrowsedKeys, Set<String> favoriteUuids, ComponentIndexResults componentsPerQualifiers,
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
+import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.component.index.ComponentIndex;
import org.sonar.server.component.index.ComponentIndexDefinition;
import static org.assertj.core.groups.Tuple.tuple;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
+import static org.sonar.api.resources.Qualifiers.FILE;
+import static org.sonar.api.resources.Qualifiers.MODULE;
+import static org.sonar.api.resources.Qualifiers.PROJECT;
+import static org.sonar.api.resources.Qualifiers.SUBVIEW;
+import static org.sonar.api.resources.Qualifiers.VIEW;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.db.component.ComponentTesting.newModuleDto;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonarqube.ws.WsComponents.SuggestionsWsResponse.Organization;
public class SuggestionsActionTest {
+ private static final String[] SUGGESTION_QUALIFIERS = Stream.of(SuggestionCategory.values())
+ .map(SuggestionCategory::getQualifier)
+ .collect(MoreCollectors.toList()).toArray(new String[0]);
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
public EsTester es = new EsTester(new ComponentIndexDefinition(new MapSettings()));
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ public ResourceTypesRule resourceTypes = new ResourceTypesRule();
private ComponentIndexer componentIndexer = new ComponentIndexer(db.getDbClient(), es.client());
private FavoriteFinder favoriteFinder = mock(FavoriteFinder.class);
private ComponentIndex index = new ComponentIndex(es.client(), new AuthorizationTypeSupport(userSessionRule));
- private SuggestionsAction underTest = new SuggestionsAction(db.getDbClient(), index, favoriteFinder, userSessionRule);
+ private SuggestionsAction underTest = new SuggestionsAction(db.getDbClient(), index, favoriteFinder, userSessionRule, resourceTypes);
private OrganizationDto organization;
private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es, componentIndexer);
private WsActionTester ws = new WsActionTester(underTest);
@Before
public void setUp() {
organization = db.organizations().insert();
+ resourceTypes.setAllQualifiers(SUGGESTION_QUALIFIERS);
}
@Test
assertThat(response.getResultsList())
.filteredOn(q -> q.getItemsCount() > 0)
.extracting(Category::getQ)
- .containsExactly(Qualifiers.PROJECT);
+ .containsExactly(PROJECT);
// assert correct id to be found
assertThat(response.getResultsList())
assertThat(response.getResultsList())
.filteredOn(q -> q.getItemsCount() > 0)
.extracting(Category::getQ)
- .containsExactly(Qualifiers.PROJECT);
+ .containsExactly(PROJECT);
// assert correct id to be found
assertThat(response.getResultsList())
assertThat(response.getResultsList())
.filteredOn(q -> q.getItemsCount() > 0)
.extracting(Category::getQ)
- .containsExactly(Qualifiers.PROJECT);
+ .containsExactly(PROJECT);
// assert correct id to be found
assertThat(response.getResultsList())
.containsExactlyInAnyOrder(tuple("VW", 0), tuple("SVW", 0), tuple("TRK", 1), tuple("BRC", 0), tuple("FIL", 0), tuple("UTS", 0));
}
+ @Test
+ public void suggestions_should_filter_allowed_qualifiers() {
+ resourceTypes.setAllQualifiers(PROJECT, MODULE, FILE);
+ ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
+ componentIndexer.indexProject(project.projectUuid(), ProjectIndexer.Cause.PROJECT_CREATION);
+ userSessionRule.addProjectPermission(USER, project);
+
+ SuggestionsWsResponse response = ws.newRequest()
+ .setMethod("POST")
+ .setParam(PARAM_RECENTLY_BROWSED, project.key())
+ .executeProtobuf(SuggestionsWsResponse.class);
+
+ assertThat(response.getResultsList())
+ .extracting(Category::getQ)
+ .containsExactlyInAnyOrder(PROJECT, MODULE, FILE);
+ }
+
@Test
public void exact_match_in_one_qualifier() throws Exception {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
assertThat(response.getResultsList())
.filteredOn(q -> q.getItemsCount() > 0)
.extracting(Category::getQ)
- .containsExactly(Qualifiers.PROJECT);
+ .containsExactly(PROJECT);
// assert correct id to be found
assertThat(response.getResultsList())
check_proposal_to_show_more_results(27, 20, 1L, SuggestionCategory.PROJECT, false);
}
+ @Test
+ public void show_more_results_filter_out_if_non_allowed_qualifiers() {
+ resourceTypes.setAllQualifiers(VIEW, SUBVIEW);
+
+ check_proposal_to_show_more_results(10, 0, 0L, SuggestionCategory.PROJECT, true);
+ }
+
private void check_proposal_to_show_more_results(int numberOfProjects, int expectedNumberOfResults, long expectedNumberOfMoreResults, @Nullable SuggestionCategory more,
boolean useQuery) {
String namePrefix = "MyProject";