@@ -148,7 +148,7 @@ import org.sonar.server.qualityprofile.QProfileFactory; | |||
import org.sonar.server.qualityprofile.QProfileLoader; | |||
import org.sonar.server.qualityprofile.QProfileLookup; | |||
import org.sonar.server.qualityprofile.QProfileProjectOperations; | |||
import org.sonar.server.qualityprofile.QProfileReset; | |||
import org.sonar.server.qualityprofile.QProfileResetImpl; | |||
import org.sonar.server.qualityprofile.QProfileService; | |||
import org.sonar.server.qualityprofile.RuleActivator; | |||
import org.sonar.server.qualityprofile.RuleActivatorContextFactory; | |||
@@ -276,7 +276,7 @@ public class PlatformLevel4 extends PlatformLevel { | |||
QProfileFactory.class, | |||
QProfileCopier.class, | |||
QProfileBackuperImpl.class, | |||
QProfileReset.class, | |||
QProfileResetImpl.class, | |||
QProfilesWsModule.class, | |||
// rule |
@@ -19,156 +19,19 @@ | |||
*/ | |||
package org.sonar.server.qualityprofile; | |||
import com.google.common.base.Preconditions; | |||
import com.google.common.collect.ArrayListMultimap; | |||
import com.google.common.collect.ListMultimap; | |||
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.profiles.ProfileDefinition; | |||
import org.sonar.api.profiles.RulesProfile; | |||
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.api.utils.ValidationMessages; | |||
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.QualityProfileDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; | |||
import org.sonar.server.qualityprofile.ws.QProfileWsSupport; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
@ServerSide | |||
public class QProfileReset { | |||
private final DbClient db; | |||
private final QProfileFactory factory; | |||
private final RuleActivator activator; | |||
private final ActiveRuleIndexer activeRuleIndexer; | |||
private final QProfileWsSupport qProfileWsSupport; | |||
private final ProfileDefinition[] definitions; | |||
public QProfileReset(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer, QProfileFactory factory, QProfileWsSupport qProfileWsSupport, | |||
ProfileDefinition... definitions) { | |||
this.db = db; | |||
this.activator = activator; | |||
this.activeRuleIndexer = activeRuleIndexer; | |||
this.factory = factory; | |||
this.qProfileWsSupport = qProfileWsSupport; | |||
this.definitions = definitions; | |||
} | |||
public QProfileReset(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer, QProfileFactory factory, | |||
QProfileWsSupport qProfileWsSupport) { | |||
this(db, activator, activeRuleIndexer, factory, qProfileWsSupport, new ProfileDefinition[0]); | |||
} | |||
public interface QProfileReset { | |||
/** | |||
* Reset built-in profiles for the given language. Missing profiles are created and | |||
* existing ones are updated. | |||
* Restore the built-in profiles provided by plugins for the specified language. | |||
* Missing profiles are created and existing ones are updated. | |||
*/ | |||
public void resetLanguage(DbSession dbSession, String language) { | |||
ListMultimap<QProfileName, RulesProfile> profilesByName = loadDefinitionsGroupedByName(language); | |||
for (Map.Entry<QProfileName, Collection<RulesProfile>> entry : profilesByName.asMap().entrySet()) { | |||
QProfileName profileName = entry.getKey(); | |||
QualityProfileDto profile = factory.getOrCreate(dbSession, qProfileWsSupport.getDefaultOrganization(dbSession), profileName); | |||
List<RuleActivation> activations = Lists.newArrayList(); | |||
for (RulesProfile def : entry.getValue()) { | |||
for (ActiveRule activeRule : def.getActiveRules()) { | |||
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()); | |||
} | |||
} | |||
activations.add(activation); | |||
} | |||
} | |||
doReset(dbSession, profile, activations); | |||
} | |||
} | |||
void resetLanguage(DbSession dbSession, OrganizationDto organization, String language); | |||
/** | |||
* Reset the profile, which is created if it does not exist | |||
*/ | |||
QProfileRestoreSummary reset(DbSession dbSession, OrganizationDto organization, QProfileName profileName, Collection<RuleActivation> activations) { | |||
QualityProfileDto profile = factory.getOrCreate(dbSession, organization, profileName); | |||
BulkChangeResult ruleChanges = doReset(dbSession, profile, activations); | |||
return new QProfileRestoreSummary(organization, profile, ruleChanges); | |||
} | |||
/** | |||
* @param dbSession | |||
* @param profile must exist | |||
*/ | |||
private BulkChangeResult doReset(DbSession dbSession, QualityProfileDto profile, Collection<RuleActivation> activations) { | |||
Preconditions.checkNotNull(profile.getId(), "Quality profile must be persisted"); | |||
BulkChangeResult result = new BulkChangeResult(); | |||
Set<RuleKey> ruleToBeDeactivated = Sets.newHashSet(); | |||
// Keep reference to all the activated rules before backup restore | |||
for (ActiveRuleDto activeRuleDto : db.activeRuleDao().selectByProfileKey(dbSession, profile.getKee())) { | |||
if (activeRuleDto.getInheritance() == null) { | |||
// inherited rules can't be deactivated | |||
ruleToBeDeactivated.add(activeRuleDto.getKey().ruleKey()); | |||
} | |||
} | |||
for (RuleActivation activation : activations) { | |||
try { | |||
List<ActiveRuleChange> changes = activator.activate(dbSession, activation, profile.getKey()); | |||
ruleToBeDeactivated.remove(activation.getRuleKey()); | |||
result.incrementSucceeded(); | |||
result.addChanges(changes); | |||
} catch (BadRequestException e) { | |||
result.incrementFailed(); | |||
result.getErrors().addAll(e.errors()); | |||
} | |||
} | |||
List<ActiveRuleChange> changes = new ArrayList<>(); | |||
changes.addAll(result.getChanges()); | |||
for (RuleKey ruleKey : ruleToBeDeactivated) { | |||
try { | |||
changes.addAll(activator.deactivate(dbSession, ActiveRuleKey.of(profile.getKee(), ruleKey))); | |||
} catch (BadRequestException e) { | |||
// ignore, probably a rule inherited from parent that can't be deactivated | |||
} | |||
} | |||
dbSession.commit(); | |||
activeRuleIndexer.index(changes); | |||
return result; | |||
} | |||
private ListMultimap<QProfileName, RulesProfile> loadDefinitionsGroupedByName(String language) { | |||
ListMultimap<QProfileName, RulesProfile> profilesByName = ArrayListMultimap.create(); | |||
for (ProfileDefinition definition : definitions) { | |||
ValidationMessages validation = ValidationMessages.create(); | |||
RulesProfile profile = definition.createProfile(validation); | |||
if (language.equals(profile.getLanguage())) { | |||
processValidationMessages(validation); | |||
profilesByName.put(new QProfileName(profile.getLanguage(), profile.getName()), profile); | |||
} | |||
} | |||
return profilesByName; | |||
} | |||
private void processValidationMessages(ValidationMessages messages) { | |||
checkRequest(messages.getErrors().isEmpty(), messages.getErrors()); | |||
} | |||
QProfileRestoreSummary reset(DbSession dbSession, OrganizationDto organization, QProfileName profileName, Collection<RuleActivation> activations); | |||
} |
@@ -0,0 +1,164 @@ | |||
/* | |||
* 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 com.google.common.base.Preconditions; | |||
import com.google.common.collect.ArrayListMultimap; | |||
import com.google.common.collect.ListMultimap; | |||
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.profiles.ProfileDefinition; | |||
import org.sonar.api.profiles.RulesProfile; | |||
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.api.utils.ValidationMessages; | |||
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.QualityProfileDto; | |||
import org.sonar.db.rule.RuleParamDto; | |||
import org.sonar.server.exceptions.BadRequestException; | |||
import org.sonar.server.qualityprofile.index.ActiveRuleIndexer; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
@ServerSide | |||
public class QProfileResetImpl implements QProfileReset { | |||
private final DbClient db; | |||
private final QProfileFactory factory; | |||
private final RuleActivator activator; | |||
private final ActiveRuleIndexer activeRuleIndexer; | |||
private final ProfileDefinition[] definitions; | |||
public QProfileResetImpl(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer, QProfileFactory factory, ProfileDefinition... definitions) { | |||
this.db = db; | |||
this.activator = activator; | |||
this.activeRuleIndexer = activeRuleIndexer; | |||
this.factory = factory; | |||
this.definitions = definitions; | |||
} | |||
public QProfileResetImpl(DbClient db, RuleActivator activator, ActiveRuleIndexer activeRuleIndexer, QProfileFactory factory) { | |||
this(db, activator, activeRuleIndexer, factory, new ProfileDefinition[0]); | |||
} | |||
@Override | |||
public void resetLanguage(DbSession dbSession, OrganizationDto organization, String language) { | |||
ListMultimap<QProfileName, RulesProfile> profilesByName = loadDefinitionsGroupedByName(language); | |||
for (Map.Entry<QProfileName, Collection<RulesProfile>> entry : profilesByName.asMap().entrySet()) { | |||
QProfileName profileName = entry.getKey(); | |||
QualityProfileDto profile = factory.getOrCreate(dbSession, organization, profileName); | |||
List<RuleActivation> activations = Lists.newArrayList(); | |||
for (RulesProfile def : entry.getValue()) { | |||
for (ActiveRule activeRule : def.getActiveRules()) { | |||
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()); | |||
} | |||
} | |||
activations.add(activation); | |||
} | |||
} | |||
doReset(dbSession, profile, activations); | |||
} | |||
} | |||
@Override | |||
public QProfileRestoreSummary reset(DbSession dbSession, OrganizationDto organization, QProfileName profileName, Collection<RuleActivation> activations) { | |||
QualityProfileDto profile = factory.getOrCreate(dbSession, organization, profileName); | |||
BulkChangeResult ruleChanges = doReset(dbSession, profile, activations); | |||
return new QProfileRestoreSummary(organization, profile, ruleChanges); | |||
} | |||
/** | |||
* @param dbSession | |||
* @param profile must exist | |||
*/ | |||
private BulkChangeResult doReset(DbSession dbSession, QualityProfileDto profile, Collection<RuleActivation> activations) { | |||
Preconditions.checkNotNull(profile.getId(), "Quality profile must be persisted"); | |||
BulkChangeResult result = new BulkChangeResult(); | |||
Set<RuleKey> ruleToBeDeactivated = Sets.newHashSet(); | |||
// Keep reference to all the activated rules before backup restore | |||
for (ActiveRuleDto activeRuleDto : db.activeRuleDao().selectByProfileKey(dbSession, profile.getKee())) { | |||
if (activeRuleDto.getInheritance() == null) { | |||
// inherited rules can't be deactivated | |||
ruleToBeDeactivated.add(activeRuleDto.getKey().ruleKey()); | |||
} | |||
} | |||
for (RuleActivation activation : activations) { | |||
try { | |||
List<ActiveRuleChange> changes = activator.activate(dbSession, activation, profile.getKey()); | |||
ruleToBeDeactivated.remove(activation.getRuleKey()); | |||
result.incrementSucceeded(); | |||
result.addChanges(changes); | |||
} catch (BadRequestException e) { | |||
result.incrementFailed(); | |||
result.getErrors().addAll(e.errors()); | |||
} | |||
} | |||
List<ActiveRuleChange> changes = new ArrayList<>(); | |||
changes.addAll(result.getChanges()); | |||
for (RuleKey ruleKey : ruleToBeDeactivated) { | |||
try { | |||
changes.addAll(activator.deactivate(dbSession, ActiveRuleKey.of(profile.getKee(), ruleKey))); | |||
} catch (BadRequestException e) { | |||
// ignore, probably a rule inherited from parent that can't be deactivated | |||
} | |||
} | |||
dbSession.commit(); | |||
activeRuleIndexer.index(changes); | |||
return result; | |||
} | |||
private ListMultimap<QProfileName, RulesProfile> loadDefinitionsGroupedByName(String language) { | |||
ListMultimap<QProfileName, RulesProfile> profilesByName = ArrayListMultimap.create(); | |||
for (ProfileDefinition definition : definitions) { | |||
ValidationMessages validation = ValidationMessages.create(); | |||
RulesProfile profile = definition.createProfile(validation); | |||
if (language.equals(profile.getLanguage())) { | |||
processValidationMessages(validation); | |||
profilesByName.put(new QProfileName(profile.getLanguage(), profile.getName()), profile); | |||
} | |||
} | |||
return profilesByName; | |||
} | |||
private static void processValidationMessages(ValidationMessages messages) { | |||
checkRequest(messages.getErrors().isEmpty(), messages.getErrors()); | |||
} | |||
} |
@@ -25,47 +25,57 @@ 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; | |||
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, 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 restoreDefault = controller.createAction("restore_built_in") | |||
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.") | |||
.setSince("4.4") | |||
.setPost(true) | |||
.setHandler(this); | |||
restoreDefault.createParam("language") | |||
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) { | |||
qProfileWsSupport.checkQProfileAdminPermission(); | |||
userSession.checkLoggedIn(); | |||
String language = request.mandatoryParam("language"); | |||
try (DbSession dbSession = dbClient.openSession(false)) { | |||
reset.resetLanguage(dbSession, language); | |||
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(); | |||
} |
@@ -36,6 +36,7 @@ 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; | |||
@@ -67,9 +68,9 @@ public class QProfileResetMediumTest { | |||
@Rule | |||
public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester); | |||
DbClient db; | |||
DbSession dbSession; | |||
QProfileReset reset; | |||
private DbClient db; | |||
private DbSession dbSession; | |||
private QProfileReset reset; | |||
@Before | |||
public void before() { | |||
@@ -139,7 +140,8 @@ public class QProfileResetMediumTest { | |||
assertThat(activeRuleParamDtos.get(0).getKey()).isEqualTo("acceptWhitespace"); | |||
assertThat(activeRuleParamDtos.get(0).getValue()).isEqualTo("false"); | |||
reset.resetLanguage(dbSession, ServerTester.Xoo.KEY); | |||
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 | |||
@@ -188,7 +190,8 @@ public class QProfileResetMediumTest { | |||
} | |||
}, defProfile); | |||
reset.resetLanguage(dbSession, ServerTester.Xoo.KEY); | |||
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); |
@@ -69,7 +69,6 @@ public class QProfilesWsTest { | |||
new RemoveProjectAction(projectAssociationParameters, null, null, dbClient), | |||
new CreateAction(null, null, null, languages, wsSupport, userSessionRule, null, importers), | |||
new ImportersAction(importers), | |||
new RestoreBuiltInAction(dbClient, null, languages, wsSupport), | |||
new SearchAction(null, languages), | |||
new SetDefaultAction(languages, null, null, wsSupport), | |||
new ProjectsAction(null, userSessionRule), | |||
@@ -109,14 +108,6 @@ public class QProfilesWsTest { | |||
assertThat(controller.actions()).isNotEmpty(); | |||
} | |||
@Test | |||
public void define_restore_built_action() { | |||
WebService.Action restoreProfiles = controller.action("restore_built_in"); | |||
assertThat(restoreProfiles).isNotNull(); | |||
assertThat(restoreProfiles.isPost()).isTrue(); | |||
assertThat(restoreProfiles.params()).hasSize(1); | |||
} | |||
@Test | |||
public void define_search() { | |||
WebService.Action search = controller.action("search"); |
@@ -22,10 +22,14 @@ 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; | |||
@@ -54,29 +58,82 @@ public class RestoreBuiltInActionTest { | |||
private QProfileReset reset = mock(QProfileReset.class); | |||
private Languages languages = LanguageTesting.newLanguages("xoo"); | |||
private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.fromUuid("ORG1"); | |||
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 WsActionTester tester = new WsActionTester(new RestoreBuiltInAction(db.getDbClient(), reset, languages, wsSupport)); | |||
@Test | |||
public void test_definition() { | |||
WebService.Action action = tester.getDef(); | |||
assertThat(action.key()).isEqualTo("restore_built_in"); | |||
assertThat(action.isPost()).isTrue(); | |||
assertThat(action.responseExampleAsString()).isNull(); | |||
// 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"); | |||
} | |||
@Test | |||
public void return_empty_result_when_no_info_or_warning() { | |||
logInAsQProfileAdministrator(); | |||
public void restore_built_in_profiles_on_default_organization() { | |||
OrganizationDto organization = db.getDefaultOrganization(); | |||
logInAsQProfileAdministrator(organization); | |||
TestResponse response = tester.newRequest().setParam("language", "xoo").execute(); | |||
verify(reset).resetLanguage(any(DbSession.class), eq("xoo")); | |||
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 fail_on_unknown_language() throws Exception { | |||
logInAsQProfileAdministrator(); | |||
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_ForbiddenException_if_not_profile_administrator() throws Exception { | |||
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); | |||
@@ -85,17 +142,33 @@ public class RestoreBuiltInActionTest { | |||
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() { | |||
private void logInAsQProfileAdministrator(OrganizationDto organization) { | |||
userSession | |||
.logIn() | |||
.addPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganizationProvider.get().getUuid()); | |||
.addPermission(ADMINISTER_QUALITY_PROFILES, organization.getUuid()); | |||
} | |||
} |