+++ /dev/null
-/*
- * 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.rule.ws;
-
-import com.google.common.collect.ImmutableMap;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.api.rule.RuleStatus;
-import org.sonar.api.rule.Severity;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.rule.RuleDao;
-import org.sonar.db.rule.RuleDefinitionDto;
-import org.sonar.db.rule.RuleDto;
-import org.sonar.db.rule.RuleParamDto;
-import org.sonar.db.rule.RuleTesting;
-import org.sonar.server.organization.DefaultOrganization;
-import org.sonar.server.organization.DefaultOrganizationProvider;
-import org.sonar.server.rule.NewCustomRule;
-import org.sonar.server.rule.RuleCreator;
-import org.sonar.server.tester.ServerTester;
-import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.WsTester;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
-import static org.sonar.db.permission.OrganizationPermission.ADMINISTER_QUALITY_PROFILES;
-
-public class UpdateActionMediumTest {
-
- @ClassRule
- public static ServerTester tester = new ServerTester().withEsIndexes();
-
- @Rule
- public UserSessionRule userSessionRule = UserSessionRule.forServerTester(tester);
-
- private WsTester wsTester;
- private RuleDao ruleDao;
- private DbSession session;
- private OrganizationDto defaultOrganization;
-
- @Before
- public void setUp() {
- tester.clearDbAndIndexes();
- wsTester = tester.get(WsTester.class);
- ruleDao = tester.get(RuleDao.class);
- DbClient dbClient = tester.get(DbClient.class);
- session = dbClient.openSession(false);
- logInAsQProfileAdministrator();
- DefaultOrganization defaultOrganization = tester.get(DefaultOrganizationProvider.class).get();
- this.defaultOrganization = dbClient.organizationDao().selectByUuid(session, defaultOrganization.getUuid()).get();
- }
-
- @After
- public void after() {
- session.close();
- }
-
- @Test
- public void update_custom_rule() throws Exception {
- // Template rule
- RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001"), defaultOrganization);
- RuleDefinitionDto definition = templateRule.getDefinition();
- ruleDao.insert(session, definition);
- ruleDao.insertOrUpdate(session, templateRule.getMetadata().setRuleId(templateRule.getId()));
- RuleParamDto param = RuleParamDto.createFor(definition).setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*");
- ruleDao.insertRuleParam(session, definition, param);
- session.commit();
-
- // Custom rule
- NewCustomRule newRule = NewCustomRule.createForCustomRule("MY_CUSTOM", templateRule.getKey())
- .setName("Old custom")
- .setHtmlDescription("Old description")
- .setSeverity(Severity.MINOR)
- .setStatus(RuleStatus.BETA)
- .setParameters(ImmutableMap.of("regex", "a"));
-
- RuleKey customRuleKey = tester.get(RuleCreator.class).create(session, newRule);
- session.clearCache();
-
- WsTester.TestRequest request = wsTester.newPostRequest("api/rules", "update")
- .setParam("key", customRuleKey.toString())
- .setParam("name", "My custom rule")
- .setParam("markdown_description", "Description")
- .setParam("severity", "MAJOR")
- .setParam("status", "BETA")
- .setParam("params", "regex=a.*");
- request.execute().assertJson(getClass(), "update_custom_rule.json");
- }
-
- @Test
- public void fail_to_update_custom_when_description_is_empty() {
- // Template rule
- RuleDto templateRule = RuleTesting.newTemplateRule(RuleKey.of("java", "S001"));
- ruleDao.insert(session, templateRule.getDefinition());
-
- // Custom rule
- RuleDto customRule = RuleTesting.newCustomRule(templateRule);
- ruleDao.insert(session, customRule.getDefinition());
- session.commit();
- session.clearCache();
-
- WsTester.TestRequest request = wsTester.newPostRequest("api/rules", "update")
- .setParam("key", customRule.getKey().toString())
- .setParam("name", "My custom rule")
- .setParam("markdown_description", "");
-
- try {
- request.execute();
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("The description is missing");
- }
- }
-
- private void logInAsQProfileAdministrator() {
- userSessionRule
- .logIn()
- .addPermission(ADMINISTER_QUALITY_PROFILES, tester.get(DefaultOrganizationProvider.class).get().getUuid());
- }
-}
package org.sonar.server.rule.ws;
import java.io.IOException;
-import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.sonar.api.config.MapSettings;
import org.sonar.api.resources.Languages;
+import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.api.rule.Severity;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.server.rule.index.RuleIndexer;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.text.MacroInterpreter;
+import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsAction;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Rules;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.sonar.api.server.debt.DebtRemediationFunction.Type.LINEAR;
import static org.sonar.api.server.debt.DebtRemediationFunction.Type.LINEAR_OFFSET;
import static org.sonar.server.rule.ws.UpdateAction.PARAM_REMEDIATION_FN_GAP_MULTIPLIER;
import static org.sonar.server.rule.ws.UpdateAction.PARAM_REMEDIATION_FN_TYPE;
import static org.sonar.server.rule.ws.UpdateAction.PARAM_TAGS;
+import static org.sonar.test.JsonAssert.assertJson;
public class UpdateActionTest {
- @org.junit.Rule
- public DbTester dbTester = DbTester.create();
- @org.junit.Rule
- public EsTester esTester = new EsTester(
- new RuleIndexDefinition(new MapSettings()));
- @org.junit.Rule
+ private static final long PAST = 10000L;
+
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public DbTester db = DbTester.create();
+
+ @Rule
+ public EsTester esTester = new EsTester(new RuleIndexDefinition(new MapSettings()));
+
+ @Rule
public UserSessionRule userSession = UserSessionRule.standalone();
- private DbClient dbClient = dbTester.getDbClient();
+ private DbClient dbClient = db.getDbClient();
private EsClient esClient = esTester.client();
- private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(dbTester);
- private MacroInterpreter macroInterpreter = mock(MacroInterpreter.class);
+ private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private Languages languages = new Languages();
- private RuleMapper mapper = new RuleMapper(languages, macroInterpreter);
+ private RuleMapper mapper = new RuleMapper(languages, createMacroInterpreter());
private RuleIndexer ruleIndexer = new RuleIndexer(esClient, dbClient);
private RuleUpdater ruleUpdater = new RuleUpdater(dbClient, ruleIndexer, System2.INSTANCE);
private RuleWsSupport ruleWsSupport = new RuleWsSupport(dbClient, userSession, defaultOrganizationProvider);
private WsAction underTest = new UpdateAction(dbClient, ruleUpdater, mapper, userSession, ruleWsSupport, defaultOrganizationProvider);
- private WsActionTester actionTester = new WsActionTester(underTest);
- private OrganizationDto defaultOrganization;
+ private WsActionTester ws = new WsActionTester(underTest);
- @Before
- public void setUp() {
- defaultOrganization = dbTester.getDefaultOrganization();
+ @Test
+ public void update_custom_rule() throws Exception {
logInAsQProfileAdministrator();
+ RuleDefinitionDto templateRule = db.rules().insert(
+ r -> r.setRuleKey(RuleKey.of("java", "S001")),
+ r -> r.setIsTemplate(true),
+ r -> r.setCreatedAt(PAST),
+ r -> r.setUpdatedAt(PAST));
+ db.rules().insertRuleParam(templateRule, param -> param.setName("regex").setType("STRING").setDescription("Reg ex").setDefaultValue(".*"));
+ RuleDefinitionDto customRule = db.rules().insert(
+ r -> r.setRuleKey(RuleKey.of("java", "MY_CUSTOM")),
+ r -> r.setName("Old custom"),
+ r -> r.setDescription("Old description"),
+ r -> r.setSeverity(Severity.MINOR),
+ r -> r.setStatus(RuleStatus.BETA),
+ r -> r.setTemplateId(templateRule.getId()),
+ r -> r.setLanguage("js"),
+ r -> r.setCreatedAt(PAST),
+ r -> r.setUpdatedAt(PAST));
+ db.rules().insertRuleParam(customRule, param -> param.setName("regex").setType("a").setDescription("Reg ex"));
+
+ TestResponse request = ws.newRequest().setMethod("POST")
+ .setParam("key", customRule.getKey().toString())
+ .setParam("name", "My custom rule")
+ .setParam("markdown_description", "Description")
+ .setParam("severity", "MAJOR")
+ .setParam("status", "BETA")
+ .setParam("params", "regex=a.*")
+ .execute();
+
+ assertJson(request.getInput()).isSimilarTo("{\n" +
+ " \"rule\": {\n" +
+ " \"key\": \"java:MY_CUSTOM\",\n" +
+ " \"repo\": \"java\",\n" +
+ " \"name\": \"My custom rule\",\n" +
+ " \"htmlDesc\": \"Description\",\n" +
+ " \"severity\": \"MAJOR\",\n" +
+ " \"status\": \"BETA\",\n" +
+ " \"isTemplate\": false,\n" +
+ " \"templateKey\": \"java:S001\",\n" +
+ " \"params\": [\n" +
+ " {\n" +
+ " \"key\": \"regex\",\n" +
+ " \"htmlDesc\": \"Reg ex\",\n" +
+ " \"defaultValue\": \"a.*\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ "}\n");
}
@Test
public void update_tags_for_default_organization() throws IOException {
- doReturn("interpreted").when(macroInterpreter).interpret(anyString());
+ logInAsQProfileAdministrator();
- RuleDefinitionDto rule = dbTester.rules().insert(setSystemTags("stag1", "stag2"));
- dbTester.rules().insertOrUpdateMetadata(rule, defaultOrganization, setTags("tag1", "tag2"));
+ RuleDefinitionDto rule = db.rules().insert(setSystemTags("stag1", "stag2"));
+ db.rules().insertOrUpdateMetadata(rule, db.getDefaultOrganization(), setTags("tag1", "tag2"));
- Rules.UpdateResponse result = actionTester.newRequest().setMethod("POST")
+ Rules.UpdateResponse result = ws.newRequest().setMethod("POST")
.setParam(PARAM_KEY, rule.getKey().toString())
.setParam(PARAM_TAGS, "tag2,tag3")
.executeProtobuf(Rules.UpdateResponse.class);
@Test
public void update_tags_for_specific_organization() throws IOException {
- doReturn("interpreted").when(macroInterpreter).interpret(anyString());
+ logInAsQProfileAdministrator();
- OrganizationDto organization = dbTester.organizations().insert();
+ OrganizationDto organization = db.organizations().insert();
- RuleDefinitionDto rule = dbTester.rules().insert(setSystemTags("stag1", "stag2"));
- dbTester.rules().insertOrUpdateMetadata(rule, organization, setTags("tagAlt1", "tagAlt2"));
+ RuleDefinitionDto rule = db.rules().insert(setSystemTags("stag1", "stag2"));
+ db.rules().insertOrUpdateMetadata(rule, organization, setTags("tagAlt1", "tagAlt2"));
- Rules.UpdateResponse result = actionTester.newRequest().setMethod("POST")
+ Rules.UpdateResponse result = ws.newRequest().setMethod("POST")
.setParam(PARAM_KEY, rule.getKey().toString())
.setParam(PARAM_TAGS, "tag2,tag3")
.setParam(PARAM_ORGANIZATION, organization.getKey())
assertThat(updatedRule.getTags().getTagsList()).containsExactly("tag2", "tag3");
// check database
- RuleMetadataDto metadataOfSpecificOrg = dbTester.getDbClient().ruleDao().selectMetadataByKey(dbTester.getSession(), rule.getKey(), organization)
+ RuleMetadataDto metadataOfSpecificOrg = db.getDbClient().ruleDao().selectMetadataByKey(db.getSession(), rule.getKey(), organization)
.orElseThrow(() -> new IllegalStateException("Cannot load metadata"));
assertThat(metadataOfSpecificOrg.getTags()).containsExactly("tag2", "tag3");
}
@Test
public void update_rule_remediation_function() throws IOException {
- doReturn("interpreted").when(macroInterpreter).interpret(anyString());
+ logInAsQProfileAdministrator();
- OrganizationDto organization = dbTester.organizations().insert();
+ OrganizationDto organization = db.organizations().insert();
- RuleDefinitionDto rule = dbTester.rules().insert(
+ RuleDefinitionDto rule = db.rules().insert(
r -> r.setDefRemediationFunction(LINEAR.toString()),
r -> r.setDefRemediationGapMultiplier("10d"),
r -> r.setDefRemediationBaseEffort(null));
String newMultiplier = "15d";
String newEffort = "5min";
- Rules.UpdateResponse result = actionTester.newRequest().setMethod("POST")
+ Rules.UpdateResponse result = ws.newRequest().setMethod("POST")
.setParam("key", rule.getKey().toString())
.setParam(PARAM_ORGANIZATION, organization.getKey())
.setParam(PARAM_REMEDIATION_FN_TYPE, newOffset)
assertThat(updatedRule.getRemFnBaseEffort()).isEqualTo(newEffort);
// check database
- RuleMetadataDto metadataOfSpecificOrg = dbTester.getDbClient().ruleDao().selectMetadataByKey(dbTester.getSession(), rule.getKey(), organization)
+ RuleMetadataDto metadataOfSpecificOrg = db.getDbClient().ruleDao().selectMetadataByKey(db.getSession(), rule.getKey(), organization)
.orElseThrow(() -> new IllegalStateException("Cannot load metadata"));
assertThat(metadataOfSpecificOrg.getRemediationFunction()).isEqualTo(newOffset);
assertThat(metadataOfSpecificOrg.getRemediationGapMultiplier()).isEqualTo(newMultiplier);
@Test
public void update_custom_rule_with_deprecated_remediation_function_parameters() throws Exception {
- doReturn("interpreted").when(macroInterpreter).interpret(anyString());
+ logInAsQProfileAdministrator();
RuleDefinitionDto rule = RuleTesting.newRule()
.setDefRemediationFunction(LINEAR_OFFSET.toString())
.setDefRemediationGapMultiplier("10d")
.setDefRemediationBaseEffort("5min");
- dbTester.rules().insert(rule);
+ db.rules().insert(rule);
String newType = LINEAR_OFFSET.toString();
String newCoeff = "11d";
String newOffset = "6min";
- Rules.UpdateResponse result = actionTester.newRequest().setMethod("POST")
+ Rules.UpdateResponse result = ws.newRequest().setMethod("POST")
.setParam(PARAM_KEY, rule.getKey().toString())
.setParam(DEPRECATED_PARAM_REMEDIATION_FN_TYPE, newType)
.setParam(DEPRECATED_PARAM_REMEDIATION_FN_COEFF, newCoeff)
assertThat(updatedRule.getGapDescription()).isEqualTo(rule.getGapDescription());
}
+ @Test
+ public void fail_to_update_custom_when_description_is_empty() {
+ logInAsQProfileAdministrator();
+ RuleDefinitionDto templateRule = db.rules().insert(
+ r -> r.setRuleKey(RuleKey.of("java", "S001")),
+ r -> r.setIsTemplate(true),
+ r -> r.setCreatedAt(PAST),
+ r -> r.setUpdatedAt(PAST));
+ RuleDefinitionDto customRule = db.rules().insert(
+ r -> r.setRuleKey(RuleKey.of("java", "MY_CUSTOM")),
+ r -> r.setName("Old custom"),
+ r -> r.setDescription("Old description"),
+ r -> r.setTemplateId(templateRule.getId()),
+ r -> r.setCreatedAt(PAST),
+ r -> r.setUpdatedAt(PAST));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The description is missing");
+
+ ws.newRequest().setMethod("POST")
+ .setParam("key", customRule.getKey().toString())
+ .setParam("name", "My custom rule")
+ .setParam("markdown_description", "")
+ .execute();
+ }
+
private void logInAsQProfileAdministrator() {
userSession
.logIn()
- .addPermission(ADMINISTER_QUALITY_PROFILES, defaultOrganization.getUuid());
+ .addPermission(ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization().getUuid());
+ }
+
+ private static MacroInterpreter createMacroInterpreter() {
+ MacroInterpreter macroInterpreter = mock(MacroInterpreter.class);
+ doAnswer(returnsFirstArg()).when(macroInterpreter).interpret(anyString());
+ return macroInterpreter;
}
}