@@ -1,6 +1,6 @@ | |||
<div class="rule-desc"> | |||
<h1 class="marginbottom10">{{name}}</h1> | |||
<div class="marginbottom10">{{{description}}}</div> | |||
<div class="marginbottom10">{{{htmlDesc}}}</div> | |||
</div> | |||
<ul class="note code-issue-bar"> | |||
@@ -8,4 +8,4 @@ | |||
{{#all characteristic subCharacteristic}} | |||
<li>{{characteristic}} > {{subCharacteristic}}{{else}}{{t 'issue.technical_debt_deleted'}}</li> | |||
{{/all}} | |||
</ul> | |||
</ul> |
@@ -124,7 +124,6 @@ import org.sonar.server.qualityprofile.index.ActiveRuleNormalizer; | |||
import org.sonar.server.qualityprofile.persistence.ActiveRuleDao; | |||
import org.sonar.server.qualityprofile.ws.*; | |||
import org.sonar.server.rule.*; | |||
import org.sonar.server.rule.ws.*; | |||
import org.sonar.server.rule2.RegisterRules; | |||
import org.sonar.server.rule2.RuleService; | |||
import org.sonar.server.rule2.index.RuleIndex; | |||
@@ -326,9 +325,6 @@ class ServerComponents { | |||
pico.addSingleton(RuleRepositories.class); | |||
pico.addSingleton(DeprecatedRulesDefinition.class); | |||
pico.addSingleton(RuleDefinitionsLoader.class); | |||
pico.addSingleton(RulesWs.class); | |||
pico.addSingleton(RuleShowWsHandler.class); | |||
pico.addSingleton(RuleSearchWsHandler.class); | |||
pico.addSingleton(RulesDefinitionXmlLoader.class); | |||
// experimental rules |
@@ -93,10 +93,6 @@ public class RubyRuleService implements ServerComponent, Startable { | |||
.setDebtRemediationOffset(Strings.emptyToNull((String) params.get("debtRemediationOffset")))); | |||
} | |||
public void updateRuleNote(int ruleId, String note) { | |||
rules.updateRuleNote(ruleId, note); | |||
} | |||
public Integer createCustomRule(int ruleId, @Nullable String name, @Nullable String severity, @Nullable String description, Map<String, String> paramsByKey) { | |||
return rules.createCustomRule(ruleId, name, severity, description, paramsByKey); | |||
} |
@@ -1,132 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.resources.Language; | |||
import org.sonar.api.resources.Languages; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.server.debt.DebtRemediationFunction; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.server.paging.PagedResult; | |||
import org.sonar.server.rule.Rule; | |||
import org.sonar.server.rule.RuleQuery; | |||
import org.sonar.server.rule.Rules; | |||
import org.sonar.server.util.RubyUtils; | |||
import javax.annotation.CheckForNull; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
/** | |||
* @deprecated to be dropped in 4.4 | |||
*/ | |||
@Deprecated | |||
public class RuleSearchWsHandler implements RequestHandler { | |||
private final Rules rules; | |||
private final Languages languages; | |||
public RuleSearchWsHandler(Rules rules, Languages languages) { | |||
this.rules = rules; | |||
this.languages = languages; | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
final String ruleKeyParam = request.param("k"); | |||
Collection<Rule> foundRules = Collections.emptyList(); | |||
boolean hasMore = false; | |||
long total = 0L; | |||
if (ruleKeyParam == null) { | |||
PagedResult<Rule> searchResult = rules.find(RuleQuery.builder() | |||
.searchQuery(request.param("s")) | |||
.languages(RubyUtils.toStrings(request.param("languages"))) | |||
.repositories(RubyUtils.toStrings(request.param("repositories"))) | |||
.severities(RubyUtils.toStrings(request.param("severities"))) | |||
.statuses(RubyUtils.toStrings(request.param("statuses"))) | |||
.tags(RubyUtils.toStrings(request.param("tags"))) | |||
.debtCharacteristics(RubyUtils.toStrings(request.param("debtCharacteristics"))) | |||
.hasDebtCharacteristic(request.paramAsBoolean("hasDebtCharacteristic")) | |||
.pageSize(request.paramAsInt("ps")) | |||
.pageIndex(request.paramAsInt("p")) | |||
.build()); | |||
foundRules = searchResult.results(); | |||
hasMore = searchResult.paging().hasNextPage(); | |||
total = searchResult.paging().total(); | |||
} else { | |||
RuleKey ruleKey = RuleKey.parse(ruleKeyParam); | |||
Rule rule = findRule(ruleKey); | |||
if (rule != null) { | |||
foundRules = Collections.singleton(rule); | |||
total = 1L; | |||
} | |||
hasMore = false; | |||
} | |||
JsonWriter json = response.newJsonWriter(); | |||
json.beginObject().name("results").beginArray(); | |||
for (Rule rule : foundRules) { | |||
json.beginObject(); | |||
writeRule(rule, json); | |||
json.endObject(); | |||
} | |||
json.endArray().prop("more", hasMore).prop("total", total).endObject().close(); | |||
} | |||
@CheckForNull | |||
private Rule findRule(RuleKey ruleKey) { | |||
return rules.findByKey(ruleKey); | |||
} | |||
private void writeRule(Rule rule, JsonWriter json) { | |||
String languageName = null; | |||
String languageKey = rule.language(); | |||
if (languageKey != null) { | |||
Language language = languages.get(languageKey); | |||
if (language != null) { | |||
languageName = language.getName(); | |||
} else { | |||
languageName = languageKey; | |||
} | |||
} | |||
json | |||
.prop("key", rule.ruleKey().toString()) | |||
.prop("repository", rule.ruleKey().repository()) | |||
.prop("name", rule.name()) | |||
.prop("language", languageName) | |||
.prop("status", rule.status()) | |||
; | |||
DebtRemediationFunction function = rule.debtRemediationFunction(); | |||
if (function != null) { | |||
json | |||
.prop("debtCharacteristic", rule.debtCharacteristicKey()) | |||
.prop("debtSubCharacteristic", rule.debtSubCharacteristicKey()) | |||
.prop("debtRemediationFunction", function.type().name()) | |||
.prop("debtRemediationCoefficient", function.coefficient()) | |||
.prop("debtRemediationOffset", function.offset()) | |||
; | |||
} | |||
} | |||
} |
@@ -1,162 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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.base.Strings; | |||
import org.sonar.api.i18n.I18n; | |||
import org.sonar.api.resources.Language; | |||
import org.sonar.api.resources.Languages; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.rules.RuleFinder; | |||
import org.sonar.api.rules.RulePriority; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.RequestHandler; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.api.utils.text.JsonWriter; | |||
import org.sonar.markdown.Markdown; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.rule.Rule; | |||
import org.sonar.server.rule.RuleNote; | |||
import org.sonar.server.rule.Rules; | |||
import org.sonar.server.user.UserSession; | |||
import javax.annotation.CheckForNull; | |||
import javax.annotation.Nullable; | |||
import java.util.Date; | |||
/** | |||
* @deprecated to be dropped in 4.4 | |||
*/ | |||
@Deprecated | |||
public class RuleShowWsHandler implements RequestHandler { | |||
private final Rules rules; | |||
private final Languages languages; | |||
// Only used to get manual rules | |||
private final RuleFinder ruleFinder; | |||
private final I18n i18n; | |||
public RuleShowWsHandler(Rules rules, RuleFinder ruleFinder, I18n i18n, Languages languages) { | |||
this.rules = rules; | |||
this.ruleFinder = ruleFinder; | |||
this.i18n = i18n; | |||
this.languages = languages; | |||
} | |||
@Override | |||
public void handle(Request request, Response response) { | |||
final String ruleKeyParam = request.mandatoryParam("key"); | |||
RuleKey ruleKey = RuleKey.parse(ruleKeyParam); | |||
Rule rule = findRule(ruleKey); | |||
if (rule == null) { | |||
throw new NotFoundException("Rule not found: " + ruleKey); | |||
} | |||
JsonWriter json = response.newJsonWriter(); | |||
json.beginObject().name("rule").beginObject(); | |||
writeRule(rule, json); | |||
writeTags(rule, json); | |||
json.endObject().endObject().close(); | |||
} | |||
@CheckForNull | |||
private Rule findRule(RuleKey ruleKey) { | |||
// TODO remove this when manual rules are indexed in E/S | |||
if (ruleKey.repository().equals(Rule.MANUAL_REPOSITORY_KEY)) { | |||
org.sonar.api.rules.Rule rule = ruleFinder.findByKey(ruleKey); | |||
if (rule != null) { | |||
RulePriority severity = rule.getSeverity(); | |||
return new Rule.Builder() | |||
.setKey(rule.getKey()) | |||
.setRepositoryKey(rule.getRepositoryKey()) | |||
.setName(rule.getName()) | |||
.setDescription(rule.getDescription()) | |||
.setSeverity(severity != null ? severity.name() : null) | |||
.setStatus(rule.getStatus()) | |||
.setCreatedAt(rule.getCreatedAt()) | |||
.setUpdatedAt(rule.getUpdatedAt()).build(); | |||
} | |||
return null; | |||
} else { | |||
return rules.findByKey(ruleKey); | |||
} | |||
} | |||
private void writeRule(Rule rule, JsonWriter json) { | |||
json | |||
.prop("key", rule.ruleKey().toString()) | |||
.prop("name", rule.name()) | |||
.prop("description", rule.description()); | |||
addLanguage(rule, json); | |||
addNote(rule, json); | |||
addDate(rule.createdAt(), "createdAt", json); | |||
addFormattedDate(rule.createdAt(), "fCreatedAt", json); | |||
addDate(rule.updatedAt(), "updatedAt", json); | |||
addFormattedDate(rule.updatedAt(), "fUpdatedAt", json); | |||
} | |||
private void addLanguage(Rule rule, JsonWriter json) { | |||
String languageKey = rule.language(); | |||
if (languageKey != null) { | |||
Language language = languages.get(languageKey); | |||
json.prop("language", language == null ? languageKey : language.getName()); | |||
} | |||
} | |||
private void addNote(Rule rule, JsonWriter json) { | |||
RuleNote ruleNote = rule.ruleNote(); | |||
if (ruleNote != null && !Strings.isNullOrEmpty(ruleNote.data())) { | |||
json.prop("noteRaw", ruleNote.data()) | |||
.prop("noteHtml", Markdown.convertToHtml(ruleNote.data())); | |||
} | |||
} | |||
private void writeTags(Rule rule, JsonWriter json) { | |||
json.name("tags").beginArray(); | |||
for (String adminTag : rule.adminTags()) { | |||
json.value(adminTag); | |||
} | |||
json.endArray(); | |||
json.name("sysTags").beginArray(); | |||
for (String systemTag : rule.systemTags()) { | |||
json.value(systemTag); | |||
} | |||
json.endArray(); | |||
} | |||
private void addDate(@Nullable Date date, String dateKey, JsonWriter json) { | |||
if (date != null) { | |||
json.prop(dateKey, DateUtils.formatDateTime(date)); | |||
} | |||
} | |||
private void addFormattedDate(@Nullable Date date, String dateKey, JsonWriter json) { | |||
if (date != null) { | |||
json.prop(dateKey, i18n.formatDateTime(UserSession.get().locale(), date)); | |||
} | |||
} | |||
} |
@@ -1,68 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.sonar.api.server.ws.WebService; | |||
/** | |||
* @deprecated to be dropped in 4.4 | |||
*/ | |||
@Deprecated | |||
public class RulesWs implements WebService { | |||
private final RuleSearchWsHandler searchHandler; | |||
private final RuleShowWsHandler showHandler; | |||
public RulesWs(RuleSearchWsHandler searchHandler, RuleShowWsHandler showHandler) { | |||
this.searchHandler = searchHandler; | |||
this.showHandler = showHandler; | |||
} | |||
@Override | |||
public void define(Context context) { | |||
NewController controller = context.createController("api/rules") | |||
.setDescription("Coding rules"); | |||
controller.createAction("list") | |||
.setDescription("List rules that match the given criteria") | |||
.setSince("4.3") | |||
.setInternal(true) | |||
.setHandler(searchHandler) | |||
.createParam("s", "To return rules whose title contains this string.") | |||
.createParam("k", "Key of the rule, for example : 'findbugs:DMI_USELESS_SUBSTRING'.") | |||
.createParam("languages", "Comma-separated list of language keys") | |||
.createParam("repositories", "Comma-separated list of repositories") | |||
.createParam("severities", "Comma-separated list of severities. Possible values: INFO | MINOR | MAJOR | CRITICAL | BLOCKER.") | |||
.createParam("statuses", "Comma-separated list of statuses. Possible values: READY | BETA | DEPRECATED.") | |||
.createParam("tags", "Comma-separated list of tags. The rule is returned if it matches all the tags.") | |||
.createParam("debtCharacteristics", "Comma-separated list of characteristics / sub-characteristics.") | |||
.createParam("hasDebtCharacteristic", "Determine if returned rules should be linked to a debt characteristic or not. Possible values: true | false") | |||
.createParam("ps", "Page size (default is 25).") | |||
.createParam("p", "Page number (default is 1)."); | |||
controller.createAction("show") | |||
.setDescription("Detail of rule") | |||
.setSince("4.2") | |||
.setHandler(showHandler) | |||
.createParam("key", "Mandatory key of rule"); | |||
controller.done(); | |||
} | |||
} |
@@ -81,4 +81,10 @@ public interface Rule { | |||
@CheckForNull | |||
String internalKey(); | |||
@CheckForNull | |||
String noteAsMarkdown(); | |||
@CheckForNull | |||
String noteLogin(); | |||
} |
@@ -67,7 +67,6 @@ public class RuleService implements ServerComponent { | |||
public RuleResult search(RuleQuery query, QueryOptions options) { | |||
// keep only supported fields and add the fields to always return | |||
options.filterFieldsToReturn(RuleIndex.PUBLIC_FIELDS); | |||
options.addFieldsToReturn(RuleNormalizer.RuleField.REPOSITORY.key(), RuleNormalizer.RuleField.KEY.key()); | |||
RuleResult result = index.search(query, options); | |||
for(Rule rule:result.getHits()){ |
@@ -153,7 +153,8 @@ class RuleDoc implements Rule { | |||
@Override | |||
@CheckForNull | |||
public String debtCharacteristicKey() { | |||
throw new UnsupportedOperationException("TODO"); | |||
// TO BE IMPLEMENTED | |||
return null; | |||
} | |||
@Override | |||
@@ -188,6 +189,20 @@ class RuleDoc implements Rule { | |||
} | |||
} | |||
@Override | |||
@CheckForNull | |||
public String noteAsMarkdown() { | |||
// TODO | |||
return null; | |||
} | |||
@Override | |||
@CheckForNull | |||
public String noteLogin() { | |||
// TODO | |||
return null; | |||
} | |||
@Override | |||
@CheckForNull | |||
public Date createdAt() { |
@@ -220,23 +220,19 @@ public class RuleIndex extends BaseIndex<Rule, RuleDto, RuleKey> { | |||
/* integrate Option's Fields */ | |||
Set<String> fields = new HashSet<String>(); | |||
if (options.getFieldsToReturn() != null && | |||
!options.getFieldsToReturn().isEmpty()) { | |||
for (String field : options.getFieldsToReturn()) { | |||
fields.add(field); | |||
} | |||
if (options.getFieldsToReturn() != null && !options.getFieldsToReturn().isEmpty()) { | |||
fields.addAll(options.getFieldsToReturn()); | |||
// required fields | |||
// TODO remove REPOSITORY ? Move this list to RuleField constant ? | |||
fields.add(RuleNormalizer.RuleField.KEY.key()); | |||
fields.add(RuleNormalizer.RuleField.REPOSITORY.key()); | |||
} else { | |||
for (RuleNormalizer.RuleField field : RuleNormalizer.RuleField.values()) { | |||
fields.add(field.key()); | |||
} | |||
fields = RuleNormalizer.RuleField.ALL_KEYS; | |||
} | |||
//Add required fields: | |||
fields.add(RuleNormalizer.RuleField.KEY.key()); | |||
fields.add(RuleNormalizer.RuleField.REPOSITORY.key()); | |||
//TODO limit source for available fields. | |||
//esSearch.addFields(fields.toArray(new String[fields.size()])); | |||
//esSearch.setSource(StringUtils.join(fields,',')); | |||
//esSearch.setSource(StringUtils.join(fields, ',')); | |||
return esSearch; | |||
} |
@@ -19,6 +19,10 @@ | |||
*/ | |||
package org.sonar.server.rule2.index; | |||
import com.google.common.base.Function; | |||
import com.google.common.collect.Collections2; | |||
import com.google.common.collect.ImmutableSet; | |||
import com.google.common.collect.Lists; | |||
import org.elasticsearch.action.update.UpdateRequest; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.check.Cardinality; | |||
@@ -28,9 +32,11 @@ import org.sonar.core.rule.RuleParamDto; | |||
import org.sonar.server.db.DbClient; | |||
import org.sonar.server.search.BaseNormalizer; | |||
import javax.annotation.Nullable; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import java.util.Set; | |||
public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> { | |||
@@ -68,6 +74,13 @@ public class RuleNormalizer extends BaseNormalizer<RuleDto, RuleKey> { | |||
public String toString() { | |||
return key; | |||
} | |||
public static final Set<String> ALL_KEYS = ImmutableSet.copyOf(Collections2.transform(Lists.newArrayList(RuleField.values()), new Function<RuleField, String>() { | |||
@Override | |||
public String apply(@Nullable RuleField input) { | |||
return input != null ? input.key : null; | |||
} | |||
})); | |||
} | |||
public static enum RuleParamField { |
@@ -43,7 +43,7 @@ public class RulesWebService implements WebService { | |||
@Override | |||
public void define(Context context) { | |||
NewController controller = context | |||
.createController("api/rules2") | |||
.createController("api/rules") | |||
.setDescription("Coding rules"); | |||
search.define(controller); |
@@ -149,12 +149,16 @@ public abstract class BaseIndex<D, E extends Dto<K>, K extends Serializable> | |||
public abstract D toDoc(GetResponse response); | |||
public D getByKey(K key) { | |||
return toDoc(getClient().prepareGet() | |||
GetResponse response = getClient().prepareGet() | |||
.setType(this.getIndexType()) | |||
.setIndex(this.getIndexName()) | |||
.setId(this.getKeyValue(key)) | |||
.setRouting(this.getKeyValue(key)) | |||
.get()); | |||
.get(); | |||
if (response.isExists()) { | |||
return toDoc(response); | |||
} | |||
return null; | |||
} | |||
private void insertDocument(UpdateRequest request, K key) throws Exception { |
@@ -1,99 +0,0 @@ | |||
# | |||
# SonarQube, open source software quality management tool. | |||
# Copyright (C) 2008-2014 SonarSource | |||
# mailto:contact AT sonarsource DOT com | |||
# | |||
# SonarQube 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. | |||
# | |||
# SonarQube 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. | |||
# | |||
require 'fastercsv' | |||
require "json" | |||
class Api::RulesController < Api::RestController | |||
def rest_call | |||
set_backward_compatibility_params | |||
language = params[:language] || '' | |||
options= {} | |||
options[:repositories]=params[:plugins].split(',') if params[:plugins] | |||
options[:language]=language | |||
options[:priorities]=params[:priorities].split(',') if params[:priorities] | |||
options[:activation]=params[:status] | |||
options[:searchtext]=params[:searchtext] | |||
options[:include_parameters_and_notes]=true | |||
options[:inheritance]=params[:inheritance] | |||
if params[:profile] | |||
profile = Profile.find_by_name_and_language(params[:profile], language) | |||
if profile.nil? | |||
rest_render([]) | |||
else | |||
options[:profile]=profile | |||
rules = Rule.search(java_facade, options) | |||
rest_render(rules, profile) | |||
end | |||
else | |||
rules = Rule.search(java_facade, options) | |||
rest_render(rules) | |||
end | |||
end | |||
def set_backward_compatibility_params | |||
params[:plugins]=params[:plugin] if params[:plugin] | |||
params[:priorities]=params[:levels] if params[:levels] | |||
end | |||
private | |||
def rest_render(rules=[], profile=nil) | |||
respond_to do |format| | |||
format.json{ render :json => rest_to_json(rules, profile) } | |||
format.xml { render :xml => rest_to_xml(rules, profile) } | |||
format.csv { | |||
send_data(rest_to_csv(rules, profile), | |||
:type => 'text/csv; charset=utf-8; header=present', | |||
:disposition => 'attachment; filename=rules.csv') | |||
} | |||
end | |||
end | |||
def rest_to_json(rules, profile) | |||
JSON(rules.collect{|rule| rule.to_hash_json(profile)}) | |||
end | |||
def rest_to_xml(rules, profile) | |||
xml = Builder::XmlMarkup.new(:indent => 0) | |||
xml.instruct! | |||
xml.rules do | |||
rules.each do |rule| | |||
rule.to_xml(profile, xml) | |||
end | |||
end | |||
end | |||
def rest_to_csv(rules, profile) | |||
FasterCSV.generate do |csv| | |||
header = ["title", "key", "plugin"] | |||
header.concat(["priority","status"]) if profile | |||
csv << header | |||
rules.each do |rule| | |||
csv << rule.to_csv(profile) | |||
end | |||
end | |||
end | |||
end |
@@ -186,7 +186,7 @@ class IssueController < ApplicationController | |||
verify_ajax_request | |||
require_parameters :id | |||
@rule = Internal.rules.findByKey(params[:id]) | |||
@rule = Internal.rules.getByKey(Java::OrgSonarApiRule::RuleKey.parse(params[:id])) | |||
if @rule.debtCharacteristicKey() | |||
@characteristic = Internal.debt.characteristicByKey(@rule.debtCharacteristicKey()) | |||
@sub_characteristic = Internal.debt.characteristicByKey(@rule.debtSubCharacteristicKey()) |
@@ -102,30 +102,6 @@ class RulesConfigurationController < ApplicationController | |||
@rule = Internal.quality_profiles.findByRule(params[:rule_id].to_i) | |||
end | |||
# | |||
# | |||
# POST /rules_configuration/create/<profile id>?rule_id=<rule id>&rule[name]=<new name>&... | |||
# | |||
# | |||
def create | |||
verify_post_request | |||
require_parameters :id, :rule_id | |||
profile_id = params[:id].to_i | |||
rule_id = params[:rule_id].to_i | |||
new_rule = nil | |||
call_backend do | |||
new_rule_id = Internal.rules.createCustomRule(rule_id, params[:rule][:name], params[:rule][:priority], params[:rule][:description], params[:rule_param]) | |||
new_rule = Internal.quality_profiles.findByRule(new_rule_id) | |||
end | |||
if new_rule | |||
redirect_to :action => 'index', :id => profile_id, :searchtext => "\"#{new_rule.name()}\"", :rule_activation => 'INACTIVE', "plugins[]" => new_rule.repositoryKey() | |||
else | |||
redirect_to :action => 'new', :id => profile_id, :rule_id => rule_id | |||
end | |||
end | |||
# deprecated since 2.3 | |||
def export | |||
@@ -154,46 +130,6 @@ class RulesConfigurationController < ApplicationController | |||
end | |||
end | |||
# | |||
# | |||
# POST /rules_configuration/update/<profile id>?rule_id=<rule id>&rule[name]=<new name>&... | |||
# | |||
# | |||
def update | |||
verify_post_request | |||
require_parameters :id, :rule_id | |||
profile_id = params[:id].to_i | |||
rule_id = params[:rule_id].to_i | |||
rule = nil | |||
call_backend do | |||
Internal.rules.updateCustomRule(rule_id, params[:rule][:name], params[:rule][:priority], params[:rule][:description], params[:rule_param]) | |||
rule = Internal.quality_profiles.findByRule(rule_id) | |||
end | |||
if rule | |||
redirect_to :action => 'index', :id => profile_id, :searchtext => "\"#{rule.name()}\"", :rule_activation => '', "plugins[]" => rule.repositoryKey() | |||
else | |||
redirect_to :action => 'new', :id => profile_id, :rule_id => rule_id | |||
end | |||
end | |||
# | |||
# | |||
# POST /rules_configuration/delete/<profile id>?rule_id=<rule id> | |||
# | |||
# | |||
def delete | |||
verify_post_request | |||
require_parameters :id, :rule_id | |||
call_backend do | |||
Internal.rules.deleteCustomRule(params[:rule_id].to_i) | |||
flash[:notice]=message('rules_configuration.rule_deleted') | |||
end | |||
redirect_to :action => 'index', :id => params[:id] | |||
end | |||
# | |||
# | |||
@@ -236,59 +172,6 @@ class RulesConfigurationController < ApplicationController | |||
redirect_to url_parameters | |||
end | |||
def update_param | |||
verify_post_request | |||
access_denied unless has_role?(:profileadmin) | |||
require_parameters :param_id, :active_rule_id, :profile_id | |||
rule = nil | |||
profile_id = params[:profile_id].to_i | |||
active_rule_id = params[:active_rule_id].to_i | |||
call_backend do | |||
Internal.quality_profiles.updateActiveRuleParam(active_rule_id, params[:param_id], params[:value]) | |||
rule = Internal.quality_profiles.findByActiveRuleId(active_rule_id) | |||
end | |||
profile = Internal.quality_profiles.profile(profile_id) | |||
parent_profile = Internal.quality_profiles.parent(profile) | |||
render :partial => 'rule', :locals => {:rule => rule, :profile => profile, :parent_profile => parent_profile} | |||
end | |||
def update_rule_note | |||
verify_post_request | |||
require_parameters :rule_id, :active_rule_id | |||
rule = nil | |||
call_backend do | |||
Internal.rules.updateRuleNote(params[:rule_id].to_i, params[:text]) | |||
rule = Internal.quality_profiles.findByActiveRuleId(params[:active_rule_id].to_i) | |||
end | |||
render :partial => 'rule_note', :locals => {:rule => rule} | |||
end | |||
def show_select_tags | |||
rule = Internal.quality_profiles.findByRule(params[:rule_id].to_i) | |||
tags = tag_selection_for_rule(rule) | |||
render :partial => 'select_tags', :locals => { :rule => rule, :tags => tags, :profile_id => params[:profile_id] } | |||
end | |||
def select_tags | |||
Internal.rules.updateRuleTags(params[:rule_id].to_i, params[:tags]) | |||
rule = Internal.quality_profiles.findByRule(params[:rule_id].to_i) | |||
render :partial => 'rule_tags', :locals => {:rule => rule} | |||
end | |||
def create_tag | |||
Internal.rule_tags.create(params[:new_tag]) | |||
rule = Internal.quality_profiles.findByRule(params[:rule_id].to_i) | |||
tags = tag_selection_for_rule(rule) | |||
render :partial => 'select_tags_list', :locals => {:tags => tags} | |||
end | |||
private | |||
def init_params |
@@ -79,7 +79,7 @@ class Internal | |||
end | |||
def self.rules | |||
component(Java::OrgSonarServerRule::RubyRuleService.java_class) | |||
component(Java::OrgSonarServerRule2::RuleService.java_class) | |||
end | |||
def self.durations |
@@ -256,34 +256,6 @@ class Rule < ActiveRecord::Base | |||
csv | |||
end | |||
# 'unused' parameter used to be available to inject java_facade, kept for compatibility w/ plugins (e.g sqale) | |||
# options :language => nil, :repositories => [], :searchtext => '', :profile => nil, :priorities => [], :activation => '', :status => [], :sort_by => nil | |||
def self.search(unused, options={}) | |||
# First, perform search with rule-specific criteria | |||
java_hash = {} | |||
options.each do |key, value| | |||
java_hash[key.to_s] = Array(value).join("|") | |||
end | |||
params = java.util.HashMap.new(java_hash) | |||
# SONAR-5048 Group results by 1000 due to fix issue on Oracle db | |||
rules = [] | |||
matching_rule_ids = Array(Internal.rules.findIds(params)) | |||
unless matching_rule_ids.empty? | |||
ids_grouped = matching_rule_ids.each_slice(1000).to_a | |||
ids_condition = [] | |||
ids_grouped.each do |group| | |||
ids_condition << 'id in (' + group.join(',') + ')' | |||
end | |||
includes=(options[:include_parameters_and_notes] ? [:rules_parameters] : nil) | |||
rules = Rule.all(:include => includes, :conditions => [ids_condition.join(' or ')]) | |||
rules = Rule.sort_by(rules, options[:sort_by]) | |||
end | |||
filter(rules, options) | |||
end | |||
def self.remove_blank(array) | |||
if array | |||
array = array - [''] |
@@ -1,21 +1,21 @@ | |||
<h1 class="marginbottom10"><%= h @rule.name %></h1> | |||
<h1 class="marginbottom10"><%= h @rule.name() -%></h1> | |||
<div class="marginbottom10"> | |||
<% if @rule.description.strip.start_with?('<p>') %> | |||
<%= Internal.text.interpretMacros(@rule.description) %> | |||
<% if @rule.htmlDescription.strip.start_with?('<p>') %> | |||
<%= Internal.text.interpretMacros(@rule.htmlDescription) %> | |||
<% else %> | |||
<p><%= Internal.text.interpretMacros(@rule.description) %></p> | |||
<p><%= Internal.text.interpretMacros(@rule.htmlDescription) %></p> | |||
<% end %> | |||
</div> | |||
<% if @rule.ruleNote() %> | |||
<% if @rule.noteAsMarkdown() %> | |||
<div class="marginbottom10"> | |||
<%= Api::Utils.markdown_to_html(@rule.ruleNote().data()) -%> | |||
<%= Api::Utils.markdown_to_html(@rule.noteAsMarkdown()) -%> | |||
</div> | |||
<% end %> | |||
<p class="note"> | |||
<span class="spacer-right"><%= h @rule.ruleKey() -%></span> | |||
<span class="spacer-right"><%= h @rule.key() -%></span> | |||
<%= image_tag 'sep12.png', :class => 'spacer-right' -%> | |||
<% if @characteristic && @sub_characteristic %> | |||
<%= @characteristic.name -%> > <%= @sub_characteristic.name -%> |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.server.rule; | |||
import com.google.common.collect.ImmutableList; | |||
import com.google.common.collect.ImmutableMap; | |||
import com.google.common.collect.Maps; | |||
import org.junit.Before; | |||
@@ -33,7 +32,6 @@ import org.sonar.api.rule.Severity; | |||
import java.util.Map; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
import static com.google.common.collect.Maps.newHashMap; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Mockito.verify; | |||
@@ -99,12 +97,6 @@ public class RubyRuleServiceTest { | |||
assertThat(ruleChange.debtRemediationOffset()).isEqualTo("10min"); | |||
} | |||
@Test | |||
public void update_rule_note() { | |||
facade.updateRuleNote(10, "My note"); | |||
verify(rules).updateRuleNote(10, "My note"); | |||
} | |||
@Test | |||
public void create_custom_rule() { | |||
facade.createCustomRule(10, "Rule name", Severity.MAJOR, "My note", ImmutableMap.of("max", "20")); | |||
@@ -129,40 +121,6 @@ public class RubyRuleServiceTest { | |||
verify(rules).findByKey(RuleKey.of("repo", "key")); | |||
} | |||
@Test | |||
public void find_by_params() { | |||
Map<String, Object> params = newHashMap(); | |||
params.put("searchQuery", "NPE"); | |||
params.put("key", "rule"); | |||
params.put("languages", newArrayList("java", "xoo")); | |||
params.put("repositories", newArrayList("pmd", "checkstyle")); | |||
params.put("severities", newArrayList("MINOR", "MAJOR")); | |||
params.put("statuses", newArrayList("READY", "BETA")); | |||
params.put("tags", newArrayList("has-params", "keep-enabled")); | |||
params.put("debtCharacteristics", newArrayList("MODULARITY", "REUSABILITY")); | |||
params.put("hasDebtCharacteristic", "true"); | |||
params.put("pageSize", 10l); | |||
params.put("pageIndex", 50); | |||
facade.find(params); | |||
ArgumentCaptor<RuleQuery> ruleQueryCaptor = ArgumentCaptor.forClass(RuleQuery.class); | |||
verify(rules).find(ruleQueryCaptor.capture()); | |||
RuleQuery query = ruleQueryCaptor.getValue(); | |||
assertThat(query.searchQuery()).isEqualTo("NPE"); | |||
assertThat(query.key()).isEqualTo("rule"); | |||
assertThat(query.languages()).containsOnly("java", "xoo"); | |||
assertThat(query.repositories()).containsOnly("pmd", "checkstyle"); | |||
assertThat(query.severities()).containsOnly("MINOR", "MAJOR"); | |||
assertThat(query.statuses()).containsOnly("READY", "BETA"); | |||
assertThat(query.tags()).containsOnly("has-params", "keep-enabled"); | |||
assertThat(query.debtCharacteristics()).containsOnly("MODULARITY", "REUSABILITY"); | |||
assertThat(query.hasDebtCharacteristic()).isTrue(); | |||
assertThat(query.pageSize()).isEqualTo(10); | |||
assertThat(query.pageIndex()).isEqualTo(50); | |||
} | |||
@Test | |||
public void just_for_fun_and_coverage() throws Exception { | |||
facade.start(); |
@@ -1,136 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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.ImmutableList; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.junit.runner.RunWith; | |||
import org.mockito.ArgumentCaptor; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.api.resources.Language; | |||
import org.sonar.api.resources.Languages; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.server.debt.DebtRemediationFunction; | |||
import org.sonar.api.server.debt.internal.DefaultDebtRemediationFunction; | |||
import org.sonar.server.ws.WsTester; | |||
import org.sonar.server.paging.PagedResult; | |||
import org.sonar.server.paging.PagingResult; | |||
import org.sonar.server.rule.Rule; | |||
import org.sonar.server.rule.RuleQuery; | |||
import org.sonar.server.rule.Rules; | |||
import org.sonar.server.user.MockUserSession; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Mockito.*; | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class RuleSearchWsHandlerTest { | |||
@Mock | |||
Rules rules; | |||
@Mock | |||
Languages languages; | |||
Rule.Builder ruleBuilder = new Rule.Builder() | |||
.setKey("AvoidCycle") | |||
.setRepositoryKey("squid") | |||
.setName("Avoid cycle") | |||
.setDescription("Avoid cycle between packages") | |||
.setLanguage("java") | |||
.setStatus("READY") | |||
.setDebtCharacteristicKey("REUSABILITY") | |||
.setDebtSubCharacteristicKey("MODULARITY") | |||
.setDebtRemediationFunction(new DefaultDebtRemediationFunction(DebtRemediationFunction.Type.LINEAR_OFFSET, "1h", "15min")); | |||
WsTester tester; | |||
@Before | |||
public void setUp() throws Exception { | |||
tester = new WsTester(new RulesWs(new RuleSearchWsHandler(rules, languages), mock(RuleShowWsHandler.class))); | |||
} | |||
@Test | |||
public void search_rules() throws Exception { | |||
final int pageSize = 10; | |||
final int pageIndex = 2; | |||
Rule rule = ruleBuilder.build(); | |||
when(rules.find(any(RuleQuery.class))).thenReturn( | |||
new PagedResult<Rule>(ImmutableList.of(rule), PagingResult.create(pageSize, pageIndex, 1))); | |||
Language lang = mock(Language.class); | |||
when(lang.getName()).thenReturn("Java"); | |||
when(languages.get("java")).thenReturn(lang); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "list").setParam("ps", "10").setParam("p", "2"); | |||
request.execute().assertJson(getClass(), "search_rules.json"); | |||
} | |||
@Test | |||
public void search_rule_by_key() throws Exception { | |||
String ruleKey = "squid:AvoidCycle"; | |||
Rule rule = ruleBuilder.build(); | |||
when(rules.findByKey(RuleKey.parse(ruleKey))).thenReturn(rule); | |||
Language lang = mock(Language.class); | |||
when(lang.getName()).thenReturn("Java"); | |||
when(languages.get("java")).thenReturn(lang); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "list").setParam("k", ruleKey); | |||
request.execute().assertJson(getClass(), "search_rules.json"); | |||
} | |||
@Test | |||
public void verify_rule_query_filters() throws Exception { | |||
Rule rule = ruleBuilder.build(); | |||
when(rules.find(any(RuleQuery.class))).thenReturn( | |||
new PagedResult<Rule>(ImmutableList.of(rule), PagingResult.create(10, 1, 1))); | |||
MockUserSession.set(); | |||
tester.newGetRequest("api/rules", "list") | |||
.setParam("languages", "java,js") | |||
.setParam("repositories", "squid,pmd") | |||
.setParam("severities", "MAJOR,MINOR") | |||
.setParam("statuses", "READY,BETA") | |||
.setParam("tags", "has-params,integration-tests") | |||
.setParam("debtCharacteristics", "MODULARITY,REUSABILITY") | |||
.setParam("hasDebtCharacteristic", "true") | |||
.execute(); | |||
ArgumentCaptor<RuleQuery> ruleQueryCaptor = ArgumentCaptor.forClass(RuleQuery.class); | |||
verify(rules).find(ruleQueryCaptor.capture()); | |||
assertThat(ruleQueryCaptor.getValue().languages()).containsOnly("java", "js"); | |||
assertThat(ruleQueryCaptor.getValue().repositories()).containsOnly("squid", "pmd"); | |||
assertThat(ruleQueryCaptor.getValue().severities()).containsOnly("MAJOR", "MINOR"); | |||
assertThat(ruleQueryCaptor.getValue().statuses()).containsOnly("READY", "BETA"); | |||
assertThat(ruleQueryCaptor.getValue().tags()).containsOnly("has-params", "integration-tests"); | |||
assertThat(ruleQueryCaptor.getValue().debtCharacteristics()).containsOnly("MODULARITY", "REUSABILITY"); | |||
assertThat(ruleQueryCaptor.getValue().hasDebtCharacteristic()).isTrue(); | |||
} | |||
} |
@@ -1,206 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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.ImmutableList; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import org.junit.runner.RunWith; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.api.i18n.I18n; | |||
import org.sonar.api.resources.Language; | |||
import org.sonar.api.resources.Languages; | |||
import org.sonar.api.rule.RuleKey; | |||
import org.sonar.api.rules.RuleFinder; | |||
import org.sonar.server.ws.WsTester; | |||
import org.sonar.api.utils.DateUtils; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import org.sonar.server.rule.Rule; | |||
import org.sonar.server.rule.RuleNote; | |||
import org.sonar.server.rule.Rules; | |||
import org.sonar.server.user.MockUserSession; | |||
import java.util.Date; | |||
import java.util.Locale; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
import static org.fest.assertions.Fail.fail; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.eq; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class RuleShowWsHandlerTest { | |||
@Mock | |||
Rules rules; | |||
@Mock | |||
Languages languages; | |||
@Mock | |||
RuleFinder ruleFinder; | |||
@Mock | |||
I18n i18n; | |||
Rule.Builder ruleBuilder = new Rule.Builder() | |||
.setKey("AvoidCycle") | |||
.setRepositoryKey("squid") | |||
.setName("Avoid cycle") | |||
.setLanguage("xoo") | |||
.setDescription("Avoid cycle between packages"); | |||
WsTester tester; | |||
@Before | |||
public void setUp() throws Exception { | |||
tester = new WsTester(new RulesWs(mock(RuleSearchWsHandler.class), new RuleShowWsHandler(rules, ruleFinder, i18n, languages))); | |||
} | |||
@Test | |||
public void show_rule() throws Exception { | |||
String ruleKey = "squid:AvoidCycle"; | |||
Rule rule = ruleBuilder.build(); | |||
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule); | |||
Language language = mock(Language.class); | |||
when(language.getName()).thenReturn("Xoo"); | |||
when(languages.get("xoo")).thenReturn(language); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey); | |||
request.execute().assertJson(getClass(), "show_rule.json"); | |||
} | |||
@Test | |||
public void return_not_found_on_unknown_rule() throws Exception { | |||
String ruleKey = "squid:AvoidCycle"; | |||
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(null); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey); | |||
try { | |||
request.execute(); | |||
fail(); | |||
} catch (Exception e) { | |||
assertThat(e).isInstanceOf(NotFoundException.class); | |||
} | |||
} | |||
@Test | |||
public void show_rule_with_dates() throws Exception { | |||
Date date1 = DateUtils.parseDateTime("2014-01-22T19:10:03+0100"); | |||
Date date2 = DateUtils.parseDateTime("2014-01-23T19:10:03+0100"); | |||
Rule rule = ruleBuilder | |||
.setCreatedAt(date1) | |||
.setUpdatedAt(date2) | |||
.build(); | |||
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule); | |||
when(i18n.formatDateTime(any(Locale.class), eq(date1))).thenReturn("Jan 22, 2014 10:03 AM"); | |||
when(i18n.formatDateTime(any(Locale.class), eq(date2))).thenReturn("Jan 23, 2014 10:03 AM"); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", rule.ruleKey().toString()); | |||
request.execute().assertJson(getClass(), "show_rule_with_dates.json"); | |||
} | |||
@Test | |||
public void show_rule_with_note() throws Exception { | |||
RuleNote note = mock(RuleNote.class); | |||
when(note.data()).thenReturn("*Extended rule description*"); | |||
Rule rule = ruleBuilder | |||
.setRuleNote(note) | |||
.build(); | |||
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", rule.ruleKey().toString()); | |||
request.execute().assertJson(getClass(), "show_rule_with_note.json"); | |||
} | |||
@Test | |||
public void show_rule_with_tags() throws Exception { | |||
Rule rule = ruleBuilder | |||
.setAdminTags(ImmutableList.of("complexity")) | |||
.setSystemTags(ImmutableList.of("security")) | |||
.build(); | |||
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(rule); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", rule.ruleKey().toString()); | |||
request.execute().assertJson(getClass(), "show_rule_with_tags.json"); | |||
} | |||
@Test | |||
public void show_manual_rule() throws Exception { | |||
String ruleKey = "manual:api"; | |||
when(ruleFinder.findByKey(RuleKey.of("manual", "api"))).thenReturn( | |||
org.sonar.api.rules.Rule.create("manual", "api", "API").setDescription("API rule description")); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey); | |||
request.execute(); | |||
request.execute().assertJson(getClass(), "show_manuel_rule.json"); | |||
} | |||
@Test | |||
public void show_manual_rule_without_severity() throws Exception { | |||
String ruleKey = "manual:api"; | |||
org.sonar.api.rules.Rule rule = mock(org.sonar.api.rules.Rule.class); | |||
when(rule.getKey()).thenReturn("api"); | |||
when(rule.getRepositoryKey()).thenReturn("manual"); | |||
when(rule.getName()).thenReturn("API"); | |||
when(rule.getDescription()).thenReturn("API rule description"); | |||
when(rule.getSeverity()).thenReturn(null); | |||
when(ruleFinder.findByKey(RuleKey.of("manual", "api"))).thenReturn(rule); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey); | |||
request.execute(); | |||
request.execute().assertJson(getClass(), "show_manuel_rule.json"); | |||
} | |||
@Test | |||
public void return_not_found_on_unknown_manual_rule() throws Exception { | |||
String ruleKey = "manual:api"; | |||
when(rules.findByKey(RuleKey.of("squid", "AvoidCycle"))).thenReturn(null); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = tester.newGetRequest("api/rules", "show").setParam("key", ruleKey); | |||
try { | |||
request.execute(); | |||
fail(); | |||
} catch (Exception e) { | |||
assertThat(e).isInstanceOf(NotFoundException.class); | |||
} | |||
} | |||
} |
@@ -1,71 +0,0 @@ | |||
/* | |||
* SonarQube, open source software quality management tool. | |||
* Copyright (C) 2008-2014 SonarSource | |||
* mailto:contact AT sonarsource DOT com | |||
* | |||
* SonarQube 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. | |||
* | |||
* SonarQube 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 org.junit.Before; | |||
import org.junit.Test; | |||
import org.junit.runner.RunWith; | |||
import org.mockito.Mock; | |||
import org.mockito.runners.MockitoJUnitRunner; | |||
import org.sonar.api.server.ws.WebService; | |||
import org.sonar.server.ws.WsTester; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
@RunWith(MockitoJUnitRunner.class) | |||
public class RulesWsTest { | |||
@Mock | |||
RuleSearchWsHandler searchHandler; | |||
@Mock | |||
RuleShowWsHandler showHandler; | |||
WsTester tester; | |||
@Before | |||
public void setUp() { | |||
tester = new WsTester(new RulesWs(searchHandler, showHandler)); | |||
} | |||
@Test | |||
public void define_ws() throws Exception { | |||
WebService.Controller controller = tester.controller("api/rules"); | |||
assertThat(controller).isNotNull(); | |||
assertThat(controller.path()).isEqualTo("api/rules"); | |||
assertThat(controller.description()).isNotEmpty(); | |||
assertThat(controller.actions()).hasSize(2); | |||
WebService.Action list = controller.action("list"); | |||
assertThat(list).isNotNull(); | |||
assertThat(list.handler()).isNotNull(); | |||
assertThat(list.since()).isEqualTo("4.3"); | |||
assertThat(list.isPost()).isFalse(); | |||
assertThat(list.isInternal()).isTrue(); | |||
assertThat(list.params()).hasSize(11); | |||
WebService.Action show = controller.action("show"); | |||
assertThat(show).isNotNull(); | |||
assertThat(show.handler()).isNotNull(); | |||
assertThat(show.since()).isEqualTo("4.2"); | |||
assertThat(show.isPost()).isFalse(); | |||
assertThat(show.isInternal()).isFalse(); | |||
} | |||
} |
@@ -123,10 +123,12 @@ public class RegisterRulesTest extends AbstractDaoTestCase { | |||
execute(new FakeRepositoryV1()); | |||
assertThat(dbClient.ruleDao().findAll(dbSession)).hasSize(2); | |||
// user adds tags | |||
// user adds tags and sets markdown note | |||
RuleKey ruleKey1 = RuleKey.of("fake", "rule1"); | |||
RuleDto rule1 = dbClient.ruleDao().getByKey(ruleKey1, dbSession); | |||
rule1.setTags(Sets.newHashSet("usertag1", "usertag2")); | |||
rule1.setNoteData("user *note*"); | |||
rule1.setNoteUserLogin("marius"); | |||
dbClient.ruleDao().update(rule1, dbSession); | |||
dbSession.commit(); | |||
@@ -141,6 +143,8 @@ public class RegisterRulesTest extends AbstractDaoTestCase { | |||
assertThat(rule1.getTags()).containsOnly("usertag1", "usertag2"); | |||
assertThat(rule1.getSystemTags()).containsOnly("tag1", "tag4"); | |||
assertThat(rule1.getConfigKey()).isEqualTo("config1 v2"); | |||
assertThat(rule1.getNoteData()).isEqualTo("user *note*"); | |||
assertThat(rule1.getNoteUserLogin()).isEqualTo("marius"); | |||
assertThat(rule1.getStatus()).isEqualTo(RuleStatus.READY.toString()); | |||
assertThat(rule1.getCreatedAt()).isEqualTo(DATE1); | |||
assertThat(rule1.getUpdatedAt()).isEqualTo(DATE2); |
@@ -17,7 +17,23 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
@ParametersAreNonnullByDefault | |||
package org.sonar.server.rule.ws; | |||
package org.sonar.server.rule2.index; | |||
import javax.annotation.ParametersAreNonnullByDefault; | |||
import org.junit.Test; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class RuleFieldTest { | |||
@Test | |||
public void all_rule_fields() throws Exception { | |||
assertThat(RuleNormalizer.RuleField.ALL_KEYS).contains( | |||
RuleNormalizer.RuleField.KEY.key(), RuleNormalizer.RuleField.REPOSITORY.key(), RuleNormalizer.RuleField.TAGS.key(), | |||
RuleNormalizer.RuleField.CREATED_AT.key()); | |||
} | |||
@Test | |||
public void key_of_rule_field() throws Exception { | |||
assertThat(RuleNormalizer.RuleField.INTERNAL_KEY.key()).isEqualTo("internalKey"); | |||
} | |||
} |
@@ -21,6 +21,7 @@ package org.sonar.server.rule2.index; | |||
import com.google.common.collect.ImmutableSet; | |||
import com.google.common.collect.Iterables; | |||
import com.google.common.collect.Sets; | |||
import org.junit.After; | |||
import org.junit.Before; | |||
import org.junit.ClassRule; | |||
@@ -66,7 +67,7 @@ public class RuleIndexMediumTest { | |||
} | |||
@Test | |||
public void insert_rule() throws InterruptedException { | |||
public void getByKey() throws InterruptedException { | |||
RuleDto ruleDto = newRuleDto(RuleKey.of("javascript", "S001")); | |||
dao.insert(ruleDto, dbSession); | |||
dbSession.commit(); | |||
@@ -78,21 +79,23 @@ public class RuleIndexMediumTest { | |||
assertThat(rule.htmlDescription()).isEqualTo(ruleDto.getDescription()); | |||
assertThat(rule.key()).isEqualTo(ruleDto.getKey()); | |||
// | |||
// assertThat(rule.debtSubCharacteristicKey()) | |||
// .isEqualTo(ruleDto.getDefaultSubCharacteristicId().toString()); | |||
assertThat(rule.debtRemediationFunction().type().name()) | |||
.isEqualTo(ruleDto.getRemediationFunction()); | |||
assertThat(Sets.newHashSet(rule.tags())).isEqualTo(ruleDto.getTags()); | |||
assertThat(Sets.newHashSet(rule.systemTags())).isEqualTo(ruleDto.getSystemTags()); | |||
} | |||
// | |||
// assertThat(rule.tags()).containsExactly(ruleDto.getTags()); | |||
// assertThat(rule.systemTags()).containsExactly(ruleDto.getSystemTags()); | |||
@Test | |||
public void getByKey_null_if_not_found() throws InterruptedException { | |||
Rule rule = index.getByKey(RuleKey.of("javascript", "unknown")); | |||
assertThat(rule).isNull(); | |||
} | |||
@Test | |||
public void facet_test_with_repository() { | |||
dao.insert(newRuleDto(RuleKey.of("javascript", "S001")).setRuleKey("X001"), dbSession); | |||
@@ -135,7 +138,6 @@ public class RuleIndexMediumTest { | |||
@Test | |||
@Ignore | |||
//TODO discuss if enforced in WS only. | |||
public void select_doc_fields_to_return() { | |||
dao.insert(newRuleDto(RuleKey.of("javascript", "S001")), dbSession); | |||
dbSession.commit(); | |||
@@ -367,7 +369,7 @@ public class RuleIndexMediumTest { | |||
// tag1 in query | |||
query = new RuleQuery().setQueryText("tag1"); | |||
assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); | |||
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(),null).tags()).containsExactly("tag1"); | |||
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag1"); | |||
// tag1 and tag2 in query | |||
query = new RuleQuery().setQueryText("tag1 tag2"); | |||
@@ -376,7 +378,7 @@ public class RuleIndexMediumTest { | |||
// tag2 in filter | |||
query = new RuleQuery().setTags(ImmutableSet.of("tag2")); | |||
assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); | |||
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(),null).tags()).containsExactly("tag2"); | |||
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag2"); | |||
// tag2 in filter and tag1 tag2 in query | |||
query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1"); | |||
@@ -385,7 +387,7 @@ public class RuleIndexMediumTest { | |||
// tag2 in filter and tag1 in query | |||
query = new RuleQuery().setTags(ImmutableSet.of("tag2")).setQueryText("tag1 tag2"); | |||
assertThat(index.search(query, new QueryOptions()).getHits()).hasSize(1); | |||
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(),null).tags()).containsExactly("tag2"); | |||
assertThat(Iterables.getFirst(index.search(query, new QueryOptions()).getHits(), null).tags()).containsExactly("tag2"); | |||
// null list => no filter | |||
query = new RuleQuery().setTags(Collections.<String>emptySet()); |
@@ -105,6 +105,6 @@ public class AppActionTest { | |||
char2.setId(24).setParentId(parentId).setKey("MODULARITY").setName("Modularity"); | |||
when(debtModel.allCharacteristics()).thenReturn(ImmutableList.<DebtCharacteristic>of(char1, char2)); | |||
tester.newGetRequest("api/rules2", "app").execute().assertJson(this.getClass(), "app.json"); | |||
tester.newGetRequest("api/rules", "app").execute().assertJson(this.getClass(), "app.json"); | |||
} | |||
} |
@@ -83,7 +83,7 @@ public class RulesWebServiceTest { | |||
WebService.Context context = new WebService.Context(); | |||
ws.define(context); | |||
WebService.Controller controller = context.controller("api/rules2"); | |||
WebService.Controller controller = context.controller("api/rules"); | |||
assertThat(controller).isNotNull(); | |||
assertThat(controller.actions()).hasSize(6); | |||
@@ -99,7 +99,7 @@ public class RulesWebServiceTest { | |||
public void search_no_rules() throws Exception { | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search"); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search"); | |||
WsTester.Result result = request.execute(); | |||
@@ -115,7 +115,7 @@ public class RulesWebServiceTest { | |||
tester.get(RuleService.class).refresh(); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search"); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search"); | |||
WsTester.Result result = request.execute(); | |||
String json = result.outputAsString(); | |||
@@ -137,7 +137,7 @@ public class RulesWebServiceTest { | |||
tester.get(RuleService.class).refresh(); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search"); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search"); | |||
WsTester.Result result = request.execute(); | |||
result.assertJson(this.getClass(),"search_debt_rule.json"); | |||
@@ -161,7 +161,7 @@ public class RulesWebServiceTest { | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search"); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search"); | |||
request.setParam("q","S001"); | |||
WsTester.Result result = request.execute(); | |||
@@ -208,7 +208,7 @@ public class RulesWebServiceTest { | |||
tester.get(RuleService.class).refresh(); | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "search"); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "search"); | |||
request.setParam("q", "S001"); | |||
WsTester.Result result = request.execute(); | |||
@@ -236,7 +236,7 @@ public class RulesWebServiceTest { | |||
MockUserSession.set(); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules2", "tags"); | |||
WsTester.TestRequest request = wsTester.newGetRequest("api/rules", "tags"); | |||
WsTester.Result result = request.execute(); | |||
result.assertJson(this.getClass(),"get_tags.json"); |