Ver código fonte

SONAR-9303 WS api/qualityprofiles/restore_built_in returns http 410 when called

tags/6.5-M1
Teryk Bellahsene 7 anos atrás
pai
commit
702b6393c7
30 arquivos alterados com 242 adições e 734 exclusões
  1. 1
    2
      it/it-tests/src/test/java/it/analysis/IssuesModeTest.java
  2. 1
    3
      it/it-tests/src/test/java/it/qualityProfile/OrganizationQualityProfilesPageTest.java
  3. 1
    3
      it/it-tests/src/test/java/it/qualityProfile/QualityProfilesPageTest.java
  4. 0
    95
      it/it-tests/src/test/resources/organization/OrganizationQualityProfilesPageTest/should_restore_built_in.html
  5. 0
    95
      it/it-tests/src/test/resources/qualityProfile/QualityProfilesPageTest/should_restore_built_in.html
  6. 9
    5
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java
  7. 0
    6
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileReset.java
  8. 3
    46
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileResetImpl.java
  9. 4
    1
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRuleAction.java
  10. 5
    1
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java
  11. 1
    0
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ChangeParentAction.java
  12. 4
    1
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRuleAction.java
  13. 4
    1
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRulesAction.java
  14. 5
    4
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeleteAction.java
  15. 16
    12
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java
  16. 5
    4
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RenameAction.java
  17. 2
    2
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreAction.java
  18. 7
    45
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInAction.java
  19. 13
    15
      server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
  20. 0
    240
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileResetMediumTest.java
  21. 21
    3
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRuleActionTest.java
  22. 14
    0
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java
  23. 21
    1
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionTest.java
  24. 16
    0
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRuleActionTest.java
  25. 15
    2
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRulesActionTest.java
  26. 15
    0
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java
  27. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
  28. 13
    3
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RenameActionTest.java
  29. 15
    128
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInActionTest.java
  30. 30
    15
      server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java

+ 1
- 2
it/it-tests/src/test/java/it/analysis/IssuesModeTest.java Ver arquivo

@@ -207,9 +207,8 @@ public class IssuesModeTest {

// SONAR-8518
@Test
public void shoud_support_sonar_profile_prop() throws IOException {
public void should_support_sonar_profile_prop() throws IOException {
restoreProfile("one-issue-per-line.xml");
restoreProfile("empty.xml");
orchestrator.getServer().provisionProject("sample", "xoo-sample");
orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "empty");


+ 1
- 3
it/it-tests/src/test/java/it/qualityProfile/OrganizationQualityProfilesPageTest.java Ver arquivo

@@ -152,9 +152,7 @@ public class OrganizationQualityProfilesPageTest {
public void testRestoration() throws Exception {
deleteProfile("xoo", "empty");

runSelenese(orchestrator,
"/organization/OrganizationQualityProfilesPageTest/should_restore.html",
"/organization/OrganizationQualityProfilesPageTest/should_restore_built_in.html");
runSelenese(orchestrator, "/organization/OrganizationQualityProfilesPageTest/should_restore.html");
}

private static void createProfile(String language, String name) {

+ 1
- 3
it/it-tests/src/test/java/it/qualityProfile/QualityProfilesPageTest.java Ver arquivo

@@ -134,9 +134,7 @@ public class QualityProfilesPageTest {
public void testRestoration() throws Exception {
deleteProfile("xoo", "empty");

runSelenese(orchestrator,
"/qualityProfile/QualityProfilesPageTest/should_restore.html",
"/qualityProfile/QualityProfilesPageTest/should_restore_built_in.html");
runSelenese(orchestrator, "/qualityProfile/QualityProfilesPageTest/should_restore.html");
}

private static void createProfile(String language, String name) {

+ 0
- 95
it/it-tests/src/test/resources/organization/OrganizationQualityProfilesPageTest/should_restore_built_in.html Ver arquivo

@@ -1,95 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="selenium.base" href="http://localhost:49506"/>
<title>should_create</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr>
<td rowspan="1" colspan="3">should_create</td>
</tr>
</thead>
<tbody>
<tr>
<td>open</td>
<td>/sessions/logout</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>/sessions/login</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>id=password</td>
<td>admin</td>
</tr>
<tr>
<td>type</td>
<td>id=login</td>
<td>admin</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>name=commit</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>css=.js-user-authenticated</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>/organizations/test-org/quality_profiles</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>css=.quality-profiles-table-row[data-name=&quot;sample&quot;]</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>css=.quality-profiles-table-row[data-name=&quot;empty&quot;]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=.js-more-admin-actions</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#quality-profiles-restore-built-in</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#restore-built-in-profiles-submit</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>css=#restore-built-in-profiles-form .alert-success</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=.js-modal-close</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>css=.quality-profiles-table-row[data-name=&quot;empty&quot;]</td>
<td></td>
</tr>
</tbody>
</table>
</body>
</html>

+ 0
- 95
it/it-tests/src/test/resources/qualityProfile/QualityProfilesPageTest/should_restore_built_in.html Ver arquivo

@@ -1,95 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="selenium.base" href="http://localhost:49506"/>
<title>should_create</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr>
<td rowspan="1" colspan="3">should_create</td>
</tr>
</thead>
<tbody>
<tr>
<td>open</td>
<td>/sessions/logout</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>/sessions/login</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>id=password</td>
<td>admin</td>
</tr>
<tr>
<td>type</td>
<td>id=login</td>
<td>admin</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>name=commit</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>css=.js-user-authenticated</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>/profiles</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>css=.quality-profiles-table-row[data-name=&quot;sample&quot;]</td>
<td></td>
</tr>
<tr>
<td>assertElementNotPresent</td>
<td>css=.quality-profiles-table-row[data-name=&quot;empty&quot;]</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=.js-more-admin-actions</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#quality-profiles-restore-built-in</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=#restore-built-in-profiles-submit</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>css=#restore-built-in-profiles-form .alert-success</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>css=.js-modal-close</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>css=.quality-profiles-table-row[data-name=&quot;empty&quot;]</td>
<td></td>
</tr>
</tbody>
</table>
</body>
</html>

+ 9
- 5
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileFactory.java Ver arquivo

@@ -34,6 +34,7 @@ import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;

import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.server.ws.WsUtils.checkRequest;

/**
@@ -55,12 +56,20 @@ public class QProfileFactory {

// ------------- CREATION

private static OrganizationDto requireNonNull(@Nullable OrganizationDto organization) {
Objects.requireNonNull(organization, "Organization is required, when creating a quality profile.");
return organization;
}

RulesProfileDto getOrCreateCustom(DbSession dbSession, OrganizationDto organization, QProfileName name) {
requireNonNull(organization);
RulesProfileDto profile = db.qualityProfileDao().selectByNameAndLanguage(organization, name.getName(), name.getLanguage(), dbSession);
if (profile == null) {
profile = doCreate(dbSession, organization, name, false, false);
} else {
checkArgument(!profile.isBuiltIn(), "Operation forbidden for built-in Quality Profile '%s' with language '%s'", profile.getName(), profile.getLanguage());
}

return profile;
}

@@ -85,11 +94,6 @@ public class QProfileFactory {
return doCreate(dbSession, requireNonNull(organization), name, isDefault, true);
}

private static OrganizationDto requireNonNull(@Nullable OrganizationDto organization) {
Objects.requireNonNull(organization, "Organization is required, when creating a quality profile.");
return organization;
}

private RulesProfileDto doCreate(DbSession dbSession, OrganizationDto organization, QProfileName name, boolean isDefault, boolean isBuiltIn) {
if (StringUtils.isEmpty(name.getName())) {
throw BadRequestException.create("quality_profiles.profile_name_cant_be_blank");

+ 0
- 6
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileReset.java Ver arquivo

@@ -21,15 +21,9 @@ package org.sonar.server.qualityprofile;

import java.util.Collection;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.RulesProfileDto;

public interface QProfileReset {
/**
* Restore the built-in profiles provided by plugins for the specified language.
* Missing profiles are created and existing ones are updated.
*/
void resetLanguage(DbSession dbSession, OrganizationDto organization, String language);

/**
* Reset the rules of the specified profile.

+ 3
- 46
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfileResetImpl.java Ver arquivo

@@ -19,84 +19,41 @@
*/
package org.sonar.server.qualityprofile;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.ActiveRule;
import org.sonar.api.rules.ActiveRuleParam;
import org.sonar.api.server.ServerSide;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.ActiveRuleKey;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.db.rule.RuleParamDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer;

import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;

@ServerSide
public class QProfileResetImpl implements QProfileReset {

private final DbClient db;
private final QProfileFactory factory;
private final RuleActivator activator;
private final ActiveRuleIndexer activeRuleIndexer;
private final BuiltInQProfileRepository builtInQProfileRepositories;

public QProfileResetImpl(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer, QProfileFactory factory,
BuiltInQProfileRepository builtInQProfileRepository) {
public QProfileResetImpl(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer) {
this.db = db;
this.activator = activator;
this.activeRuleIndexer = activeRuleIndexer;
this.factory = factory;
this.builtInQProfileRepositories = builtInQProfileRepository;
}

@Override
public void resetLanguage(DbSession dbSession, OrganizationDto organization, String language) {
builtInQProfileRepositories.getQProfilesByLanguage()
.entrySet()
.stream()
.filter(entry -> entry.getKey().equals(language))
.map(Map.Entry::getValue)
.flatMap(List::stream)
.forEach(builtInQProfile -> resetProfile(dbSession, organization, builtInQProfile));
}

private void resetProfile(DbSession dbSession, OrganizationDto organization, BuiltInQProfile builtInQProfile) {
RulesProfileDto profile = factory.getOrCreateCustom(dbSession, organization, builtInQProfile.getQProfileName());

List<RuleActivation> activations = Lists.newArrayList();
builtInQProfile.getActiveRules().forEach(activeRule -> activations.add(getRuleActivation(dbSession, activeRule)));
reset(dbSession, profile, activations);
}

private RuleActivation getRuleActivation(DbSession dbSession, ActiveRule activeRule) {
RuleActivation activation = new RuleActivation(RuleKey.of(activeRule.getRepositoryKey(), activeRule.getRuleKey()));
activation.setSeverity(activeRule.getSeverity().name());
if (!activeRule.getActiveRuleParams().isEmpty()) {
for (ActiveRuleParam param : activeRule.getActiveRuleParams()) {
activation.setParameter(param.getParamKey(), param.getValue());
}
} else {
for (RuleParamDto param : db.ruleDao().selectRuleParamsByRuleKey(dbSession, activeRule.getRule().ruleKey())) {
activation.setParameter(param.getName(), param.getDefaultValue());
}
}
return activation;
}

@Override
public BulkChangeResult reset(DbSession dbSession, RulesProfileDto profile, Collection<RuleActivation> activations) {
requireNonNull(profile.getId(), "Quality profile must be persisted");
checkArgument(!profile.isBuiltIn(), "Operation forbidden for built-in Quality Profile '%s'", profile.getKee());
BulkChangeResult result = new BulkChangeResult();
Set<RuleKey> ruleToBeDeactivated = Sets.newHashSet();
// Keep reference to all the activated rules before backup restore

+ 4
- 1
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRuleAction.java Ver arquivo

@@ -30,6 +30,7 @@ import org.sonar.api.utils.KeyValueFormat;
import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.qualityprofile.ActiveRuleChange;
import org.sonar.server.qualityprofile.RuleActivation;
import org.sonar.server.qualityprofile.RuleActivator;
@@ -106,7 +107,9 @@ public class ActivateRuleAction implements QProfileWsAction {
String profileKey = request.mandatoryParam(PARAM_PROFILE_KEY);
userSession.checkLoggedIn();
try (DbSession dbSession = dbClient.openSession(false)) {
wsSupport.checkPermission(dbSession, profileKey);
RulesProfileDto profile = wsSupport.getProfile(dbSession, QProfileReference.fromKey(profileKey));
wsSupport.checkPermission(dbSession, profile);
wsSupport.checkNotBuiltInt(profile);
List<ActiveRuleChange> changes = ruleActivator.activate(dbSession, activation, profileKey);
dbSession.commit();
activeRuleIndexer.index(changes);

+ 5
- 1
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ActivateRulesAction.java Ver arquivo

@@ -26,11 +26,13 @@ import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.qualityprofile.BulkChangeResult;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.rule.ws.RuleQueryFactory;
import org.sonar.server.user.UserSession;

import static org.sonar.server.qualityprofile.ws.QProfileReference.fromKey;
import static org.sonar.server.rule.ws.SearchAction.defineRuleSearchParameters;

@ServerSide
@@ -81,7 +83,9 @@ public class ActivateRulesAction implements QProfileWsAction {
userSession.checkLoggedIn();
BulkChangeResult result;
try (DbSession dbSession = dbClient.openSession(false)) {
wsSupport.checkPermission(dbSession, qualityProfileKey);
RulesProfileDto profile = wsSupport.getProfile(dbSession, fromKey(qualityProfileKey));
wsSupport.checkPermission(dbSession, profile);
wsSupport.checkNotBuiltInt(profile);
result = ruleActivator.bulkActivate(ruleQueryFactory.createRuleQuery(dbSession, request), qualityProfileKey, request.param(SEVERITY));
}
BulkChangeWsResponse.writeResponse(result, response);

+ 1
- 0
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/ChangeParentAction.java Ver arquivo

@@ -90,6 +90,7 @@ public class ChangeParentAction implements QProfileWsAction {
OrganizationDto organization = dbClient.organizationDao().selectByUuid(dbSession, organizationUuid)
.orElseThrow(() -> new IllegalStateException(String.format("Could not find organization with uuid '%s' of profile '%s'", organizationUuid, profile.getKee())));
userSession.checkPermission(ADMINISTER_QUALITY_PROFILES, organization);
wsSupport.checkNotBuiltInt(profile);

String parentKey = request.param(PARAM_PARENT_KEY);
String parentName = request.param(PARAM_PARENT_NAME);

+ 4
- 1
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRuleAction.java Ver arquivo

@@ -28,6 +28,7 @@ import org.sonar.core.util.Uuids;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.ActiveRuleKey;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.user.UserSession;

@@ -75,7 +76,9 @@ public class DeactivateRuleAction implements QProfileWsAction {
String qualityProfileKey = request.mandatoryParam(PARAM_PROFILE_KEY);
userSession.checkLoggedIn();
try (DbSession dbSession = dbClient.openSession(false)) {
wsSupport.checkPermission(dbSession, qualityProfileKey);
RulesProfileDto profile = wsSupport.getProfile(dbSession, QProfileReference.fromKey(qualityProfileKey));
wsSupport.checkPermission(dbSession, profile);
wsSupport.checkNotBuiltInt(profile);
ActiveRuleKey activeRuleKey = ActiveRuleKey.of(qualityProfileKey, ruleKey);
ruleActivator.deactivateAndUpdateIndex(dbSession, activeRuleKey);
}

+ 4
- 1
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeactivateRulesAction.java Ver arquivo

@@ -25,6 +25,7 @@ import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.qualityprofile.BulkChangeResult;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.rule.ws.RuleQueryFactory;
@@ -76,7 +77,9 @@ public class DeactivateRulesAction implements QProfileWsAction {
userSession.checkLoggedIn();
BulkChangeResult result;
try (DbSession dbSession = dbClient.openSession(false)) {
wsSupport.checkPermission(dbSession, qualityProfileKey);
RulesProfileDto profile = wsSupport.getProfile(dbSession, QProfileReference.fromKey(qualityProfileKey));
wsSupport.checkPermission(dbSession, profile);
wsSupport.checkNotBuiltInt(profile);
result = ruleActivator.bulkDeactivate(ruleQueryFactory.createRuleQuery(dbSession, request), qualityProfileKey);
}
BulkChangeWsResponse.writeResponse(result, response);

+ 5
- 4
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/DeleteAction.java Ver arquivo

@@ -44,14 +44,14 @@ public class DeleteAction implements QProfileWsAction {
private final QProfileFactory profileFactory;
private final DbClient dbClient;
private final UserSession userSession;
private final QProfileWsSupport qProfileWsSupport;
private final QProfileWsSupport wsSupport;

public DeleteAction(Languages languages, QProfileFactory profileFactory, DbClient dbClient, UserSession userSession, QProfileWsSupport qProfileWsSupport) {
public DeleteAction(Languages languages, QProfileFactory profileFactory, DbClient dbClient, UserSession userSession, QProfileWsSupport wsSupport) {
this.languages = languages;
this.profileFactory = profileFactory;
this.dbClient = dbClient;
this.userSession = userSession;
this.qProfileWsSupport = qProfileWsSupport;
this.wsSupport = wsSupport;
}

@Override
@@ -72,8 +72,9 @@ public class DeleteAction implements QProfileWsAction {
userSession.checkLoggedIn();

try (DbSession dbSession = dbClient.openSession(false)) {
RulesProfileDto profile = qProfileWsSupport.getProfile(dbSession, QProfileReference.from(request));
RulesProfileDto profile = wsSupport.getProfile(dbSession, QProfileReference.from(request));
userSession.checkPermission(ADMINISTER_QUALITY_PROFILES, profile.getOrganizationUuid());
wsSupport.checkNotBuiltInt(profile);

List<RulesProfileDto> descendants = selectDescendants(dbSession, profile);
ensureNoneIsMarkedAsDefault(dbSession, profile, descendants);

+ 16
- 12
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileWsSupport.java Ver arquivo

@@ -35,6 +35,7 @@ import org.sonar.server.ws.WsUtils;

import static java.util.Objects.requireNonNull;
import static org.sonar.server.ws.WsUtils.checkFound;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;

@ServerSide
@@ -50,6 +51,15 @@ public class QProfileWsSupport {
this.defaultOrganizationProvider = defaultOrganizationProvider;
}

public static NewParam createOrganizationParam(NewAction action) {
return action
.createParam(PARAM_ORGANIZATION)
.setDescription("Organization key")
.setRequired(false)
.setInternal(true)
.setExampleValue("my-org");
}

public OrganizationDto getOrganization(DbSession dbSession, RulesProfileDto profile) {
requireNonNull(profile);
String organizationUuid = profile.getOrganizationUuid();
@@ -65,15 +75,6 @@ public class QProfileWsSupport {
"No organization with key '%s'", organizationOrDefaultKey);
}

public static NewParam createOrganizationParam(NewAction action) {
return action
.createParam(PARAM_ORGANIZATION)
.setDescription("Organization key")
.setRequired(false)
.setInternal(true)
.setExampleValue("my-org");
}

/**
* Get the Quality profile specified by the reference {@code ref}.
*
@@ -93,9 +94,12 @@ public class QProfileWsSupport {
return profile;
}

public void checkPermission(DbSession dbSession, String qualityProfileKey) {
RulesProfileDto qualityProfile = dbClient.qualityProfileDao().selectByKey(dbSession, qualityProfileKey);
OrganizationDto organization = getOrganization(dbSession, qualityProfile);
public void checkPermission(DbSession dbSession, RulesProfileDto rulesProfile) {
OrganizationDto organization = getOrganization(dbSession, rulesProfile);
userSession.checkPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
}

public void checkNotBuiltInt(RulesProfileDto profile) {
checkRequest(!profile.isBuiltIn(), "Operation forbidden for built-in Quality Profile '%s' with language '%s'", profile.getName(), profile.getLanguage());
}
}

+ 5
- 4
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RenameAction.java Ver arquivo

@@ -32,7 +32,6 @@ import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.user.UserSession;

import static java.lang.String.format;
@@ -48,10 +47,12 @@ public class RenameAction implements QProfileWsAction {

private final DbClient dbClient;
private final UserSession userSession;
private final QProfileWsSupport wsSupport;

public RenameAction(DbClient dbClient, UserSession userSession) {
public RenameAction(DbClient dbClient, UserSession userSession, QProfileWsSupport wsSupport) {
this.dbClient = dbClient;
this.userSession = userSession;
this.wsSupport = wsSupport;
}

@Override
@@ -88,11 +89,11 @@ public class RenameAction implements QProfileWsAction {
userSession.checkLoggedIn();

try (DbSession dbSession = dbClient.openSession(false)) {
RulesProfileDto qualityProfile = ofNullable(dbClient.qualityProfileDao().selectByKey(dbSession, profileKey))
.orElseThrow(() -> new NotFoundException("Quality profile not found: " + profileKey));
RulesProfileDto qualityProfile = wsSupport.getProfile(dbSession, QProfileReference.fromKey(profileKey));

String organizationUuid = qualityProfile.getOrganizationUuid();
userSession.checkPermission(ADMINISTER_QUALITY_PROFILES, organizationUuid);
wsSupport.checkNotBuiltInt(qualityProfile);

if (!Objects.equals(newName, qualityProfile.getName())) {
OrganizationDto organization = dbClient.organizationDao().selectByUuid(dbSession, organizationUuid)

+ 2
- 2
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreAction.java Ver arquivo

@@ -31,7 +31,6 @@ import org.sonar.api.utils.text.JsonWriter;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.qualityprofile.BulkChangeResult;
import org.sonar.server.qualityprofile.QProfileBackuper;
@@ -40,6 +39,7 @@ import org.sonar.server.user.UserSession;

import static com.google.common.base.Preconditions.checkArgument;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.ACTION_RESTORE;
import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.RestoreActionParameters.PARAM_BACKUP;
@@ -91,7 +91,7 @@ public class RestoreAction implements QProfileWsAction {
reader = new InputStreamReader(backup, UTF_8);

OrganizationDto organization = wsSupport.getOrganizationByKey(dbSession, organizationKey);
userSession.checkPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);
userSession.checkPermission(ADMINISTER_QUALITY_PROFILES, organization);

QProfileRestoreSummary summary = backuper.restore(dbSession, reader, organization, null);
writeResponse(response.newJsonWriter(), organization, summary);

+ 7
- 45
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInAction.java Ver arquivo

@@ -19,64 +19,26 @@
*/
package org.sonar.server.qualityprofile.ws;

import org.sonar.api.resources.Languages;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.server.qualityprofile.QProfileReset;
import org.sonar.server.user.UserSession;

import static org.sonar.server.util.LanguageParamUtils.getExampleValue;
import static org.sonar.server.util.LanguageParamUtils.getLanguageKeys;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
import org.sonar.server.ws.RemovedWebServiceHandler;

public class RestoreBuiltInAction implements QProfileWsAction {

private final DbClient dbClient;
private final QProfileReset reset;
private final Languages languages;
private final UserSession userSession;
private final QProfileWsSupport qProfileWsSupport;

public RestoreBuiltInAction(DbClient dbClient, QProfileReset reset, Languages languages, UserSession userSession, QProfileWsSupport qProfileWsSupport) {
this.dbClient = dbClient;
this.reset = reset;
this.languages = languages;
this.userSession = userSession;
this.qProfileWsSupport = qProfileWsSupport;
}

@Override
public void define(WebService.NewController controller) {
WebService.NewAction action = controller.createAction("restore_built_in")
.setDescription("Restore built-in profiles from the definitions declared by plugins. " +
"Missing profiles are created, existing ones are updated.")
controller.createAction("restore_built_in")
.setDescription("This web service has no effect since 6.4. It's no more possible to restore built-in quality profiles because they are automatically " +
"updated and read only. Returns HTTP code 410.")
.setSince("4.4")
.setDeprecatedSince("6.4")
.setPost(true)
.setHandler(this);
action.createParam("language")
.setDescription("Restore the built-in profiles defined for this language")
.setExampleValue(getExampleValue(languages))
.setPossibleValues(getLanguageKeys(languages))
.setRequired(true);

QProfileWsSupport.createOrganizationParam(action).setSince("6.4");
}

@Override
public void handle(Request request, Response response) {
userSession.checkLoggedIn();

try (DbSession dbSession = dbClient.openSession(false)) {
OrganizationDto organization = qProfileWsSupport.getOrganizationByKey(dbSession, request.param(PARAM_ORGANIZATION));
userSession.checkPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, organization);

reset.resetLanguage(dbSession, organization, request.mandatoryParam("language"));
}
response.noContent();
public void handle(Request request, Response response) throws Exception {
RemovedWebServiceHandler.INSTANCE.handle(request, response);
}
}

+ 13
- 15
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java Ver arquivo

@@ -89,29 +89,27 @@ public class SearchAction implements QProfileWsAction {
.setSince("6.4");

action
.createParam(PARAM_LANGUAGE)
.setDescription(
format("Language key. If provided, only profiles for the given language are returned. " +
"It should not be used with '%s', '%s or '%s' at the same time.", PARAM_DEFAULTS, PARAM_PROJECT_KEY, PARAM_PROFILE_NAME))
.setPossibleValues(LanguageParamUtils.getLanguageKeys(languages))
.setDeprecatedSince("6.4");
.createParam(PARAM_DEFAULTS)
.setDescription(format("If set to true, return only the quality profile marked as default for each language, the '%s' parameter must not be set.", PARAM_PROJECT_KEY))
.setDefaultValue(false)
.setBooleanPossibleValues();

action.createParam(PARAM_PROJECT_KEY)
.setDescription(format("Project or module key. If provided, '%s' and '%s' parameters should not be provided.",
PARAM_LANGUAGE, PARAM_DEFAULTS))
.setDescription(format("Project or module key. If provided, the '%s' parameter should not be provided.", PARAM_DEFAULTS))
.setExampleValue("my-project-key");

action
.createParam(PARAM_DEFAULTS)
.setDescription(format("If set to true, return only the quality profile marked as default for each language, '%s' and '%s' parameters must not be set.",
PARAM_LANGUAGE, PARAM_PROJECT_KEY))
.setDefaultValue(false)
.setBooleanPossibleValues();
.createParam(PARAM_LANGUAGE)
.setDeprecatedSince("6.4")
.setDescription(
format("Language key. If provided, only profiles for the given language are returned. " +
"It should not be used with '%s', '%s or '%s' at the same time.", PARAM_DEFAULTS, PARAM_PROJECT_KEY, PARAM_PROFILE_NAME))
.setPossibleValues(LanguageParamUtils.getLanguageKeys(languages));

action.createParam(PARAM_PROFILE_NAME)
.setDeprecatedSince("6.4")
.setDescription(format("Profile name. It should be always used with the '%s' or '%s' parameter.", PARAM_PROJECT_KEY, PARAM_DEFAULTS))
.setExampleValue("SonarQube Way")
.setDeprecatedSince("6.4");
.setExampleValue("SonarQube Way");
}

@Override

+ 0
- 240
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileResetMediumTest.java Ver arquivo

@@ -1,240 +0,0 @@
/*
* SonarQube
* Copyright (C) 2009-2017 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.server.qualityprofile;

import java.util.List;
import javax.annotation.Nullable;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rules.RuleParam;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.ActiveRuleDao;
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.ActiveRuleKey;
import org.sonar.db.qualityprofile.ActiveRuleParamDto;
import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.platform.Platform;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.tester.UserSessionRule;

import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.api.rule.Severity.BLOCKER;
import static org.sonar.api.rule.Severity.CRITICAL;
import static org.sonar.api.rule.Severity.MAJOR;
import static org.sonar.api.rule.Severity.MINOR;

// TODO Replace ServerTester by EsTester and DbTester
public class QProfileResetMediumTest {

static final XooRulesDefinition RULE_DEFS = new XooRulesDefinition();
static final XooProfileDefinition PROFILE_DEFS = new XooProfileDefinition();

@ClassRule
public static ServerTester tester = new ServerTester()
.withEsIndexes()
.addXoo().addComponents(PROFILE_DEFS, RULE_DEFS);

@Rule
public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);

private DbClient db;
private DbSession dbSession;
private QProfileReset reset;
private OrganizationDto defaultOrganization;

@Before
public void before() {
tester.clearDbAndIndexes();
db = tester.get(DbClient.class);
dbSession = db.openSession(false);
reset = tester.get(QProfileReset.class);
defaultOrganization = QProfileTesting.getDefaultOrganization(tester, db, dbSession);
}

@After
public void after() {
dbSession.close();
}

private void register(@Nullable Rules rules, @Nullable RulesProfile profile) {
if (dbSession != null) {
dbSession.close();
}
RULE_DEFS.set(rules);
PROFILE_DEFS.set(profile);
tester.get(Platform.class).restart();

db = tester.get(DbClient.class);
dbSession = tester.get(DbClient.class).openSession(false);
dbSession.clearCache();

reset = tester.get(QProfileReset.class);
}

@Test
public void reset_language_profile() {
RulesProfile defProfile = RulesProfile.create("Basic", ServerTester.Xoo.KEY);
defProfile.activateRule(
org.sonar.api.rules.Rule.create("xoo", "x1").setParams(newArrayList(new RuleParam().setKey("acceptWhitespace"))),
RulePriority.CRITICAL).setParameter("acceptWhitespace", "true");

register(new Rules() {
@Override
public void init(RulesDefinition.NewRepository repository) {
RulesDefinition.NewRule x1 = repository.createRule("x1")
.setName("x1 name")
.setHtmlDescription("x1 desc")
.setSeverity(MINOR);
x1.createParam("acceptWhitespace")
.setDefaultValue("false")
.setType(RuleParamType.BOOLEAN)
.setDescription("Accept whitespaces on the line");
}
},
defProfile);

RuleKey ruleKey = RuleKey.of("xoo", "x1");
RulesProfileDto profile = tester.get(QualityProfileDao.class).selectByNameAndLanguage(defaultOrganization, "Basic", ServerTester.Xoo.KEY, dbSession);
ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profile.getKee(), ruleKey);

// Change the severity and the value of the parameter in the active rule
tester.get(RuleActivator.class).activate(dbSession,
new RuleActivation(ruleKey).setSeverity(BLOCKER)
.setParameter("acceptWhitespace", "false"),
profile.getKee());
dbSession.commit();

// Verify severity and param has changed
ActiveRuleDto activeRuleDto = tester.get(ActiveRuleDao.class).selectOrFailByKey(dbSession, activeRuleKey);
assertThat(activeRuleDto.getSeverityString()).isEqualTo(BLOCKER);
List<ActiveRuleParamDto> activeRuleParamDtos = tester.get(ActiveRuleDao.class).selectParamsByActiveRuleId(dbSession, activeRuleDto.getId());
assertThat(activeRuleParamDtos.get(0).getKey()).isEqualTo("acceptWhitespace");
assertThat(activeRuleParamDtos.get(0).getValue()).isEqualTo("false");

OrganizationDto organization = db.organizationDao().selectByUuid(dbSession, profile.getOrganizationUuid()).get();
reset.resetLanguage(dbSession, organization, ServerTester.Xoo.KEY);
dbSession.commit();

// Severity and parameter value come back to origin after reset
activeRuleDto = tester.get(ActiveRuleDao.class).selectOrFailByKey(dbSession, activeRuleKey);
assertThat(activeRuleDto.getSeverityString()).isEqualTo(CRITICAL);

activeRuleParamDtos = tester.get(ActiveRuleDao.class).selectParamsByActiveRuleId(dbSession, activeRuleDto.getId());
assertThat(activeRuleParamDtos.get(0).getKey()).isEqualTo("acceptWhitespace");
assertThat(activeRuleParamDtos.get(0).getValue()).isEqualTo("true");
}

@Test
public void reset_language_profile_param_when_rule_definition_has_changed() {
RulesProfile defProfile = RulesProfile.create("Basic", ServerTester.Xoo.KEY);
defProfile.activateRule(org.sonar.api.rules.Rule.create("xoo", "x1"), null);

register(new Rules() {
@Override
public void init(RulesDefinition.NewRepository repository) {
RulesDefinition.NewRule x1 = repository.createRule("x1")
.setName("x1 name")
.setHtmlDescription("x1 desc")
.setSeverity(MAJOR);
x1.createParam("acceptWhitespace")
.setDefaultValue("false")
.setType(RuleParamType.BOOLEAN)
.setDescription("Accept whitespaces on the line");
}
}, defProfile);

RulesProfileDto profile = tester.get(QualityProfileDao.class).selectByNameAndLanguage(defaultOrganization, "Basic", ServerTester.Xoo.KEY, dbSession);
ActiveRuleKey activeRuleKey = ActiveRuleKey.of(profile.getKee(), RuleKey.of("xoo", "x1"));

// Change param in the rule def
register(new Rules() {
@Override
public void init(RulesDefinition.NewRepository repository) {
RulesDefinition.NewRule x1 = repository.createRule("x1")
.setName("x1 name")
.setHtmlDescription("x1 desc")
.setSeverity(MAJOR);
x1.createParam("acceptWhitespace")
.setDefaultValue("true")
.setType(RuleParamType.BOOLEAN)
.setDescription("Accept whitespaces on the line");
}
}, defProfile);

OrganizationDto organization = db.organizationDao().selectByUuid(dbSession, profile.getOrganizationUuid()).get();
reset.resetLanguage(dbSession, organization, ServerTester.Xoo.KEY);

// Parameter value come back to origin after reset
ActiveRuleDto activeRuleDto = tester.get(ActiveRuleDao.class).selectOrFailByKey(dbSession, activeRuleKey);
List<ActiveRuleParamDto> params = tester.get(ActiveRuleDao.class).selectParamsByActiveRuleId(dbSession, activeRuleDto.getId());
assertThat(params).hasSize(1);
assertThat(params.get(0).getKey()).isEqualTo("acceptWhitespace");
assertThat(params.get(0).getValue()).isEqualTo("true");
}

interface Rules {
void init(RulesDefinition.NewRepository repository);
}

public static class XooRulesDefinition implements RulesDefinition {
private Rules rules = null;

void set(@Nullable Rules rules) {
this.rules = rules;
}

@Override
public void define(Context context) {
if (rules != null) {
RulesDefinition.NewRepository repository = context.createRepository("xoo", ServerTester.Xoo.KEY).setName("Xoo Repo");
rules.init(repository);
repository.done();
}
}
}

public static class XooProfileDefinition extends ProfileDefinition {
private RulesProfile profile;

void set(@Nullable RulesProfile profile) {
this.profile = profile;
}

@Override
public RulesProfile createProfile(ValidationMessages validation) {
return profile;
}
}

}

+ 21
- 3
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRuleActionTest.java Ver arquivo

@@ -36,6 +36,7 @@ import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
@@ -62,7 +63,7 @@ public class ActivateRuleActionTest {
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public ExpectedException thrown = ExpectedException.none();
public ExpectedException expectedException = ExpectedException.none();

private DbClient dbClient = dbTester.getDbClient();
private RuleActivator ruleActivator = mock(RuleActivator.class);
@@ -94,7 +95,7 @@ public class ActivateRuleActionTest {
.setParam("rule_key", RuleTesting.newRuleDto().getKey().toString())
.setParam("profile_key", randomAlphanumeric(UUID_SIZE));

thrown.expect(UnauthorizedException.class);
expectedException.expect(UnauthorizedException.class);
request.execute();
}

@@ -107,7 +108,24 @@ public class ActivateRuleActionTest {
.setParam("rule_key", RuleTesting.newRuleDto().getKey().toString())
.setParam("profile_key", qualityProfile.getKee());

thrown.expect(ForbiddenException.class);
expectedException.expect(ForbiddenException.class);

request.execute();
}

@Test
public void fail_activate_if_built_in_profile() {
userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);

RulesProfileDto qualityProfile = dbTester.qualityProfiles().insert(defaultOrganization, profile -> profile.setIsBuiltIn(true).setName("Xoo profile").setLanguage("xoo"));
TestRequest request = wsActionTester.newRequest()
.setMethod("POST")
.setParam("rule_key", RuleTesting.newRuleDto().getKey().toString())
.setParam("profile_key", qualityProfile.getKee());

expectedException.expect(BadRequestException.class);
expectedException.expectMessage("Operation forbidden for built-in Quality Profile 'Xoo profile' with language 'xoo'");

request.execute();
}


+ 14
- 0
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ActivateRulesActionTest.java Ver arquivo

@@ -29,6 +29,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
@@ -106,6 +107,19 @@ public class ActivateRulesActionTest {
request.execute();
}

@Test
public void fail_if_built_in_profile() {
userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);
RulesProfileDto qualityProfile = dbTester.qualityProfiles().insert(defaultOrganization, p -> p.setIsBuiltIn(true));
TestRequest request = wsActionTester.newRequest()
.setMethod("POST")
.setParam("profile_key", qualityProfile.getKee());

thrown.expect(BadRequestException.class);

request.execute();
}

@Test
public void should_fail_if_not_organization_quality_profile_administrator() {
userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);

+ 21
- 1
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionTest.java Ver arquivo

@@ -40,13 +40,14 @@ import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.db.qualityprofile.QualityProfileTesting;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.es.EsClient;
import org.sonar.server.es.EsTester;
import org.sonar.server.es.SearchOptions;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
@@ -325,6 +326,25 @@ public class ChangeParentActionTest {
assertThat(ruleIndex.search(new RuleQuery().setActivation(true).setQProfileKey(child.getKee()), new SearchOptions()).getIds()).isEmpty();
}

@Test
public void fail_if_built_in_profile() {
RulesProfileDto child = dbTester.qualityProfiles().insert(organization, p -> p
.setLanguage(language.getKey())
.setIsBuiltIn(true));

assertThat(dbClient.activeRuleDao().selectByProfileKey(dbSession, child.getKee())).isEmpty();
assertThat(ruleIndex.search(new RuleQuery().setActivation(true).setQProfileKey(child.getKee()), new SearchOptions()).getIds()).isEmpty();

TestRequest request = wsActionTester.newRequest()
.setMethod("POST")
.setParam(PARAM_PROFILE_KEY, child.getKee())
.setParam("parentKey", "palap");

thrown.expect(BadRequestException.class);

request.execute();
}

@Test
public void fail_if_parent_key_and_name_both_set() throws Exception {
RulesProfileDto child = createProfile();

+ 16
- 0
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRuleActionTest.java Ver arquivo

@@ -36,6 +36,7 @@ import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.qualityprofile.ActiveRuleKey;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.db.rule.RuleTesting;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
@@ -106,6 +107,21 @@ public class DeactivateRuleActionTest {
request.execute();
}

@Test
public void fail_deactivate_if_built_in_profile() {
userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);

RulesProfileDto qualityProfile = dbTester.qualityProfiles().insert(defaultOrganization, profile -> profile.setIsBuiltIn(true));
TestRequest request = wsActionTester.newRequest()
.setMethod("POST")
.setParam("rule_key", RuleTesting.newRuleDto().getKey().toString())
.setParam("profile_key", qualityProfile.getKee());

thrown.expect(BadRequestException.class);

request.execute();
}

@Test
public void deactivate_rule_in_default_organization() {
userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);

+ 15
- 2
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeactivateRulesActionTest.java Ver arquivo

@@ -29,6 +29,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.permission.OrganizationPermission;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
@@ -91,8 +92,7 @@ public class DeactivateRulesActionTest {
"available_since",
"activation",
"severities",
"organization"
);
"organization");
}

@Test
@@ -105,6 +105,19 @@ public class DeactivateRulesActionTest {
request.execute();
}

@Test
public void fail_if_built_in_profile() {
userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);
RulesProfileDto qualityProfile = dbTester.qualityProfiles().insert(defaultOrganization, p -> p.setIsBuiltIn(true));
TestRequest request = wsActionTester.newRequest()
.setMethod("POST")
.setParam("profile_key", qualityProfile.getKee());

thrown.expect(BadRequestException.class);

request.execute();
}

@Test
public void should_fail_if_not_organization_quality_profile_administrator() {
userSession.logIn().addPermission(OrganizationPermission.ADMINISTER_QUALITY_PROFILES, defaultOrganization);

+ 15
- 0
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/DeleteActionTest.java Ver arquivo

@@ -32,6 +32,7 @@ import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
@@ -131,6 +132,20 @@ public class DeleteActionTest {
verifyProfileExists(profile2);
}

@Test
public void fail_if_built_in_profile() {
OrganizationDto organization = dbTester.organizations().insert();
RulesProfileDto profile1 = dbTester.qualityProfiles().insert(organization, p -> p.setIsBuiltIn(true));
logInAsQProfileAdministrator(organization);

expectedException.expect(BadRequestException.class);

tester.newRequest()
.setMethod("POST")
.setParam("profileKey", profile1.getKee())
.execute();
}

@Test
public void throw_ForbiddenException_if_not_profile_administrator() {
OrganizationDto organization1 = dbTester.organizations().insert();

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java Ver arquivo

@@ -69,7 +69,7 @@ public class QProfilesWsTest {
new DeleteAction(languages, null, null, userSessionRule, wsSupport),
new ExportersAction(),
new InheritanceAction(null, null, null, languages),
new RenameAction(dbClient, userSessionRule))).controller(QProfilesWs.API_ENDPOINT);
new RenameAction(dbClient, userSessionRule, wsSupport))).controller(QProfilesWs.API_ENDPOINT);
}

private ProfileImporter[] createImporters(Languages languages) {

+ 13
- 3
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RenameActionTest.java Ver arquivo

@@ -66,7 +66,7 @@ public class RenameActionTest {
QProfileWsSupport wsSupport = new QProfileWsSupport(dbClient, userSessionRule, defaultOrganizationProvider);
underTest = new RenameAction(
dbClient,
userSessionRule);
userSessionRule, wsSupport);
tester = new WsTester(new QProfilesWs(
underTest));
organization = db.organizations().insert();
@@ -194,7 +194,7 @@ public class RenameActionTest {
logInAsQProfileAdministrator();

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Quality profile not found: polop");
expectedException.expectMessage("Quality Profile with key 'polop' does not exist");

tester.newPostRequest("api/qualityprofiles", "rename")
.setParam("key", "polop")
@@ -202,6 +202,16 @@ public class RenameActionTest {
.execute();
}

@Test
public void fail_if_profile_is_built_in() {
logInAsQProfileAdministrator();
String qualityProfileKey = db.qualityProfiles().insert(organization, p -> p.setIsBuiltIn(true)).getKee();

expectedException.expect(BadRequestException.class);

underTest.doHandle("the new name", qualityProfileKey);
}

@Test
public void allow_100_characters_as_name_and_not_more() throws Exception {
logInAsQProfileAdministrator();
@@ -232,7 +242,7 @@ public class RenameActionTest {
logInAsQProfileAdministrator();

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("Quality profile not found: unknown");
expectedException.expectMessage("Quality Profile with key 'unknown' does not exist");

underTest.doHandle("the new name", "unknown");
}

+ 15
- 128
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/RestoreBuiltInActionTest.java Ver arquivo

@@ -22,153 +22,40 @@ package org.sonar.server.qualityprofile.ws;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.ArgumentCaptor;
import org.sonar.api.resources.Languages;
import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.qualityprofile.QProfileReset;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.exceptions.ServerException;
import org.sonar.server.ws.WsActionTester;

import static java.net.HttpURLConnection.HTTP_GONE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
import static org.junit.Assert.fail;

public class RestoreBuiltInActionTest {
@Rule
public DbTester db = DbTester.create();

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

@Rule
public UserSessionRule userSession = UserSessionRule.standalone();

private QProfileReset reset = mock(QProfileReset.class);
private Languages languages = LanguageTesting.newLanguages("xoo");
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private QProfileWsSupport wsSupport = new QProfileWsSupport(db.getDbClient(), userSession, defaultOrganizationProvider);
private RestoreBuiltInAction underTest = new RestoreBuiltInAction(db.getDbClient(), reset, languages, userSession, wsSupport);
private WsActionTester tester = new WsActionTester(underTest);
private RestoreBuiltInAction underTest = new RestoreBuiltInAction();
private WsActionTester ws = new WsActionTester(underTest);

@Test
public void test_definition() {
WebService.Action action = tester.getDef();
WebService.Action action = ws.getDef();

assertThat(action.key()).isEqualTo("restore_built_in");
assertThat(action.isPost()).isTrue();
assertThat(action.responseExampleAsString()).isNull();
assertThat(action.deprecatedSince()).isEqualTo("6.4");

// parameters
assertThat(action.params()).hasSize(2);
WebService.Param languageParam = action.param("language");
assertThat(languageParam.isRequired()).isTrue();
assertThat(languageParam.since()).isNull();//introduced at the same time than the web service

WebService.Param organizationParam = action.param("organization");
assertThat(organizationParam.isRequired()).isFalse();
assertThat(organizationParam.since()).isEqualTo("6.4");
assertThat(action.params()).isEmpty();
}

@Test
public void restore_built_in_profiles_on_default_organization() {
OrganizationDto organization = db.getDefaultOrganization();
logInAsQProfileAdministrator(organization);
TestResponse response = tester.newRequest().setParam("language", "xoo").execute();

ArgumentCaptor<OrganizationDto> organizationArgument = ArgumentCaptor.forClass(OrganizationDto.class);
verify(reset).resetLanguage(any(DbSession.class), organizationArgument.capture(), eq("xoo"));
assertThat(organizationArgument.getValue().getUuid()).isEqualTo(organization.getUuid());
assertThat(response.getStatus()).isEqualTo(204);
}

@Test
public void restore_built_in_profiles_on_specified_organization() {
OrganizationDto organization = db.organizations().insert();
logInAsQProfileAdministrator(organization);
TestResponse response = tester.newRequest()
.setParam("language", "xoo")
.setParam("organization", organization.getKey())
.execute();

ArgumentCaptor<OrganizationDto> organizationArgument = ArgumentCaptor.forClass(OrganizationDto.class);
verify(reset).resetLanguage(any(DbSession.class), organizationArgument.capture(), eq("xoo"));
assertThat(organizationArgument.getValue().getUuid()).isEqualTo(organization.getUuid());
assertThat(response.getStatus()).isEqualTo(204);
}

@Test
public void throw_IAE_if_language_does_not_exist() throws Exception {
logInAsQProfileAdministrator(db.getDefaultOrganization());

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Value of parameter 'language' (unknown) must be one of: [xoo]");

tester.newRequest().setParam("language", "unknown").execute();
}

@Test
public void throw_NotFoundException_if_organization_does_not_exist() throws Exception {
userSession.logIn();

expectedException.expect(NotFoundException.class);
expectedException.expectMessage("No organization with key 'does_not_exist'");

tester.newRequest()
.setParam("language", "unknown")
.setParam("organization", "does_not_exist")
.execute();
}

@Test
public void throw_ForbiddenException_if_not_profile_administrator_of_default_organization() throws Exception {
userSession.logIn();

expectedException.expect(ForbiddenException.class);
expectedException.expectMessage("Insufficient privileges");

tester.newRequest().setParam("language", "xoo").execute();
}

@Test
public void throw_ForbiddenException_if_not_profile_administrator_of_specified_organization() throws Exception {
OrganizationDto org = db.organizations().insert();
userSession.logIn().addPermission(ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization());

expectedException.expect(ForbiddenException.class);
expectedException.expectMessage("Insufficient privileges");

tester.newRequest()
.setParam("language", "xoo")
.setParam("organization", org.getKey())
.execute();
}

@Test
public void throw_UnauthorizedException_if_not_logged_in() throws Exception {
userSession.anonymous();

expectedException.expect(UnauthorizedException.class);
expectedException.expectMessage("Authentication is required");

tester.newRequest().setParam("language", "xoo").execute();
}

private void logInAsQProfileAdministrator(OrganizationDto organization) {
userSession
.logIn()
.addPermission(ADMINISTER_QUALITY_PROFILES, organization.getUuid());
public void fail_when_ws_is_called() {
try {
ws.newRequest().execute();
fail();
} catch (ServerException e) {
assertThat(e.httpCode()).isEqualTo(HTTP_GONE);
}
}
}

+ 30
- 15
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java Ver arquivo

@@ -40,8 +40,8 @@ import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.organization.OrganizationTesting;
import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.db.qualityprofile.QualityProfileDbTester;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.db.qualityprofile.QualityProfileTesting;
import org.sonar.db.qualityprofile.RulesProfileDto;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.language.LanguageTesting;
@@ -106,20 +106,35 @@ public class SearchActionTest {
}

@Test
public void define_search() {
WebService.Action search = ws.getDef();
assertThat(search).isNotNull();
assertThat(search.isPost()).isFalse();
assertThat(search.param("language").possibleValues()).containsExactly("xoo1", "xoo2");
assertThat(search.param("language").deprecatedSince()).isEqualTo("6.4");
assertThat(search.param("profileName").deprecatedSince()).isEqualTo("6.4");
assertThat(search.param("projectKey")).isNotNull();
assertThat(search.param("defaults")).isNotNull();
assertThat(search.param("organization")).isNotNull();
assertThat(search.param("organization").isRequired()).isFalse();
assertThat(search.param("organization").isInternal()).isTrue();
assertThat(search.param("organization").description()).isNotEmpty();
assertThat(search.param("organization").since()).isEqualTo("6.4");
public void definition() {
WebService.Action action = ws.getDef();
assertThat(action.key()).isEqualTo("search");
assertThat(action.responseExampleAsString()).isNotEmpty();
assertThat(action.isPost()).isFalse();

WebService.Param organization = action.param("organization");
assertThat(organization).isNotNull();
assertThat(organization.isRequired()).isFalse();
assertThat(organization.isInternal()).isTrue();
assertThat(organization.description()).isNotEmpty();
assertThat(organization.since()).isEqualTo("6.4");

WebService.Param defaults = action.param("defaults");
assertThat(defaults.description()).isEqualTo("If set to true, return only the quality profile marked as default for each language, " +
"the 'projectKey' parameter must not be set.");

WebService.Param projectKey = action.param("projectKey");
assertThat(projectKey.description()).isEqualTo("Project or module key. If provided, the 'defaults' parameter should not be provided.");

WebService.Param language = action.param("language");
assertThat(language.possibleValues()).containsExactly("xoo1", "xoo2");
assertThat(language.deprecatedSince()).isEqualTo("6.4");
assertThat(language.description()).isEqualTo("Language key. If provided, only profiles for the given language are returned. " +
"It should not be used with 'defaults', 'projectKey or 'profileName' at the same time.");

WebService.Param profileName = action.param("profileName");
assertThat(profileName.deprecatedSince()).isEqualTo("6.4");
assertThat(profileName.description()).isEqualTo("Profile name. It should be always used with the 'projectKey' or 'defaults' parameter.");
}

@Test

Carregando…
Cancelar
Salvar