public class ActivityAction implements CeWsAction {
private static final int MAX_PAGE_SIZE = 1000;
- private static final List<String> POSSIBLE_QUALIFIERS = ImmutableList.of(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV", Qualifiers.MODULE);
+ private static final List<String> POSSIBLE_QUALIFIERS = ImmutableList.of(Qualifiers.PROJECT, Qualifiers.APP, Qualifiers.VIEW, "DEV", Qualifiers.MODULE);
private final UserSession userSession;
private final DbClient dbClient;
/**
* The concept of "visibility" will only be configured for these qualifiers.
*/
- private static final Set<String> QUALIFIERS_WITH_VISIBILITY = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW);
+ private static final Set<String> QUALIFIERS_WITH_VISIBILITY = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.APP);
private ComponentDtoToWsComponent() {
// prevent instantiation
public enum SuggestionCategory {
VIEW(Qualifiers.VIEW),
SUBVIEW(Qualifiers.SUBVIEW),
+ APP(Qualifiers.APP),
PROJECT(Qualifiers.PROJECT),
MODULE(Qualifiers.MODULE),
FILE(Qualifiers.FILE),
.setSince("4.2")
.setInternal(true)
.setHandler(this)
- .setResponseExample(Resources.getResource(this.getClass(), "components-example-suggestions.json"))
+ .setResponseExample(Resources.getResource(this.getClass(), "suggestions-example.json"))
.setChangelog(new Change("6.4", "Parameter 's' is optional"));
action.createParam(PARAM_QUERY)
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.BooleanUtils;
switch (qualifier) {
case Qualifiers.VIEW:
case Qualifiers.SUBVIEW:
+ case Qualifiers.APP:
addViewsOrSubViews(builder, componentUuids);
break;
case Qualifiers.PROJECT:
}
private void addViewsOrSubViews(IssueQuery.Builder builder, Collection<String> viewOrSubViewUuids) {
- List<String> filteredViewUuids = new ArrayList<>();
- for (String viewUuid : viewOrSubViewUuids) {
- if (userSession.hasComponentUuidPermission(UserRole.USER, viewUuid)) {
- filteredViewUuids.add(viewUuid);
- }
- }
+ List<String> filteredViewUuids = viewOrSubViewUuids.stream()
+ .filter(uuid -> userSession.hasComponentUuidPermission(UserRole.USER, uuid))
+ .collect(Collectors.toList());
+
if (filteredViewUuids.isEmpty()) {
filteredViewUuids.add(UNKNOWN);
}
import static java.util.Comparator.comparing;
import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;
+import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.SUBVIEW;
import static org.sonar.api.resources.Qualifiers.VIEW;
public class SearchAction implements MeasuresWsAction {
- private static final Set<String> ALLOWED_QUALIFIERS = ImmutableSet.of(PROJECT, VIEW, SUBVIEW);
+ private static final Set<String> ALLOWED_QUALIFIERS = ImmutableSet.of(PROJECT, APP, VIEW, SUBVIEW);
private final UserSession userSession;
private final DbClient dbClient;
" FROM projects " +
" INNER JOIN user_roles ON user_roles.resource_id = projects.id AND user_roles.role = 'user' " +
" WHERE " +
- " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " +
+ " (projects.qualifier = 'TRK' " +
+ " or projects.qualifier = 'VW' " +
+ " or projects.qualifier = 'APP') " +
" AND projects.copy_component_uuid is NULL " +
" {projectsCondition} " +
" UNION " +
" INNER JOIN group_roles ON group_roles.resource_id = projects.id AND group_roles.role = 'user' " +
" INNER JOIN groups ON groups.id = group_roles.group_id " +
" WHERE " +
- " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " +
+ " (projects.qualifier = 'TRK' " +
+ " or projects.qualifier = 'VW' " +
+ " or projects.qualifier = 'APP') " +
" AND projects.copy_component_uuid is NULL " +
" {projectsCondition} " +
" AND group_id IS NOT NULL " +
" NULL AS group_id " +
" FROM projects " +
" WHERE " +
- " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " +
+ " (projects.qualifier = 'TRK' " +
+ " or projects.qualifier = 'VW' " +
+ " or projects.qualifier = 'APP') " +
" AND projects.copy_component_uuid is NULL " +
" AND projects.private = ? " +
" {projectsCondition} " +
" NULL AS group_id " +
" FROM projects " +
" WHERE " +
- " (projects.qualifier = 'TRK' or projects.qualifier = 'VW') " +
+ " (projects.qualifier = 'TRK' " +
+ " or projects.qualifier = 'VW' " +
+ " or projects.qualifier = 'APP') " +
" AND projects.copy_component_uuid is NULL " +
" AND projects.private = ? " +
" {projectsCondition} " +
this.dataLoader = dataLoader;
}
+ @Override
+ public void define(WebService.NewController context) {
+ WebService.NewAction action = context.createAction("search_templates")
+ .setDescription("List permission templates.<br />" +
+ "Requires the following permission: 'Administer System'.")
+ .setResponseExample(getClass().getResource("search_templates-example.json"))
+ .setSince("5.2")
+ .addSearchQuery("defau", "permission template names")
+ .setHandler(this);
+
+ createOrganizationParameter(action).setSince("6.2");
+ }
+
+ @Override
+ public void handle(Request wsRequest, Response wsResponse) throws Exception {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ OrganizationDto org = support.findOrganization(dbSession, wsRequest.param(PARAM_ORGANIZATION));
+ SearchTemplatesWsRequest request = new SearchTemplatesWsRequest()
+ .setOrganizationUuid(org.getUuid())
+ .setQuery(wsRequest.param(Param.TEXT_QUERY));
+ checkGlobalAdmin(userSession, request.getOrganizationUuid());
+
+ SearchTemplatesWsResponse searchTemplatesWsResponse = buildResponse(dataLoader.load(dbSession, request));
+ writeProtobuf(searchTemplatesWsResponse, wsRequest, wsResponse);
+ }
+ }
+
private static void buildDefaultTemplatesResponse(SearchTemplatesWsResponse.Builder response, SearchTemplatesData data) {
TemplateIdQualifier.Builder templateUuidQualifierBuilder = TemplateIdQualifier.newBuilder();
}
}
- @Override
- public void define(WebService.NewController context) {
- WebService.NewAction action = context.createAction("search_templates")
- .setDescription("List permission templates.<br />" +
- "Requires the following permission: 'Administer System'.")
- .setResponseExample(getClass().getResource("search_templates-example.json"))
- .setSince("5.2")
- .addSearchQuery("defau", "permission template names")
- .setHandler(this);
-
- createOrganizationParameter(action).setSince("6.2");
- }
-
- @Override
- public void handle(Request wsRequest, Response wsResponse) throws Exception {
- try (DbSession dbSession = dbClient.openSession(false)) {
- OrganizationDto org = support.findOrganization(dbSession, wsRequest.param(PARAM_ORGANIZATION));
- SearchTemplatesWsRequest request = new SearchTemplatesWsRequest()
- .setOrganizationUuid(org.getUuid())
- .setQuery(wsRequest.param(Param.TEXT_QUERY));
- checkGlobalAdmin(userSession, request.getOrganizationUuid());
-
- SearchTemplatesWsResponse searchTemplatesWsResponse = buildResponse(dataLoader.load(dbSession, request));
- writeProtobuf(searchTemplatesWsResponse, wsRequest, wsResponse);
- }
- }
-
private WsPermissions.SearchTemplatesWsResponse buildResponse(SearchTemplatesData data) {
SearchTemplatesWsResponse.Builder response = SearchTemplatesWsResponse.newBuilder();
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateQualifier;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters;
import static org.sonar.server.permission.ws.template.WsTemplateRef.newTemplateRef;
-import static org.sonar.server.ws.WsParameterBuilder.createRootQualifierParameter;
import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
+import static org.sonar.server.ws.WsParameterBuilder.createDefaultTemplateQualifierParameter;
import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_QUALIFIER;
.setHandler(this);
createTemplateParameters(action);
- createRootQualifierParameter(action, newQualifierParameterContext(i18n, resourceTypes))
+ createDefaultTemplateQualifierParameter(action, newQualifierParameterContext(i18n, resourceTypes))
.setDefaultValue(Qualifiers.PROJECT);
}
import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Optional.ofNullable;
+import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.VIEW;
import static org.sonar.core.util.Protobuf.setNullable;
action.createParam(PARAM_QUALIFIERS)
.setDescription("Comma-separated list of component qualifiers. Filter the results with the specified qualifiers")
- .setPossibleValues(PROJECT, VIEW)
+ .setPossibleValues(PROJECT, VIEW, APP)
.setDefaultValue(PROJECT);
support.addOrganizationParam(action);
*/
package org.sonar.server.project.ws;
-import com.google.common.collect.ImmutableSet;
-import java.util.Set;
import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.resources.Scopes;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_VISIBILITY;
public class UpdateVisibilityAction implements ProjectsWsAction {
- private static final Set<String> ALLOWED_QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW);
-
private final DbClient dbClient;
private final ComponentFinder componentFinder;
private final UserSession userSession;
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction(ProjectsWsParameters.ACTION_UPDATE_VISIBILITY)
- .setDescription("Updates visibility of a project or a view.<br/>" +
- "Requires 'Project administer' permission on the specified project or view")
+ .setDescription("Updates visibility of a project.<br>" +
+ "Requires 'Project administer' permission on the specified project")
.setSince("6.4")
.setPost(true)
.setHandler(this);
action.createParam(PARAM_PROJECT)
- .setDescription("Project or view key")
+ .setDescription("Project key")
.setExampleValue(KEY_PROJECT_EXAMPLE_001)
.setRequired(true);
action.createParam(PARAM_VISIBILITY)
- .setDescription("new visibility of the project or view")
+ .setDescription("New visibility")
.setPossibleValues(Visibility.getLabels())
.setRequired(true);
}
try (DbSession dbSession = dbClient.openSession(false)) {
ComponentDto component = componentFinder.getByKey(dbSession, projectKey);
- checkRequest(isRoot(component), "Component must either be a project or a view");
- checkRequest(!changeToPrivate || !Qualifiers.VIEW.equals(component.qualifier()), "Views can't be made private");
+ checkRequest(component.isRootProject() && Qualifiers.PROJECT.equals(component.qualifier()), "Component must be a project");
userSession.checkComponentPermission(UserRole.ADMIN, component);
checkRequest(noPendingTask(dbSession, component), "Component visibility can't be changed as long as it has background task(s) pending or in progress");
}
}
- private static boolean isRoot(ComponentDto component) {
- return Scopes.PROJECT.equals(component.scope()) && ALLOWED_QUALIFIERS.contains(component.qualifier());
- }
-
private boolean noPendingTask(DbSession dbSession, ComponentDto rootComponent) {
return dbClient.ceQueueDao().selectByComponentUuid(dbSession, rootComponent.uuid()).isEmpty();
}
};
}
- private static final Set<String> SUPPORTED_QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.MODULE, Qualifiers.SUBVIEW);
+ private static final Set<String> SUPPORTED_QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.APP, Qualifiers.MODULE, Qualifiers.SUBVIEW);
public Consumer<SettingData> qualifier() {
return data -> {
/**
* The concept of "visibility" will only be configured for these qualifiers.
*/
- private static final Set<String> QUALIFIERS_WITH_VISIBILITY = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW);
+ private static final Set<String> QUALIFIERS_WITH_VISIBILITY = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.APP);
private final DbClient dbClient;
private final PageRepository pageRepository;
private void writeConfigPageAccess(JsonWriter json, boolean isProjectAdmin, ComponentDto component, OrganizationDto organization) {
boolean isProject = Qualifiers.PROJECT.equals(component.qualifier());
boolean showManualMeasures = isProjectAdmin && !Qualifiers.DIRECTORY.equals(component.qualifier());
- boolean showBackgroundTasks = isProjectAdmin && (isProject || Qualifiers.VIEW.equals(component.qualifier()));
+ boolean showBackgroundTasks = isProjectAdmin && (isProject || Qualifiers.VIEW.equals(component.qualifier()) || Qualifiers.APP.equals(component.qualifier()));
boolean isQualityProfileAdmin = userSession.hasPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, component.getOrganizationUuid());
boolean isQualityGateAdmin = userSession.hasPermission(OrganizationPermission.ADMINISTER_QUALITY_GATES, component.getOrganizationUuid());
boolean isOrganizationAdmin = userSession.hasPermission(OrganizationPermission.ADMINISTER, component.getOrganizationUuid());
*/
package org.sonar.server.ws;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableSet;
import java.util.Locale;
import java.util.Set;
-import javax.annotation.Nullable;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.ResourceType;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.server.ws.WebService;
-import static com.google.common.base.Predicates.not;
-import static com.google.common.collect.FluentIterable.from;
-import static com.google.common.collect.Ordering.natural;
import static java.lang.String.format;
public class WsParameterBuilder {
private static final String PARAM_QUALIFIER = "qualifier";
private static final String PARAM_QUALIFIERS = "qualifiers";
- private static final Set<String> DEPRECATED_QUALIFIERS = ImmutableSet.of(Qualifiers.LIBRARY);
private WsParameterBuilder() {
// static methods only
.setPossibleValues(getRootQualifiers(context.getResourceTypes()));
}
+ public static WebService.NewParam createDefaultTemplateQualifierParameter(WebService.NewAction action, QualifierParameterContext context) {
+ return action.createParam(PARAM_QUALIFIER)
+ .setDescription("Project qualifier. Filter the results with the specified qualifier. Possible values are:" + buildDefaultTemplateQualifiersDescription(context))
+ .setPossibleValues(getDefaultTemplateQualifiers(context.getResourceTypes()));
+ }
+
public static WebService.NewParam createQualifiersParameter(WebService.NewAction action, QualifierParameterContext context) {
return action.createParam(PARAM_QUALIFIERS)
.setDescription(
}
private static Set<String> getRootQualifiers(ResourceTypes resourceTypes) {
- return from(resourceTypes.getRoots())
- .transform(ResourceType::getQualifier)
- .filter(not(IsDeprecatedQualifier.INSTANCE))
- .toSortedSet(natural());
+ return resourceTypes.getRoots().stream()
+ .map(ResourceType::getQualifier)
+ .collect(Collectors.toCollection(TreeSet::new));
+ }
+
+ private static Set<String> getDefaultTemplateQualifiers(ResourceTypes resourceTypes) {
+ return resourceTypes.getRoots().stream()
+ .map(ResourceType::getQualifier)
+ .filter(q -> !Qualifiers.APP.equals(q))
+ .collect(Collectors.toCollection(TreeSet::new));
}
private static Set<String> getAllQualifiers(ResourceTypes resourceTypes) {
- return from(resourceTypes.getAll())
- .transform(ResourceType::getQualifier)
- .filter(not(IsDeprecatedQualifier.INSTANCE))
- .toSortedSet(natural());
+ return resourceTypes.getAll().stream()
+ .map(ResourceType::getQualifier)
+ .collect(Collectors.toCollection(TreeSet::new));
+ }
+
+ private static String buildDefaultTemplateQualifiersDescription(QualifierParameterContext context) {
+ return buildQualifiersDescription(context, getDefaultTemplateQualifiers(context.getResourceTypes()));
}
private static String buildRootQualifiersDescription(QualifierParameterContext context) {
return context.getI18n().message(Locale.ENGLISH, qualifiersPropertyPrefix + qualifier, "no description available");
}
- private enum IsDeprecatedQualifier implements Predicate<String> {
- INSTANCE;
-
- @Override
- public boolean apply(@Nullable String input) {
- return DEPRECATED_QUALIFIERS.contains(input);
- }
- }
-
public static class QualifierParameterContext {
private final I18n i18n;
private final ResourceTypes resourceTypes;
+++ /dev/null
-{
- "results": [
- {
- "q": "VW",
- "items": [],
- "more": 0
- },
- {
- "q": "SVW",
- "items": [],
- "more": 0
- },
- {
- "q": "TRK",
- "items": [
- {
- "key": "org.sonarsource:sonarqube",
- "name": "SonarSource :: SonarQube",
- "match": "<mark>Sonar</mark>Source :: <mark>Sonar</mark>Qube",
- "organization": "default-organization",
- "project": "",
- "isRecentlyBrowsed": true,
- "isFavorite": false
- },
- {
- "key": "org.sonarsource:sonarlint",
- "name": "SonarSource :: SonarLint",
- "match": "<mark>Sonar</mark>Source :: <mark>Sonar</mark>Lint",
- "organization": "default-organization",
- "project": "",
- "isRecentlyBrowsed": false,
- "isFavorite": false
- }
- ],
- "more": 0
- },
- {
- "q": "BRC",
- "items": [],
- "more": 0
- },
- {
- "q": "FIL",
- "items": [],
- "more": 0
- },
- {
- "q": "UTS",
- "items": [],
- "more": 0
- }
- ],
- "organizations": [
- {
- "key": "default-organization",
- "name": "Default Organization"
- }
- ],
- "projects": [
- ]
-}
--- /dev/null
+{
+ "results": [
+ {
+ "q": "VW",
+ "items": [],
+ "more": 0
+ },
+ {
+ "q": "SVW",
+ "items": [],
+ "more": 0
+ },
+ {
+ "q": "APP",
+ "items": [],
+ "more": 0
+ },
+ {
+ "q": "TRK",
+ "items": [
+ {
+ "key": "org.sonarsource:sonarqube",
+ "name": "SonarSource :: SonarQube",
+ "match": "<mark>Sonar</mark>Source :: <mark>Sonar</mark>Qube",
+ "organization": "default-organization",
+ "project": "",
+ "isRecentlyBrowsed": true,
+ "isFavorite": false
+ },
+ {
+ "key": "org.sonarsource:sonarlint",
+ "name": "SonarSource :: SonarLint",
+ "match": "<mark>Sonar</mark>Source :: <mark>Sonar</mark>Lint",
+ "organization": "default-organization",
+ "project": "",
+ "isRecentlyBrowsed": false,
+ "isFavorite": false
+ }
+ ],
+ "more": 0
+ },
+ {
+ "q": "BRC",
+ "items": [],
+ "more": 0
+ },
+ {
+ "q": "FIL",
+ "items": [],
+ "more": 0
+ },
+ {
+ "q": "UTS",
+ "items": [],
+ "more": 0
+ }
+ ],
+ "organizations": [
+ {
+ "key": "default-organization",
+ "name": "Default Organization"
+ }
+ ],
+ "projects": [
+ ]
+}
String[][] allScopesAndQualifierButProjectAndModule = {
{Scopes.PROJECT, Qualifiers.VIEW},
{Scopes.PROJECT, Qualifiers.SUBVIEW},
+ {Scopes.PROJECT, Qualifiers.APP},
{Scopes.FILE, Qualifiers.PROJECT},
{Scopes.DIRECTORY, Qualifiers.DIRECTORY},
{Scopes.FILE, Qualifiers.UNIT_TEST_FILE},
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsCe;
import org.sonarqube.ws.WsCe.ActivityResponse;
+import org.sonarqube.ws.WsCe.Task;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.sonar.api.utils.DateUtils.formatDate;
import static org.sonar.api.utils.DateUtils.formatDateTime;
+import static org.sonar.db.component.ComponentTesting.newApplication;
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_ID;
import static org.sonarqube.ws.client.ce.CeWsParameters.PARAM_COMPONENT_QUERY;
assertThat(activityResponse.getTasksCount()).isEqualTo(2);
// chronological order, from newest to oldest
- WsCe.Task task = activityResponse.getTasks(0);
+ Task task = activityResponse.getTasks(0);
assertThat(task.getOrganization()).isEqualTo(org2.getKey());
assertThat(task.getId()).isEqualTo("T2");
assertThat(task.getStatus()).isEqualTo(WsCe.TaskStatus.FAILED);
assertThat(activityResponse.getTasksList()).extracting("id").containsOnly("T2");
}
+ @Test
+ public void search_activity_returns_application() {
+ OrganizationDto organizationDto = dbTester.organizations().insert();
+ ComponentDto apacheApp = newApplication(organizationDto).setName("Apache App");
+ dbTester.components().insertViewAndSnapshot(apacheApp);
+ logInAsSystemAdministrator();
+ insertActivity("T2", apacheApp.uuid(), CeActivityDto.Status.SUCCESS);
+
+ ActivityResponse activityResponse = call(ws.newRequest().setParam(PARAM_COMPONENT_QUERY, "apac"));
+
+ assertThat(activityResponse.getTasksList()).extracting(Task::getId).containsOnly("T2");
+ }
+
@Test
public void search_task_id_in_queue_ignoring_other_parameters() throws IOException {
logInAsSystemAdministrator();
assertThat(loaded.getKey()).isEqualTo("view-key");
assertThat(loaded.name()).isEqualTo("view-name");
assertThat(loaded.qualifier()).isEqualTo("VW");
- verify(projectIndexers).hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION);
+ assertThat(projectIndexers.hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION)).isTrue();
+ }
+
+ @Test
+ public void persist_and_index_when_creating_application() {
+ NewComponent view = NewComponent.newComponentBuilder()
+ .setKey("app-key")
+ .setName("app-name")
+ .setQualifier(APP)
+ .setOrganizationUuid(db.getDefaultOrganization().getUuid())
+ .build();
+
+ ComponentDto returned = underTest.create(db.getSession(), view, null);
+
+ ComponentDto loaded = db.getDbClient().componentDao().selectOrFailByUuid(db.getSession(), returned.uuid());
+ assertThat(loaded.getKey()).isEqualTo("app-key");
+ assertThat(loaded.name()).isEqualTo("app-name");
+ assertThat(loaded.qualifier()).isEqualTo("APP");
+ assertThat(projectIndexers.hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION)).isTrue();
}
@Test
assertThat(loaded.getKey()).isEqualTo("app-key");
assertThat(loaded.name()).isEqualTo("app-name");
assertThat(loaded.qualifier()).isEqualTo("APP");
- verify(projectIndexers).hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION);
+ assertThat(projectIndexers.hasBeenCalled(loaded.uuid(), ProjectIndexer.Cause.PROJECT_CREATION)).isTrue();
}
@Test
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
-import org.sonar.test.JsonAssert;
import org.sonarqube.ws.MediaTypes;
import org.sonarqube.ws.WsComponents.SuggestionsWsResponse;
import org.sonarqube.ws.WsComponents.SuggestionsWsResponse.Category;
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.APP;
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.server.component.ws.SuggestionsAction.PARAM_QUERY;
import static org.sonar.server.component.ws.SuggestionsAction.PARAM_RECENTLY_BROWSED;
import static org.sonar.server.component.ws.SuggestionsAction.SHORT_INPUT_WARNING;
+import static org.sonar.test.JsonAssert.assertJson;
public class SuggestionsActionTest {
private static final String[] SUGGESTION_QUALIFIERS = Stream.of(SuggestionCategory.values())
.setMediaType(MediaTypes.JSON)
.execute();
- JsonAssert.assertJson(ws.getDef().responseExampleAsString()).isSimilarTo(wsResponse.getInput());
+ assertJson(ws.getDef().responseExampleAsString()).isSimilarTo(wsResponse.getInput());
}
@Test
assertThat(response.getResultsList())
.extracting(Category::getQ, Category::getItemsCount)
- .containsExactlyInAnyOrder(tuple("VW", 0), tuple("SVW", 0), tuple("TRK", 1), tuple("BRC", 0), tuple("FIL", 0), tuple("UTS", 0));
+ .containsExactlyInAnyOrder(tuple("VW", 0), tuple("APP", 0), tuple("SVW", 0), tuple("TRK", 1), tuple("BRC", 0), tuple("FIL", 0), tuple("UTS", 0));
}
@Test
assertThat(response.getResultsList())
.extracting(Category::getQ, Category::getItemsCount)
- .containsExactlyInAnyOrder(tuple("VW", 0), tuple("SVW", 0), tuple("TRK", 1), tuple("BRC", 0), tuple("FIL", 0), tuple("UTS", 0));
+ .containsExactlyInAnyOrder(tuple("VW", 0), tuple("SVW", 0), tuple("APP", 0), tuple("TRK", 1), tuple("BRC", 0), tuple("FIL", 0), tuple("UTS", 0));
}
@Test
public void should_only_provide_project_for_certain_qualifiers() throws Exception {
String query = randomAlphabetic(10);
+ ComponentDto app = db.components().insertApplication(organization, v -> v.setName(query));
ComponentDto view = db.components().insertView(organization, v -> v.setName(query));
ComponentDto subView = db.components().insertComponent(ComponentTesting.newSubView(view).setName(query));
ComponentDto project = db.components().insertPrivateProject(organization, p -> p.setName(query));
componentIndexer.indexOnStartup(null);
authorizationIndexerTester.allowOnlyAnyone(project);
authorizationIndexerTester.allowOnlyAnyone(view);
+ authorizationIndexerTester.allowOnlyAnyone(app);
SuggestionsWsResponse response = ws.newRequest()
.setMethod("POST")
assertThat(response.getResultsList())
.extracting(Category::getQ, c -> c.getItemsList().stream().map(Suggestion::hasProject).findFirst().orElse(null))
.containsExactlyInAnyOrder(
+ tuple(SuggestionCategory.APP.getName(), false),
tuple(SuggestionCategory.VIEW.getName(), false),
tuple(SuggestionCategory.SUBVIEW.getName(), false),
tuple(SuggestionCategory.PROJECT.getName(), false),
@Test
public void show_more_results_filter_out_if_non_allowed_qualifiers() {
- resourceTypes.setAllQualifiers(VIEW, SUBVIEW);
+ resourceTypes.setAllQualifiers(APP, VIEW, SUBVIEW);
check_proposal_to_show_more_results(10, 0, 0L, SuggestionCategory.PROJECT, true);
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.sonar.api.utils.DateUtils.parseDateTime;
+import static org.sonar.db.component.ComponentTesting.newApplication;
import static org.sonar.db.component.ComponentTesting.newDirectory;
import static org.sonar.db.component.ComponentTesting.newFileDto;
import static org.sonar.db.component.ComponentTesting.newModuleDto;
assertThat(measure.getValue()).isEqualTo("15.5");
}
+
+ @Test
+ public void return_measures_on_application() throws Exception {
+ ComponentDto application = newApplication(db.getDefaultOrganization());
+ SnapshotDto viewSnapshot = db.components().insertProjectAndSnapshot(application);
+ MetricDto coverage = insertCoverageMetric();
+ dbClient.measureDao().insert(dbSession, newMeasureDto(coverage, application, viewSnapshot).setValue(15.5d));
+ db.commit();
+
+ SearchWsResponse result = call(singletonList(application.key()), singletonList("coverage"));
+
+ List<Measure> measures = result.getMeasuresList();
+ assertThat(measures).hasSize(1);
+ Measure measure = measures.get(0);
+ assertThat(measure.getMetric()).isEqualTo("coverage");
+ assertThat(measure.getValue()).isEqualTo("15.5");
+ }
+
@Test
public void return_measures_on_sub_view() throws Exception {
ComponentDto view = newView(db.getDefaultOrganization());
insertComplexityMetric();
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Only component of qualifiers [TRK, VW, SVW] are allowed");
+ expectedException.expectMessage("Only component of qualifiers [TRK, APP, VW, SVW] are allowed");
call(singletonList(module.key()), singletonList("complexity"));
}
insertComplexityMetric();
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Only component of qualifiers [TRK, VW, SVW] are allowed");
+ expectedException.expectMessage("Only component of qualifiers [TRK, APP, VW, SVW] are allowed");
call(singletonList(dir.key()), singletonList("complexity"));
}
insertComplexityMetric();
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Only component of qualifiers [TRK, VW, SVW] are allowed");
+ expectedException.expectMessage("Only component of qualifiers [TRK, APP, VW, SVW] are allowed");
call(singletonList(file.key()), singletonList("complexity"));
}
ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project));
ComponentDto directory = db.components().insertComponent(ComponentTesting.newDirectory(module, "a/b"));
ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(module, directory));
- ComponentDto view = db.components().insertView(organization, (dto) -> {
- });
+ ComponentDto view = db.components().insertView(organization);
ComponentDto subview1 = db.components().insertComponent(ComponentTesting.newSubView(view, "v1", "ksv1"));
ComponentDto subview2 = db.components().insertComponent(ComponentTesting.newSubView(subview1, "v2", "ksv2"));
+ ComponentDto application = db.components().insertApplication(organization);
ComponentDto projectCopy = db.components().insertComponent(ComponentTesting.newProjectCopy("pc1", project, subview1));
+ ComponentDto projectCopyForApplication = db.components().insertComponent(ComponentTesting.newProjectCopy("pc2", project, application));
logInAsAdministrator(organization);
sendRequest(organization);
verifyOrganizationDoesNotExist(organization);
ArgumentCaptor<List<ComponentDto>> arg = (ArgumentCaptor<List<ComponentDto>>) ((ArgumentCaptor) ArgumentCaptor.forClass(List.class));
verify(componentCleanerService).delete(any(DbSession.class), arg.capture());
- assertThat(arg.getValue()).containsOnly(project, view);
+ assertThat(arg.getValue()).containsOnly(project, view, application);
}
@Test
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.GroupPermissionDto;
import org.sonar.db.user.GroupDto;
import org.sonar.db.user.UserDbTester;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.VIEW;
import static org.sonar.api.web.UserRole.ADMIN;
private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester);
private UserDbTester userDbTester = new UserDbTester(dbTester);
+ private OrganizationDto organization;
private ComponentDto publicProject;
private ComponentDto privateProject1;
private ComponentDto privateProject2;
private ComponentDto view1;
private ComponentDto view2;
+ private ComponentDto application;
private UserDto user1;
private UserDto user2;
private GroupDto group;
private PermissionIndexerDao underTest = new PermissionIndexerDao();
@Before
- public void setUp() throws Exception {
- publicProject = componentDbTester.insertPublicProject();
- privateProject1 = componentDbTester.insertPrivateProject();
- privateProject2 = componentDbTester.insertPrivateProject();
- view1 = componentDbTester.insertView();
- view2 = componentDbTester.insertView();
+ public void setUp() {
+ organization = dbTester.organizations().insert();
+ publicProject = componentDbTester.insertPublicProject(organization);
+ privateProject1 = componentDbTester.insertPrivateProject(organization);
+ privateProject2 = componentDbTester.insertPrivateProject(organization);
+ view1 = componentDbTester.insertView(organization);
+ view2 = componentDbTester.insertView(organization);
+ application = componentDbTester.insertApplication(organization);
user1 = userDbTester.insertUser();
user2 = userDbTester.insertUser();
- group = userDbTester.insertGroup();
+ group = userDbTester.insertGroup(organization);
}
@Test
insertTestDataForProjectsAndViews();
Collection<PermissionIndexerDao.Dto> dtos = underTest.selectAll(dbClient, dbSession);
- assertThat(dtos).hasSize(5);
+ assertThat(dtos).hasSize(6);
PermissionIndexerDao.Dto publicProjectAuthorization = getByProjectUuid(publicProject.uuid(), dtos);
isPublic(publicProjectAuthorization, PROJECT);
PermissionIndexerDao.Dto view1Authorization = getByProjectUuid(view1.uuid(), dtos);
isPublic(view1Authorization, VIEW);
+ PermissionIndexerDao.Dto applicationAuthorization = getByProjectUuid(application.uuid(), dtos);
+ isPublic(applicationAuthorization, APP);
+
PermissionIndexerDao.Dto privateProject1Authorization = getByProjectUuid(privateProject1.uuid(), dtos);
assertThat(privateProject1Authorization.getGroupIds()).containsOnly(group.getId());
assertThat(privateProject1Authorization.isAllowAnyone()).isFalse();
insertTestDataForProjectsAndViews();
Map<String, PermissionIndexerDao.Dto> dtos = underTest
- .selectByUuids(dbClient, dbSession, asList(publicProject.uuid(), privateProject1.uuid(), privateProject2.uuid(), view1.uuid(), view2.uuid()))
+ .selectByUuids(dbClient, dbSession, asList(publicProject.uuid(), privateProject1.uuid(), privateProject2.uuid(), view1.uuid(), view2.uuid(), application.uuid()))
.stream()
.collect(MoreCollectors.uniqueIndex(PermissionIndexerDao.Dto::getProjectUuid, Function.identity()));
- assertThat(dtos).hasSize(5);
+ assertThat(dtos).hasSize(6);
PermissionIndexerDao.Dto publicProjectAuthorization = dtos.get(publicProject.uuid());
isPublic(publicProjectAuthorization, PROJECT);
PermissionIndexerDao.Dto view1Authorization = dtos.get(view1.uuid());
isPublic(view1Authorization, VIEW);
+ PermissionIndexerDao.Dto applicationAuthorization = dtos.get(application.uuid());
+ isPublic(applicationAuthorization, APP);
+
PermissionIndexerDao.Dto privateProject1Authorization = dtos.get(privateProject1.uuid());
assertThat(privateProject1Authorization.getGroupIds()).containsOnly(group.getId());
assertThat(privateProject1Authorization.isAllowAnyone()).isFalse();
public void select_by_projects_with_high_number_of_projects() throws Exception {
List<String> projectUuids = new ArrayList<>();
for (int i = 0; i < 350; i++) {
- ComponentDto project = ComponentTesting.newPrivateProjectDto(dbTester.getDefaultOrganization(), Integer.toString(i));
+ ComponentDto project = ComponentTesting.newPrivateProjectDto(organization, Integer.toString(i));
dbClient.componentDao().insert(dbSession, project);
projectUuids.add(project.uuid());
GroupPermissionDto dto = new GroupPermissionDto()
userDbTester.insertProjectPermissionOnUser(user1, USER, privateProject1);
userDbTester.insertProjectPermissionOnUser(user1, USER, privateProject2);
userDbTester.insertProjectPermissionOnUser(user1, ADMIN, view1);
+ userDbTester.insertProjectPermissionOnUser(user1, ADMIN, application);
// user2 has USER access on privateProject1 only
userDbTester.insertProjectPermissionOnUser(user2, USER, privateProject1);
userDbTester.insertProjectPermissionOnGroup(group, USER, privateProject1);
userDbTester.insertProjectPermissionOnGroup(group, ADMIN, privateProject1);
userDbTester.insertProjectPermissionOnGroup(group, ADMIN, view1);
+ userDbTester.insertProjectPermissionOnGroup(group, ADMIN, application);
}
}
}
protected ResourceTypesRule newRootResourceTypes() {
- return new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW);
+ return new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, Qualifiers.APP);
}
protected PermissionUpdater newPermissionUpdater() {
import org.sonar.server.ws.TestRequest;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.VIEW;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_ORGANIZATION;
assertDefaultTemplates(organization, projectDefaultTemplate.getUuid(), template.getUuid());
}
+ @Test
+ public void fail_if_update_default_template_with_app_qualifier() throws Exception {
+ OrganizationDto organization = db.organizations().insert();
+ PermissionTemplateDto projectDefaultTemplate = db.permissionTemplates().insertTemplate(organization);
+ db.organizations().setDefaultTemplates(projectDefaultTemplate, null);
+ PermissionTemplateDto template = insertTemplate(organization);
+ loginAsAdmin(organization);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Value of parameter 'qualifier' (APP) must be one of: [TRK, VW]");
+
+ newRequest(template.getUuid(), APP);
+ }
+
@Test
public void fail_if_anonymous() throws Exception {
OrganizationDto organization = db.organizations().insert();
public void fail_on_invalid_qualifier() throws Exception {
userSession.addPermission(ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization());
expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Value of parameter 'qualifiers' (BRC) must be one of: [TRK, VW]");
+ expectedException.expectMessage("Value of parameter 'qualifiers' (BRC) must be one of: [TRK, VW, APP]");
call(SearchWsRequest.builder().setQualifiers(singletonList("BRC")).build());
}
WebService.Param qualifierParam = action.param("qualifiers");
assertThat(qualifierParam.isRequired()).isFalse();
assertThat(qualifierParam.description()).isEqualTo("Comma-separated list of component qualifiers. Filter the results with the specified qualifiers");
- assertThat(qualifierParam.possibleValues()).containsOnly("TRK", "VW");
+ assertThat(qualifierParam.possibleValues()).containsOnly("TRK", "VW", "APP");
assertThat(qualifierParam.defaultValue()).isEqualTo("TRK");
WebService.Param pParam = action.param("p");
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
+import static org.sonar.db.component.ComponentTesting.newProjectCopy;
import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
public class UpdateVisibilityActionTest {
dbTester.components().insertComponents(module, dir, file);
ComponentDto view = dbTester.components().insertView(organization);
ComponentDto subView = ComponentTesting.newSubView(view);
- ComponentDto projectCopy = ComponentTesting.newProjectCopy("foo", project, subView);
+ ComponentDto projectCopy = newProjectCopy("foo", project, subView);
dbTester.components().insertComponents(subView, projectCopy);
- Stream.of(module, dir, file, subView, projectCopy)
+ Stream.of(module, dir, file, view, subView, projectCopy)
.forEach(nonRootComponent -> {
request.setParam(PARAM_PROJECT, nonRootComponent.key())
.setParam(PARAM_VISIBILITY, randomVisibility);
request.execute();
fail("a BadRequestException should have been raised");
} catch (BadRequestException e) {
- assertThat(e.getMessage()).isEqualTo("Component must either be a project or a view");
+ assertThat(e.getMessage()).isEqualTo("Component must be a project");
}
});
}
assertThat(isPrivateInDb(file)).isEqualTo(!initiallyPrivate);
}
- @Test
- public void execute_has_no_effect_when_changing_a_view_to_public() {
- OrganizationDto organization = dbTester.organizations().insert();
- ComponentDto project = randomPublicOrPrivateProject();
- ComponentDto view = dbTester.components().insertView(organization);
- ComponentDto subView = ComponentTesting.newSubView(view);
- ComponentDto projectCopy = ComponentTesting.newProjectCopy("foo", project, subView);
- dbTester.components().insertComponents(subView, projectCopy);
- userSessionRule.addProjectPermission(UserRole.ADMIN, view);
-
- request.setParam(PARAM_PROJECT, view.key())
- .setParam(PARAM_VISIBILITY, PUBLIC)
- .execute();
-
- assertThat(isPrivateInDb(view)).isEqualTo(false);
- assertThat(isPrivateInDb(subView)).isEqualTo(false);
- assertThat(isPrivateInDb(projectCopy)).isEqualTo(false);
- }
-
- @Test
- public void execute_fails_with_BadRequestException_when_changing_a_view_to_private() {
- OrganizationDto organization = dbTester.organizations().insert();
- ComponentDto project = randomPublicOrPrivateProject();
- ComponentDto view = dbTester.components().insertView(organization);
- ComponentDto subView = ComponentTesting.newSubView(view);
- ComponentDto projectCopy = ComponentTesting.newProjectCopy("foo", project, subView);
- dbTester.components().insertComponents(subView, projectCopy);
- userSessionRule.addProjectPermission(UserRole.ADMIN, view);
- TestRequest request = this.request.setParam(PARAM_PROJECT, view.key())
- .setParam(PARAM_VISIBILITY, PRIVATE);
-
- expectedException.expect(BadRequestException.class);
- expectedException.expectMessage("Views can't be made private");
-
- request.execute();
- }
-
@Test
public void execute_has_no_effect_if_specified_project_already_has_specified_visibility() {
ComponentDto project = randomPublicOrPrivateProject();
verifyStillHasAllPermissions(project, user, group);
}
- @Test
- public void execute_does_not_delete_permissions_USER_and_BROWSE_of_specified_view_when_making_it_public() {
- OrganizationDto organization = dbTester.organizations().insert();
- ComponentDto view = dbTester.components().insertView(organization);
- UserDto user = dbTester.users().insertUser();
- GroupDto group = dbTester.users().insertGroup(organization);
- unsafeGiveAllPermissionsToRootComponent(view, user, group, organization);
- userSessionRule.addProjectPermission(UserRole.ADMIN, view);
-
- request.setParam(PARAM_PROJECT, view.key())
- .setParam(PARAM_VISIBILITY, PUBLIC)
- .execute();
-
- verifyStillHasAllPermissions(view, user, group);
- }
-
@Test
public void execute_updates_permission_of_specified_project_in_indexes_when_changing_visibility() {
ComponentDto project = randomPublicOrPrivateProject();
assertThat(projectIndexers.hasBeenCalled(project.uuid())).isFalse();
}
- @Test
- public void execute_does_not_update_permission_of_specified_view_in_indexes_when_making_it_public() {
- OrganizationDto organization = dbTester.organizations().insert();
- ComponentDto view = dbTester.components().insertView(organization);
- userSessionRule.addProjectPermission(UserRole.ADMIN, view);
-
- request.setParam(PARAM_PROJECT, view.key())
- .setParam(PARAM_VISIBILITY, PUBLIC)
- .execute();
-
- assertThat(projectIndexers.hasBeenCalled(view.uuid())).isFalse();
- }
-
@Test
public void execute_grants_USER_and_CODEVIEWER_permissions_to_any_user_with_at_least_one_permission_when_making_project_private() {
OrganizationDto organization = dbTester.organizations().insert();