Przeglądaj źródła

SONAR-13999 drop organization from Components WS

tags/8.7.0.41497
Jacek 3 lat temu
rodzic
commit
9ae766e0e8
48 zmienionych plików z 776 dodań i 1354 usunięć
  1. 24
    1
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java
  2. 19
    0
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentTesting.java
  3. 12
    0
      server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualitygate/QualityGateDbTester.java
  4. 0
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java
  5. 0
    8
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentFinder.java
  6. 9
    3
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentUpdater.java
  7. 0
    14
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/NewComponent.java
  8. 2
    22
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ComponentDtoToWsComponent.java
  9. 7
    52
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchAction.java
  10. 9
    82
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java
  11. 8
    13
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ShowAction.java
  12. 6
    32
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java
  13. 7
    9
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/TreeAction.java
  14. 0
    1
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/CreateAction.java
  15. 14
    18
      server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java
  16. 0
    1
      server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/search-components-example.json
  17. 0
    13
      server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/search_projects-example.json
  18. 0
    3
      server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/show-example.json
  19. 0
    8
      server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/suggestions-example.json
  20. 2
    6
      server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/tree-example.json
  21. 0
    1
      server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ui/ws/component-example.json
  22. 1
    1
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/queue/ReportSubmitterTest.java
  23. 10
    16
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentCleanerServiceTest.java
  24. 54
    64
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentFinderTest.java
  25. 10
    13
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentServiceTest.java
  26. 25
    24
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java
  27. 34
    69
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java
  28. 15
    35
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/NewComponentTest.java
  29. 28
    32
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/AppActionTest.java
  30. 0
    68
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/ComponentDtoToWsComponentTest.java
  31. 2
    2
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
  32. 0
    5
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/FilterParserTest.java
  33. 35
    72
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
  34. 213
    348
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java
  35. 35
    42
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/ShowActionTest.java
  36. 41
    75
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SuggestionsActionTest.java
  37. 76
    85
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/TreeActionTest.java
  38. 1
    1
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/project/ws/CreateActionTest.java
  39. 73
    99
      server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java
  40. 0
    1
      server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_bread_crumbs_on_several_levels.json
  41. 0
    1
      server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_when_anonymous_no_snapshot.json
  42. 0
    1
      server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_when_file_on_branch.json
  43. 0
    1
      server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_when_file_on_master.json
  44. 0
    1
      server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_when_snapshot.json
  45. 0
    1
      server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_with_favourite.json
  46. 1
    1
      server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_configuration_with_all_properties.json
  47. 0
    1
      sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java
  48. 3
    7
      sonar-ws/src/main/protobuf/ws-components.proto

+ 24
- 1
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java Wyświetl plik

@@ -52,6 +52,10 @@ public class ComponentDbTester {
}

public SnapshotDto insertViewAndSnapshot(ComponentDto component) {
if (component.getOrganizationUuid() == null) {
component.setOrganizationUuid(db.getDefaultOrganization().getUuid());
}

dbClient.componentDao().insert(dbSession, component);
return insertSnapshot(component);
}
@@ -101,6 +105,11 @@ public class ComponentDbTester {
dtoPopulator);
}

public final ComponentDto insertPublicProject(Consumer<ComponentDto> componentDtoPopulator, Consumer<ProjectDto> projectDtoPopulator) {
return insertComponentAndBranchAndProject(ComponentTesting.newPublicProjectDto(db.getDefaultOrganization()), false, defaults(), componentDtoPopulator,
projectDtoPopulator);
}

public final ComponentDto insertPrivateProject(OrganizationDto organizationDto, Consumer<ComponentDto> componentDtoPopulator) {
return insertPrivateProject(organizationDto, componentDtoPopulator, defaults());
}
@@ -168,6 +177,10 @@ public class ComponentDbTester {
return getProjectDto(componentDto);
}

public final ComponentDto insertPrivateProject(String uuid, Consumer<ComponentDto> dtoPopulator) {
return insertPrivateProject(db.getDefaultOrganization(), uuid, dtoPopulator);
}

public ProjectDto insertPrivateProjectDto(OrganizationDto organization, Consumer<BranchDto> branchConsumer) {
ComponentDto componentDto = insertPrivateProjectWithCustomBranch(organization, branchConsumer, defaults());
return getProjectDto(componentDto);
@@ -267,18 +280,28 @@ public class ComponentDbTester {
return insertPrivatePortfolio(organization, defaults());
}

public final ComponentDto insertPrivatePortfolio(Consumer<ComponentDto> dtoPopulator) {
return insertComponentImpl(ComponentTesting.newView(db.getDefaultOrganization()).setPrivate(true), true, dtoPopulator);
}

public final ComponentDto insertPrivatePortfolio(OrganizationDto organization, Consumer<ComponentDto> dtoPopulator) {
return insertComponentImpl(ComponentTesting.newView(organization).setPrivate(true), true, dtoPopulator);
}

public final ComponentDto insertPublicApplication() {
return insertPublicApplication(db.getDefaultOrganization());
return insertPublicApplication(db.getDefaultOrganization(), defaults());
}

public final ComponentDto insertPublicApplication(Consumer<ComponentDto> dtoPopulator) {
return insertPublicApplication(db.getDefaultOrganization(), dtoPopulator);
}

@Deprecated
public final ComponentDto insertPublicApplication(OrganizationDto organization) {
return insertPublicApplication(organization, defaults());
}

@Deprecated
public final ComponentDto insertPublicApplication(OrganizationDto organization, Consumer<ComponentDto> dtoPopulator) {
return insertComponentAndBranchAndProject(ComponentTesting.newApplication(organization).setPrivate(false), false, defaults(), dtoPopulator);
}

+ 19
- 0
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentTesting.java Wyświetl plik

@@ -147,6 +147,11 @@ public class ComponentTesting {
return newProjectDto(organizationDto.getUuid(), uuid, true);
}


public static ComponentDto newPublicProjectDto() {
return newProjectDto(Uuids.createFast(), false);
}

// TODO remove
@Deprecated
public static ComponentDto newPublicProjectDto(OrganizationDto organizationDto) {
@@ -211,10 +216,24 @@ public class ComponentTesting {
.setPrivate(isPrivate);
}

public static ComponentDto newView() {
return newView(Uuids.createFast());
}

public static ComponentDto newView(String uuid) {
return newPrivateProjectDto(uuid)
.setUuid(uuid)
.setScope(Scopes.PROJECT)
.setQualifier(Qualifiers.VIEW)
.setPrivate(false);
}

@Deprecated
public static ComponentDto newView(OrganizationDto organizationDto) {
return newView(organizationDto.getUuid(), Uuids.createFast());
}

@Deprecated
public static ComponentDto newView(OrganizationDto organizationDto, String uuid) {
return newPrivateProjectDto(organizationDto, uuid)
.setUuid(uuid)

+ 12
- 0
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/qualitygate/QualityGateDbTester.java Wyświetl plik

@@ -56,6 +56,12 @@ public class QualityGateDbTester {
return builtin;
}

@SafeVarargs
public final QGateWithOrgDto insertQualityGate(Consumer<QualityGateDto>... dtoPopulators) {
return insertQualityGate(db.getDefaultOrganization(), dtoPopulators);
}

@Deprecated
@SafeVarargs
public final QGateWithOrgDto insertQualityGate(OrganizationDto organization, Consumer<QualityGateDto>... dtoPopulators) {
QualityGateDto qualityGate = new QualityGateDto()
@@ -80,6 +86,12 @@ public class QualityGateDbTester {
}

@SafeVarargs
public final QualityGateDto createDefaultQualityGate(Consumer<QualityGateDto>... dtoPopulators) {
return createDefaultQualityGate(db.getDefaultOrganization(), dtoPopulators);
}

@SafeVarargs
@Deprecated
public final QualityGateDto createDefaultQualityGate(OrganizationDto organization, Consumer<QualityGateDto>... dtoPopulators) {
QualityGateDto defaultQGate = insertQualityGate(organization, dtoPopulators);
setDefaultQualityGate(organization, defaultQGate);

+ 0
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ce/queue/ReportSubmitter.java Wyświetl plik

@@ -164,7 +164,6 @@ public class ReportSubmitter {
boolean newProjectPrivate = dbClient.organizationDao().getNewProjectPrivate(dbSession, defaultOrgUuid);

NewComponent newProject = newComponentBuilder()
.setOrganizationUuid(defaultOrgUuid)
.setKey(componentKey.getKey())
.setName(defaultIfBlank(projectName, componentKey.getKey()))
.setQualifier(Qualifiers.PROJECT)

+ 0
- 8
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentFinder.java Wyświetl plik

@@ -32,14 +32,12 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.server.exceptions.NotFoundException;

import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static org.sonar.server.exceptions.BadRequestException.checkRequest;
import static org.sonar.server.exceptions.NotFoundException.checkFoundWithOptional;

public class ComponentFinder {
private static final String MSG_COMPONENT_ID_OR_KEY_TEMPLATE = "Either '%s' or '%s' must be provided";
@@ -178,12 +176,6 @@ public class ComponentFinder {
.collect(MoreCollectors.toSet(rootTypes.size()));
}

public OrganizationDto getOrganization(DbSession dbSession, ComponentDto component) {
String organizationUuid = component.getOrganizationUuid();
Optional<OrganizationDto> organizationDto = dbClient.organizationDao().selectByUuid(dbSession, organizationUuid);
return checkFoundWithOptional(organizationDto, "Organization with uuid '%s' not found", organizationUuid);
}

public ComponentDto getByKeyAndBranch(DbSession dbSession, String key, String branch) {
Optional<ComponentDto> componentDto = dbClient.componentDao().selectByKeyAndBranch(dbSession, key, branch);
if (componentDto.isPresent() && componentDto.get().isEnabled()) {

+ 9
- 3
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ComponentUpdater.java Wyświetl plik

@@ -39,6 +39,7 @@ import org.sonar.db.project.ProjectDto;
import org.sonar.server.es.ProjectIndexer.Cause;
import org.sonar.server.es.ProjectIndexers;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.permission.PermissionTemplateService;

import static java.util.Collections.singletonList;
@@ -58,10 +59,12 @@ public class ComponentUpdater {
private final FavoriteUpdater favoriteUpdater;
private final ProjectIndexers projectIndexers;
private final UuidFactory uuidFactory;
private final DefaultOrganizationProvider defaultOrganizationProvider;

public ComponentUpdater(DbClient dbClient, I18n i18n, System2 system2,
PermissionTemplateService permissionTemplateService, FavoriteUpdater favoriteUpdater,
ProjectIndexers projectIndexers, UuidFactory uuidFactory) {
ProjectIndexers projectIndexers, UuidFactory uuidFactory,
DefaultOrganizationProvider defaultOrganizationProvider) {
this.dbClient = dbClient;
this.i18n = i18n;
this.system2 = system2;
@@ -69,6 +72,7 @@ public class ComponentUpdater {
this.favoriteUpdater = favoriteUpdater;
this.projectIndexers = projectIndexers;
this.uuidFactory = uuidFactory;
this.defaultOrganizationProvider = defaultOrganizationProvider;
}

/**
@@ -108,8 +112,10 @@ public class ComponentUpdater {

long now = system2.now();
String uuid = uuidFactory.create();

// TODO:: remove setOrganizationUuid once column dropped
ComponentDto component = new ComponentDto()
.setOrganizationUuid(newComponent.getOrganizationUuid())
.setOrganizationUuid(defaultOrganizationProvider.get().getUuid())
.setUuid(uuid)
.setUuidPath(ComponentDto.UUID_PATH_OF_ROOT)
.setRootUuid(uuid)
@@ -142,7 +148,7 @@ public class ComponentUpdater {
.setQualifier(component.qualifier())
.setName(component.name())
.setPrivate(component.isPrivate())
.setOrganizationUuid(component.getOrganizationUuid())
.setOrganizationUuid(component.getOrganizationUuid()) // TODO:: remove once column dropped
.setDescription(component.description())
.setUpdatedAt(now)
.setCreatedAt(now);

+ 0
- 14
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/NewComponent.java Wyświetl plik

@@ -23,7 +23,6 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

import static java.util.Objects.requireNonNull;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.db.component.ComponentValidator.checkComponentKey;
import static org.sonar.db.component.ComponentValidator.checkComponentName;
@@ -31,7 +30,6 @@ import static org.sonar.db.component.ComponentValidator.checkComponentQualifier;

@Immutable
public class NewComponent {
private final String organizationUuid;
private final String key;
private final String qualifier;
private final String name;
@@ -39,7 +37,6 @@ public class NewComponent {
private final boolean isPrivate;

private NewComponent(NewComponent.Builder builder) {
this.organizationUuid = builder.organizationUuid;
this.key = builder.key;
this.qualifier = builder.qualifier;
this.name = builder.name;
@@ -51,10 +48,6 @@ public class NewComponent {
return new Builder();
}

public String getOrganizationUuid() {
return organizationUuid;
}

public String key() {
return key;
}
@@ -78,7 +71,6 @@ public class NewComponent {

public static class Builder {
private String description;
private String organizationUuid;
private String key;
private String qualifier = PROJECT;
private String name;
@@ -88,11 +80,6 @@ public class NewComponent {
// use static factory method newComponentBuilder()
}

public Builder setOrganizationUuid(String organizationUuid) {
this.organizationUuid = organizationUuid;
return this;
}

public Builder setKey(String key) {
this.key = key;
return this;
@@ -119,7 +106,6 @@ public class NewComponent {
}

public NewComponent build() {
requireNonNull(organizationUuid, "organization uuid can't be null");
checkComponentKey(key);
checkComponentName(name);
checkComponentQualifier(qualifier);

+ 2
- 22
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ComponentDtoToWsComponent.java Wyświetl plik

@@ -21,18 +21,15 @@ package org.sonar.server.component.ws;

import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;
import org.sonar.api.resources.Qualifiers;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.server.project.Visibility;
import org.sonarqube.ws.Components;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.emptyToNull;
import static java.util.Optional.ofNullable;
import static org.sonar.api.utils.DateUtils.formatDateTime;
@@ -48,15 +45,8 @@ class ComponentDtoToWsComponent {
// prevent instantiation
}

static Components.Component.Builder projectOrAppToWsComponent(ProjectDto project, OrganizationDto organizationDto, @Nullable SnapshotDto lastAnalysis) {

checkArgument(
Objects.equals(project.getOrganizationUuid(), organizationDto.getUuid()),
"OrganizationUuid (%s) of ComponentDto to convert to Ws Component is not the same as the one (%s) of the specified OrganizationDto",
project.getOrganizationUuid(), organizationDto.getUuid());

static Components.Component.Builder projectOrAppToWsComponent(ProjectDto project, @Nullable SnapshotDto lastAnalysis) {
Components.Component.Builder wsComponent = Components.Component.newBuilder()
.setOrganization(organizationDto.getKey())
.setKey(project.getKey())
.setName(project.getName())
.setQualifier(project.getQualifier());
@@ -76,19 +66,9 @@ class ComponentDtoToWsComponent {
return wsComponent;
}

static Components.Component.Builder componentDtoToWsComponent(ComponentDto dto, @Nullable ProjectDto parentProjectDto, OrganizationDto organizationDto,
@Nullable SnapshotDto lastAnalysis) {
checkArgument(
Objects.equals(dto.getOrganizationUuid(), organizationDto.getUuid()),
"OrganizationUuid (%s) of ComponentDto to convert to Ws Component is not the same as the one (%s) of the specified OrganizationDto",
dto.getOrganizationUuid(), organizationDto.getUuid());
return componentDtoToWsComponent(dto, parentProjectDto, organizationDto.getKey(), lastAnalysis);
}

private static Components.Component.Builder componentDtoToWsComponent(ComponentDto dto, @Nullable ProjectDto parentProjectDto, String organizationDtoKey,
public static Components.Component.Builder componentDtoToWsComponent(ComponentDto dto, @Nullable ProjectDto parentProjectDto,
@Nullable SnapshotDto lastAnalysis) {
Components.Component.Builder wsComponent = Components.Component.newBuilder()
.setOrganization(organizationDtoKey)
.setKey(dto.getKey())
.setName(dto.name())
.setQualifier(dto.qualifier());

+ 7
- 52
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchAction.java Wyświetl plik

@@ -22,7 +22,6 @@ package org.sonar.server.component.ws;
import com.google.common.collect.ImmutableSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
@@ -38,17 +37,13 @@ import org.sonar.core.i18n.I18n;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.component.index.ComponentIndex;
import org.sonar.server.component.index.ComponentQuery;
import org.sonar.server.es.SearchIdResult;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonarqube.ws.Components;
import org.sonarqube.ws.Components.SearchWsResponse;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toMap;
@@ -62,7 +57,6 @@ import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;

public class SearchAction implements ComponentsWsAction {
@@ -73,15 +67,12 @@ public class SearchAction implements ComponentsWsAction {
private final DbClient dbClient;
private final ResourceTypes resourceTypes;
private final I18n i18n;
private final DefaultOrganizationProvider defaultOrganizationProvider;

public SearchAction(ComponentIndex componentIndex, DbClient dbClient, ResourceTypes resourceTypes, I18n i18n,
DefaultOrganizationProvider defaultOrganizationProvider) {
public SearchAction(ComponentIndex componentIndex, DbClient dbClient, ResourceTypes resourceTypes, I18n i18n) {
this.componentIndex = componentIndex;
this.dbClient = dbClient;
this.resourceTypes = resourceTypes;
this.i18n = i18n;
this.defaultOrganizationProvider = defaultOrganizationProvider;
}

@Override
@@ -105,14 +96,6 @@ public class SearchAction implements ComponentsWsAction {
"</ul>")
.setExampleValue("sonar");

action
.createParam(PARAM_ORGANIZATION)
.setDescription("Organization key")
.setRequired(false)
.setInternal(true)
.setExampleValue("my-org")
.setSince("6.3");

createQualifiersParameter(action, newQualifierParameterContext(i18n, resourceTypes), VALID_QUALIFIERS)
.setRequired(true);
}
@@ -125,7 +108,6 @@ public class SearchAction implements ComponentsWsAction {

private static SearchRequest toSearchWsRequest(org.sonar.api.server.ws.Request request) {
return new SearchRequest()
.setOrganization(request.param(PARAM_ORGANIZATION))
.setQualifiers(request.mandatoryParamAsStrings(PARAM_QUALIFIERS))
.setQuery(request.param(Param.TEXT_QUERY))
.setPage(request.mandatoryParamAsInt(Param.PAGE))
@@ -134,14 +116,13 @@ public class SearchAction implements ComponentsWsAction {

private SearchWsResponse doHandle(SearchRequest request) {
try (DbSession dbSession = dbClient.openSession(false)) {
OrganizationDto organization = getOrganization(dbSession, request);
ComponentQuery esQuery = buildEsQuery(organization, request);
ComponentQuery esQuery = buildEsQuery(request);
SearchIdResult<String> results = componentIndex.search(esQuery, new SearchOptions().setPage(request.getPage(), request.getPageSize()));

List<ComponentDto> components = dbClient.componentDao().selectByUuids(dbSession, results.getUuids());
Map<String, String> projectKeysByUuids = searchProjectsKeysByUuids(dbSession, components);

return buildResponse(components, organization, projectKeysByUuids,
return buildResponse(components, projectKeysByUuids,
Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal((int) results.getTotal()));
}
}
@@ -158,23 +139,14 @@ public class SearchAction implements ComponentsWsAction {
return projects.stream().collect(toMap(ComponentDto::uuid, ComponentDto::getDbKey));
}

private OrganizationDto getOrganization(DbSession dbSession, SearchRequest request) {
String organizationKey = Optional.ofNullable(request.getOrganization())
.orElseGet(defaultOrganizationProvider.get()::getKey);
return NotFoundException.checkFoundWithOptional(
dbClient.organizationDao().selectByKey(dbSession, organizationKey),
"No organizationDto with key '%s'", organizationKey);
}

private static ComponentQuery buildEsQuery(OrganizationDto organization, SearchRequest request) {
private static ComponentQuery buildEsQuery(SearchRequest request) {
return ComponentQuery.builder()
.setQuery(request.getQuery())
.setOrganization(organization.getUuid())
.setQualifiers(request.getQualifiers())
.build();
}

private static SearchWsResponse buildResponse(List<ComponentDto> components, OrganizationDto organization, Map<String, String> projectKeysByUuids, Paging paging) {
private static SearchWsResponse buildResponse(List<ComponentDto> components, Map<String, String> projectKeysByUuids, Paging paging) {
SearchWsResponse.Builder responseBuilder = SearchWsResponse.newBuilder();
responseBuilder.getPagingBuilder()
.setPageIndex(paging.pageIndex())
@@ -183,20 +155,14 @@ public class SearchAction implements ComponentsWsAction {
.build();

components.stream()
.map(dto -> dtoToComponent(organization, dto, projectKeysByUuids.get(dto.projectUuid())))
.map(dto -> dtoToComponent(dto, projectKeysByUuids.get(dto.projectUuid())))
.forEach(responseBuilder::addComponents);

return responseBuilder.build();
}

private static Components.Component dtoToComponent(OrganizationDto organization, ComponentDto dto, String projectKey) {
checkArgument(
organization.getUuid().equals(dto.getOrganizationUuid()),
"No Organization found for uuid '%s'",
dto.getOrganizationUuid());

private static Components.Component dtoToComponent(ComponentDto dto, String projectKey) {
Components.Component.Builder builder = Components.Component.newBuilder()
.setOrganization(organization.getKey())
.setKey(dto.getDbKey())
.setProject(projectKey)
.setName(dto.name())
@@ -206,22 +172,11 @@ public class SearchAction implements ComponentsWsAction {
}

static class SearchRequest {
private String organization;
private List<String> qualifiers;
private Integer page;
private Integer pageSize;
private String query;

@CheckForNull
public String getOrganization() {
return organization;
}

public SearchRequest setOrganization(@Nullable String organization) {
this.organization = organization;
return this;
}

public List<String> getQualifiers() {
return qualifiers;
}

+ 9
- 82
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java Wyświetl plik

@@ -19,14 +19,12 @@
*/
package org.sonar.server.component.ws;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
@@ -54,7 +52,6 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.property.PropertyQuery;
@@ -85,19 +82,15 @@ import static org.sonar.api.server.ws.WebService.Param.FACETS;
import static org.sonar.api.server.ws.WebService.Param.FIELDS;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.core.util.stream.MoreCollectors.toList;
import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.db.measure.ProjectMeasuresIndexerIterator.METRIC_KEYS;
import static org.sonar.server.component.ws.ProjectMeasuresQueryFactory.IS_FAVORITE_CRITERION;
import static org.sonar.server.component.ws.ProjectMeasuresQueryFactory.newProjectMeasuresQuery;
import static org.sonar.server.component.ws.ProjectMeasuresQueryValidator.NON_METRIC_SORT_KEYS;
import static org.sonar.server.exceptions.NotFoundException.checkFound;
import static org.sonar.server.exceptions.NotFoundException.checkFoundWithOptional;
import static org.sonar.server.measure.index.ProjectMeasuresQuery.SORT_BY_LAST_ANALYSIS_DATE;
import static org.sonar.server.measure.index.ProjectMeasuresQuery.SORT_BY_NAME;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH_PROJECTS;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_LANGUAGES;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.FILTER_TAGS;

@@ -106,14 +99,13 @@ public class SearchProjectsAction implements ComponentsWsAction {
public static final int MAX_PAGE_SIZE = 500;
public static final int DEFAULT_PAGE_SIZE = 100;
private static final String ALL = "_all";
private static final String ORGANIZATIONS = "organizations";
private static final String ANALYSIS_DATE = "analysisDate";
private static final String LEAK_PERIOD_DATE = "leakPeriodDate";
private static final String METRIC_LEAK_PROJECTS_KEY = "leak_projects";
private static final String HTML_POSSIBLE_VALUES_TEXT = "The possible values are:";
private static final String HTML_UL_START_TAG = "<ul>";
private static final String HTML_UL_END_TAG = "</ul>";
private static final Set<String> POSSIBLE_FIELDS = newHashSet(ALL, ORGANIZATIONS, ANALYSIS_DATE, LEAK_PERIOD_DATE);
private static final Set<String> POSSIBLE_FIELDS = newHashSet(ALL, ANALYSIS_DATE, LEAK_PERIOD_DATE);

private final DbClient dbClient;
private final ProjectMeasuresIndex index;
@@ -150,11 +142,6 @@ public class SearchProjectsAction implements ComponentsWsAction {
action.createFieldsParam(POSSIBLE_FIELDS)
.setDescription("Comma-separated list of the fields to be returned in response")
.setSince("6.4");
action.createParam(PARAM_ORGANIZATION)
.setDescription("the organization to search projects in")
.setRequired(false)
.setInternal(true)
.setSince("6.3");
action.createParam(FACETS)
.setDescription("Comma-separated list of the facets to be computed. No facet is computed by default.")
.setPossibleValues(Arrays.stream(ProjectMeasuresIndex.Facet.values())
@@ -238,44 +225,19 @@ public class SearchProjectsAction implements ComponentsWsAction {

private SearchProjectsWsResponse doHandle(SearchProjectsRequest request) {
try (DbSession dbSession = dbClient.openSession(false)) {
String organizationKey = request.getOrganization();
if (organizationKey == null) {
return handleForAnyOrganization(dbSession, request);
} else {
OrganizationDto organization = checkFoundWithOptional(
dbClient.organizationDao().selectByKey(dbSession, organizationKey),
"No organization for key '%s'", organizationKey);
return handleForOrganization(dbSession, request, organization);
}
SearchResults searchResults = searchData(dbSession, request);
boolean needIssueSync = dbClient.branchDao().hasAnyBranchWhereNeedIssueSync(dbSession, true);
return buildResponse(request, searchResults, needIssueSync);
}
}

private SearchProjectsWsResponse handleForAnyOrganization(DbSession dbSession, SearchProjectsRequest request) {
SearchResults searchResults = searchData(dbSession, request, null);
Set<String> organizationUuids = searchResults.projects.stream().map(ProjectDto::getOrganizationUuid).collect(toSet());
Map<String, OrganizationDto> organizationsByUuid = dbClient.organizationDao().selectByUuids(dbSession, organizationUuids)
.stream()
.collect(MoreCollectors.uniqueIndex(OrganizationDto::getUuid));
boolean needIssueSync = dbClient.branchDao().hasAnyBranchWhereNeedIssueSync(dbSession, true);
return buildResponse(request, searchResults, organizationsByUuid, needIssueSync);
}

private SearchProjectsWsResponse handleForOrganization(DbSession dbSession, SearchProjectsRequest request, OrganizationDto organization) {
SearchResults searchResults = searchData(dbSession, request, organization);
boolean needIssueSync = dbClient.branchDao().hasAnyBranchWhereNeedIssueSync(dbSession, true);
return buildResponse(request, searchResults, ImmutableMap.of(organization.getUuid(), organization), needIssueSync);
}

private SearchResults searchData(DbSession dbSession, SearchProjectsRequest request, @Nullable OrganizationDto organization) {
private SearchResults searchData(DbSession dbSession, SearchProjectsRequest request) {
Set<String> favoriteProjectUuids = loadFavoriteProjectUuids(dbSession);
List<Criterion> criteria = FilterParser.parse(firstNonNull(request.getFilter(), ""));
ProjectMeasuresQuery query = newProjectMeasuresQuery(criteria, hasFavoriteFilter(criteria) ? favoriteProjectUuids : null)
.setIgnoreWarning(projectsInWarning.count() == 0L)
.setSort(request.getSort())
.setAsc(request.getAsc());
Optional.ofNullable(organization)
.map(OrganizationDto::getUuid)
.ifPresent(query::setOrganizationUuid);

Set<String> qualifiersBasedOnEdition = getQualifiersBasedOnEdition(query);
query.setQualifiers(qualifiersBasedOnEdition);
@@ -395,7 +357,6 @@ public class SearchProjectsAction implements ComponentsWsAction {

private static SearchProjectsRequest toRequest(Request httpRequest) {
RequestBuilder request = new RequestBuilder()
.setOrganization(httpRequest.param(PARAM_ORGANIZATION))
.setFilter(httpRequest.param(PARAM_FILTER))
.setSort(httpRequest.mandatoryParam(Param.SORT))
.setAsc(httpRequest.mandatoryParamAsBoolean(Param.ASCENDING))
@@ -407,7 +368,7 @@ public class SearchProjectsAction implements ComponentsWsAction {
if (httpRequest.hasParam(FIELDS)) {
List<String> paramsAsString = httpRequest.mandatoryParamAsStrings(FIELDS);
if (paramsAsString.contains(ALL)) {
request.setAdditionalFields(of(ORGANIZATIONS, ANALYSIS_DATE, LEAK_PERIOD_DATE));
request.setAdditionalFields(of(ANALYSIS_DATE, LEAK_PERIOD_DATE));
} else {
request.setAdditionalFields(paramsAsString);
}
@@ -415,14 +376,8 @@ public class SearchProjectsAction implements ComponentsWsAction {
return request.build();
}

private SearchProjectsWsResponse buildResponse(SearchProjectsRequest request, SearchResults searchResults, Map<String, OrganizationDto> organizationsByUuid,
boolean needIssueSync) {
Function<ProjectDto, Component> dbToWsComponent = new DbToWsComponent(request, organizationsByUuid, searchResults, userSession.isLoggedIn(), needIssueSync);

Map<String, OrganizationDto> organizationsByUuidForAdditionalInfo = new HashMap<>();
if (request.additionalFields.contains(ORGANIZATIONS)) {
organizationsByUuidForAdditionalInfo.putAll(organizationsByUuid);
}
private SearchProjectsWsResponse buildResponse(SearchProjectsRequest request, SearchResults searchResults, boolean needIssueSync) {
Function<ProjectDto, Component> dbToWsComponent = new DbToWsComponent(request, searchResults, userSession.isLoggedIn(), needIssueSync);

return Stream.of(SearchProjectsWsResponse.newBuilder())
.map(response -> response.setPaging(Common.Paging.newBuilder()
@@ -435,15 +390,6 @@ public class SearchProjectsAction implements ComponentsWsAction {
.forEach(response::addComponents);
return response;
})
.map(response -> {
organizationsByUuidForAdditionalInfo.values().stream().forEach(
dto -> response.addOrganizations(
Common.Organization.newBuilder()
.setKey(dto.getKey())
.setName(dto.getName())
.build()));
return response;
})
.map(response -> addFacets(searchResults, response))
.map(SearchProjectsWsResponse.Builder::build)
.findFirst()
@@ -526,7 +472,6 @@ public class SearchProjectsAction implements ComponentsWsAction {
private static class DbToWsComponent implements Function<ProjectDto, Component> {
private final SearchProjectsRequest request;
private final Component.Builder wsComponent;
private final Map<String, OrganizationDto> organizationsByUuid;
private final Set<String> favoriteProjectUuids;
private final List<String> projectsWithIssuesInSync;
private final boolean isUserLoggedIn;
@@ -534,13 +479,12 @@ public class SearchProjectsAction implements ComponentsWsAction {
private final Map<String, Long> applicationsLeakPeriod;
private final boolean needIssueSync;

private DbToWsComponent(SearchProjectsRequest request, Map<String, OrganizationDto> organizationsByUuid, SearchResults searchResults, boolean isUserLoggedIn,
private DbToWsComponent(SearchProjectsRequest request, SearchResults searchResults, boolean isUserLoggedIn,
boolean needIssueSync) {
this.request = request;
this.analysisByProjectUuid = searchResults.analysisByProjectUuid;
this.applicationsLeakPeriod = searchResults.applicationsLeakPeriods;
this.wsComponent = Component.newBuilder();
this.organizationsByUuid = organizationsByUuid;
this.favoriteProjectUuids = searchResults.favoriteProjectUuids;
this.projectsWithIssuesInSync = searchResults.projectsWithIssuesInSync;
this.isUserLoggedIn = isUserLoggedIn;
@@ -549,12 +493,8 @@ public class SearchProjectsAction implements ComponentsWsAction {

@Override
public Component apply(ProjectDto dbProject) {
String organizationUuid = dbProject.getOrganizationUuid();
OrganizationDto organizationDto = organizationsByUuid.get(organizationUuid);
checkFound(organizationDto, "Organization with uuid '%s' not found", organizationUuid);
wsComponent
.clear()
.setOrganization(organizationDto.getKey())
.setKey(dbProject.getKey())
.setName(dbProject.getName())
.setQualifier(dbProject.getQualifier())
@@ -673,7 +613,6 @@ public class SearchProjectsAction implements ComponentsWsAction {

private final int page;
private final int pageSize;
private final String organization;
private final String filter;
private final List<String> facets;
private final String sort;
@@ -683,7 +622,6 @@ public class SearchProjectsAction implements ComponentsWsAction {
private SearchProjectsRequest(RequestBuilder builder) {
this.page = builder.page;
this.pageSize = builder.pageSize;
this.organization = builder.organization;
this.filter = builder.filter;
this.facets = builder.facets;
this.sort = builder.sort;
@@ -691,11 +629,6 @@ public class SearchProjectsAction implements ComponentsWsAction {
this.additionalFields = builder.additionalFields;
}

@CheckForNull
public String getOrganization() {
return organization;
}

@CheckForNull
public String getFilter() {
return filter;
@@ -734,7 +667,6 @@ public class SearchProjectsAction implements ComponentsWsAction {
}

static class RequestBuilder {
private String organization;
private Integer page;
private Integer pageSize;
private String filter;
@@ -747,11 +679,6 @@ public class SearchProjectsAction implements ComponentsWsAction {
// enforce static factory method
}

public RequestBuilder setOrganization(@Nullable String organization) {
this.organization = organization;
return this;
}

public RequestBuilder setFilter(@Nullable String filter) {
this.filter = filter;
return this;

+ 8
- 13
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ShowAction.java Wyświetl plik

@@ -35,7 +35,6 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.issue.index.IssueIndexSyncProgressChecker;
@@ -113,8 +112,7 @@ public class ShowAction implements ComponentsWsAction {
userSession.checkComponentPermission(UserRole.USER, component);
Optional<SnapshotDto> lastAnalysis = dbClient.snapshotDao().selectLastAnalysisByComponentUuid(dbSession, component.projectUuid());
List<ComponentDto> ancestors = dbClient.componentDao().selectAncestors(dbSession, component);
OrganizationDto organizationDto = componentFinder.getOrganization(dbSession, component);
return buildResponse(dbSession, component, organizationDto, ancestors, lastAnalysis.orElse(null));
return buildResponse(dbSession, component, ancestors, lastAnalysis.orElse(null));
}
}

@@ -126,37 +124,34 @@ public class ShowAction implements ComponentsWsAction {
return componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, componentKey, branch, pullRequest);
}

private ShowWsResponse buildResponse(DbSession dbSession, ComponentDto component,
OrganizationDto organizationDto, List<ComponentDto> orderedAncestors,
private ShowWsResponse buildResponse(DbSession dbSession, ComponentDto component, List<ComponentDto> orderedAncestors,
@Nullable SnapshotDto lastAnalysis) {
ShowWsResponse.Builder response = ShowWsResponse.newBuilder();
response.setComponent(toWsComponent(dbSession, component, organizationDto, lastAnalysis));
addAncestorsToResponse(dbSession, response, orderedAncestors, organizationDto, lastAnalysis);
response.setComponent(toWsComponent(dbSession, component, lastAnalysis));
addAncestorsToResponse(dbSession, response, orderedAncestors, lastAnalysis);
return response.build();
}

private void addAncestorsToResponse(DbSession dbSession, ShowWsResponse.Builder response, List<ComponentDto> orderedAncestors,
OrganizationDto organizationDto,
@Nullable SnapshotDto lastAnalysis) {
// ancestors are ordered from root to leaf, whereas it's the opposite in WS response
int size = orderedAncestors.size() - 1;
IntStream.rangeClosed(0, size).forEach(
index -> response.addAncestors(toWsComponent(dbSession, orderedAncestors.get(size - index), organizationDto, lastAnalysis)));
index -> response.addAncestors(toWsComponent(dbSession, orderedAncestors.get(size - index), lastAnalysis)));
}

private Components.Component.Builder toWsComponent(DbSession dbSession, ComponentDto component, OrganizationDto organizationDto,
@Nullable SnapshotDto lastAnalysis) {
private Components.Component.Builder toWsComponent(DbSession dbSession, ComponentDto component, @Nullable SnapshotDto lastAnalysis) {
if (isProjectOrApp(component)) {
ProjectDto project = dbClient.projectDao().selectProjectOrAppByKey(dbSession, component.getKey())
.orElseThrow(() -> new IllegalStateException("Project is in invalid state."));
boolean needIssueSync = needIssueSync(dbSession, component, project);
return projectOrAppToWsComponent(project, organizationDto, lastAnalysis)
return projectOrAppToWsComponent(project, lastAnalysis)
.setNeedIssueSync(needIssueSync);
} else {
Optional<ProjectDto> parentProject = dbClient.projectDao().selectByUuid(dbSession,
ofNullable(component.getMainBranchProjectUuid()).orElse(component.projectUuid()));
boolean needIssueSync = needIssueSync(dbSession, component, parentProject.orElse(null));
return componentDtoToWsComponent(component, parentProject.orElse(null), organizationDto, lastAnalysis)
return componentDtoToWsComponent(component, parentProject.orElse(null), lastAnalysis)
.setNeedIssueSync(needIssueSync);
}
}

+ 6
- 32
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/SuggestionsAction.java Wyświetl plik

@@ -47,7 +47,6 @@ import org.sonar.core.util.stream.MoreCollectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.component.index.ComponentHit;
import org.sonar.server.component.index.ComponentHitsPerQualifier;
import org.sonar.server.component.index.ComponentIndex;
@@ -61,7 +60,6 @@ import org.sonarqube.ws.Components.SuggestionsWsResponse.Category;
import org.sonarqube.ws.Components.SuggestionsWsResponse.Project;
import org.sonarqube.ws.Components.SuggestionsWsResponse.Suggestion;

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;
@@ -72,7 +70,6 @@ import static org.sonar.core.util.stream.MoreCollectors.toSet;
import static org.sonar.server.component.index.SuggestionQuery.DEFAULT_LIMIT;
import static org.sonar.server.es.newindex.DefaultIndexSettings.MINIMUM_NGRAM_LENGTH;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.Common.Organization;
import static org.sonarqube.ws.Components.SuggestionsWsResponse.newBuilder;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SUGGESTIONS;

@@ -109,7 +106,6 @@ public class SuggestionsAction implements ComponentsWsAction {
"Internal WS for the top-right search engine. The result will contain component search results, grouped by their qualifiers.<p>"
+ "Each result contains:"
+ "<ul>"
+ "<li>the organization key</li>"
+ "<li>the component key</li>"
+ "<li>the component's name (unescaped)</li>"
+ "<li>optionally a display name, which puts emphasis to matching characters (this text contains html tags and parts of the html-escaped name)</li>"
@@ -280,9 +276,8 @@ public class SuggestionsAction implements ComponentsWsAction {

Map<String, ComponentDto> componentsByUuids = componentDtos.stream()
.collect(MoreCollectors.uniqueIndex(ComponentDto::uuid));
Map<String, OrganizationDto> organizationsByUuids = loadOrganizations(dbSession, componentsByUuids.values());
Map<String, ComponentDto> projectsByUuids = loadProjects(dbSession, componentsByUuids.values());
return toResponse(componentsPerQualifiers, recentlyBrowsedKeys, favoriteUuids, organizationsByUuids, componentsByUuids, projectsByUuids, coveredItems);
return toResponse(componentsPerQualifiers, recentlyBrowsedKeys, favoriteUuids, componentsByUuids, projectsByUuids, coveredItems);
}

private Map<String, ComponentDto> loadProjects(DbSession dbSession, Collection<ComponentDto> components) {
@@ -294,35 +289,26 @@ public class SuggestionsAction implements ComponentsWsAction {
.collect(MoreCollectors.uniqueIndex(ComponentDto::uuid));
}

private Map<String, OrganizationDto> loadOrganizations(DbSession dbSession, Collection<ComponentDto> components) {
Set<String> organizationUuids = components.stream()
.map(ComponentDto::getOrganizationUuid)
.collect(MoreCollectors.toSet());
return dbClient.organizationDao().selectByUuids(dbSession, organizationUuids).stream()
.collect(MoreCollectors.uniqueIndex(OrganizationDto::getUuid));
}

private ComponentIndexResults searchInIndex(SuggestionQuery suggestionQuery) {
return index.searchSuggestions(suggestionQuery);
}

private static SuggestionsWsResponse.Builder toResponse(ComponentIndexResults componentsPerQualifiers, Set<String> recentlyBrowsedKeys, Set<String> favoriteUuids,
Map<String, OrganizationDto> organizationsByUuids, Map<String, ComponentDto> componentsByUuids, Map<String, ComponentDto> projectsByUuids, int coveredItems) {
Map<String, ComponentDto> componentsByUuids, Map<String, ComponentDto> projectsByUuids, int coveredItems) {
if (componentsPerQualifiers.isEmpty()) {
return newBuilder();
}
return newBuilder()
.addAllResults(toCategories(componentsPerQualifiers, recentlyBrowsedKeys, favoriteUuids, componentsByUuids, organizationsByUuids, projectsByUuids, coveredItems))
.addAllOrganizations(toOrganizations(organizationsByUuids))
.addAllResults(toCategories(componentsPerQualifiers, recentlyBrowsedKeys, favoriteUuids, componentsByUuids, projectsByUuids, coveredItems))
.addAllProjects(toProjects(projectsByUuids));
}

private static List<Category> toCategories(ComponentIndexResults componentsPerQualifiers, Set<String> recentlyBrowsedKeys, Set<String> favoriteUuids,
Map<String, ComponentDto> componentsByUuids, Map<String, OrganizationDto> organizationByUuids, Map<String, ComponentDto> projectsByUuids, int coveredItems) {
Map<String, ComponentDto> componentsByUuids, Map<String, ComponentDto> projectsByUuids, int coveredItems) {
return componentsPerQualifiers.getQualifiers().map(qualifier -> {

List<Suggestion> suggestions = qualifier.getHits().stream()
.map(hit -> toSuggestion(hit, recentlyBrowsedKeys, favoriteUuids, componentsByUuids, organizationByUuids, projectsByUuids))
.map(hit -> toSuggestion(hit, recentlyBrowsedKeys, favoriteUuids, componentsByUuids, projectsByUuids))
.filter(Objects::nonNull)
.collect(toList());

@@ -340,17 +326,14 @@ public class SuggestionsAction implements ComponentsWsAction {
*/
@CheckForNull
private static Suggestion toSuggestion(ComponentHit hit, Set<String> recentlyBrowsedKeys, Set<String> favoriteUuids, Map<String, ComponentDto> componentsByUuids,
Map<String, OrganizationDto> organizationByUuids, Map<String, ComponentDto> projectsByUuids) {
Map<String, ComponentDto> projectsByUuids) {
ComponentDto result = componentsByUuids.get(hit.getUuid());
if (result == null
// SONAR-11419 this has happened in production while code does not really allow it. An inconsistency in DB may be the cause.
|| (QUALIFIERS_FOR_WHICH_TO_RETURN_PROJECT.contains(result.qualifier()) && projectsByUuids.get(result.projectUuid()) == null)) {
return null;
}
String organizationKey = organizationByUuids.get(result.getOrganizationUuid()).getKey();
checkState(organizationKey != null, "Organization with uuid '%s' not found", result.getOrganizationUuid());
Suggestion.Builder builder = Suggestion.newBuilder()
.setOrganization(organizationKey)
.setKey(result.getDbKey())
.setName(result.name())
.setMatch(hit.getHighlightedText().orElse(HtmlEscapers.htmlEscaper().escape(result.name())))
@@ -362,15 +345,6 @@ public class SuggestionsAction implements ComponentsWsAction {
return builder.build();
}

private static List<Organization> toOrganizations(Map<String, OrganizationDto> organizationByUuids) {
return organizationByUuids.values().stream()
.map(o -> Organization.newBuilder()
.setKey(o.getKey())
.setName(o.getName())
.build())
.collect(Collectors.toList());
}

private static List<Project> toProjects(Map<String, ComponentDto> projectsByUuids) {
return projectsByUuids.values().stream()
.map(p -> Project.newBuilder()

+ 7
- 9
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/TreeAction.java Wyświetl plik

@@ -48,7 +48,6 @@ import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTreeQuery;
import org.sonar.db.component.ComponentTreeQuery.Strategy;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.user.UserSession;
@@ -176,7 +175,6 @@ public class TreeAction implements ComponentsWsAction {
try (DbSession dbSession = dbClient.openSession(false)) {
ComponentDto baseComponent = loadComponent(dbSession, treeRequest);
checkPermissions(baseComponent);
OrganizationDto organizationDto = componentFinder.getOrganization(dbSession, baseComponent);

ComponentTreeQuery query = toComponentTreeQuery(treeRequest, baseComponent);
List<ComponentDto> components = dbClient.componentDao().selectDescendants(dbSession, query);
@@ -186,7 +184,7 @@ public class TreeAction implements ComponentsWsAction {

Map<String, ComponentDto> referenceComponentsByUuid = searchReferenceComponentsByUuid(dbSession, components);

return buildResponse(dbSession, baseComponent, organizationDto, components, referenceComponentsByUuid,
return buildResponse(dbSession, baseComponent, components, referenceComponentsByUuid,
Paging.forPageIndex(treeRequest.getPage()).withPageSize(treeRequest.getPageSize()).andTotal(total));
}
}
@@ -215,7 +213,7 @@ public class TreeAction implements ComponentsWsAction {
userSession.checkComponentPermission(UserRole.USER, baseComponent);
}

private TreeWsResponse buildResponse(DbSession dbSession, ComponentDto baseComponent, OrganizationDto organizationDto, List<ComponentDto> components,
private TreeWsResponse buildResponse(DbSession dbSession, ComponentDto baseComponent, List<ComponentDto> components,
Map<String, ComponentDto> referenceComponentsByUuid, Paging paging) {
TreeWsResponse.Builder response = TreeWsResponse.newBuilder();
response.getPagingBuilder()
@@ -224,26 +222,26 @@ public class TreeAction implements ComponentsWsAction {
.setTotal(paging.total())
.build();

response.setBaseComponent(toWsComponent(dbSession, baseComponent, organizationDto, referenceComponentsByUuid));
response.setBaseComponent(toWsComponent(dbSession, baseComponent, referenceComponentsByUuid));
for (ComponentDto dto : components) {
response.addComponents(toWsComponent(dbSession, dto, organizationDto, referenceComponentsByUuid));
response.addComponents(toWsComponent(dbSession, dto, referenceComponentsByUuid));
}

return response.build();
}

private Components.Component.Builder toWsComponent(DbSession dbSession, ComponentDto component, OrganizationDto organizationDto,
private Components.Component.Builder toWsComponent(DbSession dbSession, ComponentDto component,
Map<String, ComponentDto> referenceComponentsByUuid) {

Components.Component.Builder wsComponent;
if (component.getMainBranchProjectUuid() == null && component.isRootProject() &&
PROJECT_OR_APP_QUALIFIERS.contains(component.qualifier())) {
ProjectDto projectDto = componentFinder.getProjectOrApplicationByKey(dbSession, component.getKey());
wsComponent = projectOrAppToWsComponent(projectDto, organizationDto, null);
wsComponent = projectOrAppToWsComponent(projectDto, null);
} else {
Optional<ProjectDto> parentProject = dbClient.projectDao().selectByUuid(dbSession,
ofNullable(component.getMainBranchProjectUuid()).orElse(component.projectUuid()));
wsComponent = componentDtoToWsComponent(component, parentProject.orElse(null), organizationDto, null);
wsComponent = componentDtoToWsComponent(component, parentProject.orElse(null), null);
}

ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyResourceUuid());

+ 0
- 1
server/sonar-webserver-webapi/src/main/java/org/sonar/server/project/ws/CreateAction.java Wyświetl plik

@@ -112,7 +112,6 @@ public class CreateAction implements ProjectsWsAction {
support.checkCanUpdateProjectsVisibility(organization, changeToPrivate);

ComponentDto componentDto = componentUpdater.create(dbSession, newComponentBuilder()
.setOrganizationUuid(organization.getUuid())
.setKey(request.getProjectKey())
.setName(request.getName())
.setPrivate(changeToPrivate)

+ 14
- 18
server/sonar-webserver-webapi/src/main/java/org/sonar/server/ui/ws/ComponentAction.java Wyświetl plik

@@ -54,8 +54,6 @@ import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.organization.BillingValidations;
import org.sonar.server.organization.BillingValidationsProxy;
import org.sonar.server.project.Visibility;
import org.sonar.server.qualitygate.QualityGateFinder;
import org.sonar.server.qualityprofile.QPMeasureData;
@@ -99,17 +97,15 @@ public class ComponentAction implements NavigationWsAction {
private final UserSession userSession;
private final ComponentFinder componentFinder;
private final QualityGateFinder qualityGateFinder;
private final BillingValidationsProxy billingValidations;

public ComponentAction(DbClient dbClient, PageRepository pageRepository, ResourceTypes resourceTypes, UserSession userSession,
ComponentFinder componentFinder, QualityGateFinder qualityGateFinder, BillingValidationsProxy billingValidations) {
ComponentFinder componentFinder, QualityGateFinder qualityGateFinder) {
this.dbClient = dbClient;
this.pageRepository = pageRepository;
this.resourceTypes = resourceTypes;
this.userSession = userSession;
this.componentFinder = componentFinder;
this.qualityGateFinder = qualityGateFinder;
this.billingValidations = billingValidations;
}

@Override
@@ -158,19 +154,18 @@ public class ComponentAction implements NavigationWsAction {
!userSession.isSystemAdministrator()) {
throw insufficientPrivilegesException();
}
OrganizationDto org = componentFinder.getOrganization(session, component);
Optional<SnapshotDto> analysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(session, component.projectUuid());

try (JsonWriter json = response.newJsonWriter()) {
json.beginObject();
boolean isFavourite = isFavourite(session, rootProject);
writeComponent(json, component, org, analysis.orElse(null), isFavourite);
writeComponent(json, component, analysis.orElse(null), isFavourite);
writeProfiles(json, session, component);
writeQualityGate(json, session, org, rootProject);
writeQualityGate(json, session, rootProject);
if (userSession.hasComponentPermission(ADMIN, component) ||
userSession.hasPermission(ADMINISTER_QUALITY_PROFILES) ||
userSession.hasPermission(ADMINISTER_QUALITY_GATES)) {
writeConfiguration(json, component, org);
writeConfiguration(json, component);
}
writeBreadCrumbs(json, session, component);
json.endObject().close();
@@ -206,9 +201,8 @@ public class ComponentAction implements NavigationWsAction {
.endObject();
}

private void writeComponent(JsonWriter json, ComponentDto component, OrganizationDto organizationDto, @Nullable SnapshotDto analysis, boolean isFavourite) {
private void writeComponent(JsonWriter json, ComponentDto component, @Nullable SnapshotDto analysis, boolean isFavourite) {
json.prop("key", component.getKey())
.prop("organization", organizationDto.getKey())
.prop("id", component.uuid())
.prop("name", component.name())
.prop("description", component.description())
@@ -251,8 +245,11 @@ public class ComponentAction implements NavigationWsAction {
json.endArray();
}

private void writeQualityGate(JsonWriter json, DbSession session, OrganizationDto organization, ComponentDto component) {
QualityGateFinder.QualityGateData qualityGateData = qualityGateFinder.getQualityGate(session, organization, component.uuid())
private void writeQualityGate(JsonWriter json, DbSession session, ComponentDto component) {
// TODO:: remove while dropping for quality gate
OrganizationDto organizationDto = dbClient.organizationDao().selectByUuid(session, component.getOrganizationUuid())
.orElseThrow(IllegalStateException::new);
QualityGateFinder.QualityGateData qualityGateData = qualityGateFinder.getQualityGate(session, organizationDto, component.uuid())
.orElseThrow(() -> new NotFoundException(format("Quality Gate not found for %s", component.getKey())));
QualityGateDto qualityGateDto = qualityGateData.getQualityGate();
json.name("qualityGate").beginObject()
@@ -274,11 +271,11 @@ public class ComponentAction implements NavigationWsAction {
json.endArray();
}

private void writeConfiguration(JsonWriter json, ComponentDto component, OrganizationDto organization) {
private void writeConfiguration(JsonWriter json, ComponentDto component) {
boolean isProjectAdmin = userSession.hasComponentPermission(ADMIN, component);

json.name("configuration").beginObject();
writeConfigPageAccess(json, isProjectAdmin, component, organization);
writeConfigPageAccess(json, isProjectAdmin, component);

if (isProjectAdmin) {
json.name("extensions").beginArray();
@@ -289,7 +286,7 @@ public class ComponentAction implements NavigationWsAction {
json.endObject();
}

private void writeConfigPageAccess(JsonWriter json, boolean isProjectAdmin, ComponentDto component, OrganizationDto organization) {
private void writeConfigPageAccess(JsonWriter json, boolean isProjectAdmin, ComponentDto component) {
boolean isProject = Qualifiers.PROJECT.equals(component.qualifier());
boolean showManualMeasures = isProjectAdmin && !Qualifiers.DIRECTORY.equals(component.qualifier());
boolean showBackgroundTasks = isProjectAdmin && (isProject || Qualifiers.VIEW.equals(component.qualifier()) || Qualifiers.APP.equals(component.qualifier()));
@@ -309,8 +306,7 @@ public class ComponentAction implements NavigationWsAction {
json.prop("showBackgroundTasks", showBackgroundTasks);
json.prop("canApplyPermissionTemplate", isOrganizationAdmin);
json.prop("canBrowseProject", canBrowseProject);
json.prop("canUpdateProjectVisibilityToPrivate", isProjectAdmin &&
billingValidations.canUpdateProjectVisibilityToPrivate(new BillingValidations.Organization(organization.getKey(), organization.getUuid(), organization.getName())));
json.prop("canUpdateProjectVisibilityToPrivate", isProjectAdmin);
}

private boolean componentTypeHasProperty(ComponentDto component, String resourceTypeProperty) {

+ 0
- 1
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/search-components-example.json Wyświetl plik

@@ -6,7 +6,6 @@
},
"components": [
{
"organization": "my-org-1",
"key": "project-key",
"qualifier": "TRK",
"name": "Project Name",

+ 0
- 13
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/search_projects-example.json Wyświetl plik

@@ -4,19 +4,8 @@
"pageSize": 100,
"total": 3
},
"organizations": [
{
"key": "my-org-key-1",
"name": "Foo"
},
{
"key": "my-org-key-2",
"name": "Bar"
}
],
"components": [
{
"organization": "my-org-key-1",
"key": "my_project",
"name": "My Project 1",
"qualifier": "TRK",
@@ -29,7 +18,6 @@
"needIssueSync": true
},
{
"organization": "my-org-key-1",
"key": "another_project",
"name": "My Project 2",
"qualifier": "TRK",
@@ -39,7 +27,6 @@
"needIssueSync": false
},
{
"organization": "my-org-key-2",
"key": "third_project",
"name": "My Project 3",
"qualifier": "TRK",

+ 0
- 3
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/show-example.json Wyświetl plik

@@ -1,6 +1,5 @@
{
"component": {
"organization": "my-org-1",
"key": "com.sonarsource:java-markdown:src/main/java/com/sonarsource/markdown/impl/Rule.java",
"name": "Rule.java",
"qualifier": "FIL",
@@ -12,7 +11,6 @@
},
"ancestors": [
{
"organization": "my-org-1",
"key": "com.sonarsource:java-markdown:src/main/java/com/sonarsource/markdown/impl",
"name": "src/main/java/com/sonarsource/markdown/impl",
"qualifier": "DIR",
@@ -21,7 +19,6 @@
"version": "1.1"
},
{
"organization": "my-org-1",
"key": "com.sonarsource:java-markdown",
"name": "Java Markdown",
"description": "Java Markdown Project",

+ 0
- 8
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/suggestions-example.json Wyświetl plik

@@ -22,7 +22,6 @@
"key": "org.sonarsource:sonarqube",
"name": "SonarSource :: SonarQube",
"match": "<mark>Sonar</mark>Source :: <mark>Sonar</mark>Qube",
"organization": "default-organization",
"project": "",
"isRecentlyBrowsed": true,
"isFavorite": false
@@ -31,7 +30,6 @@
"key": "org.sonarsource:sonarlint",
"name": "SonarSource :: SonarLint",
"match": "<mark>Sonar</mark>Source :: <mark>Sonar</mark>Lint",
"organization": "default-organization",
"project": "",
"isRecentlyBrowsed": false,
"isFavorite": false
@@ -40,12 +38,6 @@
"more": 0
}
],
"organizations": [
{
"key": "default-organization",
"name": "Default Organization"
}
],
"projects": [
]
}

+ 2
- 6
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/component/ws/tree-example.json Wyświetl plik

@@ -5,7 +5,6 @@
"total": 3
},
"baseComponent": {
"organization": "my-org-1",
"key": "MY_PROJECT_KEY",
"description": "MY_PROJECT_DESCRIPTION",
"qualifier": "TRK",
@@ -17,23 +16,20 @@
},
"components": [
{
"organization": "my-org-1",
"key": "com.sonarsource:java-markdown:src/test/java/com/sonarsource/markdown/BasicMarkdownParser.java",
"name": "BasicMarkdownParser.java",
"qualifier": "UTS",
"path": "src/test/java/com/sonarsource/markdown/BasicMarkdownParser.java",
"language":"java"
"language": "java"
},
{
"organization": "my-org-1",
"key": "com.sonarsource:java-markdown:src/test/java/com/sonarsource/markdown/BasicMarkdownParserTest.java",
"name": "BasicMarkdownParserTest.java",
"qualifier": "UTS",
"path": "src/test/java/com/sonarsource/markdown/BasicMarkdownParserTest.java",
"language":"java"
"language": "java"
},
{
"organization": "my-org-1",
"key": "com.sonarsource:java-markdown:src/main/java/com/sonarsource/markdown",
"name": "src/main/java/com/sonarsource/markdown",
"qualifier": "DIR",

+ 0
- 1
server/sonar-webserver-webapi/src/main/resources/org/sonar/server/ui/ws/component-example.json Wyświetl plik

@@ -1,5 +1,4 @@
{
"organization": "my-org-1",
"key": "org.codehaus.sonar:sonar",
"id": "ABCD",
"name": "Sonarqube",

+ 1
- 1
server/sonar-webserver-webapi/src/test/java/org/sonar/server/ce/queue/ReportSubmitterTest.java Wyświetl plik

@@ -87,7 +87,7 @@ public class ReportSubmitterTest {
private final TestProjectIndexers projectIndexers = new TestProjectIndexers();
private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
private final ComponentUpdater componentUpdater = new ComponentUpdater(db.getDbClient(), mock(I18n.class), mock(System2.class), permissionTemplateService,
new FavoriteUpdater(db.getDbClient()), projectIndexers, new SequenceUuidFactory());
new FavoriteUpdater(db.getDbClient()), projectIndexers, new SequenceUuidFactory(), defaultOrganizationProvider);
private final BranchSupport ossEditionBranchSupport = new BranchSupport();

private final ReportSubmitter underTest = new ReportSubmitter(queue, userSession, componentUpdater, permissionTemplateService, db.getDbClient(), ossEditionBranchSupport,

+ 10
- 16
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentCleanerServiceTest.java Wyświetl plik

@@ -21,7 +21,6 @@ package org.sonar.server.component;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.ResourceType;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.utils.System2;
@@ -33,7 +32,6 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.issue.IssueDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.webhook.WebhookDto;
@@ -41,6 +39,7 @@ import org.sonar.server.es.TestProjectIndexers;

import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -52,10 +51,7 @@ public class ComponentCleanerServiceTest {
private final System2 system2 = System2.INSTANCE;

@Rule
public DbTester db = DbTester.create(system2);

@Rule
public ExpectedException expectedException = ExpectedException.none();
public final DbTester db = DbTester.create(system2);

private final DbClient dbClient = db.getDbClient();
private final DbSession dbSession = db.getSession();
@@ -128,14 +124,13 @@ public class ComponentCleanerServiceTest {

@Test
public void delete_webhooks_from_projects() {
OrganizationDto organization = db.organizations().insert();
ProjectDto project1 = db.components().insertPrivateProjectDto(organization);
ProjectDto project1 = db.components().insertPrivateProjectDto();
WebhookDto webhook1 = db.webhooks().insertWebhook(project1);
db.webhookDelivery().insert(webhook1);
ProjectDto project2 = db.components().insertPrivateProjectDto(organization);
ProjectDto project2 = db.components().insertPrivateProjectDto();
WebhookDto webhook2 = db.webhooks().insertWebhook(project2);
db.webhookDelivery().insert(webhook2);
ProjectDto projectNotToBeDeleted = db.components().insertPrivateProjectDto(organization);
ProjectDto projectNotToBeDeleted = db.components().insertPrivateProjectDto();
WebhookDto webhook3 = db.webhooks().insertWebhook(projectNotToBeDeleted);
db.webhookDelivery().insert(webhook3);

@@ -153,19 +148,18 @@ public class ComponentCleanerServiceTest {
@Test
public void fail_with_IAE_if_not_a_project() {
mockResourceTypeAsValidProject();
ComponentDto project = ComponentTesting.newPrivateProjectDto(db.organizations().insert());
dbClient.componentDao().insert(dbSession, project);
ComponentDto project = ComponentTesting.newPrivateProjectDto();
db.components().insertComponent(project);
ComponentDto file = newFileDto(project, null);
dbClient.componentDao().insert(dbSession, file);
dbSession.commit();

expectedException.expect(IllegalArgumentException.class);
underTest.delete(dbSession, file);
assertThatThrownBy(() -> underTest.delete(dbSession, file))
.isInstanceOf(IllegalArgumentException.class);
}

private DbData insertProjectData() {
OrganizationDto organization = db.organizations().insert();
ComponentDto componentDto = db.components().insertPublicProject(organization);
ComponentDto componentDto = db.components().insertPublicProject();
ProjectDto project = dbClient.projectDao().selectByUuid(dbSession, componentDto.uuid()).get();
BranchDto branch = dbClient.branchDao().selectByUuid(dbSession, project.getUuid()).get();


+ 54
- 64
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentFinderTest.java Wyświetl plik

@@ -21,7 +21,6 @@ package org.sonar.server.component;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
@@ -30,6 +29,7 @@ import org.sonar.server.exceptions.NotFoundException;

import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.sonar.db.component.BranchType.PULL_REQUEST;
import static org.sonar.db.component.ComponentTesting.newDirectory;
import static org.sonar.db.component.ComponentTesting.newFileDto;
@@ -39,60 +39,52 @@ import static org.sonar.server.component.ComponentFinder.ParamNames.ID_AND_KEY;

public class ComponentFinderTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);

private final DbSession dbSession = db.getSession();
private ComponentFinder underTest = TestComponentFinder.from(db);
private final ComponentFinder underTest = TestComponentFinder.from(db);

@Test
public void fail_when_the_uuid_and_key_are_null() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Either 'id' or 'key' must be provided");

underTest.getByUuidOrKey(dbSession, null, null, ID_AND_KEY);
assertThatThrownBy(() -> underTest.getByUuidOrKey(dbSession, null, null, ID_AND_KEY))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Either 'id' or 'key' must be provided");
}

@Test
public void fail_when_the_uuid_and_key_are_provided() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Either 'id' or 'key' must be provided");

underTest.getByUuidOrKey(dbSession, "project-uuid", "project-key", ID_AND_KEY);
assertThatThrownBy(() -> underTest.getByUuidOrKey(dbSession, "project-uuid", "project-key", ID_AND_KEY))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Either 'id' or 'key' must be provided");
}

@Test
public void fail_when_the_uuid_is_empty() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'id' parameter must not be empty");

underTest.getByUuidOrKey(dbSession, "", null, ID_AND_KEY);
assertThatThrownBy(() -> underTest.getByUuidOrKey(dbSession, "", null, ID_AND_KEY))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("The 'id' parameter must not be empty");
}

@Test
public void fail_when_the_key_is_empty() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'key' parameter must not be empty");

underTest.getByUuidOrKey(dbSession, null, "", ID_AND_KEY);
assertThatThrownBy(() -> underTest.getByUuidOrKey(dbSession, null, "", ID_AND_KEY))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("The 'key' parameter must not be empty");
}

@Test
public void fail_when_component_uuid_not_found() {
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Component id 'project-uuid' not found");

underTest.getByUuidOrKey(dbSession, "project-uuid", null, ID_AND_KEY);
assertThatThrownBy(() -> underTest.getByUuidOrKey(dbSession, "project-uuid", null, ID_AND_KEY))
.isInstanceOf(NotFoundException.class)
.hasMessage("Component id 'project-uuid' not found");
}

@Test
public void fail_when_component_key_not_found() {
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Component key 'project-key' not found");

underTest.getByUuidOrKey(dbSession, null, "project-key", ID_AND_KEY);
assertThatThrownBy(() -> underTest.getByUuidOrKey(dbSession, null, "project-key", ID_AND_KEY))
.isInstanceOf(NotFoundException.class)
.hasMessage("Component key 'project-key' not found");
}

@Test
@@ -100,10 +92,10 @@ public class ComponentFinderTest {
ComponentDto project = db.components().insertPublicProject();
ComponentDto branch = db.components().insertProjectBranch(project);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(format("Component id '%s' not found", branch.uuid()));
underTest.getByUuidOrKey(dbSession, branch.uuid(), null, ID_AND_KEY);
String branchUuid = branch.uuid();
assertThatThrownBy(() -> underTest.getByUuidOrKey(dbSession, branchUuid, null, ID_AND_KEY))
.isInstanceOf(NotFoundException.class)
.hasMessage(format("Component id '%s' not found", branchUuid));
}

@Test
@@ -111,21 +103,20 @@ public class ComponentFinderTest {
ComponentDto project = db.components().insertPublicProject();
ComponentDto branch = db.components().insertProjectBranch(project);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey()));
underTest.getByUuidOrKey(dbSession, null, branch.getDbKey(), ID_AND_KEY);
String branchDbKey = branch.getDbKey();
assertThatThrownBy(() -> underTest.getByUuidOrKey(dbSession, null, branchDbKey, ID_AND_KEY))
.isInstanceOf(NotFoundException.class)
.hasMessage(format("Component key '%s' not found", branch.getDbKey()));
}

@Test
public void fail_when_component_uuid_is_removed() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization()));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
db.components().insertComponent(newFileDto(project, null, "file-uuid").setEnabled(false));

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Component id 'file-uuid' not found");

underTest.getByUuid(dbSession, "file-uuid");
assertThatThrownBy(() -> underTest.getByUuid(dbSession, "file-uuid"))
.isInstanceOf(NotFoundException.class)
.hasMessage("Component id 'file-uuid' not found");
}

@Test
@@ -133,21 +124,20 @@ public class ComponentFinderTest {
ComponentDto project = db.components().insertPublicProject();
ComponentDto branch = db.components().insertProjectBranch(project);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(format("Component id '%s' not found", branch.uuid()));
underTest.getByUuid(dbSession, branch.uuid());
String branchUuid = branch.uuid();
assertThatThrownBy(() -> underTest.getByUuid(dbSession, branchUuid))
.isInstanceOf(NotFoundException.class)
.hasMessage(format("Component id '%s' not found", branchUuid));
}

@Test
public void fail_when_component_key_is_removed() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization()));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
db.components().insertComponent(newFileDto(project).setDbKey("file-key").setEnabled(false));

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Component key 'file-key' not found");

underTest.getByKey(dbSession, "file-key");
assertThatThrownBy(() -> underTest.getByKey(dbSession, "file-key"))
.isInstanceOf(NotFoundException.class)
.hasMessage("Component key 'file-key' not found");
}

@Test
@@ -155,15 +145,15 @@ public class ComponentFinderTest {
ComponentDto project = db.components().insertPublicProject();
ComponentDto branch = db.components().insertProjectBranch(project);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey()));
underTest.getByKey(dbSession, branch.getDbKey());
String branchDbKey = branch.getDbKey();
assertThatThrownBy(() -> underTest.getByKey(dbSession, branchDbKey))
.isInstanceOf(NotFoundException.class)
.hasMessage(format("Component key '%s' not found", branchDbKey));
}

@Test
public void get_component_by_uuid() {
db.components().insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
db.components().insertComponent(newPrivateProjectDto("project-uuid"));

ComponentDto component = underTest.getByUuidOrKey(dbSession, "project-uuid", null, ID_AND_KEY);

@@ -172,7 +162,7 @@ public class ComponentFinderTest {

@Test
public void get_component_by_key() {
db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization()).setDbKey("project-key"));
db.components().insertComponent(newPrivateProjectDto().setDbKey("project-key"));

ComponentDto component = underTest.getByUuidOrKey(dbSession, null, "project-key", ID_AND_KEY);

@@ -212,10 +202,10 @@ public class ComponentFinderTest {
ComponentDto project = db.components().insertPublicProject();
ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setKey("pr-123").setBranchType(PULL_REQUEST));

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Either branch or pull request can be provided, not both");
assertThat(underTest.getByKeyAndOptionalBranchOrPullRequest(dbSession, project.getKey(), "pr-123", "pr-123").uuid()).isEqualTo(pullRequest.uuid());
String projectKey = project.getKey();
assertThatThrownBy(() -> underTest.getByKeyAndOptionalBranchOrPullRequest(dbSession, projectKey, "pr-123", "pr-123"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Either branch or pull request can be provided, not both");
}

@Test
@@ -231,9 +221,9 @@ public class ComponentFinderTest {
ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
ComponentDto file = db.components().insertComponent(newFileDto(branch));

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(format("Component '%s' on branch 'other_branch' not found", file.getKey()));
underTest.getByKeyAndBranch(dbSession, file.getKey(), "other_branch");
String fileKey = file.getKey();
assertThatThrownBy(() -> underTest.getByKeyAndBranch(dbSession, fileKey, "other_branch"))
.isInstanceOf(NotFoundException.class)
.hasMessage(format("Component '%s' on branch 'other_branch' not found", fileKey));
}
}

+ 10
- 13
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentServiceTest.java Wyświetl plik

@@ -21,7 +21,6 @@ package org.sonar.server.component;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
@@ -40,28 +39,26 @@ import static org.sonar.db.component.ComponentTesting.newModuleDto;
public class ComponentServiceTest {

@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
public final UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester dbTester = DbTester.create(System2.INSTANCE);
public final DbTester dbTester = DbTester.create(System2.INSTANCE);

private ComponentDbTester componentDb = new ComponentDbTester(dbTester);
private DbClient dbClient = dbTester.getDbClient();
private DbSession dbSession = dbTester.getSession();
private TestProjectIndexers projectIndexers = new TestProjectIndexers();
private ProjectLifeCycleListeners projectLifeCycleListeners = mock(ProjectLifeCycleListeners.class);
private final ComponentDbTester componentDb = new ComponentDbTester(dbTester);
private final DbClient dbClient = dbTester.getDbClient();
private final DbSession dbSession = dbTester.getSession();
private final TestProjectIndexers projectIndexers = new TestProjectIndexers();
private final ProjectLifeCycleListeners projectLifeCycleListeners = mock(ProjectLifeCycleListeners.class);

private ComponentService underTest = new ComponentService(dbClient, userSession, projectIndexers, projectLifeCycleListeners);
private final ComponentService underTest = new ComponentService(dbClient, userSession, projectIndexers, projectLifeCycleListeners);

@Test
public void bulk_update() {
ComponentDto project = componentDb.insertPublicProject(dbTester.organizations().insert(), c -> c.setDbKey("my_project"));
ComponentDto project = componentDb.insertPublicProject(c -> c.setDbKey("my_project"));
ComponentDto module = componentDb.insertComponent(newModuleDto(project).setDbKey("my_project:root:module"));
ComponentDto inactiveModule = componentDb.insertComponent(newModuleDto(project).setDbKey("my_project:root:inactive_module").setEnabled(false));
ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/File.xoo"));
ComponentDto inactiveFile = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/InactiveFile.xoo").setEnabled(false));
underTest.bulkUpdateKey(dbSession, componentDb.getProjectDto(project), "my_", "your_");

assertComponentKeyUpdated(project.getDbKey(), "your_project");

+ 25
- 24
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentServiceUpdateKeyTest.java Wyświetl plik

@@ -22,7 +22,6 @@ package org.sonar.server.component;
import com.google.common.collect.ImmutableSet;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
@@ -31,6 +30,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.db.project.ProjectDto;
import org.sonar.server.es.ProjectIndexer;
import org.sonar.server.es.TestProjectIndexers;
import org.sonar.server.exceptions.ForbiddenException;
@@ -41,6 +41,7 @@ import org.sonar.server.tester.UserSessionRule;

import static java.util.Collections.emptyList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.sonar.db.component.ComponentTesting.newFileDto;
@@ -48,14 +49,12 @@ import static org.sonar.db.component.ComponentTesting.newModuleDto;

public class ComponentServiceUpdateKeyTest {

private System2 system2 = System2.INSTANCE;
private final System2 system2 = System2.INSTANCE;

@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
public final UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester db = DbTester.create(system2);
public final DbTester db = DbTester.create(system2);

private ComponentDbTester componentDb = new ComponentDbTester(db);
private DbClient dbClient = db.getDbClient();
@@ -106,12 +105,12 @@ public class ComponentServiceUpdateKeyTest {

@Test
public void fail_to_update_project_key_without_admin_permission() {
expectedException.expect(ForbiddenException.class);

ComponentDto project = insertSampleProject();
userSession.logIn("john").addProjectPermission(UserRole.USER, project);

underTest.updateKey(dbSession, componentDb.getProjectDto(project), "sample2:root");
ProjectDto projectDto = componentDb.getProjectDto(project);
assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto, "sample2:root"))
.isInstanceOf(ForbiddenException.class);
}

@Test
@@ -120,10 +119,12 @@ public class ComponentServiceUpdateKeyTest {
ComponentDto anotherProject = componentDb.insertPrivateProject();
logInAsProjectAdministrator(project);

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Impossible to update key: a component with key \"" + anotherProject.getDbKey() + "\" already exists.");

underTest.updateKey(dbSession, componentDb.getProjectDto(project), anotherProject.getDbKey());
ProjectDto projectDto = componentDb.getProjectDto(project);
String anotherProjectDbKey = anotherProject.getDbKey();
assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto,
anotherProjectDbKey))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Impossible to update key: a component with key \"" + anotherProjectDbKey + "\" already exists.");
}

@Test
@@ -131,10 +132,10 @@ public class ComponentServiceUpdateKeyTest {
ComponentDto project = insertSampleProject();
logInAsProjectAdministrator(project);

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Malformed key for ''. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
underTest.updateKey(dbSession, componentDb.getProjectDto(project), "");
ProjectDto projectDto = componentDb.getProjectDto(project);
assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto, ""))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Malformed key for ''. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
}

@Test
@@ -142,15 +143,15 @@ public class ComponentServiceUpdateKeyTest {
ComponentDto project = insertSampleProject();
logInAsProjectAdministrator(project);

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Malformed key for 'sample?root'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
underTest.updateKey(dbSession, componentDb.getProjectDto(project), "sample?root");
ProjectDto projectDto = componentDb.getProjectDto(project);
assertThatThrownBy(() -> underTest.updateKey(dbSession, projectDto, "sample?root"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Malformed key for 'sample?root'. Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.");
}

@Test
public void bulk_update_key() {
ComponentDto project = componentDb.insertPublicProject(db.organizations().insert(), c -> c.setDbKey("my_project"));
ComponentDto project = componentDb.insertPublicProject(c -> c.setDbKey("my_project"));
ComponentDto module = componentDb.insertComponent(newModuleDto(project).setDbKey("my_project:root:module"));
ComponentDto inactiveModule = componentDb.insertComponent(newModuleDto(project).setDbKey("my_project:root:inactive_module").setEnabled(false));
ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/File.xoo"));
@@ -169,7 +170,7 @@ public class ComponentServiceUpdateKeyTest {

@Test
public void bulk_update_key_with_branch_and_pr() {
ComponentDto project = componentDb.insertPublicProject(db.organizations().insert(), c -> c.setDbKey("my_project"));
ComponentDto project = componentDb.insertPublicProject(c -> c.setDbKey("my_project"));
ComponentDto branch = componentDb.insertProjectBranch(project);
ComponentDto module = componentDb.insertComponent(newModuleDto(branch).setDbKey("my_project:root:module"));
ComponentDto file = componentDb.insertComponent(newFileDto(module, null).setDbKey("my_project:root:module:src/File.xoo"));
@@ -193,7 +194,7 @@ public class ComponentServiceUpdateKeyTest {
}

private ComponentDto insertProject(String key) {
return componentDb.insertPrivateProject(db.organizations().insert(), c -> c.setDbKey(key));
return componentDb.insertPrivateProject(c -> c.setDbKey(key));
}

private void assertComponentKeyHasBeenUpdated(String oldKey, String newKey) {

+ 34
- 69
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java Wyświetl plik

@@ -22,7 +22,6 @@ package org.sonar.server.component;
import java.util.Optional;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.api.utils.System2;
@@ -32,17 +31,19 @@ import org.sonar.db.DbTester;
import org.sonar.db.component.BranchDto;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.es.ProjectIndexer;
import org.sonar.server.es.TestProjectIndexers;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.favorite.FavoriteUpdater;
import org.sonar.server.l18n.I18nRule;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.permission.PermissionTemplateService;

import static java.util.stream.IntStream.rangeClosed;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -56,29 +57,27 @@ public class ComponentUpdaterTest {
private static final String DEFAULT_PROJECT_KEY = "project-key";
private static final String DEFAULT_PROJECT_NAME = "project-name";

private System2 system2 = System2.INSTANCE;
private final System2 system2 = System2.INSTANCE;

@Rule
public ExpectedException expectedException = ExpectedException.none();
public final DbTester db = DbTester.create(system2);
@Rule
public DbTester db = DbTester.create(system2);
@Rule
public I18nRule i18n = new I18nRule().put("qualifier.TRK", "Project");
public final I18nRule i18n = new I18nRule().put("qualifier.TRK", "Project");

private TestProjectIndexers projectIndexers = new TestProjectIndexers();
private PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
private final TestProjectIndexers projectIndexers = new TestProjectIndexers();
private final PermissionTemplateService permissionTemplateService = mock(PermissionTemplateService.class);
private final DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);

private ComponentUpdater underTest = new ComponentUpdater(db.getDbClient(), i18n, system2,
permissionTemplateService,
new FavoriteUpdater(db.getDbClient()),
projectIndexers, new SequenceUuidFactory());
projectIndexers, new SequenceUuidFactory(), defaultOrganizationProvider);

@Test
public void persist_and_index_when_creating_project() {
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.setPrivate(true)
.build();
ComponentDto returned = underTest.create(db.getSession(), project, null);
@@ -89,7 +88,6 @@ public class ComponentUpdaterTest {
assertThat(loaded.longName()).isEqualTo(DEFAULT_PROJECT_NAME);
assertThat(loaded.qualifier()).isEqualTo(Qualifiers.PROJECT);
assertThat(loaded.scope()).isEqualTo(Scopes.PROJECT);
assertThat(loaded.getOrganizationUuid()).isEqualTo(db.getDefaultOrganization().getUuid());
assertThat(loaded.uuid()).isNotNull();
assertThat(loaded.projectUuid()).isEqualTo(loaded.uuid());
assertThat(loaded.moduleUuid()).isNull();
@@ -111,11 +109,9 @@ public class ComponentUpdaterTest {

@Test
public void persist_private_flag_true_when_creating_project() {
OrganizationDto organization = db.organizations().insert();
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(organization.getUuid())
.setPrivate(true)
.build();
ComponentDto returned = underTest.create(db.getSession(), project, null);
@@ -125,11 +121,9 @@ public class ComponentUpdaterTest {

@Test
public void persist_private_flag_false_when_creating_project() {
OrganizationDto organization = db.organizations().insert();
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(organization.getUuid())
.setPrivate(false)
.build();
ComponentDto returned = underTest.create(db.getSession(), project, null);
@@ -143,7 +137,6 @@ public class ComponentUpdaterTest {
.setKey("view-key")
.setName("view-name")
.setQualifier(VIEW)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();

ComponentDto returned = underTest.create(db.getSession(), view, null);
@@ -163,7 +156,6 @@ public class ComponentUpdaterTest {
.setKey("app-key")
.setName("app-name")
.setQualifier(APP)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();

ComponentDto returned = underTest.create(db.getSession(), application, null);
@@ -188,7 +180,6 @@ public class ComponentUpdaterTest {
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();
ComponentDto dto = underTest.create(db.getSession(), project, userUuid);

@@ -201,7 +192,6 @@ public class ComponentUpdaterTest {
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();
when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(any(DbSession.class), any(ComponentDto.class)))
.thenReturn(true);
@@ -218,7 +208,6 @@ public class ComponentUpdaterTest {
NewComponent project = NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build();
when(permissionTemplateService.hasDefaultTemplateWithPermissionOnProjectCreator(eq(db.getSession()), any(ComponentDto.class)))
.thenReturn(true);
@@ -236,7 +225,6 @@ public class ComponentUpdaterTest {
NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build(),
null);

@@ -249,7 +237,6 @@ public class ComponentUpdaterTest {
NewComponent.newComponentBuilder()
.setKey(DEFAULT_PROJECT_KEY)
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build(),
null);

@@ -260,59 +247,37 @@ public class ComponentUpdaterTest {
public void fail_when_project_key_already_exists() {
ComponentDto existing = db.components().insertPrivateProject();

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Could not create Project, key already exists: " + existing.getDbKey());

underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
.setKey(existing.getDbKey())
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(existing.getOrganizationUuid())
.build(),
null);
}

@Test
public void fail_when_project_key_already_exists_on_other_organization() {
ComponentDto existing = db.components().insertPrivateProject(db.organizations().insert());

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Could not create Project, key already exists: " + existing.getDbKey());

underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
.setKey(existing.getDbKey())
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(existing.getOrganizationUuid())
.build(),
null);
DbSession session = db.getSession();
NewComponent newComponent = NewComponent.newComponentBuilder()
.setKey(existing.getDbKey())
.setName(DEFAULT_PROJECT_NAME)
.build();
assertThatThrownBy(() -> underTest.create(session, newComponent, null))
.isInstanceOf(BadRequestException.class)
.hasMessage("Could not create Project, key already exists: " + existing.getDbKey());
}

@Test
public void fail_when_key_has_bad_format() {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Malformed key for Project: '1234'");

underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
.setKey("1234")
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build(),
null);
DbSession session = db.getSession();
NewComponent newComponent = NewComponent.newComponentBuilder()
.setKey("1234")
.setName(DEFAULT_PROJECT_NAME)
.build();
assertThatThrownBy(() -> underTest.create(session, newComponent, null))
.isInstanceOf(BadRequestException.class)
.hasMessageContaining("Malformed key for Project: '1234'");
}

@Test
public void fail_when_key_contains_percent_character() {
expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Malformed key for Project: 'roject%Key'");

underTest.create(db.getSession(),
NewComponent.newComponentBuilder()
.setKey("roject%Key")
.setName(DEFAULT_PROJECT_NAME)
.setOrganizationUuid(db.getDefaultOrganization().getUuid())
.build(),
null);
DbSession session = db.getSession();
NewComponent newComponent = NewComponent.newComponentBuilder()
.setKey("roject%Key")
.setName(DEFAULT_PROJECT_NAME)
.build();
assertThatThrownBy(() -> underTest.create(session, newComponent, null))
.isInstanceOf(BadRequestException.class)
.hasMessageContaining("Malformed key for Project: 'roject%Key'");
}
}

+ 15
- 35
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/NewComponentTest.java Wyświetl plik

@@ -19,33 +19,23 @@
*/
package org.sonar.server.component;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static com.google.common.base.Strings.repeat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.server.component.NewComponent.newComponentBuilder;

public class NewComponentTest {
private static final String ORGANIZATION_UUID = "org1";
private static final String KEY = "key";
private static final String NAME = "name";

@Rule
public ExpectedException expectedException = ExpectedException.none();

private NewComponent.Builder underTest = newComponentBuilder();

@Test
public void build_throws_NPE_if_organizationUuid_is_null() {
expectBuildException(NullPointerException.class, "organization uuid can't be null");
}
private final NewComponent.Builder underTest = newComponentBuilder();

@Test
public void build_throws_IAE_when_key_is_null() {
underTest.setOrganizationUuid(ORGANIZATION_UUID);
underTest.setKey(null);

expectBuildException(IllegalArgumentException.class, "Component key can't be empty");
}
@@ -53,16 +43,14 @@ public class NewComponentTest {
@Test
public void build_throws_IAE_when_key_is_empty() {
underTest
.setKey("")
.setOrganizationUuid(ORGANIZATION_UUID);
.setKey("");

expectBuildException(IllegalArgumentException.class, "Component key can't be empty");
}

@Test
public void build_throws_IAE_when_key_is_longer_than_400_characters() {
underTest.setOrganizationUuid(ORGANIZATION_UUID)
.setKey(repeat("a", 400 + 1));
underTest.setKey(repeat("a", 400 + 1));

expectBuildException(
IllegalArgumentException.class,
@@ -71,16 +59,14 @@ public class NewComponentTest {

@Test
public void build_fails_with_IAE_when_name_is_null() {
underTest.setOrganizationUuid(ORGANIZATION_UUID)
.setKey(KEY);
underTest.setKey(KEY);

expectBuildException(IllegalArgumentException.class, "Component name can't be empty");
}

@Test
public void build_fails_with_IAE_when_name_is_empty() {
underTest.setOrganizationUuid(ORGANIZATION_UUID)
.setKey(KEY)
underTest.setKey(KEY)
.setName("");

expectBuildException(IllegalArgumentException.class, "Component name can't be empty");
@@ -88,8 +74,7 @@ public class NewComponentTest {

@Test
public void build_fails_with_IAE_when_name_is_longer_than_2000_characters() {
underTest.setOrganizationUuid(ORGANIZATION_UUID)
.setKey(KEY)
underTest.setKey(KEY)
.setName(repeat("a", 501));

expectBuildException(
@@ -99,8 +84,7 @@ public class NewComponentTest {

@Test
public void build_fails_with_IAE_when_qualifier_is_null() {
underTest.setOrganizationUuid(ORGANIZATION_UUID)
.setKey(KEY)
underTest.setKey(KEY)
.setName(NAME)
.setQualifier(null);

@@ -109,8 +93,7 @@ public class NewComponentTest {

@Test
public void build_fails_with_IAE_when_qualifier_is_empty() {
underTest.setOrganizationUuid(ORGANIZATION_UUID)
.setKey(KEY)
underTest.setKey(KEY)
.setName(NAME)
.setQualifier("");

@@ -119,8 +102,7 @@ public class NewComponentTest {

@Test
public void build_fails_with_IAE_when_qualifier_is_longer_than_10_characters() {
underTest.setOrganizationUuid(ORGANIZATION_UUID)
.setKey(KEY)
underTest.setKey(KEY)
.setName(NAME)
.setQualifier(repeat("a", 10 + 1));

@@ -131,8 +113,7 @@ public class NewComponentTest {

@Test
public void getQualifier_returns_PROJECT_when_no_set_in_builder() {
NewComponent newComponent = underTest.setOrganizationUuid(ORGANIZATION_UUID)
.setKey(KEY)
NewComponent newComponent = underTest.setKey(KEY)
.setName(NAME)
.build();

@@ -140,9 +121,8 @@ public class NewComponentTest {
}

private void expectBuildException(Class<? extends Exception> expectedExceptionType, String expectedMessage) {
expectedException.expect(expectedExceptionType);
expectedException.expectMessage(expectedMessage);

underTest.build();
assertThatThrownBy(() -> underTest.build())
.isInstanceOf(expectedExceptionType)
.hasMessageContaining(expectedMessage);
}
}

+ 28
- 32
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/AppActionTest.java Wyświetl plik

@@ -21,7 +21,6 @@ package org.sonar.server.component.ws;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
@@ -30,9 +29,11 @@ import org.sonar.server.component.TestComponentFinder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.sonar.api.measures.CoreMetrics.COVERAGE_KEY;
import static org.sonar.api.measures.CoreMetrics.DUPLICATED_LINES_DENSITY_KEY;
import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
@@ -49,15 +50,13 @@ import static org.sonar.test.JsonAssert.assertJson;
public class AppActionTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();
public final UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public DbTester db = DbTester.create();
public final DbTester db = DbTester.create();

private ComponentViewerJsonWriter componentViewerJsonWriter = new ComponentViewerJsonWriter(db.getDbClient());
private final ComponentViewerJsonWriter componentViewerJsonWriter = new ComponentViewerJsonWriter(db.getDbClient());

private WsActionTester ws = new WsActionTester(new AppAction(db.getDbClient(), userSession,
private final WsActionTester ws = new WsActionTester(new AppAction(db.getDbClient(), userSession,
TestComponentFinder.from(db), componentViewerJsonWriter));

@Test
@@ -290,10 +289,10 @@ public class AppActionTest {

@Test
public void fail_if_no_parameter_provided() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'component' parameter is missing");
ws.newRequest().execute();
TestRequest request = ws.newRequest();
assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("The 'component' parameter is missing");
}

@Test
@@ -361,15 +360,13 @@ public class AppActionTest {
ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(PULL_REQUEST));
ComponentDto file = db.components().insertComponent(newFileDto(branch));

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Either branch or pull request can be provided, not both");

ws.newRequest()
TestRequest request = ws.newRequest()
.setParam("component", file.getDbKey())
.setParam("branch", "unknown_branch")
.setParam("pullRequest", "unknown_component")
.execute()
.getInput();
.setParam("pullRequest", "unknown_component");
assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Either branch or pull request can be provided, not both");
}

@Test
@@ -377,11 +374,10 @@ public class AppActionTest {
ComponentDto project = db.components().insertPrivateProject();
ComponentDto file = db.components().insertComponent(newFileDto(project));

expectedException.expect(NotFoundException.class);

ws.newRequest()
.setParam("component", "unknown")
.execute();
TestRequest request = ws.newRequest()
.setParam("component", "unknown");
assertThatThrownBy(request::execute)
.isInstanceOf(NotFoundException.class);
}

@Test
@@ -390,12 +386,12 @@ public class AppActionTest {
ComponentDto branch = db.components().insertProjectBranch(project);
ComponentDto file = db.components().insertComponent(newFileDto(branch));

expectedException.expect(NotFoundException.class);

ws.newRequest()
TestRequest request = ws.newRequest()
.setParam("component", file.getKey())
.setParam("branch", "unknown")
.execute();
.setParam("branch", "unknown");

assertThatThrownBy(request::execute)
.isInstanceOf(NotFoundException.class);
}

@Test
@@ -403,11 +399,11 @@ public class AppActionTest {
ComponentDto project = db.components().insertPrivateProject();
ComponentDto file = db.components().insertComponent(newFileDto(project));

expectedException.expect(ForbiddenException.class);
TestRequest request = ws.newRequest()
.setParam("component", file.getKey());

ws.newRequest()
.setParam("component", file.getKey())
.execute();
assertThatThrownBy(request::execute)
.isInstanceOf(ForbiddenException.class);
}

@Test

+ 0
- 68
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/ComponentDtoToWsComponentTest.java Wyświetl plik

@@ -1,68 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2020 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.component.ws;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.db.component.BranchType;
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.project.ProjectDto;

import static org.sonar.server.component.ws.ComponentDtoToWsComponent.componentDtoToWsComponent;
import static org.sonar.server.component.ws.ComponentDtoToWsComponent.projectOrAppToWsComponent;

public class ComponentDtoToWsComponentTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void componentDtoToWsComponent_throws_IAE_if_organization_uuid_of_component_does_not_match_organizationDto_uuid() {
OrganizationDto organizationDto1 = OrganizationTesting.newOrganizationDto();
OrganizationDto organizationDto2 = OrganizationTesting.newOrganizationDto();

ProjectDto parentProjectDto = ComponentTesting.createPrivateProjectDto(organizationDto1);
ComponentDto componentDto = ComponentTesting.newBranchComponent(parentProjectDto,
ComponentTesting.newBranchDto(parentProjectDto.getUuid(), BranchType.BRANCH));

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("OrganizationUuid (" + organizationDto1.getUuid() + ") of ComponentDto to convert " +
"to Ws Component is not the same as the one (" + organizationDto2.getUuid() + ") of the specified OrganizationDto");

componentDtoToWsComponent(componentDto, parentProjectDto, organizationDto2, null);
}

@Test
public void projectOrAppToWsComponent_throws_IAE_if_organization_uuid_of_component_does_not_match_organizationDto_uuid() {
OrganizationDto organizationDto1 = OrganizationTesting.newOrganizationDto();
OrganizationDto organizationDto2 = OrganizationTesting.newOrganizationDto();
ProjectDto projectDto = ComponentTesting.createPrivateProjectDto(organizationDto1);

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("OrganizationUuid (" + organizationDto1.getUuid() + ") of ComponentDto to convert " +
"to Ws Component is not the same as the one (" + organizationDto2.getUuid() + ") of the specified OrganizationDto");

projectOrAppToWsComponent(projectDto, organizationDto2, null);
}

}

+ 2
- 2
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java Wyświetl plik

@@ -30,8 +30,8 @@ import static org.sonarqube.ws.client.component.ComponentsWsParameters.CONTROLLE

public class ComponentsWsTest {

private String actionKey = randomAlphanumeric(10);
private ComponentsWsAction action = new ComponentsWsAction() {
private final String actionKey = randomAlphanumeric(10);
private final ComponentsWsAction action = new ComponentsWsAction() {

@Override
public void handle(Request request, Response response) {

+ 0
- 5
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/FilterParserTest.java Wyświetl plik

@@ -20,9 +20,7 @@
package org.sonar.server.component.ws;

import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.server.component.ws.FilterParser.Criterion;

import static java.util.Arrays.asList;
@@ -38,9 +36,6 @@ import static org.sonar.server.measure.index.ProjectMeasuresQuery.Operator.LTE;

public class FilterParserTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void parse_filter_having_operator_and_value() {
List<Criterion> criterion = FilterParser.parse("ncloc > 10 and coverage <= 80");

+ 35
- 72
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SearchActionTest.java Wyświetl plik

@@ -26,8 +26,6 @@ import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Language;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
@@ -35,14 +33,12 @@ 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.db.user.UserDto;
import org.sonar.server.component.index.ComponentIndex;
import org.sonar.server.component.index.ComponentIndexer;
import org.sonar.server.component.ws.SearchAction.SearchRequest;
import org.sonar.server.es.EsTester;
import org.sonar.server.l18n.I18nRule;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.permission.index.WebAuthorizationTypeSupport;
import org.sonar.server.tester.UserSessionRule;
@@ -56,6 +52,7 @@ import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.DIRECTORY;
@@ -69,34 +66,29 @@ import static org.sonar.db.component.ComponentTesting.newModuleDto;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;

public class SearchActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
public final UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
public final DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public EsTester es = EsTester.create();
public final EsTester es = EsTester.create();

private I18nRule i18n = new I18nRule();
private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private ResourceTypesRule resourceTypes = new ResourceTypesRule();
private ComponentIndexer indexer = new ComponentIndexer(db.getDbClient(), es.client());
private PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es, indexer);
private ComponentIndex index = new ComponentIndex(es.client(), new WebAuthorizationTypeSupport(userSession), System2.INSTANCE);
private final I18nRule i18n = new I18nRule();
private final ResourceTypesRule resourceTypes = new ResourceTypesRule();
private final ComponentIndexer indexer = new ComponentIndexer(db.getDbClient(), es.client());
private final PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es, indexer);
private final ComponentIndex index = new ComponentIndex(es.client(), new WebAuthorizationTypeSupport(userSession), System2.INSTANCE);

private UserDto user;

private WsActionTester ws;
private WsActionTester underTest;

@Before
public void setUp() {
resourceTypes.setAllQualifiers(APP, PROJECT, DIRECTORY, FILE);
ws = new WsActionTester(new SearchAction(index, db.getDbClient(), resourceTypes, i18n, defaultOrganizationProvider));
underTest = new WsActionTester(new SearchAction(index, db.getDbClient(), resourceTypes, i18n));

user = db.users().insertUser("john");
userSession.logIn(user);
@@ -104,7 +96,7 @@ public class SearchActionTest {

@Test
public void verify_definition() {
WebService.Action action = ws.getDef();
WebService.Action action = underTest.getDef();

assertThat(action.since()).isEqualTo("6.3");
assertThat(action.isPost()).isFalse();
@@ -118,7 +110,7 @@ public class SearchActionTest {
tuple("7.6", "The use of 'BRC' as value for parameter 'qualifiers' is deprecated"));
assertThat(action.responseExampleAsString()).isNotEmpty();

assertThat(action.params()).hasSize(5);
assertThat(action.params()).hasSize(4);

WebService.Param pageSize = action.param("ps");
assertThat(pageSize.isRequired()).isFalse();
@@ -128,20 +120,13 @@ public class SearchActionTest {

WebService.Param qualifiers = action.param("qualifiers");
assertThat(qualifiers.isRequired()).isTrue();

WebService.Param organization = action.param("organization");
assertThat(organization.isRequired()).isFalse();
assertThat(organization.description()).isEqualTo("Organization key");
assertThat(organization.isInternal()).isTrue();
assertThat(organization.exampleValue()).isEqualTo("my-org");
assertThat(organization.since()).isEqualTo("6.3");
}

@Test
public void search_by_key_query() {
insertProjectsAuthorizedForUser(
ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setDbKey("project-_%-key"),
ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setDbKey("project-key-without-escaped-characters"));
ComponentTesting.newPrivateProjectDto().setDbKey("project-_%-key"),
ComponentTesting.newPrivateProjectDto().setDbKey("project-key-without-escaped-characters"));

SearchWsResponse response = call(new SearchRequest().setQuery("project-_%-key").setQualifiers(singletonList(PROJECT)));

@@ -150,23 +135,22 @@ public class SearchActionTest {

@Test
public void search_with_pagination() {
OrganizationDto organizationDto = db.organizations().insert();
List<ComponentDto> componentDtoList = new ArrayList<>();
for (int i = 1; i <= 9; i++) {
componentDtoList.add(newPrivateProjectDto(organizationDto, "project-uuid-" + i).setDbKey("project-key-" + i).setName("Project Name " + i));
componentDtoList.add(newPrivateProjectDto("project-uuid-" + i).setDbKey("project-key-" + i).setName("Project Name " + i));
}
insertProjectsAuthorizedForUser(componentDtoList.toArray(new ComponentDto[] {}));

SearchWsResponse response = call(new SearchRequest().setOrganization(organizationDto.getKey()).setPage(2).setPageSize(3).setQualifiers(singletonList(PROJECT)));
SearchWsResponse response = call(new SearchRequest().setPage(2).setPageSize(3).setQualifiers(singletonList(PROJECT)));

assertThat(response.getComponentsList()).extracting(Component::getKey).containsExactly("project-key-4", "project-key-5", "project-key-6");
}

@Test
public void return_only_projects_on_which_user_has_browse_permission() {
ComponentDto project1 = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
ComponentDto project2 = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization());
ComponentDto portfolio = ComponentTesting.newView(db.getDefaultOrganization());
ComponentDto project1 = ComponentTesting.newPrivateProjectDto();
ComponentDto project2 = ComponentTesting.newPrivateProjectDto();
ComponentDto portfolio = ComponentTesting.newView();

db.components().insertComponents(project1, project2, portfolio);
setBrowsePermissionOnUserAndIndex(project1);
@@ -180,7 +164,7 @@ public class SearchActionTest {

@Test
public void return_project_key() {
ComponentDto project = ComponentTesting.newPublicProjectDto(db.getDefaultOrganization());
ComponentDto project = ComponentTesting.newPublicProjectDto();
ComponentDto module = ComponentTesting.newModuleDto(project);
ComponentDto dir1 = newDirectory(module, "dir1").setDbKey("dir1");
ComponentDto dir2 = newDirectory(module, "dir2").setDbKey("dir2");
@@ -208,37 +192,35 @@ public class SearchActionTest {

@Test
public void fail_if_unknown_qualifier_provided() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Value of parameter 'qualifiers' (Unknown-Qualifier) must be one of: [APP, TRK]");
call(new SearchRequest().setQualifiers(singletonList("Unknown-Qualifier")));
SearchRequest searchRequest = new SearchRequest().setQualifiers(singletonList("Unknown-Qualifier"));
assertThatThrownBy(() -> call(searchRequest))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Value of parameter 'qualifiers' (Unknown-Qualifier) must be one of: [APP, TRK]");
}

@Test
public void fail_when_no_qualifier_provided() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'qualifiers' parameter is missing");
call(new SearchRequest());
SearchRequest searchRequest = new SearchRequest();
assertThatThrownBy(() -> call(searchRequest))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("The 'qualifiers' parameter is missing");
}

@Test
public void test_json_example() {
OrganizationDto organizationDto = db.organizations().insertForKey("my-org-1");
db.components().insertComponent(newView(organizationDto));
ComponentDto project = newPrivateProjectDto(organizationDto, "project-uuid").setName("Project Name").setDbKey("project-key");
db.components().insertComponent(newView());
ComponentDto project = newPrivateProjectDto("project-uuid").setName("Project Name").setDbKey("project-key");
ComponentDto module = newModuleDto("module-uuid", project).setName("Module Name").setDbKey("module-key");
ComponentDto directory = newDirectory(module, "path/to/directoy").setUuid("directory-uuid").setDbKey("directory-key").setName("Directory Name");
ComponentDto view = newView(organizationDto);
ComponentDto view = newView();
db.components().insertComponents(project, module, directory, view);
setBrowsePermissionOnUserAndIndex(project);

String response = ws.newRequest()
String response = underTest.newRequest()
.setMediaType(MediaTypes.JSON)
.setParam(PARAM_ORGANIZATION, organizationDto.getKey())
.setParam(PARAM_QUALIFIERS, PROJECT)
.execute().getInput();
assertJson(response).isSimilarTo(ws.getDef().responseExampleAsString());
assertJson(response).isSimilarTo(underTest.getDef().responseExampleAsString());
}

private void insertProjectsAuthorizedForUser(ComponentDto... projects) {
@@ -253,8 +235,7 @@ public class SearchActionTest {
}

private SearchWsResponse call(SearchRequest wsRequest) {
TestRequest request = ws.newRequest();
ofNullable(wsRequest.getOrganization()).ifPresent(p3 -> request.setParam(PARAM_ORGANIZATION, p3));
TestRequest request = underTest.newRequest();
ofNullable(wsRequest.getQualifiers()).ifPresent(p1 -> request.setParam(PARAM_QUALIFIERS, Joiner.on(",").join(p1)));
ofNullable(wsRequest.getQuery()).ifPresent(p -> request.setParam(TEXT_QUERY, p));
ofNullable(wsRequest.getPage()).ifPresent(page -> request.setParam(PAGE, String.valueOf(page)));
@@ -266,22 +247,4 @@ public class SearchActionTest {
indexer.indexAll();
}

private static Language[] javaLanguage() {
return new Language[] {new Language() {
@Override
public String getKey() {
return "java";
}

@Override
public String getName() {
return "Java";
}

@Override
public String[] getFileSuffixes() {
return new String[0];
}
}};
}
}

+ 213
- 348
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java
Plik diff jest za duży
Wyświetl plik


+ 35
- 42
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/ShowActionTest.java Wyświetl plik

@@ -24,7 +24,6 @@ import java.util.Optional;
import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.WebService;
@@ -32,7 +31,6 @@ import org.sonar.api.utils.System2;
import org.sonar.api.web.UserRole;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.component.TestComponentFinder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
@@ -44,6 +42,7 @@ import org.sonarqube.ws.Components.Component;
import org.sonarqube.ws.Components.ShowWsResponse;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.api.utils.DateUtils.parseDateTime;
@@ -62,13 +61,11 @@ import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_PUL

public class ShowActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
public final UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
public final DbTester db = DbTester.create(System2.INSTANCE);

private WsActionTester ws = new WsActionTester(new ShowAction(userSession, db.getDbClient(), TestComponentFinder.from(db),
private final WsActionTester ws = new WsActionTester(new ShowAction(userSession, db.getDbClient(), TestComponentFinder.from(db),
new IssueIndexSyncProgressChecker(db.getDbClient())));

@Test
@@ -126,7 +123,7 @@ public class ShowActionTest {

@Test
public void show_with_browse_permission() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
ComponentDto project = newPrivateProjectDto("project-uuid");
db.components().insertProjectAndSnapshot(project);
userSession.logIn().addProjectPermission(USER, project);

@@ -316,8 +313,8 @@ public class ShowActionTest {

@Test
public void verify_need_issue_sync_pr() {
ComponentDto portfolio1 = db.components().insertPublicPortfolio(db.getDefaultOrganization());
ComponentDto portfolio2 = db.components().insertPublicPortfolio(db.getDefaultOrganization());
ComponentDto portfolio1 = db.components().insertPublicPortfolio();
ComponentDto portfolio2 = db.components().insertPublicPortfolio();
ComponentDto subview = db.components().insertSubView(portfolio1);

ComponentDto project1 = db.components().insertPrivateProject();
@@ -383,31 +380,30 @@ public class ShowActionTest {
public void throw_ForbiddenException_if_user_doesnt_have_browse_permission_on_project() {
userSession.logIn();

expectedException.expect(ForbiddenException.class);
ComponentDto componentDto = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
ComponentDto componentDto = newPrivateProjectDto("project-uuid");
db.components().insertProjectAndSnapshot(componentDto);

newRequest(componentDto.getDbKey());
String componentDtoDbKey = componentDto.getDbKey();
assertThatThrownBy(() -> newRequest(componentDtoDbKey))
.isInstanceOf(ForbiddenException.class);
}

@Test
public void fail_if_component_does_not_exist() {
expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Component key 'unknown-key' not found");

newRequest("unknown-key");
assertThatThrownBy(() -> newRequest("unknown-key"))
.isInstanceOf(NotFoundException.class)
.hasMessage("Component key 'unknown-key' not found");
}

@Test
public void fail_if_component_is_removed() {
userSession.logIn().setRoot();
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization()));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
db.components().insertComponent(newFileDto(project).setDbKey("file-key").setEnabled(false));

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Component key 'file-key' not found");

newRequest("file-key");
assertThatThrownBy(() -> newRequest("file-key"))
.isInstanceOf(NotFoundException.class)
.hasMessage("Component key 'file-key' not found");
}

@Test
@@ -417,13 +413,13 @@ public class ShowActionTest {
userSession.addProjectPermission(UserRole.USER, project);
db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", file.getKey(), "another_branch"));

ws.newRequest()
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, file.getKey())
.setParam(PARAM_BRANCH, "another_branch")
.execute();
.setParam(PARAM_BRANCH, "another_branch");

assertThatThrownBy(request::execute)
.isInstanceOf(NotFoundException.class)
.hasMessage(String.format("Component '%s' on branch '%s' not found", file.getKey(), "another_branch"));
}

@Test
@@ -432,12 +428,11 @@ public class ShowActionTest {
userSession.addProjectPermission(UserRole.USER, project);
ComponentDto branch = db.components().insertProjectBranch(project);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(String.format("Component key '%s' not found", branch.getDbKey()));

ws.newRequest()
.setParam(PARAM_COMPONENT, branch.getDbKey())
.executeProtobuf(ShowWsResponse.class);
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, branch.getDbKey());
assertThatThrownBy(() -> request.executeProtobuf(ShowWsResponse.class))
.isInstanceOf(NotFoundException.class)
.hasMessage(String.format("Component key '%s' not found", branch.getDbKey()));
}

private ShowWsResponse newRequest(@Nullable String key) {
@@ -449,14 +444,12 @@ public class ShowActionTest {
}

private void insertJsonExampleComponentsAndSnapshots() {
OrganizationDto organizationDto = db.organizations().insertForKey("my-org-1");
ComponentDto project = db.components().insertPrivateProject(organizationDto,
c -> c.setUuid("AVIF98jgA3Ax6PH2efOW")
.setProjectUuid("AVIF98jgA3Ax6PH2efOW")
.setDbKey("com.sonarsource:java-markdown")
.setName("Java Markdown")
.setDescription("Java Markdown Project")
.setQualifier(Qualifiers.PROJECT),
ComponentDto project = db.components().insertPrivateProject(c -> c.setUuid("AVIF98jgA3Ax6PH2efOW")
.setProjectUuid("AVIF98jgA3Ax6PH2efOW")
.setDbKey("com.sonarsource:java-markdown")
.setName("Java Markdown")
.setDescription("Java Markdown Project")
.setQualifier(Qualifiers.PROJECT),
p -> p.setTagsString("language, plugin"));
db.components().insertSnapshot(project, snapshot -> snapshot
.setProjectVersion("1.1")

+ 41
- 75
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/SuggestionsActionTest.java Wyświetl plik

@@ -23,7 +23,6 @@ import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.assertj.core.groups.Tuple;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -36,7 +35,6 @@ 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.ComponentIndexer;
import org.sonar.server.es.EsTester;
@@ -47,7 +45,6 @@ import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Common.Organization;
import org.sonarqube.ws.Components.SuggestionsWsResponse;
import org.sonarqube.ws.Components.SuggestionsWsResponse.Category;
import org.sonarqube.ws.Components.SuggestionsWsResponse.Suggestion;
@@ -58,7 +55,6 @@ import static java.util.Collections.singletonList;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.joining;
import static java.util.stream.IntStream.range;
import static java.util.stream.Stream.of;
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.groups.Tuple.tuple;
@@ -87,24 +83,22 @@ public class SuggestionsActionTest {
.collect(MoreCollectors.toList()).toArray(new String[0]);

@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
public final DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public EsTester es = EsTester.create();
public final EsTester es = EsTester.create();
@Rule
public UserSessionRule userSessionRule = UserSessionRule.standalone();
public ResourceTypesRule resourceTypes = new ResourceTypesRule();
public final UserSessionRule userSessionRule = UserSessionRule.standalone();
public final 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 WebAuthorizationTypeSupport(userSessionRule), System2.INSTANCE);
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);
private final ComponentIndexer componentIndexer = new ComponentIndexer(db.getDbClient(), es.client());
private final FavoriteFinder favoriteFinder = mock(FavoriteFinder.class);
private final ComponentIndex index = new ComponentIndex(es.client(), new WebAuthorizationTypeSupport(userSessionRule), System2.INSTANCE);
private final SuggestionsAction underTest = new SuggestionsAction(db.getDbClient(), index, favoriteFinder, userSessionRule, resourceTypes);
private final PermissionIndexerTester authorizationIndexerTester = new PermissionIndexerTester(es, componentIndexer);
private final WsActionTester ws = new WsActionTester(underTest);

@Before
public void setUp() {
organization = db.organizations().insert();
resourceTypes.setAllQualifiers(SUGGESTION_QUALIFIERS);
}

@@ -138,9 +132,8 @@ public class SuggestionsActionTest {

@Test
public void test_example_json_response() {
OrganizationDto organization = db.organizations().insert(o -> o.setKey("default-organization").setName("Default Organization"));
ComponentDto project1 = db.components().insertPublicProject(organization, p -> p.setDbKey("org.sonarsource:sonarqube").setName("SonarSource :: SonarQube"));
ComponentDto project2 = db.components().insertPublicProject(organization, p -> p.setDbKey("org.sonarsource:sonarlint").setName("SonarSource :: SonarLint"));
ComponentDto project1 = db.components().insertPublicProject(p -> p.setDbKey("org.sonarsource:sonarqube").setName("SonarSource :: SonarQube"));
ComponentDto project2 = db.components().insertPublicProject(p -> p.setDbKey("org.sonarsource:sonarlint").setName("SonarSource :: SonarLint"));
componentIndexer.indexAll();
authorizationIndexerTester.allowOnlyAnyone(project1);
authorizationIndexerTester.allowOnlyAnyone(project2);
@@ -157,7 +150,7 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_contain_recently_browsed() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());

componentIndexer.indexAll();
userSessionRule.addProjectPermission(USER, project);
@@ -182,7 +175,7 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_contain_recently_browsed_public_project() {
ComponentDto project = db.components().insertComponent(newPublicProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPublicProjectDto());

componentIndexer.indexAll();

@@ -206,7 +199,7 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_not_contain_recently_browsed_without_permission() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());

componentIndexer.indexAll();

@@ -222,7 +215,7 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_contain_favorites() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
doReturn(singletonList(project)).when(favoriteFinder).list();

componentIndexer.indexAll();
@@ -247,7 +240,7 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_not_contain_favorites_without_permission() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
doReturn(singletonList(project)).when(favoriteFinder).list();

componentIndexer.indexAll();
@@ -263,7 +256,7 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_contain_recently_browsed_favorites() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
doReturn(singletonList(project)).when(favoriteFinder).list();

componentIndexer.indexAll();
@@ -289,7 +282,7 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_not_contain_matches_that_are_neither_favorites_nor_recently_browsed() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());

componentIndexer.indexAll();
userSessionRule.addProjectPermission(USER, project);
@@ -307,10 +300,10 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_order_results() {
ComponentDto project1 = db.components().insertComponent(newPrivateProjectDto(organization).setName("Alpha"));
ComponentDto project2 = db.components().insertComponent(newPrivateProjectDto(organization).setName("Bravo"));
ComponentDto project3 = db.components().insertComponent(newPrivateProjectDto(organization).setName("Charlie"));
ComponentDto project4 = db.components().insertComponent(newPrivateProjectDto(organization).setName("Delta"));
ComponentDto project1 = db.components().insertComponent(newPrivateProjectDto().setName("Alpha"));
ComponentDto project2 = db.components().insertComponent(newPrivateProjectDto().setName("Bravo"));
ComponentDto project3 = db.components().insertComponent(newPrivateProjectDto().setName("Charlie"));
ComponentDto project4 = db.components().insertComponent(newPrivateProjectDto().setName("Delta"));
doReturn(asList(project4, project2)).when(favoriteFinder).list();

componentIndexer.indexAll();
@@ -337,7 +330,7 @@ public class SuggestionsActionTest {

@Test
public void suggestions_without_query_should_return_empty_qualifiers() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
componentIndexer.indexOnAnalysis(project.projectUuid());
userSessionRule.addProjectPermission(USER, project);

@@ -355,7 +348,7 @@ public class SuggestionsActionTest {
@Test
public void suggestions_should_filter_allowed_qualifiers() {
resourceTypes.setAllQualifiers(PROJECT, MODULE, FILE, UNIT_TEST_FILE);
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
componentIndexer.indexOnAnalysis(project.projectUuid());
userSessionRule.addProjectPermission(USER, project);

@@ -371,7 +364,7 @@ public class SuggestionsActionTest {

@Test
public void exact_match_in_one_qualifier() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());

componentIndexer.indexAll();
authorizationIndexerTester.allowOnlyAnyone(project);
@@ -390,13 +383,13 @@ public class SuggestionsActionTest {
// assert correct id to be found
assertThat(response.getResultsList())
.flatExtracting(Category::getItemsList)
.extracting(Suggestion::getKey, Suggestion::getOrganization)
.containsExactly(tuple(project.getDbKey(), organization.getKey()));
.extracting(Suggestion::getKey)
.containsExactly(project.getDbKey());
}

@Test
public void should_not_return_suggestion_on_non_existing_project() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());

componentIndexer.indexAll();
authorizationIndexerTester.allowOnlyAnyone(project);
@@ -417,7 +410,7 @@ public class SuggestionsActionTest {

@Test
public void must_not_search_if_no_valid_tokens_are_provided() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization).setName("SonarQube"));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto().setName("SonarQube"));

componentIndexer.indexAll();
authorizationIndexerTester.allowOnlyAnyone(project);
@@ -443,7 +436,7 @@ public class SuggestionsActionTest {

@Test
public void should_warn_about_short_inputs_but_return_results_based_on_other_terms() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization).setName("SonarQube"));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto().setName("SonarQube"));

componentIndexer.indexAll();
authorizationIndexerTester.allowOnlyAnyone(project);
@@ -462,9 +455,7 @@ public class SuggestionsActionTest {

@Test
public void should_contain_component_names() {
OrganizationDto organization1 = db.organizations().insert(o -> o.setKey("org-1").setName("Organization One"));

ComponentDto project1 = db.components().insertComponent(newPrivateProjectDto(organization1).setName("Project1"));
ComponentDto project1 = db.components().insertComponent(newPrivateProjectDto().setName("Project1"));
componentIndexer.indexOnAnalysis(project1.projectUuid());
authorizationIndexerTester.allowOnlyAnyone(project1);

@@ -479,34 +470,9 @@ public class SuggestionsActionTest {
.containsExactlyInAnyOrder(tuple(project1.getDbKey(), project1.name()));
}

@Test
public void should_contain_organization_names() {
OrganizationDto organization1 = db.organizations().insert(o -> o.setKey("org-1").setName("Organization One"));
OrganizationDto organization2 = db.organizations().insert(o -> o.setKey("org-2").setName("Organization Two"));

ComponentDto project1 = db.components().insertComponent(newPrivateProjectDto(organization1).setName("Project1"));
componentIndexer.indexOnAnalysis(project1.projectUuid());
authorizationIndexerTester.allowOnlyAnyone(project1);

ComponentDto project2 = db.components().insertComponent(newPrivateProjectDto(organization2).setName("Project2"));
componentIndexer.indexOnAnalysis(project2.projectUuid());
authorizationIndexerTester.allowOnlyAnyone(project2);

SuggestionsWsResponse response = ws.newRequest()
.setMethod("POST")
.setParam(PARAM_QUERY, "Project")
.executeProtobuf(SuggestionsWsResponse.class);

assertThat(response.getOrganizationsList())
.extracting(Organization::getKey, Organization::getName)
.containsExactlyInAnyOrder(
of(organization1, organization2)
.map(o -> tuple(o.getKey(), o.getName())).toArray(Tuple[]::new));
}

@Test
public void should_not_return_modules() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization).setName("ProjectWithModules"));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto().setName("ProjectWithModules"));
db.components().insertComponent(newModuleDto(project).setName("Module1"));
db.components().insertComponent(newModuleDto(project).setName("Module2"));
componentIndexer.indexOnAnalysis(project.projectUuid());
@@ -525,7 +491,7 @@ public class SuggestionsActionTest {

@Test
public void should_mark_recently_browsed_items() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization).setName("ProjectModule"));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto().setName("ProjectModule"));
ComponentDto module1 = newModuleDto(project).setName("Module1");
db.components().insertComponent(module1);
ComponentDto module2 = newModuleDto(project).setName("Module2");
@@ -547,8 +513,8 @@ public class SuggestionsActionTest {

@Test
public void should_mark_favorite_items() {
ComponentDto favouriteProject = db.components().insertComponent(newPrivateProjectDto(organization).setName("Project1"));
ComponentDto nonFavouriteProject = db.components().insertComponent(newPublicProjectDto(organization).setName("Project2"));
ComponentDto favouriteProject = db.components().insertComponent(newPrivateProjectDto().setName("Project1"));
ComponentDto nonFavouriteProject = db.components().insertComponent(newPublicProjectDto().setName("Project2"));

doReturn(singletonList(favouriteProject)).when(favoriteFinder).list();
componentIndexer.indexOnAnalysis(favouriteProject.projectUuid());
@@ -568,7 +534,7 @@ public class SuggestionsActionTest {

@Test
public void should_return_empty_qualifiers() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organization));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
componentIndexer.indexOnAnalysis(project.projectUuid());
authorizationIndexerTester.allowOnlyAnyone(project);

@@ -586,10 +552,10 @@ public class SuggestionsActionTest {
public void should_only_provide_project_for_certain_qualifiers() {
String query = randomAlphabetic(10);

ComponentDto app = db.components().insertPublicApplication(organization, v -> v.setName(query));
ComponentDto view = db.components().insertView(organization, v -> v.setName(query));
ComponentDto app = db.components().insertPublicApplication(v -> v.setName(query));
ComponentDto view = db.components().insertView(v -> v.setName(query));
ComponentDto subView = db.components().insertComponent(ComponentTesting.newSubView(view).setName(query));
ComponentDto project = db.components().insertPrivateProject(organization, p -> p.setName(query));
ComponentDto project = db.components().insertPrivateProject(p -> p.setName(query));
ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project).setName(query));
ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(module).setName(query));
ComponentDto test = db.components().insertComponent(ComponentTesting.newFileDto(module).setName(query).setQualifier(UNIT_TEST_FILE));
@@ -733,7 +699,7 @@ public class SuggestionsActionTest {
String namePrefix = "MyProject";

List<ComponentDto> projects = range(0, numberOfProjects)
.mapToObj(i -> db.components().insertComponent(newPublicProjectDto(organization).setName(namePrefix + i)))
.mapToObj(i -> db.components().insertComponent(newPublicProjectDto().setName(namePrefix + i)))
.collect(Collectors.toList());

componentIndexer.indexAll();

+ 76
- 85
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/TreeActionTest.java Wyświetl plik

@@ -30,7 +30,6 @@ import javax.annotation.Nullable;
import org.apache.commons.io.IOUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.Param;
@@ -42,19 +41,21 @@ 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.ComponentFinder;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import org.sonar.test.JsonAssert;
import org.sonarqube.ws.Components;
import org.sonarqube.ws.Components.Component;
import org.sonarqube.ws.Components.TreeWsResponse;

import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.sonar.api.resources.Qualifiers.APP;
@@ -76,8 +77,6 @@ import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUA
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_STRATEGY;

public class TreeActionTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
@@ -132,7 +131,7 @@ public class TreeActionTest {

@Test
public void return_children() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
ComponentDto project = newPrivateProjectDto("project-uuid");
db.components().insertProjectAndSnapshot(project);
ComponentDto module = newModuleDto("module-uuid-1", project);
db.components().insertComponent(module);
@@ -162,7 +161,7 @@ public class TreeActionTest {

@Test
public void return_descendants() {
ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid");
ComponentDto project = newPrivateProjectDto("project-uuid");
db.components().insertProjectAndSnapshot(project);
ComponentDto module = newModuleDto("module-uuid-1", project);
db.components().insertComponent(module);
@@ -192,7 +191,7 @@ public class TreeActionTest {

@Test
public void filter_descendants_by_qualifier() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
ComponentDto project = newPrivateProjectDto("project-uuid");
db.components().insertProjectAndSnapshot(project);
db.components().insertComponent(newFileDto(project, 1));
db.components().insertComponent(newFileDto(project, 2));
@@ -210,7 +209,7 @@ public class TreeActionTest {

@Test
public void return_leaves() {
ComponentDto project = newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid");
ComponentDto project = newPrivateProjectDto("project-uuid");
db.components().insertProjectAndSnapshot(project);
ComponentDto module = newModuleDto("module-uuid-1", project);
db.components().insertComponent(module);
@@ -234,7 +233,7 @@ public class TreeActionTest {

@Test
public void sort_descendants_by_qualifier() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
ComponentDto project = newPrivateProjectDto("project-uuid");
db.components().insertProjectAndSnapshot(project);
db.components().insertComponent(newFileDto(project, 1));
db.components().insertComponent(newFileDto(project, 2));
@@ -254,10 +253,9 @@ public class TreeActionTest {

@Test
public void project_reference_from_portfolio() {
OrganizationDto organizationDto = db.organizations().insert();
ComponentDto view = newView(organizationDto, "view-uuid");
ComponentDto view = newView("view-uuid");
db.components().insertViewAndSnapshot(view);
ComponentDto project = newPrivateProjectDto(organizationDto, "project-uuid-1").setName("project-name").setDbKey("project-key-1");
ComponentDto project = newPrivateProjectDto("project-uuid-1").setName("project-name").setDbKey("project-key-1");
db.components().insertProjectAndSnapshot(project);
db.components().insertComponent(newProjectCopy("project-uuid-1-copy", project, view));
db.components().insertComponent(newSubView(view, "sub-view-uuid", "sub-view-key").setName("sub-view-name"));
@@ -300,7 +298,7 @@ public class TreeActionTest {

@Test
public void response_is_empty_on_provisioned_projects() {
ComponentDto project = db.components().insertPrivateProject(db.getDefaultOrganization(), "project-uuid");
ComponentDto project = db.components().insertPrivateProject("project-uuid");
logInWithBrowsePermission(project);

TreeWsResponse response = ws.newRequest()
@@ -315,9 +313,9 @@ public class TreeActionTest {

@Test
public void return_projects_composing_a_view() {
ComponentDto project = newPrivateProjectDto(db.organizations().insert(), "project-uuid");
ComponentDto project = newPrivateProjectDto("project-uuid");
db.components().insertProjectAndSnapshot(project);
ComponentDto view = newView(db.getDefaultOrganization(), "view-uuid");
ComponentDto view = newView("view-uuid");
db.components().insertViewAndSnapshot(view);
ComponentDto projectCopy = db.components().insertComponent(newProjectCopy("project-copy-uuid", project, view));
userSession.logIn()
@@ -385,12 +383,11 @@ public class TreeActionTest {
userSession.addProjectPermission(UserRole.USER, project);
ComponentDto branch = db.components().insertProjectBranch(project);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(String.format("Component key '%s' not found", branch.getDbKey()));

ws.newRequest()
.setParam(PARAM_COMPONENT, branch.getDbKey())
.executeProtobuf(Components.ShowWsResponse.class);
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, branch.getDbKey());
assertThatThrownBy(() -> request.executeProtobuf(Components.ShowWsResponse.class))
.isInstanceOf(NotFoundException.class)
.hasMessage(format("Component key '%s' not found", branch.getDbKey()));
}

@Test
@@ -399,107 +396,104 @@ public class TreeActionTest {
userSession.addProjectPermission(UserRole.USER, project);
ComponentDto branch = db.components().insertProjectBranch(project);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(String.format("Component key '%s' not found", branch.getDbKey()));

ws.newRequest()
.setParam(PARAM_COMPONENT, branch.getDbKey())
.executeProtobuf(Components.ShowWsResponse.class);
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, branch.getDbKey());
assertThatThrownBy(() -> request.executeProtobuf(Components.ShowWsResponse.class))
.isInstanceOf(NotFoundException.class)
.hasMessage(format("Component key '%s' not found", branch.getDbKey()));
}

@Test
public void fail_when_not_enough_privileges() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto("project-uuid"));
userSession.logIn()
.addProjectPermission(UserRole.CODEVIEWER, project);
db.commit();

expectedException.expect(ForbiddenException.class);

ws.newRequest()
.setParam(PARAM_COMPONENT, project.getDbKey())
.execute();
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, project.getDbKey());
assertThatThrownBy(request::execute)
.isInstanceOf(ForbiddenException.class);
}

@Test
public void fail_when_page_size_above_500() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("'ps' value (501) must be less than 500");
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid"));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto("project-uuid"));
db.commit();

ws.newRequest()
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, project.getDbKey())
.setParam(Param.PAGE_SIZE, "501")
.execute();
.setParam(Param.PAGE_SIZE, "501");

assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("'ps' value (501) must be less than 500");
}

@Test
public void fail_when_search_query_has_less_than_3_characters() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("'q' length (2) is shorter than the minimum authorized (3)");
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto("project-uuid"));
db.commit();

ws.newRequest()
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, project.getDbKey())
.setParam(Param.TEXT_QUERY, "fi")
.execute();
.setParam(Param.TEXT_QUERY, "fi");
assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("'q' length (2) is shorter than the minimum authorized (3)");
}

@Test
public void fail_when_sort_is_unknown() {
expectedException.expect(IllegalArgumentException.class);
db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization(), "project-uuid"));
db.components().insertComponent(newPrivateProjectDto("project-uuid"));
db.commit();

ws.newRequest()
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, "project-key")
.setParam(Param.SORT, "unknown-sort")
.execute();
.setParam(Param.SORT, "unknown-sort");
assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class);
}

@Test
public void fail_when_strategy_is_unknown() {
expectedException.expect(IllegalArgumentException.class);
db.components().insertComponent(newPrivateProjectDto(db.organizations().insert(), "project-uuid"));
db.components().insertComponent(newPrivateProjectDto("project-uuid"));
db.commit();

ws.newRequest()
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, "project-key")
.setParam(PARAM_STRATEGY, "unknown-strategy")
.execute();
.setParam(PARAM_STRATEGY, "unknown-strategy");
assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class);
}

@Test
public void fail_when_base_component_not_found() {
expectedException.expect(NotFoundException.class);

ws.newRequest()
.setParam(PARAM_COMPONENT, "project-key")
.execute();
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, "project-key");
assertThatThrownBy(request::execute)
.isInstanceOf(NotFoundException.class);
}

@Test
public void fail_when_base_component_is_removed() {
ComponentDto project = db.components().insertComponent(newPrivateProjectDto(db.getDefaultOrganization()));
ComponentDto project = db.components().insertComponent(newPrivateProjectDto());
db.components().insertComponent(ComponentTesting.newFileDto(project).setDbKey("file-key").setEnabled(false));
logInWithBrowsePermission(project);

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Component key 'file-key' not found");

ws.newRequest()
.setParam(PARAM_COMPONENT, "file-key")
.execute();
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, "file-key");
assertThatThrownBy(request::execute)
.isInstanceOf(NotFoundException.class)
.hasMessage("Component key 'file-key' not found");
}

@Test
public void fail_when_no_base_component_parameter() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("The 'component' parameter is missing");
ws.newRequest().execute();
TestRequest request = ws.newRequest();
assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("The 'component' parameter is missing");
}

@Test
@@ -508,13 +502,12 @@ public class TreeActionTest {
userSession.addProjectPermission(UserRole.USER, project);
db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));

expectedException.expect(NotFoundException.class);
expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", project.getKey(), "another_branch"));

ws.newRequest()
TestRequest request = ws.newRequest()
.setParam(PARAM_COMPONENT, project.getKey())
.setParam(PARAM_BRANCH, "another_branch")
.execute();
.setParam(PARAM_BRANCH, "another_branch");
assertThatThrownBy(request::execute)
.isInstanceOf(NotFoundException.class)
.hasMessage(format("Component '%s' on branch '%s' not found", project.getKey(), "another_branch"));
}

private static ComponentDto newFileDto(ComponentDto moduleOrProject, @Nullable ComponentDto directory, int i) {
@@ -529,13 +522,11 @@ public class TreeActionTest {
}

private ComponentDto initJsonExampleComponents() throws IOException {
OrganizationDto organizationDto = db.organizations().insertForKey("my-org-1");
ComponentDto project = db.components().insertPrivateProject(organizationDto,
c -> c.setUuid("MY_PROJECT_ID")
.setDescription("MY_PROJECT_DESCRIPTION")
.setDbKey("MY_PROJECT_KEY")
.setName("Project Name")
.setProjectUuid("MY_PROJECT_ID"),
ComponentDto project = db.components().insertPrivateProject(c -> c.setUuid("MY_PROJECT_ID")
.setDescription("MY_PROJECT_DESCRIPTION")
.setDbKey("MY_PROJECT_KEY")
.setName("Project Name")
.setProjectUuid("MY_PROJECT_ID"),
p -> p.setTagsString("abc,def"));
db.components().insertSnapshot(project);

@@ -546,7 +537,7 @@ public class TreeActionTest {
for (int i = 0; i < components.size(); i++) {
JsonElement componentAsJsonElement = components.get(i);
JsonObject componentAsJsonObject = componentAsJsonElement.getAsJsonObject();
String uuid = String.format("child-component-uuid-%d", i);
String uuid = format("child-component-uuid-%d", i);
db.components().insertComponent(newChildComponent(uuid, project, project)
.setDbKey(getJsonField(componentAsJsonObject, "key"))
.setName(getJsonField(componentAsJsonObject, "name"))

+ 1
- 1
server/sonar-webserver-webapi/src/test/java/org/sonar/server/project/ws/CreateActionTest.java Wyświetl plik

@@ -93,7 +93,7 @@ public class CreateActionTest {
new ProjectsWsSupport(db.getDbClient(), defaultOrganizationProvider, billingValidations),
db.getDbClient(), userSession,
new ComponentUpdater(db.getDbClient(), i18n, system2, permissionTemplateService, new FavoriteUpdater(db.getDbClient()),
projectIndexers, new SequenceUuidFactory())));
projectIndexers, new SequenceUuidFactory(), defaultOrganizationProvider)));

@Test
public void create_project() {

+ 73
- 99
server/sonar-webserver-webapi/src/test/java/org/sonar/server/ui/ws/ComponentActionTest.java Wyświetl plik

@@ -25,7 +25,6 @@ import java.util.Date;
import java.util.List;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.ResourceType;
import org.sonar.api.resources.ResourceTypes;
import org.sonar.api.server.ws.Change;
@@ -47,7 +46,6 @@ import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.GlobalPermission;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.property.PropertyDbTester;
@@ -59,17 +57,17 @@ import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.organization.BillingValidations;
import org.sonar.server.organization.BillingValidationsProxy;
import org.sonar.server.qualitygate.QualityGateFinder;
import org.sonar.server.qualityprofile.QPMeasureData;
import org.sonar.server.qualityprofile.QualityProfile;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ui.PageRepository;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import org.sonar.updatecenter.common.Version;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
@@ -92,23 +90,20 @@ import static org.sonar.test.JsonAssert.assertJson;
public class ComponentActionTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();
public final DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
public final UserSessionRule userSession = UserSessionRule.standalone();

private DbClient dbClient = db.getDbClient();
private ComponentDbTester componentDbTester = db.components();
private PropertyDbTester propertyDbTester = new PropertyDbTester(db);
private ResourceTypes resourceTypes = mock(ResourceTypes.class);
private BillingValidationsProxy billingValidations = mock(BillingValidationsProxy.class);
private final DbClient dbClient = db.getDbClient();
private final ComponentDbTester componentDbTester = db.components();
private final PropertyDbTester propertyDbTester = new PropertyDbTester(db);
private final ResourceTypes resourceTypes = mock(ResourceTypes.class);

private WsActionTester ws;

@Test
public void return_info_if_user_has_browse_permission_on_project() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.logIn().addProjectPermission(UserRole.USER, project);
init();

@@ -117,7 +112,7 @@ public class ComponentActionTest {

@Test
public void return_info_if_user_has_administration_permission_on_project() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
init();

@@ -126,7 +121,7 @@ public class ComponentActionTest {

@Test
public void return_info_if_user_is_system_administrator() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.logIn().setSystemAdministrator();
init();

@@ -135,7 +130,7 @@ public class ComponentActionTest {

@Test
public void return_component_info_when_anonymous_no_snapshot() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.addProjectPermission(UserRole.USER, project);
init();

@@ -144,7 +139,7 @@ public class ComponentActionTest {

@Test
public void return_component_info_with_favourite() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
UserDto user = db.users().insertUser("obiwan");
propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setComponentUuid(project.uuid()).setUserUuid(user.getUuid()));
userSession.logIn(user).addProjectPermission(UserRole.USER, project);
@@ -155,7 +150,7 @@ public class ComponentActionTest {

@Test
public void return_favourite_for_branch() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
ComponentDto branch = componentDbTester.insertProjectBranch(project, b -> b.setKey("feature1").setUuid("xyz"));
UserDto user = db.users().insertUser("obiwan");
propertyDbTester.insertProperty(new PropertyDto().setKey("favourite").setComponentUuid(project.uuid()).setUserUuid(user.getUuid()));
@@ -169,7 +164,6 @@ public class ComponentActionTest {
.getInput();

assertJson(json).isSimilarTo("{\n" +
" \"organization\": \"my-org\",\n" +
" \"key\": \"polop\",\n" +
" \"isFavorite\": true,\n" +
" \"id\": \"xyz\",\n" +
@@ -181,7 +175,7 @@ public class ComponentActionTest {

@Test
public void return_component_info_when_snapshot() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
db.components().insertSnapshot(project, snapshot -> snapshot
.setCreatedAt(parseDateTime("2015-04-22T11:44:00+0200").getTime())
.setProjectVersion("3.14"));
@@ -193,9 +187,8 @@ public class ComponentActionTest {

@Test
public void return_component_info_when_file_on_master() {
OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org2"));
db.qualityGates().createDefaultQualityGate(organization);
ComponentDto main = componentDbTester.insertPrivateProject(organization, p -> p.setName("Sample").setDbKey("sample"));
db.qualityGates().createDefaultQualityGate();
ComponentDto main = componentDbTester.insertPrivateProject(p -> p.setName("Sample").setDbKey("sample"));
userSession.addProjectPermission(UserRole.USER, main);
init();

@@ -211,9 +204,8 @@ public class ComponentActionTest {

@Test
public void return_component_info_when_file_on_branch() {
OrganizationDto organization = db.organizations().insertForKey("my-org2");
db.qualityGates().createDefaultQualityGate(organization);
ComponentDto project = componentDbTester.insertPrivateProject(organization, p -> p.setName("Sample").setDbKey("sample"));
db.qualityGates().createDefaultQualityGate();
ComponentDto project = componentDbTester.insertPrivateProject(p -> p.setName("Sample").setDbKey("sample"));
ComponentDto branch = componentDbTester.insertProjectBranch(project, b -> b.setKey("feature1"));
userSession.addProjectPermission(UserRole.USER, project);
init();
@@ -254,8 +246,7 @@ public class ComponentActionTest {

@Test
public void return_quality_profiles_and_supports_deleted_ones() {
OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org"));
ComponentDto project = insertProject(organization);
ComponentDto project = insertProject();
QProfileDto qp1 = db.qualityProfiles().insert(t -> t.setKee("qp1").setName("Sonar Way Java").setLanguage("java"));
QProfileDto qp2 = db.qualityProfiles().insert(t -> t.setKee("qp2").setName("Sonar Way Xoo").setLanguage("xoo"));
addQualityProfiles(project,
@@ -274,7 +265,7 @@ public class ComponentActionTest {

@Test
public void return_empty_quality_profiles_when_no_measure() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.addProjectPermission(UserRole.USER, project);
init();

@@ -283,10 +274,9 @@ public class ComponentActionTest {

@Test
public void return_quality_gate_defined_on_project() {
OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org"));
db.qualityGates().createDefaultQualityGate(organization);
ProjectDto project = db.components().insertPrivateProjectDto(organization);
QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(organization, qg -> qg.setName("Sonar way"));
db.qualityGates().createDefaultQualityGate();
ProjectDto project = db.components().insertPrivateProjectDto();
QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way"));
db.qualityGates().associateProjectToQualityGate(project, qualityGateDto);
userSession.addProjectPermission(UserRole.USER, project);
init();
@@ -296,11 +286,10 @@ public class ComponentActionTest {

@Test
public void quality_gate_for_a_branch() {
OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org"));
db.qualityGates().createDefaultQualityGate(organization);
ProjectDto project = db.components().insertPrivateProjectDto(organization);
db.qualityGates().createDefaultQualityGate();
ProjectDto project = db.components().insertPrivateProjectDto();
BranchDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH));
QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(organization, qg -> qg.setName("Sonar way"));
QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way"));
db.qualityGates().associateProjectToQualityGate(project, qualityGateDto);
userSession.addProjectPermission(UserRole.USER, project);
init();
@@ -316,9 +305,8 @@ public class ComponentActionTest {

@Test
public void return_default_quality_gate() {
OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org"));
ComponentDto project = db.components().insertPrivateProject(organization);
db.qualityGates().createDefaultQualityGate(organization, qg -> qg.setName("Sonar way"));
ComponentDto project = db.components().insertPrivateProject();
db.qualityGates().createDefaultQualityGate(qg -> qg.setName("Sonar way"));
userSession.addProjectPermission(UserRole.USER, project);
init();

@@ -327,7 +315,7 @@ public class ComponentActionTest {

@Test
public void return_extensions() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.anonymous().addProjectPermission(UserRole.USER, project);
init(createPages());

@@ -336,16 +324,15 @@ public class ComponentActionTest {

@Test
public void return_extensions_for_application() {
OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org"));
db.qualityGates().createDefaultQualityGate(organization);
ProjectDto project = db.components().insertPrivateProjectDto(organization);
db.qualityGates().createDefaultQualityGate();
ProjectDto project = db.components().insertPrivateProjectDto();
Page page = Page.builder("my_plugin/app_page")
.setName("App Page")
.setScope(COMPONENT)
.setComponentQualifiers(Qualifier.VIEW, Qualifier.APP)
.build();
ComponentDto application = componentDbTester.insertPublicApplication(organization);
QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(organization, qg -> qg.setName("Sonar way"));
ComponentDto application = componentDbTester.insertPublicApplication();
QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way"));
db.qualityGates().associateProjectToQualityGate(project, qualityGateDto);
userSession.registerComponents(application);
init(page);
@@ -359,7 +346,7 @@ public class ComponentActionTest {

@Test
public void return_extensions_for_admin() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.anonymous()
.addProjectPermission(UserRole.USER, project)
.addProjectPermission(UserRole.ADMIN, project);
@@ -370,7 +357,7 @@ public class ComponentActionTest {

@Test
public void return_configuration_for_admin() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
UserDto user = db.users().insertUser();
userSession.logIn(user)
.addProjectPermission(UserRole.USER, project)
@@ -394,7 +381,7 @@ public class ComponentActionTest {

@Test
public void return_configuration_with_all_properties() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.anonymous()
.addProjectPermission(UserRole.USER, project)
.addProjectPermission(UserRole.ADMIN, project);
@@ -415,7 +402,7 @@ public class ComponentActionTest {

@Test
public void return_configuration_for_quality_profile_admin() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.logIn()
.addProjectPermission(UserRole.USER, project)
.addPermission(ADMINISTER_QUALITY_PROFILES);
@@ -426,7 +413,7 @@ public class ComponentActionTest {

@Test
public void return_configuration_for_quality_gate_admin() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.logIn()
.addProjectPermission(UserRole.USER, project)
.addPermission(ADMINISTER_QUALITY_GATES);
@@ -437,7 +424,7 @@ public class ComponentActionTest {

@Test
public void return_configuration_for_private_projects() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
UserSessionRule userSessionRule = userSession.logIn();
init();

@@ -455,7 +442,7 @@ public class ComponentActionTest {
" \"showBackgroundTasks\": true,\n" +
" \"canApplyPermissionTemplate\": false,\n" +
" \"canBrowseProject\": false,\n" +
" \"canUpdateProjectVisibilityToPrivate\": false\n" +
" \"canUpdateProjectVisibilityToPrivate\": true\n" +
" }\n" +
"}");

@@ -473,14 +460,14 @@ public class ComponentActionTest {
" \"showBackgroundTasks\": true,\n" +
" \"canApplyPermissionTemplate\": false,\n" +
" \"canBrowseProject\": true,\n" +
" \"canUpdateProjectVisibilityToPrivate\": false\n" +
" \"canUpdateProjectVisibilityToPrivate\": true\n" +
" }\n" +
"}");
}

@Test
public void return_bread_crumbs_on_several_levels() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
ComponentDto module = componentDbTester.insertComponent(newModuleDto("bcde", project).setDbKey("palap").setName("Palap"));
ComponentDto directory = componentDbTester.insertComponent(newDirectory(module, "src/main/xoo"));
ComponentDto file = componentDbTester.insertComponent(newFileDto(directory, directory, "cdef").setName("Source.xoo")
@@ -494,7 +481,7 @@ public class ComponentActionTest {

@Test
public void project_administrator_is_allowed_to_get_information() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
userSession.addProjectPermission(UserRole.ADMIN, project);
init(createPages());

@@ -503,9 +490,8 @@ public class ComponentActionTest {

@Test
public void should_return_private_flag_for_project() {
OrganizationDto org = db.organizations().insert();
db.qualityGates().createDefaultQualityGate(org);
ComponentDto project = db.components().insertPrivateProject(org);
db.qualityGates().createDefaultQualityGate();
ComponentDto project = db.components().insertPrivateProject();
init();

userSession.logIn()
@@ -516,9 +502,8 @@ public class ComponentActionTest {

@Test
public void should_return_public_flag_for_project() {
OrganizationDto org = db.organizations().insert();
db.qualityGates().createDefaultQualityGate(org);
ComponentDto project = db.components().insertPublicProject(org);
db.qualityGates().createDefaultQualityGate();
ComponentDto project = db.components().insertPublicProject();
init();

userSession.logIn()
@@ -528,10 +513,9 @@ public class ComponentActionTest {
}

@Test
public void canApplyPermissionTemplate_is_true_if_logged_in_as_organization_administrator() {
OrganizationDto org = db.organizations().insert();
db.qualityGates().createDefaultQualityGate(org);
ComponentDto project = db.components().insertPrivateProject(org);
public void canApplyPermissionTemplate_is_true_if_logged_in_as_administrator() {
db.qualityGates().createDefaultQualityGate();
ComponentDto project = db.components().insertPrivateProject();
init(createPages());

userSession.logIn()
@@ -546,54 +530,49 @@ public class ComponentActionTest {
}

@Test
public void canUpdateProjectVisibilityToPrivate_is_true_if_logged_in_as_project_administrator_and_extension_returns_false() {
OrganizationDto org = db.organizations().insert();
db.qualityGates().createDefaultQualityGate(org);
ComponentDto project = db.components().insertPublicProject(org);
public void canUpdateProjectVisibilityToPrivate_is_true_if_logged_in_as_project_administrator() {
db.qualityGates().createDefaultQualityGate();
ComponentDto project = db.components().insertPublicProject();
init(createPages());

userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
when(billingValidations.canUpdateProjectVisibilityToPrivate(any(BillingValidations.Organization.class))).thenReturn(false);
assertJson(execute(project.getDbKey())).isSimilarTo("{\"configuration\": {\"canUpdateProjectVisibilityToPrivate\": false}}");

userSession.logIn().addProjectPermission(UserRole.ADMIN, project);
when(billingValidations.canUpdateProjectVisibilityToPrivate(any(BillingValidations.Organization.class))).thenReturn(true);
assertJson(execute(project.getDbKey())).isSimilarTo("{\"configuration\": {\"canUpdateProjectVisibilityToPrivate\": true}}");
}

@Test
public void fail_on_missing_parameters() {
insertOrganizationAndProject();
insertProject();
init();

expectedException.expect(IllegalArgumentException.class);
ws.newRequest().execute();
TestRequest request = ws.newRequest();
assertThatThrownBy(request::execute)
.isInstanceOf(IllegalArgumentException.class);
}

@Test
public void fail_on_unknown_component_key() {
insertOrganizationAndProject();
insertProject();
init();

expectedException.expect(NotFoundException.class);
execute("unknoen");
assertThatThrownBy(() -> execute("unknoen"))
.isInstanceOf(NotFoundException.class);
}

@Test
public void throw_ForbiddenException_if_required_permission_is_not_granted() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
init();
userSession.logIn();

expectedException.expect(ForbiddenException.class);
execute(project.getDbKey());
String projectDbKey = project.getDbKey();
assertThatThrownBy(() -> execute(projectDbKey))
.isInstanceOf(ForbiddenException.class);
}

@Test
public void test_example_response() {
init(createPages());
OrganizationDto organizationDto = db.organizations().insertForKey("my-org-1");
ComponentDto project = newPrivateProjectDto(organizationDto, "ABCD")
ComponentDto project = newPrivateProjectDto("ABCD")
.setDbKey("org.codehaus.sonar:sonar")
.setName("Sonarqube")
.setDescription("Open source platform for continuous inspection of code quality");
@@ -609,7 +588,7 @@ public class ComponentActionTest {
addQualityProfiles(project,
createQProfile("qp1", "Sonar Way Java", "java"),
createQProfile("qp2", "Sonar Way Xoo", "xoo"));
QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(db.getDefaultOrganization(), qg -> qg.setName("Sonar way"));
QualityGateDto qualityGateDto = db.qualityGates().insertQualityGate(qg -> qg.setName("Sonar way"));
db.qualityGates().associateProjectToQualityGate(db.components().getProjectDto(project), qualityGateDto);
userSession.logIn(user)
.addProjectPermission(UserRole.USER, project)
@@ -644,7 +623,7 @@ public class ComponentActionTest {

@Test(expected = BadRequestException.class)
public void fail_on_module_key_as_param() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
ComponentDto module = componentDbTester.insertComponent(newModuleDto("bcde", project).setDbKey("palap").setName("Palap"));
init();

@@ -653,7 +632,7 @@ public class ComponentActionTest {

@Test(expected = BadRequestException.class)
public void fail_on_directory_key_as_param() {
ComponentDto project = insertOrganizationAndProject();
ComponentDto project = insertProject();
ComponentDto module = componentDbTester.insertComponent(newModuleDto("bcde", project).setDbKey("palap").setName("Palap"));
ComponentDto directory = componentDbTester.insertComponent(newDirectory(module, "src/main/xoo"));
userSession.addProjectPermission(UserRole.USER, project);
@@ -662,14 +641,9 @@ public class ComponentActionTest {
execute(directory.getDbKey());
}

private ComponentDto insertOrganizationAndProject() {
OrganizationDto organization = db.organizations().insert(o -> o.setKey("my-org"));
return insertProject(organization);
}

private ComponentDto insertProject(OrganizationDto organization) {
db.qualityGates().createDefaultQualityGate(organization);
return db.components().insertPrivateProject(organization, "abcd", p -> p.setDbKey("polop").setName("Polop").setDescription("test project"));
private ComponentDto insertProject() {
db.qualityGates().createDefaultQualityGate();
return db.components().insertPrivateProject("abcd", p -> p.setDbKey("polop").setName("Polop").setDescription("test project"));
}

private void init(Page... pages) {
@@ -686,7 +660,7 @@ public class ComponentActionTest {
pageRepository.start();
ws = new WsActionTester(
new ComponentAction(dbClient, pageRepository, resourceTypes, userSession, new ComponentFinder(dbClient, resourceTypes),
new QualityGateFinder(dbClient), billingValidations));
new QualityGateFinder(dbClient)));
}

private String execute(String componentKey) {

+ 0
- 1
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_bread_crumbs_on_several_levels.json Wyświetl plik

@@ -1,5 +1,4 @@
{
"organization": "my-org",
"key": "palap:src/main/xoo/Source.xoo",
"id": "cdef",
"name": "Source.xoo",

+ 0
- 1
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_when_anonymous_no_snapshot.json Wyświetl plik

@@ -1,5 +1,4 @@
{
"organization": "my-org",
"key": "polop",
"id": "abcd",
"name": "Polop",

+ 0
- 1
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_when_file_on_branch.json Wyświetl plik

@@ -1,6 +1,5 @@
{
"key": "sample:src/Main.xoo",
"organization": "my-org2",
"id": "abcd",
"name": "Main.xoo",
"isFavorite": false,

+ 0
- 1
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_when_file_on_master.json Wyświetl plik

@@ -1,6 +1,5 @@
{
"key": "sample:src/Main.xoo",
"organization": "my-org2",
"id": "abcd",
"name": "Main.xoo",
"isFavorite": false,

+ 0
- 1
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_when_snapshot.json Wyświetl plik

@@ -1,5 +1,4 @@
{
"organization": "my-org",
"key": "polop",
"id": "abcd",
"name": "Polop",

+ 0
- 1
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_component_info_with_favourite.json Wyświetl plik

@@ -1,5 +1,4 @@
{
"organization": "my-org",
"key": "polop",
"id": "abcd",
"name": "Polop",

+ 1
- 1
server/sonar-webserver-webapi/src/test/resources/org/sonar/server/ui/ws/ComponentActionTest/return_configuration_with_all_properties.json Wyświetl plik

@@ -11,7 +11,7 @@
"showBackgroundTasks": true,
"canApplyPermissionTemplate": false,
"canBrowseProject": true,
"canUpdateProjectVisibilityToPrivate": false,
"canUpdateProjectVisibilityToPrivate": true,
"extensions": []
}
}

+ 0
- 1
sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java Wyświetl plik

@@ -31,7 +31,6 @@ public class ComponentsWsParameters {
public static final String ACTION_SUGGESTIONS = "suggestions";

// parameters
public static final String PARAM_ORGANIZATION = "organization";
public static final String PARAM_QUALIFIERS = "qualifiers";
public static final String PARAM_STRATEGY = "strategy";
public static final String PARAM_FILTER = "filter";

+ 3
- 7
sonar-ws/src/main/protobuf/ws-components.proto Wyświetl plik

@@ -50,8 +50,7 @@ message ShowWsResponse {
message SuggestionsWsResponse {
repeated Category results = 1;
optional string warning = 2;
repeated sonarqube.ws.commons.Organization organizations = 3;
repeated Project projects = 4;
repeated Project projects = 3;

message Category {
optional string q = 1;
@@ -63,7 +62,6 @@ message SuggestionsWsResponse {
optional string key = 1;
optional string name = 2;
optional string match = 3;
optional string organization = 4;
optional string project = 5;
optional bool isRecentlyBrowsed = 6;
optional bool isFavorite = 7;
@@ -78,9 +76,8 @@ message SuggestionsWsResponse {
// WS api/components/search_projects
message SearchProjectsWsResponse {
optional sonarqube.ws.commons.Paging paging = 1;
repeated sonarqube.ws.commons.Organization organizations = 2;
repeated Component components = 3;
optional sonarqube.ws.commons.Facets facets = 4;
repeated Component components = 2;
optional sonarqube.ws.commons.Facets facets = 3;
}

// WS api/components/provisioned
@@ -98,7 +95,6 @@ message ProvisionedWsResponse {
}

message Component {
optional string organization = 12;
optional string key = 2;
optional string refId = 3;
optional string refKey = 4;

Ładowanie…
Anuluj
Zapisz