@@ -62,7 +62,7 @@ public class IssueDao implements Dao { | |||
} | |||
public void scrollNonClosedByComponentUuidExcludingExternals(DbSession dbSession, String componentUuid, ResultHandler<IssueDto> handler) { | |||
mapper(dbSession).scrollNonClosedByComponentUuid(componentUuid, handler); | |||
mapper(dbSession).scrollNonClosedByComponentUuidExcludingExternals(componentUuid, handler); | |||
} | |||
public void scrollNonClosedByModuleOrProjectExcludingExternals(DbSession dbSession, ComponentDto module, ResultHandler<IssueDto> handler) { |
@@ -43,6 +43,8 @@ public interface IssueMapper { | |||
int updateIfBeforeSelectedDate(IssueDto issue); | |||
void scrollNonClosedByComponentUuid(@Param("componentUuid") String componentUuid, ResultHandler<IssueDto> handler); | |||
void scrollNonClosedByComponentUuidExcludingExternals(@Param("componentUuid") String componentUuid, ResultHandler<IssueDto> handler); | |||
void scrollNonClosedByModuleOrProject( | |||
@Param("projectUuid") String projectUuid, |
@@ -22,6 +22,7 @@ package org.sonar.db.rule; | |||
import com.google.common.base.Splitter; | |||
import com.google.common.collect.ImmutableSet; | |||
import java.util.Set; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.rule.RuleStatus; | |||
import org.sonar.api.rules.RuleType; | |||
@@ -121,8 +122,9 @@ public class RuleForIndexingDto { | |||
return updatedAt; | |||
} | |||
@CheckForNull | |||
public RuleType getTypeAsRuleType() { | |||
return RuleType.valueOf(type); | |||
return RuleType.valueOfNullable(type); | |||
} | |||
public String getSeverityAsString() { |
@@ -185,6 +185,18 @@ | |||
</select> | |||
<select id="scrollNonClosedByComponentUuid" parameterType="String" resultType="Issue" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY"> | |||
select | |||
<include refid="issueColumns"/> | |||
from issues i | |||
inner join rules r on r.id=i.rule_id | |||
inner join projects p on p.uuid=i.component_uuid | |||
inner join projects root on root.uuid=i.project_uuid | |||
where | |||
i.component_uuid = #{componentUuid,jdbcType=VARCHAR} and | |||
i.status <> 'CLOSED' | |||
</select> | |||
<select id="scrollNonClosedByComponentUuidExcludingExternals" parameterType="String" resultType="Issue" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY"> | |||
select | |||
<include refid="issueColumns"/> | |||
from issues i |
@@ -19,15 +19,13 @@ | |||
*/ | |||
package org.sonar.server.platform.db.migration.version.v72; | |||
import java.sql.SQLException; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
import org.sonar.db.CoreDbTester; | |||
import java.sql.SQLException; | |||
import static java.sql.Types.BOOLEAN; | |||
import static java.sql.Types.VARCHAR; | |||
import static org.junit.rules.ExpectedException.none; | |||
import static org.sonar.db.CoreDbTester.createForSchema; | |||
@@ -22,7 +22,6 @@ package org.sonar.server.computation.task.projectanalysis.issue; | |||
import java.util.Collections; | |||
import java.util.Set; | |||
import javax.annotation.concurrent.Immutable; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.rule.RuleStatus; | |||
import org.sonar.api.rules.RuleType; | |||
@@ -31,22 +30,15 @@ import org.sonar.api.server.debt.DebtRemediationFunction; | |||
@Immutable | |||
public class NewExternalRule implements Rule { | |||
private final RuleKey key; | |||
private final String severity; | |||
private final String name; | |||
private final RuleType type; | |||
private final String pluginKey; | |||
private NewExternalRule(Builder builder) { | |||
this.key = checkNotNull(builder.key, "key"); | |||
this.severity = checkNotEmpty(builder.severity, "severity"); | |||
this.type = checkNotNull(builder.type, "type"); | |||
this.pluginKey = builder.pluginKey; | |||
} | |||
private static String checkNotEmpty(String str, String name) { | |||
if (StringUtils.isEmpty(str)) { | |||
throw new IllegalStateException("'" + name + "' not expected to be empty for an external rule"); | |||
} | |||
return str; | |||
this.name = builder.name; | |||
} | |||
private static <T> T checkNotNull(T obj, String name) { | |||
@@ -56,10 +48,6 @@ public class NewExternalRule implements Rule { | |||
return obj; | |||
} | |||
public String getSeverity() { | |||
return severity; | |||
} | |||
@Override | |||
public int getId() { | |||
return 0; | |||
@@ -72,7 +60,7 @@ public class NewExternalRule implements Rule { | |||
@Override | |||
public String getName() { | |||
return key.toString(); | |||
return name; | |||
} | |||
@Override | |||
@@ -110,14 +98,15 @@ public class NewExternalRule implements Rule { | |||
private String severity; | |||
private RuleType type; | |||
private String pluginKey; | |||
private String name; | |||
public Builder setKey(RuleKey key) { | |||
this.key = key; | |||
return this; | |||
} | |||
public Builder setSeverity(String severity) { | |||
this.severity = StringUtils.trimToNull(severity); | |||
public Builder setName(String name) { | |||
this.name = name; | |||
return this; | |||
} | |||
@@ -134,6 +123,10 @@ public class NewExternalRule implements Rule { | |||
return type; | |||
} | |||
public String name() { | |||
return name; | |||
} | |||
public NewExternalRule build() { | |||
return new NewExternalRule(this); | |||
} |
@@ -36,8 +36,9 @@ public interface Rule { | |||
RuleStatus getStatus(); | |||
@CheckForNull | |||
RuleType getType(); | |||
boolean isExternal(); | |||
/** |
@@ -53,7 +53,7 @@ public class RuleImpl implements Rule { | |||
this.status = dto.getStatus(); | |||
this.tags = union(dto.getSystemTags(), dto.getTags()); | |||
this.remediationFunction = effectiveRemediationFunction(dto); | |||
this.type = RuleType.valueOf(dto.getType()); | |||
this.type = RuleType.valueOfNullable(dto.getType()); | |||
this.pluginKey = dto.getPluginKey(); | |||
this.external = dto.isExternal(); | |||
} |
@@ -49,7 +49,7 @@ import static com.google.common.collect.Lists.newArrayList; | |||
import static org.apache.commons.lang.StringUtils.isNotEmpty; | |||
public class TrackerRawInputFactory { | |||
private static final long DEFAULT_EXTERNAL_ISSUE_EFFORT = 0l; | |||
private final TreeRootHolder treeRootHolder; | |||
private final BatchReportReader reportReader; | |||
private final SourceLinesRepository sourceLinesRepository; | |||
@@ -167,6 +167,7 @@ public class TrackerRawInputFactory { | |||
dbLocationsBuilder.addFlow(dbFlowBuilder); | |||
} | |||
} | |||
issue.setFromExternalRuleEngine(false); | |||
issue.setLocations(dbLocationsBuilder.build()); | |||
return issue; | |||
} | |||
@@ -189,9 +190,7 @@ public class TrackerRawInputFactory { | |||
if (reportIssue.getSeverity() != Severity.UNSET_SEVERITY) { | |||
issue.setSeverity(reportIssue.getSeverity().name()); | |||
} | |||
if (reportIssue.getEffort() != 0) { | |||
issue.setEffort(Duration.create(reportIssue.getEffort())); | |||
} | |||
issue.setEffort(Duration.create(reportIssue.getEffort() != 0 ? reportIssue.getEffort() : DEFAULT_EXTERNAL_ISSUE_EFFORT)); | |||
DbIssues.Locations.Builder dbLocationsBuilder = DbIssues.Locations.newBuilder(); | |||
if (reportIssue.hasTextRange()) { | |||
dbLocationsBuilder.setTextRange(convertTextRange(reportIssue.getTextRange())); | |||
@@ -205,6 +204,7 @@ public class TrackerRawInputFactory { | |||
dbLocationsBuilder.addFlow(dbFlowBuilder); | |||
} | |||
} | |||
issue.setFromExternalRuleEngine(true); | |||
issue.setLocations(dbLocationsBuilder.build()); | |||
issue.setType(toRuleType(reportIssue.getType())); | |||
@@ -215,8 +215,8 @@ public class TrackerRawInputFactory { | |||
private NewExternalRule toExternalRule(ScannerReport.ExternalIssue reportIssue) { | |||
NewExternalRule.Builder builder = new NewExternalRule.Builder() | |||
.setType(toRuleType(reportIssue.getType())) | |||
.setKey(RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + reportIssue.getRuleRepository(), reportIssue.getRuleKey())) | |||
.setPluginKey(reportIssue.getRuleRepository()); | |||
.setName(RuleKey.of(reportIssue.getRuleRepository(), reportIssue.getRuleKey()).toString()) | |||
.setKey(RuleKey.of(RuleKey.EXTERNAL_RULE_REPO_PREFIX + reportIssue.getRuleRepository(), reportIssue.getRuleKey())); | |||
if (reportIssue.getSeverity() != Severity.UNSET_SEVERITY) { | |||
builder.setSeverity(reportIssue.getSeverity().name()); |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.server.rule; | |||
import org.sonar.api.rule.RuleStatus; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
@@ -56,10 +55,7 @@ public class ExternalRuleCreator { | |||
.setPluginKey(external.getPluginKey()) | |||
.setIsExternal(external.isExternal()) | |||
.setName(external.getName()) | |||
.setType(external.getType()) | |||
.setScope(ALL) | |||
.setStatus(RuleStatus.READY) | |||
.setSeverity(external.getSeverity()) | |||
.setStatus(READY) | |||
.setCreatedAt(system2.now()) | |||
.setUpdatedAt(system2.now())); |
@@ -190,12 +190,13 @@ public class RuleDoc extends BaseDoc { | |||
return this; | |||
} | |||
@CheckForNull | |||
public RuleType type() { | |||
return RuleType.valueOf(getField(RuleIndexDefinition.FIELD_RULE_TYPE)); | |||
return RuleType.valueOfNullable(getNullableField(RuleIndexDefinition.FIELD_RULE_TYPE)); | |||
} | |||
public RuleDoc setType(RuleType ruleType) { | |||
setField(RuleIndexDefinition.FIELD_RULE_TYPE, ruleType.name()); | |||
public RuleDoc setType(@Nullable RuleType ruleType) { | |||
setField(RuleIndexDefinition.FIELD_RULE_TYPE, ruleType == null ? null : ruleType.name()); | |||
return this; | |||
} | |||
@@ -72,7 +72,7 @@ public class RuleQueryFactory { | |||
*/ | |||
public RuleQuery createRuleSearchQuery(DbSession dbSession, Request request) { | |||
RuleQuery query = createRuleQuery(dbSession, request); | |||
query.setIsExternal(request.paramAsBoolean(PARAM_IS_EXTERNAL)); | |||
query.setIsExternal(request.mandatoryParamAsBoolean(PARAM_IS_EXTERNAL)); | |||
return query; | |||
} | |||
@@ -203,12 +203,16 @@ public class SearchAction implements RulesWsAction { | |||
// Rule-specific search parameters | |||
defineGenericRuleSearchParameters(action); | |||
defineIsExternalParam(action); | |||
} | |||
static void defineIsExternalParam(WebService.NewAction action) { | |||
action | |||
.createParam(PARAM_IS_EXTERNAL) | |||
.setDescription("Filter external engine rules") | |||
.setBooleanPossibleValues() | |||
.setSince("7.2"); | |||
.createParam(PARAM_IS_EXTERNAL) | |||
.setDescription("Filter external engine rules") | |||
.setDefaultValue(false) | |||
.setBooleanPossibleValues() | |||
.setSince("7.2"); | |||
} | |||
public static void defineGenericRuleSearchParameters(WebService.NewAction action) { |
@@ -179,8 +179,13 @@ public class BatchReportReaderRule implements TestRule, BatchReportReader { | |||
return closeableIterator(externalIssues.get(componentRef)); | |||
} | |||
public BatchReportReaderRule putIssues(int componentRef, List<ScannerReport.Issue> issue) { | |||
this.issues.put(componentRef, issue); | |||
public BatchReportReaderRule putIssues(int componentRef, List<ScannerReport.Issue> issues) { | |||
this.issues.put(componentRef, issues); | |||
return this; | |||
} | |||
public BatchReportReaderRule putExternalIssues(int componentRef, List<ScannerReport.ExternalIssue> externalIssues) { | |||
this.externalIssues.put(componentRef, externalIssues); | |||
return this; | |||
} | |||
@@ -35,15 +35,17 @@ public class NewExternalRuleTest { | |||
NewExternalRule.Builder builder = new NewExternalRule.Builder() | |||
.setKey(RuleKey.of("repo", "rule")) | |||
.setPluginKey("repo") | |||
.setName("name") | |||
.setSeverity("MAJOR") | |||
.setType(RuleType.BUG); | |||
assertThat(builder.severity()).isEqualTo("MAJOR"); | |||
assertThat(builder.type()).isEqualTo(RuleType.BUG); | |||
assertThat(builder.name()).isEqualTo("name"); | |||
NewExternalRule rule = builder.build(); | |||
assertThat(rule.getName()).isEqualTo("repo:rule"); | |||
assertThat(rule.getName()).isEqualTo("name"); | |||
assertThat(rule.getPluginKey()).isEqualTo("repo"); | |||
assertThat(rule.getSeverity()).isEqualTo("MAJOR"); | |||
assertThat(rule.getType()).isEqualTo(RuleType.BUG); |
@@ -26,6 +26,7 @@ import org.junit.Test; | |||
import org.sonar.api.issue.Issue; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.rule.Severity; | |||
import org.sonar.api.utils.Duration; | |||
import org.sonar.core.issue.DefaultIssue; | |||
import org.sonar.core.issue.tracking.Input; | |||
import org.sonar.scanner.protocol.Constants; | |||
@@ -62,7 +63,7 @@ public class TrackerRawInputFactoryTest { | |||
@Rule | |||
public SourceLinesRepositoryRule fileSourceRepository = new SourceLinesRepositoryRule(); | |||
@Rule | |||
public RuleRepositoryRule ruleRepository = new RuleRepositoryRule(); | |||
@@ -118,6 +119,68 @@ public class TrackerRawInputFactoryTest { | |||
assertThat(issue.gap()).isEqualTo(3.14); | |||
assertThat(issue.message()).isEqualTo("the message"); | |||
// fields set by compute engine | |||
assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2)); | |||
assertThat(issue.tags()).isEmpty(); | |||
assertInitializedIssue(issue); | |||
assertThat(issue.debt()).isNull(); | |||
} | |||
@Test | |||
public void load_external_issues_from_report() { | |||
fileSourceRepository.addLines(FILE_REF, "line 1;", "line 2;"); | |||
ScannerReport.ExternalIssue reportIssue = ScannerReport.ExternalIssue.newBuilder() | |||
.setTextRange(TextRange.newBuilder().setStartLine(2).build()) | |||
.setMsg("the message") | |||
.setRuleRepository("eslint") | |||
.setRuleKey("S001") | |||
.setSeverity(Constants.Severity.BLOCKER) | |||
.setEffort(20l) | |||
.build(); | |||
reportReader.putExternalIssues(FILE.getReportAttributes().getRef(), asList(reportIssue)); | |||
Input<DefaultIssue> input = underTest.create(FILE); | |||
Collection<DefaultIssue> issues = input.getIssues(); | |||
assertThat(issues).hasSize(1); | |||
DefaultIssue issue = Iterators.getOnlyElement(issues.iterator()); | |||
// fields set by analysis report | |||
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_eslint", "S001")); | |||
assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); | |||
assertThat(issue.line()).isEqualTo(2); | |||
assertThat(issue.effort()).isEqualTo(Duration.create(20l)); | |||
assertThat(issue.message()).isEqualTo("the message"); | |||
// fields set by compute engine | |||
assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2)); | |||
assertThat(issue.tags()).isEmpty(); | |||
assertInitializedIssue(issue); | |||
} | |||
@Test | |||
public void load_external_issues_from_report_with_default_effort() { | |||
fileSourceRepository.addLines(FILE_REF, "line 1;", "line 2;"); | |||
ScannerReport.ExternalIssue reportIssue = ScannerReport.ExternalIssue.newBuilder() | |||
.setTextRange(TextRange.newBuilder().setStartLine(2).build()) | |||
.setMsg("the message") | |||
.setRuleRepository("eslint") | |||
.setRuleKey("S001") | |||
.setSeverity(Constants.Severity.BLOCKER) | |||
.build(); | |||
reportReader.putExternalIssues(FILE.getReportAttributes().getRef(), asList(reportIssue)); | |||
Input<DefaultIssue> input = underTest.create(FILE); | |||
Collection<DefaultIssue> issues = input.getIssues(); | |||
assertThat(issues).hasSize(1); | |||
DefaultIssue issue = Iterators.getOnlyElement(issues.iterator()); | |||
// fields set by analysis report | |||
assertThat(issue.ruleKey()).isEqualTo(RuleKey.of("external_eslint", "S001")); | |||
assertThat(issue.severity()).isEqualTo(Severity.BLOCKER); | |||
assertThat(issue.line()).isEqualTo(2); | |||
assertThat(issue.effort()).isEqualTo(Duration.create(0l)); | |||
assertThat(issue.message()).isEqualTo("the message"); | |||
// fields set by compute engine | |||
assertThat(issue.checksum()).isEqualTo(input.getLineHashSequence().getHashForLine(2)); | |||
assertThat(issue.tags()).isEmpty(); | |||
@@ -198,6 +261,5 @@ public class TrackerRawInputFactoryTest { | |||
assertThat(issue.status()).isEqualTo(Issue.STATUS_OPEN); | |||
assertThat(issue.key()).isNull(); | |||
assertThat(issue.authorLogin()).isNull(); | |||
assertThat(issue.debt()).isNull(); | |||
} | |||
} |
@@ -81,6 +81,7 @@ public class PersistExternalRulesStepTest extends BaseStepTest { | |||
.setKey(ruleKey) | |||
.setPluginKey("eslint") | |||
.setSeverity(BLOCKER) | |||
.setName("eslint:no-cond-assign") | |||
.setType(BUG) | |||
.build()); | |||
@@ -30,7 +30,6 @@ import org.sonar.server.es.EsTester; | |||
import org.sonar.server.rule.index.RuleIndexer; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.rule.Severity.BLOCKER; | |||
import static org.sonar.api.rules.RuleType.BUG; | |||
public class ExternalRuleCreatorTest { | |||
@@ -50,8 +49,8 @@ public class ExternalRuleCreatorTest { | |||
NewExternalRule externalRule = new NewExternalRule.Builder() | |||
.setKey(ruleKey) | |||
.setPluginKey("eslint") | |||
.setSeverity(BLOCKER) | |||
.setType(BUG) | |||
.setName("name") | |||
.build(); | |||
Rule rule1 = underTest.persistAndIndex(dbSession, externalRule); | |||
@@ -61,9 +60,8 @@ public class ExternalRuleCreatorTest { | |||
assertThat(rule1.getId()).isGreaterThan(0); | |||
assertThat(rule1.getKey()).isEqualTo(ruleKey); | |||
assertThat(rule1.getPluginKey()).isEqualTo("eslint"); | |||
assertThat(rule1.getName()).isEqualTo(ruleKey.toString()); | |||
assertThat(rule1.getType()).isEqualTo(BUG); | |||
assertThat(rule1.getName()).isEqualTo("name"); | |||
assertThat(rule1.getType()).isNull(); | |||
} | |||
} |
@@ -26,6 +26,7 @@ import org.junit.rules.ExpectedException; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.api.server.ws.internal.SimpleGetRequest; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbTester; | |||
@@ -51,14 +52,13 @@ import static org.sonar.api.server.ws.WebService.Param.SORT; | |||
import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; | |||
import static org.sonar.db.qualityprofile.ActiveRuleDto.INHERITED; | |||
import static org.sonar.db.qualityprofile.ActiveRuleDto.OVERRIDES; | |||
import static org.sonar.server.rule.ws.SearchAction.defineGenericRuleSearchParameters; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVATION; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ACTIVE_SEVERITIES; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_AVAILABLE_SINCE; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_COMPARE_TO_PROFILE; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_INHERITANCE; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_EXTERNAL; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_IS_TEMPLATE; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_LANGUAGES; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_ORGANIZATION; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_QPROFILE; | |||
@@ -69,6 +69,7 @@ import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_STATUSES; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TAGS; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TEMPLATE_KEY; | |||
import static org.sonar.server.rule.ws.RulesWsParameters.PARAM_TYPES; | |||
import static org.sonar.server.rule.ws.SearchAction.defineGenericRuleSearchParameters; | |||
public class RuleQueryFactoryTest { | |||
@@ -116,6 +117,50 @@ public class RuleQueryFactoryTest { | |||
assertThat(result.getCompareToQProfile()).isNull(); | |||
} | |||
@Test | |||
public void create_rule_search_query() { | |||
QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization); | |||
QProfileDto compareToQualityProfile = dbTester.qualityProfiles().insert(organization); | |||
RuleQuery result = executeRuleSearchQuery( | |||
PARAM_RULE_KEY, "ruleKey", | |||
PARAM_ACTIVATION, "true", | |||
PARAM_ACTIVE_SEVERITIES, "MINOR,MAJOR", | |||
PARAM_AVAILABLE_SINCE, "2016-01-01", | |||
PARAM_INHERITANCE, "INHERITED,OVERRIDES", | |||
PARAM_IS_TEMPLATE, "true", | |||
PARAM_IS_EXTERNAL, "false", | |||
PARAM_LANGUAGES, "java,js", | |||
TEXT_QUERY, "S001", | |||
PARAM_ORGANIZATION, organization.getKey(), | |||
PARAM_QPROFILE, qualityProfile.getKee(), | |||
PARAM_COMPARE_TO_PROFILE, compareToQualityProfile.getKee(), | |||
PARAM_REPOSITORIES, "pmd,checkstyle", | |||
PARAM_SEVERITIES, "MINOR,CRITICAL", | |||
PARAM_STATUSES, "DEPRECATED,READY", | |||
PARAM_TAGS, "tag1,tag2", | |||
PARAM_TEMPLATE_KEY, "architectural", | |||
PARAM_TYPES, "CODE_SMELL,BUG", | |||
SORT, "updatedAt", | |||
ASCENDING, "false"); | |||
assertResult(result, qualityProfile, compareToQualityProfile); | |||
assertThat(result.isExternal()).isFalse(); | |||
} | |||
@Test | |||
public void is_external_is_mandatory_for_rule_search_query() { | |||
dbTester.qualityProfiles().insert(organization); | |||
dbTester.qualityProfiles().insert(organization); | |||
Request request = new SimpleGetRequest(); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("The 'is_external' parameter is missing"); | |||
underTest.createRuleSearchQuery(dbTester.getSession(), request); | |||
} | |||
@Test | |||
public void create_query() { | |||
QProfileDto qualityProfile = dbTester.qualityProfiles().insert(organization); | |||
@@ -128,7 +173,7 @@ public class RuleQueryFactoryTest { | |||
PARAM_ACTIVE_SEVERITIES, "MINOR,MAJOR", | |||
PARAM_AVAILABLE_SINCE, "2016-01-01", | |||
PARAM_INHERITANCE, "INHERITED,OVERRIDES", | |||
PARAM_IS_TEMPLATE, "true", | |||
PARAM_IS_TEMPLATE, "true", | |||
PARAM_IS_EXTERNAL, "true", | |||
PARAM_LANGUAGES, "java,js", | |||
TEXT_QUERY, "S001", | |||
@@ -145,6 +190,11 @@ public class RuleQueryFactoryTest { | |||
SORT, "updatedAt", | |||
ASCENDING, "false"); | |||
assertResult(result, qualityProfile, compareToQualityProfile); | |||
assertThat(result.isExternal()).isNull(); | |||
} | |||
private void assertResult(RuleQuery result, QProfileDto qualityProfile, QProfileDto compareToQualityProfile) { | |||
assertThat(result.getKey()).isEqualTo("ruleKey"); | |||
assertThat(result.getActivation()).isTrue(); | |||
@@ -165,7 +215,6 @@ public class RuleQueryFactoryTest { | |||
assertThat(result.getTags()).containsOnly("tag1", "tag2"); | |||
assertThat(result.templateKey()).isEqualTo("architectural"); | |||
assertThat(result.getTypes()).containsOnly(BUG, CODE_SMELL); | |||
assertThat(result.getSortField()).isEqualTo("updatedAt"); | |||
} | |||
@@ -250,7 +299,8 @@ public class RuleQueryFactoryTest { | |||
QProfileDto compareToQualityProfile = dbTester.qualityProfiles().insert(otherOrganization); | |||
expectedException.expect(IllegalArgumentException.class); | |||
expectedException.expectMessage("The specified quality profile '" + compareToQualityProfile.getKee() + "' is not part of the specified organization '" + organization.getKey() + "'"); | |||
expectedException | |||
.expectMessage("The specified quality profile '" + compareToQualityProfile.getKee() + "' is not part of the specified organization '" + organization.getKey() + "'"); | |||
execute(PARAM_QPROFILE, qualityProfile.getKee(), | |||
PARAM_COMPARE_TO_PROFILE, compareToQualityProfile.getKee(), | |||
@@ -298,6 +348,15 @@ public class RuleQueryFactoryTest { | |||
return fakeAction.getRuleQuery(); | |||
} | |||
private RuleQuery executeRuleSearchQuery(String... paramsKeyAndValue) { | |||
SimpleGetRequest request = new SimpleGetRequest(); | |||
for (int i = 0; i < paramsKeyAndValue.length; i += 2) { | |||
request.setParam(paramsKeyAndValue[i], paramsKeyAndValue[i + 1]); | |||
} | |||
return underTest.createRuleSearchQuery(dbTester.getSession(), request); | |||
} | |||
private class FakeAction implements WsAction { | |||
private final RuleQueryFactory ruleQueryFactory; |
@@ -21,6 +21,7 @@ package org.sonar.api.rules; | |||
import java.util.LinkedHashSet; | |||
import java.util.Set; | |||
import javax.annotation.CheckForNull; | |||
import static java.lang.String.format; | |||
import static java.util.Arrays.stream; | |||
@@ -60,5 +61,19 @@ public enum RuleType { | |||
} | |||
throw new IllegalArgumentException(format("Unsupported type value : %d", dbConstant)); | |||
} | |||
@CheckForNull | |||
public static RuleType valueOfNullable(int dbConstant) { | |||
// iterating the array is fast-enough as size is small. No need for a map. | |||
for (RuleType type : values()) { | |||
if (type.getDbConstant() == dbConstant) { | |||
return type; | |||
} | |||
} | |||
if (dbConstant == 0) { | |||
return null; | |||
} | |||
throw new IllegalArgumentException(format("Unsupported type value : %d", dbConstant)); | |||
} | |||
} |